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 simpulan someInt:I  # the :I means integer .field public simpulan someBool:Z # the :Z means boolean  # Do you see how to make arrays? .field public simpulan 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

Komentar