Sunday, September 26, 2010

example.smali

this is a basic example of smali code with some comments. view it with ultraedit and syntax highlighting to get the full effect. this file is also included and updated in lesson 0 of the way of the android cracker.

for reference of dalvik opcodes, visit Dalvik opcodes.

update: if you like this, you may also want to see some example structures.

update #2:  threw in a little bit about primitives and arrays.

# class name, also determines file path when dumped
.class public Lcom/packageName/example;

# inherits from Object (could be activity, view, etc.)
# note class structure is L;
.super Ljava/lang/Object;

# original java file name
.source "example.java"


# these are class instance variables
.field private someString:Ljava/lang/String;

# finals are not actually used directly, because references
# to them are replaced by the value itself
# primitive cheat sheet:
# V - void, B - byte, S - short, C - char, I - int
# J - long (uses two registers), F - float, D - double
.field public final someInt:I  # the :I means integer
.field public final someBool:Z # the :Z means boolean

# Do you see how to make arrays?
.field public final someCharArray:[C
.field private someStringArray:[Ljava/lang/String;


# this is the <init> of the constructor
# it calls the <init> of it's super, which in this case
# is Ljava/lang/Object; as you can see at the top
# the parameter list reads: ZLjava/lang/String;I
# Z - boolean
# Ljava/lang/String; - java String object
#   (semi-colon after non-primitive data types)
# I - integer
#   (no semi-colon)
# also notice this constructor returns V, which means void
.method public constructor <init>(ZLjava/lang/String;I)V
 # declare how many variable spaces we will need
 # we can have: v0, v1, v2, v3, v4 and v5 as variables.
 # smali/baksmali by default uses .registers
 # but you can change this by using --use-locals
 # apktool uses --use-locals and --sequential-labels
 .locals 6

 # these are not always present and are usuaully taken
 # out by optimization/obfuscation but they tell us
 # the names of Z, Ljava/lang/String; and I before
 # when it was in Java
 .parameter "someBool"
 .parameter "someInt"
 .parameter "exampleString"
 
 # the .prologue and .line directives can be mostly ignored
 # sometimes line numbers are useful for debugging errors
 .prologue
 .line 10
 
 # p0 means parameter 0
 # p0, in this case, is like "this" from a java class.
 # we are calling the constructor of our mother class.
 # what would p1 be?
 invoke-direct {p0}, Ljava/lang/Object;-><init>()V
 
 # store string in v0
 const-string v0, "i will not fear. fear is the mind-killer."
 
 # store 0xF hex value in v0 (or 15 in base 10)
 # this destroys previous value string in v0
 # variables do not have types they are just registers
 # for storing any type of value.
 # hexadecimal is base 15 is used in all machine languages
 # you normally use base 10
 # read up on it:
 # http://en.wikipedia.org/wiki/Hexadecimal
 const/4 v0, 0xF
 
 # create instance of StringBuilder in v1
 new-instance v1, Ljava/lang/StringBuilder;
 
 # initialize StringBuilder with v2
 # notice it returns V, or void
 const-string v2, "the spice must flow"
 invoke-direct {v1, v2}, Ljava/lang/StringBuilder;-><init>(Ljava/lang/String;)V
 
 # append p1, which is our first paramater and is boolean
 # therefore we use append(Z)
 # notice how append returns a StringBuilder
 invoke-virtual {v1, p1}, Ljava/lang/StringBuilder;->append(Z)Ljava/lang/StringBuilder;
 
 # use move-result-object to store previous result in v1
 move-result-object v1
 # non-objects use move-result or move-result-wide

 # append v2 to our StringBuilder
 # notice how this append takes a string and not Z
 const-string v2, "some random string"
 invoke-virtual {v1, v2}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder;
 move-result-object v1
  
 # call toString() on our StringBuilder
 # if you use Java you know that most objects have toString()
 invoke-virtual {v1}, Ljava/lang/StringBuilder;->toString()Ljava/lang/String;
 move-result-object v1
 
 # send our new string to the log.
 # this can be used to debug and can be picked up with ddms, logcat
 # or log collector. as an exercise look up what the d() function does
 # in the android developer documentation.
 const-string v0, "Tag"
 invoke-static {v0, v1}, Landroid/util/Log;->d(Ljava/lang/String;Ljava/lang/String;)I
 move-result v0
 
 # get the current time in milliseconds
 # J denotes a float or wide return value
 invoke-static {}, Ljava/lang/System;->currentTimeMillis()J
 move-result-wide v2
 # note!! since it is a wide value, it takes up v2 AND v3

 # so we must use v4 next
 # try to reuse variables if possible.
 const-wide/16 v4, 0x300 # this takes up v4 and v5
 div-long/2addr v2, v4   # divide v2 by v4
 long-to-int v2, v2      # convert v2 to an integer
 
 # since i wrote this in my head, there was no Java
 # compiler to add the .line's in the right places
 # but normally they would relate to actual Java lines
 # these are often removed with proguard optimization
 .line 12
 
 # store p1 as an instance variable (someBool) for this class
 # in java this may look like this.someBool = p1;
 iput-boolean p1, p0, Lcom/packageName/example;->someBool:Z
 
 .line 14
 
 # do the same for p3 and someInt
 iput p3, p0, Lcom/packageName/example;->someInt:I
 
 
 # get the value from p0.someInt
 iget v0, p0, Lcom/packageName/example;->someInt:I
 
 # now we will invoke a static method.
 # {} means empty parameters then the full package name followed by ->
 # then the method and it's return value. everything must be there.
 invoke-static {}, Lcom/packageName/example;->someMethod()Ljava/lang/String;
 
 # for different types of invoke-*, try this:
 # http://www.netmite.com/android/mydroid/dalvik/docs/dalvik-bytecode.html
 # invoke-virtual and direct take the class instance as a first parameter.
 
 .line 16
 return-void # meditate on the void.
.end method

# try and figure this one out
.method public static someMethod()Ljava/lang/String;
 # could i have used fewer variables?
 .locals 4
 
 new-instance v0, Ljava/lang/Long;
 
 invoke-static {}, Ljava/lang/System;->currentTimeMillis()J
 move-result-wide v1
 
 invoke-direct {v0, v1, v2}, Ljava/lang/Long;-><init>(J)V
 
 invoke-static {v0}, Ljava/lang/String;->valueOf(Ljava/lang/Object;)Ljava/lang/String;
 move-result-object v1
 
 # notice use of return-object and not just return
 return-object v1
.end method

49 comments :

  1. I can't believe there are no more comments here. VERY helpful. I'm trying to dig into smali files and it's sometimes frustrating. Digging the Dune references there also ;)

    Since you are already doing this:
    what does if-eqz v4, :cond_2 mean?
    I'm trying to translate it in my mind to java:
    if (v4==0)
    (whatever is after the :cond_2 tag)
    else
    (whatever set of instructions follows)

    Am I correct?

    ReplyDelete
    Replies
    1. Yes, if v4 is equal to zero go to the line where :cond_2 is placed and continue on from there,
      otherwise just continue on at the next line.

      Delete
  2. i'm glad you find it helpful and you enjoy dune :D.

    you are correct. it helps to mentally read it as "if equals zero v4 jump to label :cond_2". this goto-style branching is typical of lower level languages.

    ReplyDelete
  3. Thanks for the quick reply
    I was figuring it out myself in the meantime. In this case v4 is a Z (boolean as I learned today :), so I'm assuming it could be read as if (!v4), which would make sense in the context of the rest of the code.

    I will go over your lessons 0 and 1. I'll probably come with a few more questions after that if you don't mind.

    ReplyDelete
  4. Thanks a LOT! This is really helpful!

    ReplyDelete
  5. OMG!!!! Thank u for this great work. The comment is really helpful to me. Great Job. Thank you

    ReplyDelete
  6. I'm working on project which is based on baksmali but outputs java-code instead of smali-code, because it's much easier than smali and there is no application around which produces compileable java-code(dex2jar is very buggy).

    I already got simple classes and method-definitions converted but now I'm about to convert variables.

    So I need to know how this works exactly :)
    One problem I have is the number behind "const/" which always differs. what does it mean?

    Maybe you can contact me via email so I don't have to go offtopic in the comments.

    ReplyDelete
    Replies
    1. Hi, have you finished the project, coz I badly need that now, not only me so many developers are waiting forward for suc sort of project which could directly convert to java files and you are absolutely right about dex2jar, but there are no further improvements or later versions released in that. So looking eagerly forward for your project.

      Delete
    2. hi, did you manage to find the meaning of the numbers behind the "const/" ?

      Delete
    3. It refers to the number of bits for the literal. const/4 would be 4 bits sign extended to 32 bits. See http://source.android.com/tech/dalvik/dalvik-bytecode.html for more information.

      Delete
  7. Hi, lohan+

    I'm writing a tutorial on android malware analysis here:
    http://code.google.com/p/amatutor

    I hope it can use your code in example.smali, example-structures.java, and example-structure.smali to introduce smali syntax and dalvik opcode to readers. Because current version is writen by Chinese, I hope I can delete some comments and explain it in Chinese.
    I will add your name and the refer URLs near these code.

    Can I use it like that? Hope for your confirm email, my address is iClaudXiao@gmail.com
    Thank u very much.

    Claud Xiao

    ReplyDelete
  8. Hi there can u please help me in writing coding in smali format to add an edittext...??

    ReplyDelete
  9. how important is ".line"?

    # .line directives can be mostly ignored
    # sometimes line numbers are useful for debugging errors

    .line 10

    based on your comment .line it's used mostly for error debug?
    or some code it's called through that ".line"?
    thanks!

    ReplyDelete
  10. No code is called. It's just debugging information. It shows up in error logs and stack dumps

    ReplyDelete
  11. This is great helpful!Thank you!

    ReplyDelete
  12. Thanks for the interesting info.
    A small correction: it should be "15 in base 10" on line 68 ;)

    ReplyDelete
  13. In line 68 and line 72, don't you mean 16? :)

    ReplyDelete
  14. I made the same mistake originally. You'll notice the comment above yours corrected it. Intuitively, the maximum value of a single digit in base 10 can only be 9. 0x9 = 9, 0xA = 10, 0xB = 11, 0xC = 12, 0xD = 13, 0xE = 14, 0xF = 15

    ReplyDelete
  15. Do you know if its possible to link in libraries that weren't included in the original build?
    ex. if you add a log statement and Landroid/util/Log results in a ClassDefNotFound

    ReplyDelete
  16. Explanations through your comments were really helpful...thanks

    ReplyDelete
  17. Anonymous, short answer: go ahead, shouldn't be a problem.
    long answer: you will only get ClassDefNotFound if the class is not available to the class loader. if you're referring to java's adding of "import" statements, those are not really present in the bytecode, so i'm guessing they're just there to help the compiler know what you're referring to. if you're on a normal android system Landroid/util/Log will be there.

    ReplyDelete
  18. dude you are awesome i need to contact you

    ReplyDelete
  19. Dude, you just made things A LOT less of a headache! I can't thank you enough for this!

    ReplyDelete
  20. Helped me alot here but sadly im still stuck not sure what the goto or cond tags are for i see in a comment they mean to like jump somewhere

    ReplyDelete
  21. I am just a begineer. and i am trying to edit an app that send "call me back" message to a phoe number that i entered but it don't list my contact list. A problem of that app is i need to remember phone number that i want message to. So what i want to know is how to list phone contact list and use it in .smali file. thank you.

    ReplyDelete
  22. This very very helpfull, thanks brothers, i am newbe and wanted to learn

    ReplyDelete
  23. This very very helpfull, thanks brothers, i am newbe and wanted to learn

    ReplyDelete
  24. Hi sir how can I create an int array in smali?

    In java I do this COLOR_ARRAY = new int[]{Color.rgb(int, int, int), Color.rgb(int, int, int), Color.rgb(int, int, int), Color.rgb(int, int, int)}

    How to do this in smali?

    ReplyDelete
    Replies
    1. best way is to actually learn how to convert arbitrary java to smali.
      1.) write the code in java and compile using javac. this will create .class files.
      2.) compile .class files using dx (part of android sdk) into a .dex file
      3.) baksmali the dex file to get the smali
      4.) automate this using aliases and functions in bash

      Delete
  25. Hello. I want to make this method return a "false" value.
    .method public isLocked()Z
    .locals 1
    iget-boolean v0, p0, Lahc;->isLocked:z
    return v0
    .end method

    ReplyDelete
    Replies
    1. replace "iget-boolean ..." with "const/4 v0"
      better would be to find where isLocked is set and fix it so it's set to true. you don't know where else that field is getting checked. may be through reflection and not obvious with static analysis.

      Delete
  26. What is the use of smali? Pls explain briefly...

    ReplyDelete
    Replies
    1. smali is how the bytecode of dalvik executables can be represented. it's good because it's easy to modify and read. most of the time you don't use it directly. you only "use" it when you need to read and modify it. though it's entirely possible to write programs purely in smali and compile them to dalvik executables using smali. you can also write java, convert to java class files (javac), then convert to dalvik (dx) then convert back to smali.

      Delete
  27. As the job seekers does not only rely on the employment news, they also expect information related to the exam as well as the sarkari results which we find here very apt.

    ReplyDelete
  28. That was a wonderful article. Smali material on the internet is very scarce and this article is a perfect place to get started. Btw, I had a question (though I will follow-up with more questions): When I try to print the byte array using toString() function, I get an overflow error on logcat. Is there a way to get around and print the byte array contents? Any short cuts, hacks? Thanks in advance.

    ReplyDelete
  29. This comment has been removed by the author.

    ReplyDelete
  30. This comment has been removed by the author.

    ReplyDelete
  31. when i try crack app after change smali code and building and singing i installed it the app open for 2 or 3 second then automatically close can u tell me why

    ReplyDelete

  32. Flipkart is one of the biggest world wide eCommerce Site so here you will get Flipkart bank cashback offersthere

    ReplyDelete
  33. Recruitment Notification is one of the Top most Job Portal Govt jobs in AP 2017 there

    ReplyDelete
  34. this is very very very helpful!!!
    thx a lot!!

    ReplyDelete
  35. Congratulations for this really good and galvanizing submit!. Here you can Get More jntu fast updates..!

    ReplyDelete

Do NOT post about or link to specific apps!