I have been trying to reverse engineer an Android application and was wondering how I would go about logging a certain string. Here is the method I am trying to log the String from:

.method private getValue(Ljava/lang/String;)[B
.locals 2
.param p1, "parameter"    # Ljava/lang/String;

.line 216
new-instance v0, Ljava/lang/StringBuilder;

invoke-direct {v0}, Ljava/lang/StringBuilder;-><init>()V

iget-object v1, p0, Lcom/directory/theseSettings;->newSettings:Lcom/directory/NewSettings;

iget-object v1, v1, Lcom/directory/NewSettings;->newValue:Ljava/lang/String;

invoke-virtual {v0, v1}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder;

move-result-object v0

invoke-virtual {v0, p1}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder;

move-result-object v0

invoke-virtual {v0}, Ljava/lang/StringBuilder;->toString()Ljava/lang/String;

move-result-object v0

const-string v1, "UTF-8"

invoke-static {v0, v1}, Lorg/apache/http/util/EncodingUtils;->getBytes(Ljava/lang/String;Ljava/lang/String;)[B

move-result-object v0

return-object v0
.end method

For reference, here is that method again when decompiled with jadx.

private byte[] getValue(String parameter) {
    return EncodingUtils.getBytes(this.newSettings.newValue + parameter, "UTF-8");

I was hoping to log “this.newSettings.newValue” as seen in the jadx method, and I’m guessing it would be:

iget-object v1, v1, Lcom/directory/NewSettings;->newValue:Ljava/lang/String;

In the smali.

The only problem is I don’t know how to log it, I am able to log “parameter” by using

const-string v0, “PARAMETER:” 
invoke-static {v0, p1}, Landroid/util/Log;->e(Ljava/lang/String;Ljava/lang/String;)I 

But I’m not sure how to go about it if its referenced within the method, rather than being "passed" to it.


In Dalvik, intermediate values are stored in "registers", which you can think of as being like local variables, except that they are numbered instead of named and they can have different types at different points in the method.

When you write

const-string v0, “PARAMETER:” 
invoke-static {v0, p1}, Landroid/util/Log;->e(Ljava/lang/String;Ljava/lang/String;)I

the code does two things. First it stores the literal string "PARAMETER:" in register 0 (referred to as v0) and then passes the values in registers v0 and p1 as the arguments to Log.e().

At the bytecode level, registers are just a flat array, but the last few registers are special because that is where the parameters are passed upon entry to the method. Therefore, Smali provides syntax sugar for dealing with parameters. In this case, there are two local variables, so the parameters start at register 2. p0 is just an alias for v2 and p1 is just an alias for v3.

Note: by convention, the parameter registers are left untouched, but they are registers like any others, and you can store different things in them if you want to. The reason your code works is because p1 contains the second parameter at the start of the method (the first parameter, this, is stored in p0), and nothing stores to it, so it still contains the value you want when control reaches your log statement.

Anyway, it's not any different if you want to log the value in a different register, you just name a different register as the argument to Log.e(). In this case, the value you want is stored in register 1, so you should do

invoke-static {v0, v1}, Landroid/util/Log;->e(Ljava/lang/String;Ljava/lang/String;)I

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.