天空飘来五字:Android逆向smali

2018-12-11 10:47:32 浏览数 (1)

本期,我们将继续Android逆向动态分析之smali篇。内容包括smali语言介绍与动态调试。

0X01 smali语言简述

smali语言是Dalvik的反汇编语言因Android虚拟机Dalvik不是执行java虚拟机JVM编译后生成的class文件,而是执行再重新整合打包后生成的dex文件,dex文件反编译之后就是smali代码。

接触过Android逆向的小伙伴都会遇到smali语言,简单的逆向过程 [apk -> smali -> java]。有的逆向工具无法将smali语言反编译成java源码,只逆向到smali语言这层。或者反编译成java源码无法运行(smali宽松型语言)。

0X02 smali语言语法

原始数据类型:

代码语言:javascript复制
//smali----java
B----byte
C----char
D----double
F----float
I----int
J----long
S----short
V----void
Z----boolean
[XXX-----array
Lxxx/yyy----object

基础语法:

代码语言:javascript复制
语法:

.field  定义变量

.method  方法

.parameter  方法参数

.prologue  方法开始

.line 12  此方法位于第12行

invoke-super  调用父函数

const/high16  v0, 0x7fo3  把0x7fo3赋值给v0

invoke-direct  调用函数

return-void  函数返回void

.end method  函数结束

new-instance  创建实例

iput-object  对象赋值

iget-object  调用对象

invoke-static  调用静态函数

smali跳转语句:

代码语言:javascript复制
"if-eq vA, vB, :cond_**" 如果vA等于vB则跳转到:cond_**

"if-ne vA, vB, :cond_**" 如果vA不等于vB则跳转到:cond_**

"if-lt vA, vB, :cond_**" 如果vA小于vB则跳转到:cond_**

"if-ge vA, vB, :cond_**" 如果vA大于等于vB则跳转到:cond_**

"if-gt vA, vB, :cond_**" 如果vA大于vB则跳转到:cond_**
//le 小于等于
//eqz 等于0
//nez 不等于0
//ltz 小于0
//gez 大于等于0
//gtz 大于0
//lez 小于等于0

例子:

代码语言:javascript复制
//smali
.method public onClick(View)V
          .registers 12
00000000  const/4             v9, 3
00000002  const/4             v8, 2
00000004  const/4             v7, 0
00000006  const/4             v6, 1
00000008  iget                v5, p0, MainActivity->flag:I
0000000C  if-ne               v5, v6, :12
00000032  const               v5, 0x7F0C0050
00000050  move-result-object  v3
00000052  check-cast          v3, TextView
00000056  iput                v7, p0, MainActivity->m:I
0000005A  new-instance        v0, Random
0000005E  invoke-direct       Random-><init>()V, v0
00000064  invoke-virtual      Random->nextInt(I)I, v0, v9
0000006A  move-result         v5
0000006C  iput                v5, p0, MainActivity->n:I
00000070  new-array           v1, v9, [String
00000074  const-string        v5, "CPU: Paper"
00000078  aput-object         v5, v1, v7
0000007C  const-string        v5, "CPU: Rock"
00000080  aput-object         v5, v1, v6
00000084  const-string        v5, "CPU: Scissors"
00000088  aput-object         v5, v1, v8
0000008C  iget                v5, p0, MainActivity->n:I
00000090  aget-object         v5, v1, v5
00000094  invoke-virtual      TextView->setText(CharSequence)V, v3, v5
0000009A  iget-object         v5, p0, MainActivity->P:Button
0000009E  if-ne               p1, v5, :B0
:A2
000000A2  const-string        v5, "YOU: Paper"
000000A6  invoke-virtual      TextView->setText(CharSequence)V, v2, v5
000000AC  iput                v7, p0, MainActivity->m:I
:B0
000000B0  iget-object         v5, p0, MainActivity->r:Button
000000B4  if-ne               p1, v5, :C6
:B8
000000B8  const-string        v5, "YOU: Rock"
000000BC  invoke-virtual      TextView->setText(CharSequence)V, v2, v5
000000C2  iput                v6, p0, MainActivity->m:I
:C6
000000C6  iget-object         v5, p0, MainActivity->S:Button
000000CA  if-ne               p1, v5, :DC
:CE
000000CE  const-string        v5, "YOU: Scissors"
000000D2  invoke-virtual      TextView->setText(CharSequence)V, v2, v5
000000D8  iput                v8, p0, MainActivity->m:I
:DC
000000DC  iget-object         v5, p0, MainActivity->handler:Handler
000000E0  iget-object         v6, p0, MainActivity->showMessageTask:Runnable
000000E4  const-wide/16       v8, 1000
000000E8  invoke-virtual      Handler->postDelayed(Runnable, J)Z, v5, v6, v8, v9
000000EE  goto                :10
.end method
代码语言:javascript复制
//java
public void onClick(View arg11) {
    int v9 = 3;
    int v8 = 2;
    if(this.flag != 1) {
        this.flag = 1;
        this.findViewById(0x7F0C0052).setText("");
        View v2 = this.findViewById(0x7F0C0050);
        View v3 = this.findViewById(0x7F0C0051);
        this.m = 0;
        this.n = new Random().nextInt(v9);
        String[] v1 = new String[v9];
        v1[0] = "CPU: Paper";
        v1[1] = "CPU: Rock";
        v1[v8] = "CPU: Scissors";
        ((TextView)v3).setText(v1[this.n]);
        if(arg11 == this.P) {
            ((TextView)v2).setText("YOU: Paper");
            this.m = 0;
        }

        if(arg11 == this.r) {
            ((TextView)v2).setText("YOU: Rock");
            this.m = 1;
        }

        if(arg11 == this.S) {
            ((TextView)v2).setText("YOU: Scissors");
            this.m = v8;
        }

        this.handler.postDelayed(this.showMessageTask, 1000);
    }
}

0X03 动态调试smali

IntelliJ IDEA/Android Studio 利用smalidea插件可实现动态调试smali代码 下载smalidea插件(https://bitbucket.org/JesusFreke/smali/downloads/) 添加smalidea插件[File->Settings->Plugins]

点击Install plugin from disk添加下载好插件。

加载插件后关闭Android Studio再重新打开。 导入源码(apk逆向的smali)。

选择要加载smali源码。

连续next。

加载后就能看到smali。

将存放smali文件的文件夹设置为项目源码。

给项目添加相应的SDK[File->Project Structure]。

运行模拟器并启动要调试的APP。 开启模拟器端口转发。

使用adb shell ps命令查看程序APP的运行的端口与名称。

添加远程调试环境。

开启程序端口调试转发。 tcp后的端口为上图添加的端口,jdwp后的端口为在apk中运行的APP端口。

为smali打上断点,运行Debug[Run->Debug],开始调试。

0X04 小小总结

本期的Android逆向之动态分析smali篇就介绍到这里啦 !如果你有疑问或是更好的思路,欢迎给斗哥留言哦~!祝各位周末愉快~!

0 人点赞