【移动安全基础篇】——28、Apk加固

1. java  混淆

【移动安全基础篇】——28、Apk加固_第1张图片

1)  名称替换
proguard:
                -printmapping map.txt
                -applymapping map.txt
dex2jar:
                d2j-init-deobf –f –o map.txt x.jar
                d2j-jar-remap –f –c map.txt –o x2.jar x.jar
jeb:
                script
2)  字符串加密

【移动安全基础篇】——28、Apk加固_第2张图片

3)  反射替换

【移动安全基础篇】——28、Apk加固_第3张图片

4)  其他
日志清除:Log.x
XML  混淆:清除 string 信息
Assert  加密:Hook AssertManager.open 方法

【移动安全基础篇】——28、Apk加固_第4张图片

5)  Demo 演示
执行了恢复脚本后的效果对比,左为混淆版本,右为恢复版本

【移动安全基础篇】——28、Apk加固_第5张图片

【移动安全基础篇】——28、Apk加固_第6张图片

恢复脚本:

【移动安全基础篇】——28、Apk加固_第7张图片

【移动安全基础篇】——28、Apk加固_第8张图片

【移动安全基础篇】——28、Apk加固_第9张图片

【移动安全基础篇】——28、Apk加固_第10张图片

【移动安全基础篇】——28、Apk加固_第11张图片

【移动安全基础篇】——28、Apk加固_第12张图片

【移动安全基础篇】——28、Apk加固_第13张图片

【移动安全基础篇】——28、Apk加固_第14张图片

【移动安全基础篇】——28、Apk加固_第15张图片

【移动安全基础篇】——28、Apk加固_第16张图片

【移动安全基础篇】——28、Apk加固_第17张图片

【移动安全基础篇】——28、Apk加固_第18张图片

【移动安全基础篇】——28、Apk加固_第19张图片

【移动安全基础篇】——28、Apk加固_第20张图片

【移动安全基础篇】——28、Apk加固_第21张图片

【移动安全基础篇】——28、Apk加固_第22张图片

【移动安全基础篇】——28、Apk加固_第23张图片

【移动安全基础篇】——28、Apk加固_第24张图片

【移动安全基础篇】——28、Apk加固_第25张图片

2. ELF  内存加载
加载 so 文件的函数,so 文件在 assert 文件夹中

【移动安全基础篇】——28、Apk加固_第26张图片

【移动安全基础篇】——28、Apk加固_第27张图片

【移动安全基础篇】——28、Apk加固_第28张图片

so 文件是被加密的,只能看到几个段。因为文件格式不正确,所以需要先将文件格式进行修复。

修改后拖到 IDA 里就不会报错了。

【移动安全基础篇】——28、Apk加固_第29张图片

因为 JNI_OnLoad 是被加密的,程序的执行首先会在 init_array 处。

【移动安全基础篇】——28、Apk加固_第30张图片

程序在执行的时候只用到了程序头部表和各个段,节区头部表没有被用到。有时候节区头部表会被删掉,如果要恢复的话就需要用到链接视图中的相关信息。

【移动安全基础篇】——28、Apk加固_第31张图片

对流程混淆的 so 文件进行恢复

【移动安全基础篇】——28、Apk加固_第32张图片

动态调试 so 文件

【移动安全基础篇】——28、Apk加固_第33张图片

【移动安全基础篇】——28、Apk加固_第34张图片

设置断点

【移动安全基础篇】——28、Apk加固_第35张图片

【移动安全基础篇】——28、Apk加固_第36张图片

不过由于该 app 中存在反调试,所以调试出错,接下来换另一种方法

手动对 so 文件的该部分进行修改,将其改成死循环。然后对该文件重新打包并签名将该 app 安装之后直接运行并用 ida 进行 attach

【移动安全基础篇】——28、Apk加固_第37张图片

程序停在了所修改的地方,然后将其改回去

【移动安全基础篇】——28、Apk加固_第38张图片

【移动安全基础篇】——28、Apk加固_第39张图片

可以进行动态调试,在解密函数处下个断点,加密方式是 RC4

【移动安全基础篇】——28、Apk加固_第40张图片

使用脚本将解密后的部分 patch 出来

打开 patch 后的 so 文件,可以看到代码正常

【移动安全基础篇】——28、Apk加固_第41张图片

【移动安全基础篇】——28、Apk加固_第42张图片

在这三个函数中,前两个是为了防止 dump,后面一个是对程序的 upx 段进行解码

【移动安全基础篇】——28、Apk加固_第43张图片

对其中的加密字符串进行还原

【移动安全基础篇】——28、Apk加固_第44张图片

【移动安全基础篇】——28、Apk加固_第45张图片

【移动安全基础篇】——28、Apk加固_第46张图片

【移动安全基础篇】——28、Apk加固_第47张图片

接下来使用动态跟踪的方式对 RC4 操作进行跟踪

【移动安全基础篇】——28、Apk加固_第48张图片

【移动安全基础篇】——28、Apk加固_第49张图片

整个 upx 的内存段已经被解密了,将其直接 dump 下来

对其文件头进行修改,使其能够被识别

【移动安全基础篇】——28、Apk加固_第50张图片

使用 ida 打开后发现该 so 文件依旧是被加密的

【移动安全基础篇】——28、Apk加固_第51张图片

【移动安全基础篇】——28、Apk加固_第52张图片

此处的 dlopen 实现内存加载在 dlopen 处下好断点

【移动安全基础篇】——28、Apk加固_第53张图片

【移动安全基础篇】——28、Apk加固_第54张图片

【移动安全基础篇】——28、Apk加固_第55张图片

将解密后的数据 patch 出来,将该文件用 ida 打开后,代码已经完全被还原,得到了原始的 so 文件

【移动安全基础篇】——28、Apk加固_第56张图片

3. Dex  整体加密
1)  Dex 整体加密方案

【移动安全基础篇】——28、Apk加固_第57张图片

替换 classloader 时机:
               Application:attachBaseContext()
              ContentProvider:OnCreate()
              Application:OnCreate()
加载原始 application:
              获取原始 application 的 class name
              加载原始 application 并生成对象
              替换 API 层的所有 Application 引用
              设置 baseContext 并调用原始 application 的 OnCreate()

【移动安全基础篇】——28、Apk加固_第58张图片

【移动安全基础篇】——28、Apk加固_第59张图片

【移动安全基础篇】——28、Apk加固_第60张图片

旧版本中存在的是 DexClassLoader

【移动安全基础篇】——28、Apk加固_第61张图片

DexFile 的结构体

【移动安全基础篇】——28、Apk加固_第62张图片

【移动安全基础篇】——28、Apk加固_第63张图片

【移动安全基础篇】——28、Apk加固_第64张图片

得到 DvmDex  结构之后就能够获取原始 Dex  文件
加载 dex 文件操作

【移动安全基础篇】——28、Apk加固_第65张图片

2)  Demo 

【移动安全基础篇】——28、Apk加固_第66张图片

 

【移动安全基础篇】——28、Apk加固_第67张图片

【移动安全基础篇】——28、Apk加固_第68张图片

StubApplication 继承自 Application,通过 StubApplication.interface()释放 so 文件

【移动安全基础篇】——28、Apk加固_第69张图片

【移动安全基础篇】——28、Apk加固_第70张图片

此处注册了两个 native 方法的函数

【移动安全基础篇】——28、Apk加固_第71张图片

【移动安全基础篇】——28、Apk加固_第72张图片

【移动安全基础篇】——28、Apk加固_第73张图片

【移动安全基础篇】——28、Apk加固_第74张图片

【移动安全基础篇】——28、Apk加固_第75张图片

【移动安全基础篇】——28、Apk加固_第76张图片

先执行 classLoader,然后再执行 interface7()函数,该函数更改了 ContentProvider,也更改了 Application 和 Context 的一些相关引用。stubApplication 的 OnCreate()函数执行结束时,内存中的 Application 的对象(ClassLoader)都指向了新的 Application,与 stubApplication 没有关系了。取 获取 dex  明文将脱壳后的 so 文件替换之前 apk 文件中的 so 文件,并在 so 文件执行时设置了断点。

【移动安全基础篇】——28、Apk加固_第77张图片

启动监听端口,然后进行端口转发,然后将目标 app 安装并调试运行

【移动安全基础篇】——28、Apk加固_第78张图片

【移动安全基础篇】——28、Apk加固_第79张图片

【移动安全基础篇】——28、Apk加固_第80张图片

【移动安全基础篇】——28、Apk加固_第81张图片

修改入口点

【移动安全基础篇】——28、Apk加固_第82张图片

【移动安全基础篇】——28、Apk加固_第83张图片

memory 起始地地方和大小

【移动安全基础篇】——28、Apk加固_第84张图片

根据 dex 文件头部数据信息 dump 出原始 dex 文件。

【移动安全基础篇】——28、Apk加固_第85张图片

4. Dex  方法隐藏
1)  Dex  文件

【移动安全基础篇】——28、Apk加固_第86张图片

【移动安全基础篇】——28、Apk加固_第87张图片

文件头结构

【移动安全基础篇】——28、Apk加固_第88张图片

【移动安全基础篇】——28、Apk加固_第89张图片

【移动安全基础篇】——28、Apk加固_第90张图片

将被隐藏的方法索引值改为 0,或者将方法的属性改成 native 并将 codeoffset 改为 0

【移动安全基础篇】——28、Apk加固_第91张图片

样本中的修复相关信息
2)  Demo  演示

【移动安全基础篇】——28、Apk加固_第92张图片

构造函数已经被隐藏了,显示的为 native 方法

初始化功能的函数 StartShell()

【移动安全基础篇】——28、Apk加固_第93张图片

StartShell(packageName, iIndex)函数

【移动安全基础篇】——28、Apk加固_第94张图片

InitStartShell()函数

【移动安全基础篇】——28、Apk加固_第95张图片

native 的 load()方法

【移动安全基础篇】——28、Apk加固_第96张图片

【移动安全基础篇】——28、Apk加固_第97张图片

找到 fixDvm()函数

【移动安全基础篇】——28、Apk加固_第98张图片

该函数中通过内存映射,得到 dex 文件数据

【移动安全基础篇】——28、Apk加固_第99张图片

【移动安全基础篇】——28、Apk加固_第100张图片

FixDexData 结构

【移动安全基础篇】——28、Apk加固_第101张图片

根据修正得到以下数据

【移动安全基础篇】——28、Apk加固_第102张图片

FixMethod 函数中根据 MethodID 得到相关字段

【移动安全基础篇】——28、Apk加固_第103张图片

【移动安全基础篇】——28、Apk加固_第104张图片

【移动安全基础篇】——28、Apk加固_第105张图片

修复效果对比

【移动安全基础篇】——28、Apk加固_第106张图片

5.  常见的 Anti  手段
1)  java

【移动安全基础篇】——28、Apk加固_第107张图片

通过监听这两个函数来进行反调试
绕过手段:定位到相关函数并修改
2)  native

  • ptrace  自身进程:同一时间进程最多只能被一个调试器进行调试
  • 检查父进程名称:由调试器启动时,被调试时的二进制文件的父进程为调试器
  • 态 检查进程运行状态:attach 时被调试进程父进程不再是调试器,此时检查
  • /proc/self/status TracerPid 的值,如果被调试状态 TracerPid 的值为调试进程的 Pid
  • 设置程序运行最大时间:程序调试时运行时间往往大于正常运行时间
  • 防 防 dump:关注/proc/self/mem 和/proc/self/pagemem,检查是否被 dump
  • 检查调试器进程 程:系统中有无调试器进程存在
  • 完整性校验
  • 断点检测
  • 单步检测

3)  emulator

  • 属性检测:Build.BRAND、Build.DEVICE、IMEI、IMSI
  • 虚拟机文件检测:/system/bin/qemu-props、/system/lib/libc_malloc_debug_qemu.so、
  • /sys/qemu_trace
  • 于 基于 cache  行为检测

【移动安全基础篇】——28、Apk加固_第108张图片

如果是在模拟器中的 modify 生效,在真实机器中 modify 无效基于代码指令执行检测:

【移动安全基础篇】——28、Apk加固_第109张图片

真实机器的 a 值为中间值,模拟器中可能会被合并为一句,a 值为最终值
4)  res

【移动安全基础篇】——28、Apk加固_第110张图片

【移动安全基础篇】——28、Apk加固_第111张图片

在 string 池的尾部加上一个相同 name 的字段指向一个指定的索引,在 resource 池中对应索引的位置加上不存在的一个 ID,然后在 apk 重打包后会多出来一个属性。

 

 

你可能感兴趣的:(【移动安全】,———移动安全基础篇)