Monday, January 3, 2011

example-structures.smali

many people find this blog by searching for smali syntax examples and finding a previous post on example smali syntax. since i originally hastily wrote it, i have learned more so i updated it as best i could for now. more helpfully, i worked out a syntax highlighter for smali using syntaxhighlighter. i'll upload it somewhere official when i'm finished so others can use it. because i know there are throngs of people just itching to have highlighted smali code!

so for the googler's out there trying to make sense of smali, here's example-structures.smali from lesson 1 from way of the android cracker.

.class public Lcom/lohan/crackme1/example;
.super Ljava/lang/Object;
.source "example.java"


# static fields
.field private static Counter:I


# direct methods
# all the constructor does is set Counter to 0x10 (or 16)
.method public constructor <init>()V
    .registers 2

    .prologue
    .line 11
    invoke-direct {p0}, Ljava/lang/Object;-><init>()V

    const/16 v0, 0x10
    sput v0, Lcom/lohan/crackme1/example;->Counter:I

    return-void
.end method

.method public static ArrayExample()V
    .registers 4

    .prologue
    const/4 v3, 0x1
    const/4 v2, 0x0

    .line 50
    const/4 v1, 0x5

    new-array v0, v1, [Ljava/lang/String;

    .line 52
    .local v0, someArray:[Ljava/lang/String;

    # put value v1 inside array v0 at index v2 (0x0)
    const-string v1, "set value at index 0"
    aput-object v1, v0, v2

    .line 53
    # put value v1 inside array v0 at index v3 (0x1)
    const-string v1, "index 1 has this value"
    aput-object v1, v0, v3

    .line 55
    # store in v1 the value from array v0 at index v2
    aget-object v1, v0, v2

    # store in v2 the value from array v0 at index v3
    aget-object v2, v0, v3

    # compare two strings
    invoke-virtual {v1, v2}, Ljava/lang/String;->equals(Ljava/lang/Object;)Z
    move-result v1

    # if equals() returns 0, it means they are not equal, so just return
    if-eqz v1, :cond_1e

    .line 57
    sget-object v1, Ljava/lang/System;->out:Ljava/io/PrintStream;
    const-string v2, "array at index 0 = 1 (wont happen)"
    invoke-virtual {v1, v2}, Ljava/io/PrintStream;->println(Ljava/lang/String;)V

    .line 59
    :cond_1e
    return-void
.end method

# loop from 0 to Counter
# just a few lines in java
.method public static LoopExample()V
    .registers 4

    .prologue
    .line 15
    const/4 v0, 0x0

    .local v0, i:I
    :goto_1
    sget v1, Lcom/lohan/crackme1/example;->Counter:I

    if-lt v0, v1, :cond_6

    .line 17
    return-void

    .line 16
    :cond_6
    sget-object v1, Ljava/lang/System;->out:Ljava/io/PrintStream;

    new-instance v2, Ljava/lang/StringBuilder;
    const-string v3, "current val for loop: "
    invoke-direct {v2, v3}, Ljava/lang/StringBuilder;-><init>(Ljava/lang/String;)V
    invoke-virtual {v2, v0}, Ljava/lang/StringBuilder;->append(I)Ljava/lang/StringBuilder;
    move-result-object v2

    invoke-virtual {v2}, Ljava/lang/StringBuilder;->toString()Ljava/lang/String;
    move-result-object v2

    invoke-virtual {v1, v2}, Ljava/io/PrintStream;->println(Ljava/lang/String;)V

    .line 15
    add-int/lit8 v0, v0, 0x1

    goto :goto_1
.end method

.method public static SwitchExample()V
    .registers 3

    .prologue
    .line 21
    const/16 v0, 0x2a

    .line 22
    .local v0, val:I
    
    # begin the switch
    # look down at .sparse_switch directive
    sparse-switch v0, :sswitch_data_2e

    # switch default just passes through to here
    .line 27
    sget-object v1, Ljava/lang/System;->out:Ljava/io/PrintStream;
    const-string v2, "invalid value"
    invoke-virtual {v1, v2}, Ljava/io/PrintStream;->println(Ljava/lang/String;)V

    .line 29
    :goto_c
    return-void

    .line 23
    :sswitch_d # if v0 is 1, we'll be here
    sget-object v1, Ljava/lang/System;->out:Ljava/io/PrintStream;
    const-string v2, "val 1"
    invoke-virtual {v1, v2}, Ljava/io/PrintStream;->println(Ljava/lang/String;)V
    goto :goto_c

    .line 24
    :sswitch_15 # if v0 is 2
    sget-object v1, Ljava/lang/System;->out:Ljava/io/PrintStream;
    const-string v2, "val 2"
    invoke-virtual {v1, v2}, Ljava/io/PrintStream;->println(Ljava/lang/String;)V
    goto :goto_c

    .line 25
    :sswitch_1d # if v0 is 42
    sget-object v1, Ljava/lang/System;->out:Ljava/io/PrintStream;
    const-string v2, "val 42"
    invoke-virtual {v1, v2}, Ljava/io/PrintStream;->println(Ljava/lang/String;)V
    goto :goto_c

    .line 26
    :sswitch_25 # if v0 is 5
    sget-object v1, Ljava/lang/System;->out:Ljava/io/PrintStream;
    const-string v2, "val 5"
    invoke-virtual {v1, v2}, Ljava/io/PrintStream;->println(Ljava/lang/String;)V
    goto :goto_c

    .line 22
    nop

    :sswitch_data_2e
    # if v0 is 0x1 goto :sswitch_d
    # if 0x2 :sswitch_15
    # and so on...
    .sparse-switch
        0x1 -> :sswitch_d   # 1
        0x2 -> :sswitch_15  # 2
        0x5 -> :sswitch_25  # 5
        0x2a -> :sswitch_1d # 42
    .end sparse-switch
.end method

.method public static TryCatchExample()V
    .registers 8

    .prologue
    const-string v7, ": "

    .line 33
    const-string v3, "google.com"

    .line 36
    .local v3, urlStr:Ljava/lang/String;
    # begin try here
    :try_start_4
    new-instance v2, Ljava/net/URL;

    invoke-direct {v2, v3}, Ljava/net/URL;-><init>(Ljava/lang/String;)V

    .line 37
    .local v2, url:Ljava/net/URL;
    invoke-virtual {v2}, Ljava/net/URL;->openStream()Ljava/io/InputStream;

    move-result-object v1

    .line 38
    .local v1, is:Ljava/io/InputStream;
    invoke-virtual {v1}, Ljava/io/InputStream;->close()V
    :try_end_10
    # end of the try
    
     # if there was a MalformedURLException, goto :catch_11
    .catch Ljava/net/MalformedURLException; {:try_start_4 .. :try_end_10} :catch_11
    
    # IOException goes to :catch_36
    .catch Ljava/io/IOException; {:try_start_4 .. :try_end_10} :catch_36

    # if NO exception, just pass through:
    .line 46
    .end local v1           #is:Ljava/io/InputStream;
    .end local v2           #url:Ljava/net/URL;
    :goto_10
    return-void

    .line 39
    :catch_11
    # move the exception to v4, then to v0
    # all of the code below is what happens with an exception
    move-exception v4
    move-object v0, v4

    .line 41
    .local v0, e:Ljava/net/MalformedURLException;
    sget-object v4, Ljava/lang/System;->out:Ljava/io/PrintStream;

    new-instance v5, Ljava/lang/StringBuilder;
    const-string v6, "Invalid URL "
    invoke-direct {v5, v6}, Ljava/lang/StringBuilder;-><init>(Ljava/lang/String;)V
    invoke-virtual {v5, v3}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder;
    move-result-object v5

    const-string v6, ": "
    invoke-virtual {v5, v7}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder;
    move-result-object v5

    invoke-virtual {v0}, Ljava/net/MalformedURLException;->getMessage()Ljava/lang/String;
    move-result-object v6

    invoke-virtual {v5, v6}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder;
    move-result-object v5

    invoke-virtual {v5}, Ljava/lang/StringBuilder;->toString()Ljava/lang/String;
    move-result-object v5

    invoke-virtual {v4, v5}, Ljava/io/PrintStream;->println(Ljava/lang/String;)V

    goto :goto_10

    .line 42
    .end local v0           #e:Ljava/net/MalformedURLException;
    # end exception code
    
    # begin exception code    
    :catch_36
    move-exception v4
    move-object v0, v4

    .line 44
    .local v0, e:Ljava/io/IOException;
    sget-object v4, Ljava/lang/System;->out:Ljava/io/PrintStream;

    new-instance v5, Ljava/lang/StringBuilder;
    const-string v6, "Unable to execute "
    invoke-direct {v5, v6}, Ljava/lang/StringBuilder;-><init>(Ljava/lang/String;)V
    invoke-virtual {v5, v3}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder;
    move-result-object v5

    const-string v6, ": "
    invoke-virtual {v5, v7}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder;
    move-result-object v5

    invoke-virtual {v0}, Ljava/io/IOException;->getMessage()Ljava/lang/String;
    move-result-object v6

    invoke-virtual {v5, v6}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder;
    move-result-object v5

    invoke-virtual {v5}, Ljava/lang/StringBuilder;->toString()Ljava/lang/String;
    move-result-object v5

    invoke-virtual {v4, v5}, Ljava/io/PrintStream;->println(Ljava/lang/String;)V

    goto :goto_10
    # end exception code
.end method

11 comments :

Do NOT post about or link to specific apps!