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

smali syntax highlighting for ultraedit

syntax highlighting is handy dandy if you are staring at code for more than 10 seconds. you can install this into ultraedit by following the steps here:
http://www.ultraedit.com/downloads/extras.html


get a copy here:
smali.uew

this file is included and kept up to date in lesson 0 of the way of the android cracker series.

cracking vs reversing

reversing is just a polite, politically correct term for cracking. the term cracking has developed a bad reputation in the past few years and those that don't want to look like they are breaking the law like to use the word reversing.

as if it's fooling anyone.


i wont post anything illegal, probably, and i have nothing against the word reversing. it's a nice word. it sounds mature, professional, clean. i still like the term cracking. one cracks nuts, safes, codes, bones, whips. it just sounds right and i'm not ashamed of it.

way of the android cracker 0

this is the first tutorial in a series. it lays the foundation. as you follow along you will set up your cracking environment, learn to use apktool and will have a general idea on how various cracking methods can be implemented.

also included is a crackme, an ultraedit syntax highlighting file and some heavily commented dalvik code.

if you learn anything new on your journey share it with others.

download it here:
https://sites.google.com/site/lohanplus/files/WayoftheAndroidCracker0.zip?attredirects=0&d=1