Android 混淆技巧与反混淆 dac519c3b5927f2762a2fa6a94b630f44ad9d11f # About Me 小波 Bob Pan 混淆 反混淆 dex2jar 加固 脱壳 pxb1988@gmail.com Image from: http://www.usmile.at/sites/default/files/publications/201306_obf_report_0.pdf # 混淆VS加固 混淆 加固 •  将代码变得难以阅读 •  配置复杂 需要开发配合 •  隐藏代码 •  对抗自动化工具 •  反调试/反篡改/反注入 •  一键搞定 不需要开发配合 不冲突, 可联⽤用! # 工具 •  ProGuard •  DexGuard Ref: http://www.saikoa.com/comparison-proguard-and-dexguard # 名字替换 •  替换类名 •  替换函数名 •  替换成员名 •  替换所有引用 优点: λ 代码可读性差 λ 减少文件大小 缺点: λ 接⼝口相关的名字⽆无法替换 λ 反射很难⾃自动识别 # 名字替换:奇葩的名字 •  超长名字 oooooooooooooo... •  找茬 Oo0o0OO00oooOOo0oo ijijijjiiiJiIIjii •  __$$_$$$$__$$_ •  java语法关键字 int int = 5; •  Unicode •  ȷava \u0237 •  CJK字符 •  难以阅读字符 •  盲文点字模型 2800-28FF # 名字替换:如何对付奇葩 ? •  相对来说'abc'是比较好阅读的 -dontshrink -dontoptimize -dontusemixedcaseclassnames -keepattributes *Annotation* •  Proguard 再混淆一次! # ⼏几⼤大组件 -keep public class * extends Activity/Application/... ... #其他keep, 这⾥里略去 -dontwarn ** -printmapping mapping0.txt -injars obad-dex2jar.jar -outjars aaa.jar -libraryjars android.jar # 名字替换:结果比较 处理前 处理后 # 名字替换:如何对付abc ? •  没办法自动化, 只能靠阅读代码 •  高富帅 JEB •  普通大众 Proguard 名字替换: Proguard重命名 # 1. ⽣生成默认的mapping文件 λ  Proguard配置 -dontshrink -dontoptimize -injars aaa.jar -libraryjars android.jar -keep class * -printmapping mapping1.txt Mapping文件 com.android.system.admin.x -> com.android.system.admin.x: java.lang.String a -> a java.lang.String d -> d int e -> e ... 名字替换: Proguard重命名 # 2. 修改mapping文件, 重新运行Proguard λ  Mapping文件 com.android.system.admin.x -> ...ObadSQLiteOpenHelper: android.database.sqlite.SQLiteDatabase f -> database byte[] g -> encoded_data_array java.lang.String a(int,int,int) -> decrypt Proguard配置 -dontshrink -dontoptimize -injars aaa.jar -outjars bbb.jar -libraryjars android.jar -applymapping mapping1.txt # Proguard重命名结果 # 反混淆大项目(名字恢复) 识别开源SDK 再混淆一次 ⾃自动化重命名 a → Clz_a b → fld_b c → mtd_c d → Clz_d_List ⾃自动化分析 Source Enum ACC_BRIDGE Getter/setter ⼿手⼯工分析代码 ⾃自动反编译 + 源码在⼿手 日志 toString ⼿手⼯工调整 # 字符串加密 •  将字符串在运行时恢复 •  DexGuard •  String a(int, int, int) •  Other •  String a(String) 优点: λ 静态看不到字符串 Class.forName(a(130, 1, -10)) .getMethod(a(53, 19, -21), Class.forName(a(79, 1, -11))) .invoke(j, instance); 缺点: λ 内存消耗增加 λ 性能降低 # 字符串加密:简单实现 •  Java bytecode 使用LDC指令加载字符串 •  替换对应的LDC指令即可实现加密 System.out.println(“hello world!”); getstatic System.out LDC “hello world!” invokevirtual println(String) getstatic System.out sipush 130 sipush 1 sipush -10 invokestatic a(int,int,int) invokevirtual println(String) 字符串加密:带来的问题 # 使用'==' ⽐比较字符串 λ  void fa(){ fb(“1.0”); } void fb(String version) { if(version == “1.0”){ print(“yes!”); } } void fa(){ fb(new String(...)); } void fb(String version) { if(version == new String(...)){ print(“yes!”); } } 条件成立, 打印yes 解决办法: 使用'equals' ⽐比较字符串 λ  条件不成立, 什么都没有 字符串加密: 如何应对? # private static String decrypt(int n, int n2, int n3) { … } String a = decrypt(-20, 842, -576); •  静态函数 •  返回值是String •  解密函数没有对外引用 •  参数是固定值 解决办法: 找到对应的函数和参数, 反射调⽤用, 将结果写回. # 字符串解密结果 解密前 注:t.q(...)也是解密函数 解密后 # 反射替换 •  将函数替换为等价的反射API调用 String c = "abc".substring(2,3); String c = (String)Class.forName("java.lang.String") .getMethod("substring", int.class, int.class) .invoke("abc", 2, 3) 优点: λ 与字符加密串结合效果更佳 缺点: λ 代码⼤大⼩小增加 λ 性能降低 # 反射替换: 简单实现 Local Stack Opcode ldc "abc" String c = "abc".substring(2,3); 思路: “abc” sipush 2 “abc”, 2 sipush 3 “abc”, 2, 3 invokevirtual substring(II) 1. 将Stack的数据保存到Local 2. 构建Class对象 3. 构建Method对象 4. 重新加载Local中的值到Stack 5. 调⽤用invoke函数

pdf文档 2015-《Android混淆技巧与反混淆-小波》

安全研究库 > 网络论坛材料 > 阿里巴巴2015年安全峰会PPT > 文档预览
34 页 0 下载 35 浏览 0 评论 0 收藏 3.0分
温馨提示:如果当前文档出现乱码或未能正常浏览,请先下载原文档进行浏览。
2015-《Android混淆技巧与反混淆-小波》 第 1 页 2015-《Android混淆技巧与反混淆-小波》 第 2 页 2015-《Android混淆技巧与反混淆-小波》 第 3 页 2015-《Android混淆技巧与反混淆-小波》 第 4 页 2015-《Android混淆技巧与反混淆-小波》 第 5 页
下载文档到电脑,方便使用
还有 29 页可预览,继续阅读
本文档由 张玉竹2022-04-07 17:43:46上传分享
给文档打分
您好可以输入 255 个字符
安信天行文库的中文名是什么?( 答案:安信天行 )
评论列表
  • 暂时还没有评论,期待您的金玉良言