不是我的原创,是从网上两篇博客组合而成
安装
- 下载插件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指针。