• 大家好,我叫 Jack Darren,目前主要担任国内游戏发行 Android SDK 开发

写这篇文章的布景

  • 自从上次 Android 逆向入门保姆级教程 发布之后,便冲上了 Android 热榜榜首,而且还是连续两天榜首,首要非常感谢粉丝们的支撑。

Android 逆向之脱壳实战篇

  • 其间谈论区有许多粉丝反馈现在许多 App 都有加固,要逆向需求先脱壳,而且期望作者出一期《脱壳教程》

Android 逆向之脱壳实战篇

  • 已然话都到这个份上了,肯定是搞起来了

前语

  • 这篇文章比较干,比较偏实战,看之前建议先喝足水,慎入。

  • 在学脱壳之前,咱们先来复习一下,什么时分是加固?

    • 加固实质上便是对 dex 文件进行加壳处理,让一些反编译工具反编译到的是 dex 壳,而不是 dex 文件自身。详细的完成方式是,将原 dex 文件进行加密,再组成到 dex 壳中,而体系运转应用的时分,会加载 dex 壳文件,而 dex 壳里面有一个自定义的 ClassLoader 类,它会将原有 dex 文件进行解密,然后再加载到 dex 数组中。
  • 学完了加固,那么什么是脱壳呢?

    • 刚刚讲到了加固的原理,它实质的原理便是加壳,而脱壳就对应着加壳,咱们要对这层壳脱掉,漏出它本来的姿态,再简略点讲便是破解加固,市面上比较常见的脱壳手段便是《内存 dump》,刚刚咱们讲到的,体系会加载壳 dex,壳 dex 才会加载原 dex,那这个时分原 dex 现已被加载到内存中了,咱们只需求从内存中把它 dump 出来就能够了,这个原理是不是灰常简略呢?
  • 以下运用 360 加壳过的 apk,拖到 jadx 打开是这姿态的,这个便是壳的源码

Android 逆向之脱壳实战篇

了解 frida

  • 说到脱壳,咱们先认识一个东西:frida,它能够帮咱们从内存 dump 出原 dex 文件,why?什么是 frida,这个问题就由 ChatGPT 替我解答这个问题

Android 逆向之脱壳实战篇

  • 简略理解 frida 便是一个跨渠道的 hook 结构,那什么是 hook 结构呢?顾名思义,hook 是钩子的意思,在代码中,代表用钩子勾住代码,那么勾住代码有什么用呢?在实践开发中,咱们常常在需求代码前后刺进一段代码,比较常见的状况是计算办法的耗时,那么这个时分在办法前后各刺进代码,惯例的写法是直接在某个类的某个办法中写代码,这种做法的好处是代码看起来比较直观,但是一旦需求写的当地比较多的时分,前期开发和后续维护的工作量会呈几何增长,而 hook 结构能够处理这一问题,它能够帮你动态植入这些代码,不需求在每个办法写一遍重复代码,运用了面向切面的思维,类似 AOP,但它又不是 AOP,AOP 和它的差异在于,AOP 是在编译的进程中就会帮你植入代码,而 hook 结构是在运转的进程中植入代码。

  • 这儿为了照顾小白朋友,所以说得有点烦琐了,但是我的文章风格便是这样,高大上不是我的寻求,我的寻求是每一个看过文章的朋友都能看懂,下降大家的学习本钱,假如不能的话,还不如直接看官方文档。

电脑 frida 环境建立

  • 咱们这儿用的是 macOs 体系进行演示,windows 进程也差不多

  • 榜首步:输入以下指令装置 frida

pip install frida
  • 假如装置成功则会提示
Installing collected packages: frida
Successfully installed frida-16.0.2
  • 第二步:再输入下面指令装置 frida-tools
pip install frida-tools
  • 假如装置成功则会提示
Successfully installed colorama-0.4.6 frida-tools-12.0.1 prompt-toolkit-3.0.32 pygments-2.13.0 wcwidth-0.2.5
  • 假如装置进程呈现正告,提示以下信息的话
WARNING: The script pygmentize is installed in '/Users/xxx/Library/Python/3.8/bin' which is not on PATH.
Consider adding this directory to PATH or, if you prefer to suppress this warning, use --no-warn-script-location.
WARNING: The scripts frida, frida-apk, frida-compile, frida-create, frida-discover, frida-join, frida-kill, frida-ls, frida-ls-devices, frida-ps, frida-pull, frida-push, frida-rm and frida-trace are installed in '/Users/xxx/Library/Python/3.8/bin' which is not on PATH.
Consider adding this directory to PATH or, if you prefer to suppress this warning, use --no-warn-script-location.
  • 在环境变量中参加以下配置即可
export PATH="/Users/xxx/Library/Python/3.8/bin":"$PATH"
  • 第三步:然后测试 frida 是否装置成功,在指令行中输入(下面两个指令行任选一个即可)
frida --v
frida --version
  • 假如有输出 frida 的版别号的话,则证明现已装置成功了
16.0.2
  • 弥补:假如需求装置 frida 指定版别,则需求修改装置指令行为下面这样即可
pip install frida==12.8.0
pip install frida-tools==5.3.0
  • frida 和 frida-tools 版别之间的对应联系能够从 Github 发布的 relese assets 看到

Frida 手机环境建立

  • 前提条件:需求预备一台现已 root 的手机

  • 榜首步:输入 adb 指令来获取手机 CPU 处理器架构

adb shell getprop ro.product.cpu.abi
arm64-v8a
  • 第二步:到 Github 发布的 releases assets 中下载对应 CPU 处理架构的 frida-server,然后进行解压,这儿下载的是 frida-server-16.0.2-android-arm64.xz,注意 frida-server 需求和之前电脑装置版别共同才能够

  • 第三步:将下载好的 so 库经过 adb 指令复制到手机 /data/local/tmp 目录上面

adb push /Users/xxx/Downloads/frida-server-16.0.2-android-arm64 /data/local/tmp
  • 假如想修改复制到的 frida-server 文件名称,则将上面的指令行换成下面的即可
adb push /Users/xxx/Downloads/frida-server-16.0.2-android-arm64 /data/local/tmp/frida-server-16.0.2
  • 第四步:运用 adb 切换到 /data/local/tmp 目录下
adb shell
su
cd data/local/tmp
  • 第五步:给刚刚复制到手机上面的 frida-server 加履行权限(默认只有读写权限)
// 表明可读可写可履行
chmod 777 frida-server-16.0.2

运转 Frida

  • 榜首步:先运用 adb 切换到 /data/local/tmp 目录下
adb shell
su
cd data/local/tmp
  • 第二步:在上面指令行的基础上输入运转手机上面的 frida-server 的指令,履行后会堵塞当时指令窗口,这个是正常的,假如是堵塞了一瞬间就重启,证明是不正常的,能够换个手机试一下
./frida-server-16.0.2
  • 第三步:验证是否成功, 从头创建一个指令行窗口,输入以下指令来检查当时手机进程列表
frida-ps -U
  • 假如呈现以下过错提示,则需求将手机数据线拔下来从头插一次,然后从头运转一遍上面的指令即可
Failed to enumerate processes: unable to handle 64-bit processes due to build configuration
  • 假如呈现以下过错提示,证明端口被占用了,能够重启一下手机
Unable to start: Could not listen on address 127.0.0.1, port 27042: Error binding to address 127.0.0.1:27042: Address already in use
  • 假如呈现以下信息,则表明 Frida 现已装置成功
  PID  Name
-----  -----------------------------
 3374   Google
12041   Magisk
10795   QQ
12776   企业微信
 3720   当时界面
 8697   微信
 9401   相册
............
  • 第四步:最后再进行端口映射
adb forward tcp:27042 tcp:27042

运用 Frida-Apk-Unpack 进行脱壳

  • 榜首步:下载或许克隆 Frida-Apk-Unpack 工程
cd /Users/xxx/Desktop/FridaProject/App\ 脱壳/Frida-Apk-Unpack
  • 第二步:履行脱壳指令
// xxx.xxx.xxx 是应用的包名
// dexDump.js 是工程目录下的文件
frida -U -f xxx.xxx.xxx -l dexDump.js  --no-pause
  • 假如失利了,并提示以下信息
usage: frida [options] target
frida: error: unrecognized arguments: --no-pause
  • 则换成下面这个命名再履行
frida -U -f xxx.xxx.xxx -l dexDump.js
  • 假如失利了,并提示以下信息
Failed to spawn: unable to access PID 765 (zygote64) while preparing for app launch; try disabling Magisk Hide in case it is active
  • 处理这个问题也很简略,只需求关闭 MagiskHide 功能
Magisk 管理器 -> 设置 -> Magisk 选项 -> MagiskHide(关闭即可)
  • 又或许履行以下指令行来关闭
adb shell "su -c magiskhide disable"
  • 完事之后能够履行以下指令行来敞开
adb shell "su -c magiskhide enable"

最终效果展现

Android 逆向之脱壳实战篇

[PH 1::xxx.xxx.xx ]-> [16:54:09:927] magic : dex
035
[16:54:09:927] dex_size :1107632
[16:54:09:933] dump dex success, saved path: /data/data/xxx.xxx.xxx/1107632.dex
[16:54:10:167] magic : dex
035
[16:54:10:167] dex_size :3568668
[16:54:10:177] dump dex success, saved path: /data/data/xxx.xxx.xxx/3568668.dex
[16:54:10:181] magic : dex
035
[16:54:10:181] dex_size :284
[16:54:10:181] dump dex success, saved path: /data/data/xxx.xxx.xxx/284.dex
[16:54:10:278] magic : dex
035
[16:54:10:278] dex_size :284
[16:54:10:278] dump dex success, saved path: /data/data/xxx.xxx.xxx/284.dex
  • 其间 /data/data/xxx.xxx.xxx/1107632.dex/data/data/xxx.xxx.xxx/3568668.dex/data/data/xxx.xxx.xxx/284.dex 这几个便是脱壳之后得到真实的 dex 文件寄存途径了,咱们再运用 jadx 随机打开一个 dex 看看

Android 逆向之脱壳实战篇

  • 是不是灰常简略呢?

完结,撒花 ✿✿ヽ(▽)ノ✿