安卓应用层逆向——打造自己的smali代码库

smali代码编写

返回字符串的静态方法:

.class public Lf8/helloworld/helloStr;  #类声明
.super Ljava/lang/Object;

.method public static retHello()Ljava/lang/String;  #函数声明
.locals 1       #寄存器数量
const-string v0, "Hello World From StaticMethod."
return-object v0
.end method

返回静态field的方法:

.field public static final hStr:Ljava/lang/String; = "Hello World From Static Field."
.method public static retHello2()Ljava/lang/String;
.locals 1
sget-object v0, Lf8/helloworld/helloStr;->hStr:Ljava/lang/String;   #获取field
return-object v0
.end method

普通的函数

.method public constructor <init>()V
    .locals 0
    invoke-direct {p0}, Ljava/lang/Object;-><init>()V
    return-void
.end method

.method public retHello3()Ljava/lang/String;
    .locals 1
    const-string v0, "Hello World From Method"
    return-object v0
.end method

普通的field与返回其的函数

.field public hStr2:Ljava/lang/String;
.method public constructor <init>()V
    .locals 1
    invoke-direct {p0}, Ljava/lang/Object;-><init>()V
    const-string v0, "Hello World"
    iput-object v0, p0, Lf8/helloworld/helloStr;->hStr2:Ljava/lang/String;
    return-void
.end method

.method public retHello4()Ljava/lang/String;
.locals 1
iget-object v0, p0, Lf8/helloworld/helloStr;->hStr2:Ljava/lang/String;
return-object v0
.end method

调用普通函数返回其field的时候需要先初始化一个实例

new-instance v1, Lf8/helloworld/helloStr;
invoke-direct {v1}, Lf8/helloworld/helloStr;-><init>()V
invoke-virtue {v1}, Lf8/helloworld/helloStr;->retHello3()Ljava/lang/String;
move-result-object v1

上面的代码只是为了进一步熟悉smali语法以代码的编写,实践中一个比较取巧的方法是先用java写好代码以及相关调用后,反汇编直接抠出代码。

smali代码模板实例

Android Killer 自带3种代码模版
1)LoadLibrary

const-string v0, "so name"
invoke-static {v0}, Ljava/lang/System;->loadLibrary(Ljava/lang/String;)V

2)logcat

const-string v0, "you message"
invoke-static {v0}, Lcom/android/killer/Log;->LogStr(Ljava/lang/String;)V

这个模版实质上会在代码中插入一个包。
在smali中注入上述代码会在ddms中的Log窗口打印出日志信息。

3)toast

const-string v0, "you message"
const/4 v1, 0x1
invoke-static {p0, v0, v1}, Landroid/widget/Toast;->makeText(Landroid/content/Context;Ljava/lang/CharSequence;I)Landroid/widget/Toast;
move-result-object v0
invoke-virtual {v0}, Landroid/widget/Toast;->show()V

4)dumpStack

invoke-static {}, Ljava/lang/Thread;->dumpStack()V

在smali中注入上述代码可以打印出程序执行过程中的调用堆栈,当在Jeb中反调试smali代码之后,当通过x查看引用没有结果时可以尝试使用注入该代码并在DDMS日志中查看相应调用。

5) traceview

invoke-static {}, Landroid/os/Debug;->startMethodTracing()V
invoke-static {}, Landroid/os/Debug;->stopMethodTracing()V

同时需要声明权限:

<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

traceView可以生成.trace文件显示出从某一个开始点到结束点的调用线程信息,用于追踪函数也可用来性能测试,需要读写权限。

6)等待调试:

invoke-static {}, Landroid/os/Debug;->waitForDebugger()V

…….以上只是一些示例smali代码库,在对安卓应用层的逆向过程中可以不断扩充。

猜你喜欢

转载自blog.csdn.net/hbhgyu/article/details/81160470