Android smalidea无源码调试

 
 

   不是我的原创,是从网上两篇博客组合而成

安装

  • 下载插件smalidea
  • 从上面的地址下载这3个文件。 
    这里写图片描述
  • 进入IntelliJ IDEA/Android Studio开始安装插件,进入Settings->Plugins点击Install plugin from disk选中下载好的压缩包
  • 点击apply

开启应用调试

要调试一个apk里面的dex代码,必须满足以下两个条件中的任何一个:

  • apk中的AndroidManifest.xml文件中的Application标签包含属性android:debuggable=”true”
  • /default.prop中ro.debuggable的值为1

可选方案:

apktool d [apkPackage]

其中当apktool 2.1.0以后,不再提供 apktool d -d 功能生成 .java 的 smali 文件了

  • apktool 反编译app 后在AndroidManifest.xml文件中插入android:debuggable=”true”
  • 在启动类的 onCreate 中 加入
// 这个是smali语法的,其实对应的Java代码就是:android.os.Debug.waitForDebugger();
invoke-static {}, Landroid/os/Debug;->waitForDebugger()V
  • hook system debug (Xinstaller)
  • 修改boot.img

这里采用 hook 方式达到开启所有应用调试的目的

xposed 插件代码如下

public class Debug implements IXposedHookLoadPackage {

    public boolean debugApps = true ;
    public static final int DEBUG_ENABLE_DEBUGGER = 0x1;
    public String tag = "IDG";

    @Override
    public void handleLoadPackage(XC_LoadPackage.LoadPackageParam lpparam) throws Throwable {

        if(lpparam.appInfo == null ||
                (lpparam.appInfo.flags & (ApplicationInfo.FLAG_SYSTEM | ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) !=0){
            return;
        }

        tag = tag + lpparam.packageName;

        XposedBridge.hookAllMethods(Process.class, "start", new XC_MethodHook() {
            @Override
            protected void beforeHookedMethod(MethodHookParam param) throws Throwable {

                int id = 5;
                int flags = (Integer) param.args[id];

                Log.d(tag,"flags is : "+flags);

                if (debugApps) {
                    if ((flags & DEBUG_ENABLE_DEBUGGER) == 0) {
                        flags |= DEBUG_ENABLE_DEBUGGER;
                    }
                }

                param.args[id] = flags;
                Log.d(tag,"flags changed : "+flags);

            }
        });
    }

}

如果遇到如下错误

  • Adb rejected connection to client
    可以使用重启 adb server 来解决
adb kill-server
adb start-server

调试应用

调试前准备

IDEA 14.1及以上版本才支持单步调试

  • 使用 baksmali 反编译应用
baksmali myapp.apk -o [outPath]

IDEA调试应用

  • 转到 IDEA 中,导入新module,选中之前的目录

导入时选择Create project from existing sources

  • 导入工程后右键点击 src 目录,设定Mark Directory As->Sources Root

  • 打开Module setting设置对应的 JDK

  • 安装debug应用

  • 找到debug应用进程,启动应用


这里也可以使用这种方式

adb shell am start -D -W -n  [packageName/LauncheActivity]
adb shell ps |grep [packageName]
adb forward tcp:[portNumber] jdwp:[PID]
  • IDEA 配置远程调试

Run->Edit Configurations, use localhost Port in jdwp show [portNumber]

打断点调试

这个时候将你的断点打在smali中,运行断点,触发断点后就是跟普通调试差不多了

Android Studio调试应用

创建新的工程并导入smali

1.Project from Existing Sources… 
这里写图片描述

选择工程目录 
这里写图片描述

接着一路Next… 
这里写图片描述

2.工程创建成功后,在src目录上右键并选择”Mark Directory As——Sources Root”。 
这里写图片描述

开始调试app

1.打开DDMS 
工程创建成功后,发现Android Device Monitor按钮不能点击,因为这不是一个完整的安卓工程,不过可以到Android SDK/tools目录下点击monitor.bat打开DDMS。 
这里写图片描述

2.Run/Debug Configurations 
创建一个”Remote” debug configuration (Run->Edit Configurations), 设置Port为8700。 
这里写图片描述

3.在smali代码中你需要的地方打上断点。

4.运行应用,并在DDMS中选中该应用的进程。 
这里写图片描述

5.点击Debug按钮,开始调试。当运行到断点时应用就会被暂停,这时就可以像平时调试应用一样操作了。 
这里写图片描述

说明:在smali中所有的局部变量用v开头,方法的顶部.locals n表示这个方法使用n个局部变量。所有的参数用p开头,局部变量和参数都是从0开始编号。对于非静态方法来说,p0就是对象本身的引用,即this指针。

猜你喜欢

转载自blog.csdn.net/justFWD/article/details/52461188