安卓学习思路方法总结(三)
字数 3160 2025-08-09 18:44:12

Android逆向工程学习指南(三):Dalvik指令集与APK破解实战

一、Dalvik指令集详解

1. 基础字节码分析

  • 名称后缀:如wide表示数据宽度为64位
  • 字节码后缀:如from16表示源寄存器为16位
  • 寄存器表示
    • A/B/C/D/E/F/G/H:4位数值
    • AA/BB/CC/DD/EE/FF/GG/HH:8位数值
    • AAAA/BBBB/...HHH:16位数值

2. 常用指令类型

空操作指令

  • 助记符:nop
  • 值:00
  • 用途:对齐代码,无实际操作

返回指令

  • return-void:从void方法返回,返回值为空
  • return vAA:返回32位非对象类型值
  • return-wide vAA:返回64位非对象类型值
  • return-object vAA:返回对象类型值

数据定义指令

  • const/4 vA,#+B:将数值符号扩展为32位后赋给vA
  • const/16 vAA,#+BBBB:将数据符号扩展为32位后赋给vAA
  • const-string vAA,string@BBBB:通过字符串索引构造字符串
  • const-class vAA,type@BBBB:通过类型索引获取类引用

跳转指令

  • goto:无条件跳转
  • switch:分支跳转
  • packed-switch:有规律跳转
  • sparse-switch:无规律跳转
  • if条件跳转:
    • if-eq/if-ne:等于/不等于
    • if-lt/if-le:小于/小于等于
    • if-gt/if-ge:大于/大于等于
    • if-eqz/if-nez:等于0/不等于0

实例操作指令

  • check-cast vAA,type@BBBB:将对象引用转换成指定类型
  • instance-of vA,vB:判断vB对象引用是否可以转换
  • new-instance vAA,type@BBBB:构造指定类型新实例

数组操作指令

  • array-length vA,vB:获取数组长度
  • new-array vA,vB,type@CCCC:构造指定类型与大小的数组

方法调用指令

  • invoke-virtual:调用实例虚方法
  • invoke-super:调用父类方法
  • invoke-direct:调用直接方法
  • invoke-static:调用静态方法
  • invoke-interface:调用接口方法

二、APK破解实战技巧

1. 快速定位关键代码方法

  1. 搜索特征字符串:如"支付"、"VIP"、"余额不足"等
  2. 搜索关键API:如支付宝、微信相关API
  3. 通过方法名判断功能:分析程序命名规范
  4. 反编译APK
    • 分析AndroidManifest.xml:包名、系统版本、组件
    • 定位主Activity(程序入口界面)
    • 关注application执行时间和授权验证

2. 定位关键代码技巧

  1. 信息反馈法:通过资源ID或字符串定位
  2. 特征函数法:通过API函数定位
  3. 顺序查看法:分析程序执行流程
  4. 代码注入法:动态调试,插入log查看
  5. 栈跟踪法:动态调试,分析函数调用流程
  6. Method Profiling:方法剖析,热点分析

3. 常见支付关键词

  • 支付宝:搜索字符串"9000"(支付成功)
  • 咪咕游戏:搜索常量"onresult"
  • 中国移动:特征码46000、46002、46007、46020
  • 中国联通:特征码46001、46006、46010
  • 中国电信:特征码46003、46005、46011

三、实战案例解析

案例1:单机斗地主破解

目标:跳过支付宝支付购买记牌器

  1. jadx-gui分析

    • 搜索字符串"9000"定位支付成功代码
    • 分析if判断逻辑,发现支付成功(9000)和失败(8000)的判断
  2. Android Killer修改

    • 找到if-eqz v1, :cond_4判断
    • 修改为if-nez v1, :cond_4使支付失败时执行成功逻辑
  3. 效果:支付失败但程序认为成功,可使用记牌器功能

案例2:卧龙影视VIP破解

目标:绕过VIP验证

  1. jadx-gui分析

    • 搜索"getVip"定位VIP验证方法
    • 分析UserVip实体类中的isVipEndStart字段
  2. Android Killer修改

    • 找到public getVip()方法
    • 修改为const v0,0x1强制返回VIP状态
  3. 效果:登录后显示VIP状态,解锁全部功能

案例3:起名软件VIP破解

目标:绕过五行选择限制

  1. jadx-gui分析

    • 搜索"getVip"定位验证代码
    • 分析switch判断逻辑
  2. Android Killer修改

    • 找到两处if-eqz v1, :cond_0
    • 修改为if-nez v1, :cond_0
    • 或直接注释getVip方法
  3. 效果:可无限制使用五行选择功能

案例4:RE文件管理器广告去除

目标:去除退出时的广告

  1. adb抓包

    • 使用adb shell dumpsys activity top获取当前界面进程
    • 定位广告Activitycom.AddDouDouWall2.WebPageDownLoadMainActivity
  2. jadx-gui分析

    • 找到广告URL和DownLoadManagerService
    • 分析onDestroy方法中的网络检查和启动逻辑
  3. Android Killer修改

    • 修改if-eqz v0, :cond_0if-nez v0, :cond_0
    • 或替换广告URL为自定义页面
  4. 效果:退出时不再显示广告

案例5:车来了广告去除

目标:去除中间广告

  1. DDMS分析

    • 使用DDMS监控应用行为
    • 过滤com.ygkj.chelaile.standard包名
    • 定位广告域名atrace.chelaile.net.cn
  2. Android Killer修改

    • 搜索并替换广告域名为127.0.0.1
  3. 效果:中间广告消失

案例6:好搜小说大全插桩分析

目标:学习代码插桩技术

  1. Log信息输出插桩

    • onCreate()方法中插入Log输出
    • 使用Unicode编码特殊字符
    • 注意寄存器数量调整(locals)
  2. StackTrace栈跟踪

    • 在关键方法如loadData()中插入栈跟踪代码
    • 使用Exception.printStackTrace()输出调用链
  3. DDMS分析

    • 观察入口点和入口界面的执行顺序
    • 分析栈跟踪信息,理解调用关系

四、常见问题解决

  1. 回编译失败

    • APKTOOL版本问题:尝试不同版本
    • Java环境问题:检查Java版本和环境变量
  2. 程序崩溃

    • 插桩导致寄存器不足:增加locals数量
    • 方法调用错误:检查指令使用是否正确
  3. init()方法插桩

    • init方法在初始化时不会调用寄存器
    • 是安全的插桩位置

五、高级技巧

  1. 栈跟踪分析

    • 使用DDMS暂停分析栈
    • 理解Parents(父节点)和Children(子节点)关系
    • 分析调用链和循环体
  2. 动态调试

    • 结合jadx-gui静态分析和动态调试
    • 使用logcat监控程序行为
  3. 代码注入

    • 修改关键判断逻辑(如if条件)
    • 替换关键字符串和URL
    • 强制返回值绕过验证

六、注意事项

  1. 法律风险:所述技术仅用于学习目的
  2. 道德考量:尊重开发者劳动成果
  3. 技术边界:不得用于非法用途

通过系统学习Dalvik指令集和实战案例,可以逐步掌握Android逆向工程的核心技术。建议从简单案例入手,逐步深入理解Android应用的运行机制和破解方法。

Android逆向工程学习指南(三):Dalvik指令集与APK破解实战 一、Dalvik指令集详解 1. 基础字节码分析 名称后缀 :如 wide 表示数据宽度为64位 字节码后缀 :如 from16 表示源寄存器为16位 寄存器表示 : A/B/C/D/E/F/G/H :4位数值 AA/BB/CC/DD/EE/FF/GG/HH :8位数值 AAAA/BBBB/...HHH :16位数值 2. 常用指令类型 空操作指令 助记符: nop 值: 00 用途:对齐代码,无实际操作 返回指令 return-void :从void方法返回,返回值为空 return vAA :返回32位非对象类型值 return-wide vAA :返回64位非对象类型值 return-object vAA :返回对象类型值 数据定义指令 const/4 vA,#+B :将数值符号扩展为32位后赋给vA const/16 vAA,#+BBBB :将数据符号扩展为32位后赋给vAA const-string vAA,string@BBBB :通过字符串索引构造字符串 const-class vAA,type@BBBB :通过类型索引获取类引用 跳转指令 goto :无条件跳转 switch :分支跳转 packed-switch :有规律跳转 sparse-switch :无规律跳转 if 条件跳转: if-eq / if-ne :等于/不等于 if-lt / if-le :小于/小于等于 if-gt / if-ge :大于/大于等于 if-eqz / if-nez :等于0/不等于0 实例操作指令 check-cast vAA,type@BBBB :将对象引用转换成指定类型 instance-of vA,vB :判断vB对象引用是否可以转换 new-instance vAA,type@BBBB :构造指定类型新实例 数组操作指令 array-length vA,vB :获取数组长度 new-array vA,vB,type@CCCC :构造指定类型与大小的数组 方法调用指令 invoke-virtual :调用实例虚方法 invoke-super :调用父类方法 invoke-direct :调用直接方法 invoke-static :调用静态方法 invoke-interface :调用接口方法 二、APK破解实战技巧 1. 快速定位关键代码方法 搜索特征字符串 :如"支付"、"VIP"、"余额不足"等 搜索关键API :如支付宝、微信相关API 通过方法名判断功能 :分析程序命名规范 反编译APK : 分析 AndroidManifest.xml :包名、系统版本、组件 定位主Activity(程序入口界面) 关注 application 执行时间和授权验证 2. 定位关键代码技巧 信息反馈法 :通过资源ID或字符串定位 特征函数法 :通过API函数定位 顺序查看法 :分析程序执行流程 代码注入法 :动态调试,插入log查看 栈跟踪法 :动态调试,分析函数调用流程 Method Profiling :方法剖析,热点分析 3. 常见支付关键词 支付宝 :搜索字符串"9000"(支付成功) 咪咕游戏 :搜索常量"onresult" 中国移动 :特征码46000、46002、46007、46020 中国联通 :特征码46001、46006、46010 中国电信 :特征码46003、46005、46011 三、实战案例解析 案例1:单机斗地主破解 目标 :跳过支付宝支付购买记牌器 jadx-gui分析 : 搜索字符串"9000"定位支付成功代码 分析 if 判断逻辑,发现支付成功(9000)和失败(8000)的判断 Android Killer修改 : 找到 if-eqz v1, :cond_4 判断 修改为 if-nez v1, :cond_4 使支付失败时执行成功逻辑 效果 :支付失败但程序认为成功,可使用记牌器功能 案例2:卧龙影视VIP破解 目标 :绕过VIP验证 jadx-gui分析 : 搜索"getVip"定位VIP验证方法 分析 UserVip 实体类中的 isVip 、 End 、 Start 字段 Android Killer修改 : 找到 public getVip() 方法 修改为 const v0,0x1 强制返回VIP状态 效果 :登录后显示VIP状态,解锁全部功能 案例3:起名软件VIP破解 目标 :绕过五行选择限制 jadx-gui分析 : 搜索"getVip"定位验证代码 分析 switch 判断逻辑 Android Killer修改 : 找到两处 if-eqz v1, :cond_0 修改为 if-nez v1, :cond_0 或直接注释 getVip 方法 效果 :可无限制使用五行选择功能 案例4:RE文件管理器广告去除 目标 :去除退出时的广告 adb抓包 : 使用 adb shell dumpsys activity top 获取当前界面进程 定位广告Activity com.AddDouDouWall2.WebPageDownLoadMainActivity jadx-gui分析 : 找到广告URL和 DownLoadManagerService 分析 onDestroy 方法中的网络检查和启动逻辑 Android Killer修改 : 修改 if-eqz v0, :cond_0 为 if-nez v0, :cond_0 或替换广告URL为自定义页面 效果 :退出时不再显示广告 案例5:车来了广告去除 目标 :去除中间广告 DDMS分析 : 使用DDMS监控应用行为 过滤 com.ygkj.chelaile.standard 包名 定位广告域名 atrace.chelaile.net.cn Android Killer修改 : 搜索并替换广告域名为 127.0.0.1 效果 :中间广告消失 案例6:好搜小说大全插桩分析 目标 :学习代码插桩技术 Log信息输出插桩 : 在 onCreate() 方法中插入Log输出 使用Unicode编码特殊字符 注意寄存器数量调整( locals ) StackTrace栈跟踪 : 在关键方法如 loadData() 中插入栈跟踪代码 使用 Exception.printStackTrace() 输出调用链 DDMS分析 : 观察入口点和入口界面的执行顺序 分析栈跟踪信息,理解调用关系 四、常见问题解决 回编译失败 : APKTOOL版本问题:尝试不同版本 Java环境问题:检查Java版本和环境变量 程序崩溃 : 插桩导致寄存器不足:增加 locals 数量 方法调用错误:检查指令使用是否正确 init()方法插桩 : init方法在初始化时不会调用寄存器 是安全的插桩位置 五、高级技巧 栈跟踪分析 : 使用DDMS暂停分析栈 理解Parents(父节点)和Children(子节点)关系 分析调用链和循环体 动态调试 : 结合jadx-gui静态分析和动态调试 使用logcat监控程序行为 代码注入 : 修改关键判断逻辑(如if条件) 替换关键字符串和URL 强制返回值绕过验证 六、注意事项 法律风险 :所述技术仅用于学习目的 道德考量 :尊重开发者劳动成果 技术边界 :不得用于非法用途 通过系统学习Dalvik指令集和实战案例,可以逐步掌握Android逆向工程的核心技术。建议从简单案例入手,逐步深入理解Android应用的运行机制和破解方法。