1

I want to add the following call of method "send()" to a smali method:

invoke-direct {p0}, X->send()V

send() is a method of the current class. X is a wildcard for the current class name. Now i have two unresolved problems:

  1. Why does invoke-direct need register p0? I thought this was a parameter.

  2. Do i have take into consideration the p0 register? Is it possible that this additional code makes the entire app not compile if i just keep it? If so, how can i find out which register must be used?

I want to add this method call to an arbitrary method. I don't know the method structure and can't predict any register usage. Therefore I need to know exactly if p0 in the upper code can change and under which conditions.

I provide a simple example to emphasize my intention:

Let's assume we have this method that just reads the contacts that are saved on your smartphone:

.method private getContacts()Ljava/util/ArrayList;
.locals 12
.annotation system Ldalvik/annotation/Signature;
value = {
"()",
"Ljava/util/ArrayList",
"<",
"Ljava/lang/String;",
">;"
}
.end annotation
.prologue
const/4 v2, 0x0
.line 43
new-instance v7, Ljava/util/ArrayList;
invoke-direct {v7}, Ljava/util/ArrayList;-><init>()V
.line 44
.local v7, "contacts":Ljava/util/ArrayList;, "Ljava/util/ArrayList<Ljava/lang/String;>;"
invoke-virtual {p0}, Lorg/puellen/contacts/MainActivity;->getContentResolver()Landroid/content/ContentResolver;
move-result-object v0
sget-object v1, Landroid/provider/ContactsContract$Contacts;->CONTENT_URI:Landroid/net/Uri;
move-object v3, v2
move-object v4, v2
move-object v5, v2
...

I wrote a parser which automatically extracts this code from an .apk file. Now i want to extend the methods functionality, by adding the upper method call.

In this case i can simply add the call at the beginning. The only difference appears in line 13 (see comment)

.method private getContacts()Ljava/util/ArrayList;
.locals 12
.annotation system Ldalvik/annotation/Signature;
value = {
"()",
"Ljava/util/ArrayList",
"<",
"Ljava/lang/String;",
">;"
}
.end annotation
.prologue
invoke-direct {p0}, Lorg/my_package/custom_class/MainActivity;->send()V # added method call
const/4 v2, 0x0
.line 43
new-instance v7, Ljava/util/ArrayList;
invoke-direct {v7}, Ljava/util/ArrayList;-><init>()V
.line 44
.local v7, "contacts":Ljava/util/ArrayList;, "Ljava/util/ArrayList<Ljava/lang/String;>;"
invoke-virtual {p0}, Lorg/puellen/contacts/MainActivity;->getContentResolver()Landroid/content/ContentResolver;
move-result-object v0
sget-object v1, Landroid/provider/ContactsContract$Contacts;->CONTENT_URI:Landroid/net/Uri;
move-object v3, v2
move-object v4, v2
move-object v5, v2

Until know i just add the method call after .prologue. But i am sure that this behaviour does not work always. Is there a "perfect" place to add the call? Can i always use p0 in "invoke-direct" or how do i find out what register can be used?


Question: Can i always use p0 in "invoke-direct" or how do i find out what register can be used?

Answer: "The first parameter to a non-static methods is always the object that the method is being invoked on." (link see blow in first comment). As my method is not static, i can use always p0

Now i only need to know where to place the method call.

null
  • 1,369
  • 2
  • 18
  • 38
  • if you could show a little more context codewise it may be easier to help you. Could you show an example of where you want to add that call? The p0 parameters are dependant from the method you are calling and how many local registers are being allocated. This may help: https://code.google.com/p/smali/wiki/Registers – XFCC Dec 01 '14 at 14:15
  • the p0 register references X in that code but, as i said in the previous comment, it depends on your method. – XFCC Dec 01 '14 at 14:17
  • I just improved my question. Maybe it became clearer and you can help me out ;) – null Dec 02 '14 at 14:06

0 Answers0