Android动态调试小记
安卓动态调试——apk加上动态可调试属性
刷了一下2024xyctf的DebugMe题目,记一下这次动态调试过程。
用jeb打开后看到有调试检查,再根据题目提示为动态调试。知道需要进行动调。
先用雷电模拟器在程序里面运行这个程序,接着用adb测试远程连接:输入adb devices。如图显示就算端口连接好了。
adb devices -l查看连接的设备
adb shell ps查看线程状态
然后才能在jeb里面点击调试器或者甲虫下图标进行动态调试,不然会显示调试的目标不存在。
点击attach附上。
提示程序不可调试nondebuggable。
提示无法attach上。
一、用Android Killer编译的方法修改apk为可调式
- 用Android Killer打开apk,可以解包这个程序。
点开AndroidMainfest.xml,在<application那一行后面加上android:debuggable=”true”这个属性(记得要ctrl+s保存)。
把编译先设置成AndroidKiller选项,然后进行编译。会生成编译后可调试的apk(如果有报错根据提示修改)。
在Android Killer工具中,“default” 和 “AndroidKiller” 是两种不同的编译配置选项,它们的核心区别在于 签名配置 和 编译参数。以下是具体分析:
1. 两者的核心区别
配置项 default(默认配置) AndroidKiller(工具自定义配置) 签名文件 通常使用空签名或无有效签名 预置工具自带的调试签名(如 debug.keystore
)签名对齐 可能未启用 zipalign
优化默认启用 zipalign
对齐优化兼容性 可能因签名问题导致安装失败 针对重新打包场景优化,兼容性更好 适用场景 临时测试或无需安装的场景(如静态分析) 需要重新打包并安装到设备的调试场景
2. 如何选择?
- 选择
AndroidKiller
配置的情况:- 需要重新打包APK并安装到设备(尤其是非Root设备)。
- 希望自动处理签名和对齐,避免手动操作。
- 遇到安装失败问题时(如
INSTALL_PARSE_FAILED_NO_CERTIFICATES
错误)。
- 选择
default
配置的情况:- 仅需反编译查看代码/资源,无需重新安装。
- 已手动配置签名文件(如自有证书)或有特殊编译需求。
3. 验证配置差异的方法
- 检查签名配置:
- 在Android Killer中打开
配置
→签名配置
,查看两种选项是否使用不同的.keystore
文件。 - 若
AndroidKiller
使用debug.keystore
而default
为空,则前者能生成有效签名的APK。
- 在Android Killer中打开
- 查看编译日志:
- 编译时观察日志中是否包含
zipalign
步骤。AndroidKiller
配置通常会自动对齐优化。
- 编译时观察日志中是否包含
- 安装测试:
- 分别用两种配置编译APK,尝试安装到模拟器或真机。若
default
失败,说明其签名无效。
- 分别用两种配置编译APK,尝试安装到模拟器或真机。若
4. 常见问题解决
- 安装失败(签名错误):
- 使用
AndroidKiller
配置(自带有效签名)。 - 若仍需自定义签名,手动替换配置中的
.keystore
文件。
- 使用
- APK无法运行(对齐问题):
- 确保启用
zipalign
(在AndroidKiller
配置中默认开启)。
- 确保启用
总结
- 优先选择
AndroidKiller
配置:它能自动处理签名和对齐,适合大多数重新打包场景。 - 仅在特殊需求时使用
default
:如需自定义签名或调试未安装的APK逻辑。
通过理解配置差异并针对性选择,可显著提高逆向工程和APK修改的效率。
- 选择
最后用jeb再进行动态调试,发现可以附上了,click一下flag就出来了。
二、用apktool手动解包修改他的属性,再进行对齐签名的方法
参考自视频27分21秒开始
参考自文章APK反编译、重打包、签名之apktool实现
把apk放到apk目录下面,并且在apktool目录下打开cmd输入
apktool d DebugeMe.apk
会将解包的数据输出在其目录下。在AndroidMainfest.xml的application里面添加
android:debuggable="true"
的属性。再输入
apktool b DebugeMe
进行打包,打包后在DebugeMe的dist目录下看到新的apk。生成keystone:
Keystore生成命令:
1
keytool -genkey -alias abc.keystore -keyalg RSA -validity 20000 -keystore abc.keystore
签名
签名命令:
1
jarsigner -verbose -keystore abc.keystore -signedjar TestPrint_1.apk TestPrint.APK abc.keystore
输入之前填写的密码
此时,签名完毕,apktool文件夹下出现新的APK–>TestPrint_1.apk
至此,apk反编译,修改文件,重打包,签名全部完成。
三、绕过apk不可调试的属性限制
- 无需开启apk的可调试(debuggable)属性
打开Root权限和adb调试的远程连接模式
adb devices后,直接用jadx远程调试(点击甲虫图标)
直接click得到flag。
1. 原APK无法调试的原因
- 默认不可调试属性:原APK可能在构建时未设置
android:debuggable="true"
,导致JEB/Jadx无法附加调试器(端口报错是典型表现)。- 调试依赖条件:正常调试需要APK的
AndroidManifest.xml
中明确声明可调试,否则ADB会拒绝连接。
2. 修改APK后安装失败的原因
- 签名问题:修改APK后需重新签名。若未正确签名(如使用调试密钥对齐签名),雷电模拟器会拒绝安装。
- Manifest格式错误:手动修改XML可能导致格式错误(如标签未闭合),引发解析失败。
- 回编工具问题:使用
apktool
等工具解包/回编时,若版本不兼容或参数错误,可能导致APK损坏。
3. Root权限+远程ADB成功的原因
- 绕过调试属性限制:Root权限允许通过系统级操作(如修改
ro.debuggable
属性)强制开启全局调试,此时无需APK自身可调试。- ADB远程连接模式:远程连接可能绕过了本地ADB的某些限制,或直接以更高权限附加到进程(如通过
ptrace
)。- 原APK的漏洞利用:若APK本身存在逻辑漏洞(如硬编码密钥),Root后可直接提取内存数据或修改运行时行为,无需动态调试。
关键结论
- Root权限的作用:开启Root后,可通过系统命令(如
setprop ro.debuggable 1
)强制允许调试所有应用,此时原APK即使未标记为可调试也能被调试。- 修改APK的替代方案:直接使用Root权限调试,避免了因签名或打包错误导致安装失败的问题,是一种更高效的绕过手段。
解决方案建议
签名验证:若需修改APK,务必用
jarsigner
或apksigner
重新签名,并使用zipalign
对齐。Root环境利用:优先在Root环境下调试,通过
frida
、GDB
等工具直接注入或分析内存,避免修改APK的繁琐流程。系统属性修改:Root后执行以下命令强制开启全局调试:
bash
复制
1
2
3 adb root # 获取ADB Root权限
adb shell setprop ro.debuggable 1
adb shell stop && adb shell start # 重启ADB此后可调试任意APK,无需修改Manifest。
通过Root权限绕过APK本身的调试限制,是CTF中常见的技巧,既能避免打包错误,又能直接深入分析进程内存,是高效解题的关键。
参考文献: