For every instance (virtual, non-static) method in Dalvik, the first parameter is a reference to itself, or, in Java, the
this reference. I wanted to know if it was legal to reassign the register value.
Just so I’m sure you know what I’m talking about, here’s a simple Java class with an instance method called
The above Smali gets turned into this (you can safely ignore the
For more information on how to convert Java to Smali, check out: Understanding Dalvik Static Fields 1 of 2 and Building with and Detecting Android’s Jack Compiler.
PROTIP: If your decompilation looks different than mine, it may be because mine was generated using
baksmali --use-locals which separates the registers into those registers used within the method body (locals) and those passed as parameters. Local registers are named
v2, and so on and the parameters are named
p1, etc. I always use
--use-locals because it makes it a bit easier to visually distinguish between local method registers and method arguments.
The default behavior is to name all registers based on how they’re actually laid out by Dalvik:
r2 and so on, regardless of if they’re local or parameters. To clarify, a method like this:
Has a register layout like this:
r2- local registers
Jparameter (wide types use two registers)
I wondered if
p0 was somehow special and if it was possible to rewrite it. One of the optimizers I’m working on needs to rewrite Smali, and it works best if it knows all of the available registers at a certain point in code. A register is “available” if it’s not used for the rest of the execution. If you’ve ever written a tool to automatically modify Smali, you have probably run into this problem.
p0 is not special and it is possible to reassign!
Here’s the code I used to test:
And then to compile and run it:
The test code outputs the expected
5 with no errors or warnings. It makes sense that a register should be able to hold a reference to anything, but the only way to be absolutely sure (without closely examining the source) is to test it.
Now you know the
p0 register can be re-purposed within code, but more importantly you’ve hopefully also picked up some techniques for testing hypotheses. If you’re doing a lot of low-level Smali analysis, it’s really handy to know how to translate Java to Smali and how to execute DEX files directly on the command line.