安卓学习思路方法总结(七)
字数 1931 2025-08-09 13:33:35
ARM架构安卓动态调试与静态分析教程
环境搭建与准备
调试环境配置
-
连接真机调试:
- 上传IDA中的
android_server到安卓设备 - 切换root权限运行程序:
adb shell su -c "/data/local/tmp/android_server" - 端口转发:
adb forward tcp:23946 tcp:23946
- 上传IDA中的
-
安装APK:
- 使用命令:
adb install C:\javandk1.apk - 如果已安装可跳过此步骤
- 使用命令:
-
启动调试模式:
- 挂起程序:
adb shell am start -D -n com.example.javandk1/.MainActivity - 使用DDMS查看进程状态(变红色表示已挂起)
- 挂起程序:
-
IDA连接:
- 启动IDA Debugger
- 搜索并选择目标安卓程序
- 设置断点后按F9运行
-
附加jdb调试器:
jdb -connect com.sun.jdi.SocketAttach:hostname=127.0.0.1,port=8600
ARM指令集基础
关键概念
-
条件码表:ARM指令可条件执行,根据条件码决定是否执行
-
三级流水线:ARM处理器采用取指、译码、执行三级流水线
-
数据存储格式:
- 小端模式:低位在前,高位在后
- 大端模式:高位在前,低位在后
- ARM通常采用小端模式
-
寄存器与内存:
- 32位系统可处理4GB内存(2^32)
- 一个字节=8位,四个字节=32位
- 一个十六进制数=4位,两个十六进制数=1字节
常用指令解析
-
LDR指令:
- 格式:
LDR Rd, [Rn, #offset] - 功能:将内存地址
Rn+offset处的数据加载到寄存器Rd
- 格式:
-
STR指令:
- 格式:
STR Rd, [Rn, #offset] - 功能:将寄存器Rd的值存储到内存地址
Rn+offset处
- 格式:
-
MOV/MOVT指令:
- MOV:移动低16位
- MOVT:移动高16位(T表示Top)
-
ADD/SUB指令:
- ADD:加法运算
- SUB:减法运算
-
BLX/BL/BX指令:
- BLX:带链接和状态切换的跳转(会改变LR和PC,可能改变T标志)
- BL:带链接的跳转(改变LR和PC)
- BX:带状态切换的跳转(改变PC和T标志)
-
STMFD/LDMED指令:
- STMFD(Store Multiple Full Descending):多寄存器存储,满递减堆栈
- LDMED(Load Multiple Empty Descending):多寄存器加载,与STMFD对应
动态调试实战
调试流程
-
下断点:
- 在目标位置设置断点
- 按F9运行到断点处
-
单步调试:
- F7:单步步入(进入函数调用)
- F8:单步步过(不进入函数调用)
- ESC:从当前函数返回
-
寄存器窗口观察:
- 观察PC(程序计数器)、LR(链接寄存器)、SP(栈指针)等关键寄存器变化
- 注意T标志位变化(表示Thumb/ARM模式切换)
-
栈操作分析:
- 栈指针SP变化示例:
原SP: FFEE2B60 新SP: FFEE2B5C (60-4) 计算过程:6×16+0=96 → 96-4=92 → 92/16=5余12 → 5C
调试示例分析
-
第一条指令:
LDR R0, [R3]- 将R3指向的内存值加载到R0
- 执行后:R0=F54BC000, R3=00000001
-
栈操作指令:
STR LR, [SP, #var_4]!- 将LR的值存储到SP-4的位置,并更新SP
- 栈变化:FFEE2B60 → FFEE2B5C
-
跳转指令:
BLX R3- 带链接和状态切换的跳转
- 会改变LR和PC,可能改变T标志位
静态so库分析
分析流程
-
加载so文件:
- 直接将so文件拖入IDA
- 使用空格键在流程图和文本视图间切换
-
关键指令解析:
-
偏移量计算:
LDR R2, =(aAge - 0x1288)双击aAge查看实际地址(如00002C34),然后计算偏移量
-
PC相对寻址:
ADD R2, PC, R2计算当前PC值加上R2中的偏移量,得到实际地址
-
-
函数调用分析:
- 注意BLX/BL指令后的寄存器变化
- 跟踪参数传递(通常R0-R3用于参数传递)
示例分析
-
字符串加载:
LDR R2, =(aAge - 0x1288) ; aAge地址为00002C34 ADD R2, PC, R2 ; PC+偏移量得到实际地址最终R2指向字符串"age"
-
方法调用:
BLX R3- 跳转到R3指向的地址
- 调用后R0通常包含返回值
总结与技巧
-
调试技巧:
- 栈指针变化计算要熟练掌握十六进制运算
- 注意T标志位变化对指令解码的影响
- 重新下断点可按F9快速跳转到目标位置
-
分析技巧:
- 静态分析时注意PC相对寻址的计算
- 跟踪字符串和方法的交叉引用
- 结合动态调试验证静态分析结果
-
常见模式:
- 方法调用前通常会有参数设置(R0-R3)
- 返回值通常存放在R0
- 栈操作遵循满递减模式(STMFD/LDMED)
通过本教程,您应该掌握了ARM架构下的安卓应用动态调试和静态分析的基本方法,包括环境搭建、指令解析、寄存器观察和栈操作分析等关键技能。