smali 调试方法(动态调试)

来源:互联网 发布:巨人网络借壳辽宁成大 编辑:程序博客网 时间:2024/05/16 09:56

smali文件

1.下图为基本的smali结构

一个smali文件对应一个class

2.字段描述符

Java中Void在smali中对应V

Void -> V

其他具体描述符参考下面表格:

下面粘贴两段例子代码对应看下:
Android代码:

    package com.test.myapplication;    import android.app.Activity;    import android.os.Bundle;    import android.widget.TextView;    public class MainActivity extends Activity {        @Override        protected void onCreate(Bundle savedInstanceState) {            super.onCreate(savedInstanceState);            setContentView(R.layout.activity_main);            TextView tv = (TextView) findViewById(R.id.text);            tv.setText("hello");        }    }

smali代码:

    .class public Lcom/test/myapplication/MainActivity;    .super Landroid/app/Activity;    .source "MainActivity.java"    # direct methods    .method public constructor <init>()V        .locals 0        .prologue        .line 7        invoke-direct {p0}, Landroid/app/Activity;-><init>()V        return-void    .end method    # virtual methods    .method protected onCreate(Landroid/os/Bundle;)V        .locals 2        .param p1, "savedInstanceState"    # Landroid/os/Bundle;        .prologue        .line 11        invoke-super {p0, p1}, Landroid/app/Activity;->onCreate(Landroid/os/Bundle;)V        .line 12        const/high16 v1, 0x7f030000        invoke-virtual {p0, v1}, Lcom/test/myapplication/MainActivity;->setContentView(I)V        .line 13        const v1, 0x7f070009        invoke-virtual {p0, v1}, Lcom/test/myapplication/MainActivity;->findViewById(I)Landroid/view/View;        move-result-object v0        check-cast v0, Landroid/widget/TextView;        .line 14        .local v0, "tv":Landroid/widget/TextView;        const-string v1, "hello"        invoke-virtual {v0, v1}, Landroid/widget/TextView;->setText(Ljava/lang/CharSequence;)V        .line 15        return-void    .end method

smali头部分析:

.class public 对应 java class public

Lcom/test/myapplication/MainActivity; 类描述符 L+包+名+; 可查看上面表中对应 Object —> Ljava/lang/Object;

.super字段,表示从哪个类中扩展出来的, 此处对应 extends Activity

.source字段,对应源文件.source “MainActivity.java”表示java文件就是MainActivity.java

smali方法分析:

固定格式

.method 开始

.end method 结尾

.method protected onCreate(Landroid/os/Bundle;)V -> protected void onCreate(Bundle savedInstanceState)

Landroid/os/Bundle; 传入的参数, 最后面的V 表示返回值类型Void

invoke-virtual {p0, v1}, Lcom/test/myapplication/MainActivity;->findViewById(I)Landroid/view/View; -> TextView tv = (TextView) findViewById(R.id.text);

invoke-virtual 调用方法

move-result-object v0

把结果放到v0

const-string v1, “hello”

invoke-virtual {v0, v1}, Landroid/widget/TextView;->setText(Ljava/lang/CharSequence;)V

调用setText方法,把v1传入

动态调试:

工具:apktool

下载地址:https://bitbucket.org/iBotPeaches/apktool/downloads/

注意:此处介绍的动态调试方法是比较旧的方法,下载2.1.0版本以下的,因为新版本的apktool -d 选项已经移除

反编译源码中添加调试:

1)java -jar apktool.jar d -d 目标.apk -o 结果放置目录

2)修改AndroidMainfest文件,在application节点添加 android:debuggable=”true”

3)在入口类的onCreate方法中添加:

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

添加后示例:

a=0;// .method protected onCreate(Landroid/os/Bundle;)Va=0;//     .locals 2a=0;//     .param p1, "savedInstanceState"    # Landroid/os/Bundle;a=0;// a=0;//     .prologuea=0;//     .line 11a=0;//     invoke-static{},Landroid/os/Debug;->waitForDebugger()Va=0;//     invoke-super {p0, p1}, Landroid/app/Activity;->onCreate(Landroid/os/Bundle;)V

4)回编译修改过的apk文件

java -jar apktool.jar b -d 代码目录 -o 目标apk名称

问题:我在此处用android studio 编译了一个apk回编译失败,暂时没有解决,直接使用eclipse编译了一个demo.apk

5)对生成的apk进行签名,签名方法可以参照之前的Android反编译和回编译文章

使用android studio进行动态调试:

1)导入已经反编译修改好的功能代码

打开Android Studio ->File -> Open -> 选择刚才反编译的目录

2)在相应位置设置断点

3)设置远程调试选项

Run -> Edit Configurations… -> 点击“+” -> Remote -> Host:localhost Port:8700

4)切换到另外一个编写android代码的android studio窗口

打开Android Device Monitor

点击要调试的程序的进程

5) 切换到smali工程窗口

点击调试按钮,开始调试

至此就可以像调试android代码一样调试smali 代码啦