Why
While working on a new class loading system for SmaliVM, I needed to understand exactly how DalvikVM handles the case of a DEX file including a system / framework class such as Ljava/lang/Object;
. I’d originally assumed, naively, in retrospect, that class files in a DEX file should take precedence. Thinking about this for a half second, I have no idea what the hell I was thinking. That would be stupid.
If Dalvik let apps redefine framework classes, it has huge security implications. Sure, each app runs it its own zygote-spawned sandbox, but what if somewhere, somehow, my malicious app’s DEX file was loaded by an app with system or root access? I could just backdoor Ljava/lang/Object;
. Even if that’s not possible, I’m sure I could think of something nefarious if you gave me the ability to backdoor any class.
Well, derp, so now I have to rewrite part of Simplify and (hopefully) fix some tests. I might as well know exactly how it fails and document it for other researchers, right?
How
First, I created two small Smali files.
smali/hello.smali:
1 | .class public LHelloWorld; |
The purpose of this is just to provide a main(String[])
method and to have Object
as a super
.
smali/object.smali:
1 | .class Ljava/lang/Object; |
This is the real test. If I can overwrite framework classes, I should get a lot of errors, duh, but not before <clinit>
prints out something witty.
After that, it was just packing it up and shoving it onto an emulator:
1 | $ smali smali -o classes.dex |
I’ll also wanted to see the error explosions in the logs. You’d be surprised how many people have an app crash or something and don’t bother looking at the logs. monitor
is your friend. It usually has bad news, and confuses Eclipse and IntelliJ if it’s running, but at least it’s honest.
1 | $ monitor &disown |
Finally, just invoke dalvikvm
with our ZIP as the classpath:
1 | $ adb shell |
No "crazyballs"
, so I guess my hunch was right. I wonder what the error looked like?
1 | 12-21 11:07:22.035: D/dalvikvm(1065): DexOpt: --- BEGIN 'hello.zip' (bootstrap=0) --- |
If you read between the lines, the actual error message is “has an earlier definition; blocking out (idiot)”.