拓十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

安卓逆向学习路线:从应用层分析到Native层对抗

安卓逆向学习路线:从应用层分析到Native层对抗

这几年时不时就有人跑来问我:安卓逆向怎么学?是不是得会汇编?要不要先学破解?也有人直接在搜索框里敲“android 逆向学习路线”“安卓逆向教程”,然后被一堆零散的资料劝退。作为常年在这行折腾的人,我太清楚这种迷茫了。今天这篇就把我自己的学习路径、带人带项目的思路,以及踩过的坑一次性讲清楚,尽量让不同基础的读者都能找到自己的入口。

先说清楚一点:安卓逆向不是一门单点技术,而是一套组合技能,涉及APK结构、Java/Kotlin代码分析、Smali指令、Native层So库、HTTP协议、密码学、脱壳与反调试对抗等等。它也不是只用来“破解App”,更常出现在漏洞挖掘、恶意软件分析、CTF竞赛、商业竞品分析、自动化爬虫与合规性检测等场景。你平时热搜里看到的“淘宝app逆向”“得物app逆向”“企查查api接口逆向”“大麦逆向”,本质上都是在跟这套组合拳打交道。

这篇文章适合谁?如果你会一点Python或Java,但完全没碰过逆向;或者你已经在用jadx看代码,却不知道下一步该学什么;再或者你被加固、混淆、Frida检测这些名词劝退过,那今天这篇就是给你准备的。

1. 先把方向定下来:安卓逆向到底在逆什么

很多人一上来就搜“安卓逆向教学”,结果被各种Demo和脱壳工具淹没。其实在动手之前,你得先搞清楚:逆向一个App,目标到底是什么?我习惯把安卓逆向分成四个常见方向,它们的侧重点完全不一样。

1.1 应用层逆向

应用层逆向是绝大多数新手的切入点。目标通常是APK中的Dex字节码和Smali代码,也就是App的Java/Kotlin逻辑层。比如你想知道一个App的登录接口参数是怎么拼出来的、某个按钮点击后调用了什么函数、某个VIP状态是怎么判断的,都可以通过反编译APK、阅读Java层代码来解决。

这层技术的核心工具是静态分析。用jadx或GDA打开APK,直接看到近乎源码的Java代码,再用AndroidStudio的SDK工具辅助定位。更底层的做法是直接看Smali,虽然阅读成本高,但在修改逻辑、手工打补丁时绕不开。很多新手会问要不要先学Smali,我的建议是:先能读懂,不急着会写,后面做重打包和过签名校验时会慢慢熟练。

1.2 协议层逆向

协议层逆向关注的是App与服务器之间的通信数据。你抓包看到一个登录请求的URL是/api/login,参数里有username、password、timestamp、sign,其中sign一看就是某种加密签名。只要搞清楚sign的生成规则,就能在自己的脚本里完整复现这个请求,这就是协议逆向。

协议层逆向的核心技能是抓包与Hook。Charles、Fiddler、mitmproxy都能拿来抓HTTP/HTTPS流量。但如果App做了证书校验,也就是常说的SSL Pinning,那么抓包工具会直接失效。这时候要么用Frida主动绕过证书校验,要么把App的Root CA证书装进系统信任区。这一层几乎是所有自动化采集、接口模拟、安全测试都必须掌握的内容。

1.3 Native层逆向

随着App安全水位提高,越来越多的核心逻辑不再放在Java层,而是下沉到So动态库里。你还是能看到Java层的入口函数,但它内部调用System.loadLibrary("core")加载Native库,真正的加密算法、关键校验都在C/C++代码里。这就是Native层逆向。

Native层逆向的主要工具是IDA Pro、Ghidra和Frida。你需要看得懂ARM汇编,至少要能识别函数调用、参数传递、字符串引用。很多新手在这层被劝退,因为“汇编劝退”“OLLVM混淆劝退”。我的建议是:如果你只做应用层分析和协议复现,Native层可以缓一缓;但如果想深入对抗和商业级逆向,这关迟早得过。

1.4 安全对抗

安全对抗是前面所有知识的综合应用。包括脱壳、反混淆、绕过反调试、绕过模拟器检测、修复签名校验等。现在的商业App基本都上了腾讯乐固、360加固、梆梆、爱加密这些加固方案,直接用jadx打开只会看到壳的入口,真正的Dex被加密藏在Native层或assets里。

安全对抗本身不是一个独立方向,而是你在分析真实目标时不断被逼出来的能力。你可以理解为,逆向前面的步骤是“看懂App”,到了对抗阶段,你是在“帮App脱掉外衣看清内脏”。

1.5 学习逆向的边界与价值

这里必须多说一句:逆向技术本身是双刃剑。我写这篇文章分享路线和工具,目的是帮你做安全研究、CTF竞赛、漏洞分析、恶意软件检测这类合法合规的事情,而不是去破解付费软件、绕过商业授权或者搞灰黑产。未经授权去分析真实商业App,本身就涉及法律风险,这一点希望每位读者都心里有数。

从价值角度看,逆向能力在工作市场里非常吃香。移动安全工程师、风控算法工程师、爬虫工程师,甚至游戏安全、物联网固件分析,都离不开这套技能。它也是理解整个移动应用运行机制的一条捷径。

2. 学习路线总览:四个阶段,一步一个脚印

很多教程一上来就教你“如何用Frida hook某个函数”,这是典型的“知其然不知其所以然”。我带的学员如果基本功不扎实,遇到一点点变化就会卡死。所以我的建议是,把学习过程分成四个阶段,每个阶段都有明确的目标和通过标准。

2.1 阶段零:环境与工具链搭建

这个阶段的目标不是写代码,而是把“折腾环境”的恐惧感消除掉。你需要准备:

  • 一台电脑,Windows/Linux/macOS都行,内存建议16G以上,因为要同时跑模拟器和Android Studio。
  • 一款安卓模拟器,比如Android Studio自带的AVD,或者第三方模拟器。逆向调试最好用原生模拟器或真机,很多App会检测模拟器,后期你还需要会绕过检测。
  • Android SDK与ADB工具。ADB(Android Debug Bridge)是你连接设备和电脑的桥梁,几乎所有动态操作都靠它。
  • 一台可以Root的真机或支持Root的模拟器,推荐Pixel系列,主要是因为解锁Bootloader、刷Magisk方便。
  • Frida环境,包括PC端的frida-tools和移动端的frida-server,这是目前最好用的动态插桩框架。
  • 静态分析工具:jadx-gui、GDA。
  • 抓包工具:Charles或mitmproxy。

很多新手在网上搜“android studio下载”“android sdk官网下载”“android studio安装教程”,其实把Android Studio装好、把SDK配齐就够了。这里有个容易踩的坑:Android Studio主要用来跑模拟器和看工程代码,逆向分析本身并不需要它,但如果你后面要自己写验证脚本、编译Xposed模块或Frida插件,那它又成了必需品。

阶段零的通过标准:能用ADB连接模拟器或真机,能成功安装并打开一个普通APK,能在设备上运行adb logcat看到日志。这个阶段通常1周内可以完成。

2.2 阶段一:Java层静态分析

这一阶段的核心是“看懂App在干什么”。建议从自己写的Demo App开始练手,或者找一些没有加固的开源项目来拆解。

先了解APK的基本结构:classes.dex是Java字节码集合,AndroidManifest.xml是入口和权限声明,res/是资源文件,lib/是So库,META-INF/是签名信息。然后用jadx打开APK,试着回答这几个问题:

  • App的入口Activity是哪个?
  • 登录按钮点击后,代码走到了哪些函数?
  • 有没有把关键字符串硬编码在里面?

静态分析的关键是“跟着逻辑走”。比如你在jadx里搜索password关键字,找到一处赋值或比较逻辑,再跳转到对应方法,逐渐还原整个调用链。这个过程很像读侦探小说,每条线索都会指向下一个目标。

同时,你还要学会重打包的基本操作。用apktool解包APK、修改Smali代码、重新打包、签名、安装到设备。这是理解Smali和校验逻辑的必经之路。很多人做重打包后App闪退,就是因为没处理签名校验或完整性校验。这个阶段能真正走通一遍,你对App结构的理解会上一个档次。

阶段一通过标准:能独立阅读一个未加固App的Java层逻辑,能定位到关键函数,能完成一次Smali修改和重打包签名。

2.3 阶段二:动态调试与Hook

静态分析能让你“看懂”代码,但动态调试才能让你“验证”代码。很多时候你猜某个加密函数被调用了,但不确定传参是什么,直接Hook一下就知道答案了。

这个阶段的陈咬金是Frida。Frida允许你在App运行时注入JavaScript代码,Hook Java函数、Native函数,甚至直接调用类的方法。我还记得自己第一次用Frida打印出目标函数的入参和返回值时,那种“开了天眼”的感觉。你会觉得整个App在你面前变成了透明的。

Frida的实际操作模式很简单:

  • 把frida-server推到手机/data/local/tmp/,开启端口监听。
  • 电脑端用frida-ps -U看设备进程列表。
  • 用frida-trace -U -i "open" 包名跟踪Native层函数调用。
  • 或者写一个hook.js脚本,用Java.perform在运行时改变函数行为。

这阶段同时可以引入Xposed/LSPosed框架,它和Frida的区别在于,Xposed偏持久化Hook,Frida偏即时注入。实际工作中Frida用得更多,Xposed通常用来开发固定模块。你还可以用objection这个基于Frida的工具,一条命令就能完成内存搜索、绕过Root检测、SSL Pinning绕过等操作,非常适合新手建立信心。

阶段二通过标准:能用Frida Hook任意Java方法,能打印参数和返回值,能主动调用目标方法,能定位并绕过简单的检测逻辑。

2.4 阶段三:协议分析与算法还原

完成了前面几个阶段,你已经具备“分析一个功能点”的能力。现在可以挑战一个完整的业务接口了。比如一个App的登录接口,你需要在抓包软件里看到完整的请求参数,并通过代码分析还原出参数生成算法,最终在Python脚本里模拟登录。

这一步通常要做三件事:

  • 抓包:用Charles配置SSL代理,看到请求和响应明文。
  • 定位加密逻辑:在jadx中搜索参数名(如sign、token),找到生成方法,判断是纯Java层还是Native层。
  • 还原算法:如果是MD5、AES、RSA这类常见算法,直接根据代码逻辑重写;如果是复杂算法或So层逻辑,就需要用Frida调用原函数拿到结果,或者用Unidbg在PC端模拟执行So文件。

我在实际项目中见过太多“加密函数藏在So里”的情况。这时候你不需要一上来就逆汇编,先用Frida Hook住Native函数边界,拿到输入输出,很多场景下就足够复现协议了。等遇到必须改算法本身的场景,再回头啃Native。

这一阶段也绕不开脱壳。如果目标App上了加固,jadx里只看得到壳代码,你需要先用frida-dexdump在内存中dump出真正的Dex,再用jadx分析。BlackDex和FART也是我常用的脱壳工具,后面会细说。

阶段三通过标准:能独立分析一个App的某个业务接口,把请求参数生成过程完整复现到Python或Java脚本里,并且能处理简单的加固与SSL Pinning。

2.5 阶段四:Native层与反对抗

等你想挑战更高难度的目标,比如分析某个安全SDK的签名算法,或者绕过App的反调试机制,就需要进入Native层。

这个阶段的知识跨度很大。你需要懂ARM64汇编、ELF文件格式、So库加载流程,还要会用IDA Pro和Ghidra做静态分析,用Frida的Native Hook能力做动态插桩。常见的学习路径是:

  • 学习ARM汇编基础:寄存器、指令、栈帧、函数调用约定。
  • 用IDA打开一个So文件,找到导出函数,F5反编译成伪代码。
  • 结合动态调试,确认输入输出,还原关键算法。
  • 学习OLLVM混淆的特征,尝试识别控制流平坦化和字符串加密。

刚接触时建议用一些CTF题练手,像babyre这类入门级Reverse题目,就是为这个阶段准备的。自己编译一个带混淆和反调试的So文件,再尝试分析自己写的东西,会大幅降低学习曲线。

阶段四通过标准:能分析一个中低难度的So库,能还原出关键算法的逻辑,能绕过简单的反调试和模拟器检测。

3. 实操案例:从登录接口的sign参数到完整协议复现

光讲路线太虚了,我拿一个非常典型的Demo来走一遍全流程。假设目标App很简单,只有一个登录功能,点击登录后会向/api/login发送POST请求,参数包括username、password、timestamp、sign。现在我们要搞清楚sign是怎么生成的,并用Python复现登录。

3.1 抓包定位目标接口

第一步永远是抓包。把手机代理指向电脑上的Charles或mitmproxy,安装好证书后,打开App执行一次登录操作。请求长这样:

POST http://api.example.com/api/login HTTP/1.1 Content-Type: application/x-www-form-urlencoded username=test&password=123456&timestamp=1710000000&sign=9f6a1f2e...

你一眼能看出sign是32位十六进制字符串,很像MD5。但到底是对哪些字段做MD5?顺序是什么?有没有拼接固定Salt?这些信息抓包看不出来,得回到代码里分析。

3.2 静态分析:用jadx定位sign生成逻辑

把APK拖进jadx-gui,搜索sign关键字。如果代码没有被混淆,通常你会直接看到类似这样的方法:

public static String getSign(String username, String password, String timestamp) { String raw = username + password + timestamp + "a1b2c3d4"; return MD5.md5(raw); }

这就拿到了关键逻辑:sign = md5(username + password + timestamp + "a1b2c3d4")。

如果搜索sign出现太多无关结果,可以换个思路:去定位网络请求发送的代码。搜索OkHttp或HttpURLConnection相关代码,找到封装请求参数的工具类,再顺着调用关系找到getSign。这个小技巧在实际项目中很管用,因为网络层代码往往是固定结构,比直接搜业务参数更容易命中。

3.3 动态验证:用Frida验证你的判断

静态分析只能告诉你“大概是这样”,但你不确定代码到底走没走这个分支。这时候用Frida直接验证。假设你分析出的类名是com.example.demo.LoginHelper,方法名是getSign,Frida脚本可以这样写:

Java.perform(function () { var LoginHelper = Java.use("com.example.demo.LoginHelper"); LoginHelper.getSign.implementation = function (username, password, timestamp) { var result = this.getSign(username, password, timestamp); console.log("getSign(" + username + ", " + password + ", " + timestamp + ") => " + result); return result; }; });

把脚本保存为hook_sign.js,执行:

frida -U -f com.example.demo -l hook_sign.js --no-pause

App启动后你再点一次登录,控制台就会打印出getSign的入参和返回值。如果返回值跟抓包结果一致,说明你判断对了。如果对不上,说明真正的加密逻辑可能在Native层,或者走的不是这个方法,继续跟进。

3.4 Native层情况:当代码不在Java层怎么办

如果jadx里找不到getSign的实现,或者只看到System.loadLibrary("core"),那加密逻辑很可能在So库里。应对方案有两种。

第一种,用Frida Hook Native函数。先在jadx里找到Java层的Native方法声明,比如:

public static native String getSign(String username, String password, String timestamp);

然后Frida可以用Interceptor.attach拦截So中的导出函数,打印输入输出。这种方式不还原算法,但能动态拿到结果,已经足够做协议复现。

第二种,用Unidbg在PC上模拟执行So文件。Unidbg是一个基于JNI模拟的开源项目,可以在电脑上直接加载目标App的So库并调用其Native方法。它的好处是不需要真机,不需要Root,还能绕过一些设备环境检测。我第一次用Unidbg跑通一个加固App的So算法时,真的觉得打开了新世界。

3.5 协议复现:Python脚本模拟登录

拿到签名算法后,就可以在Python里写脚本了。如下所示:

import hashlib import time import requests username = "test" password = "123456" timestamp = str(int(time.time())) salt = "a1b2c3d4" raw = username + password + timestamp + salt sign = hashlib.md5(raw.encode()).hexdigest() data = { "username": username, "password": password, "timestamp": timestamp, "sign": sign, } resp = requests.post("http://api.example.com/api/login", data=data) print(resp.text)

如果请求返回的JSON和App内一致,说明整个逆向链路已经跑通。这个案例非常简单,但它的方法论是通用的:抓包定位参数、静态分析找算法、动态Hook验证、脚本复现。遇到再复杂的App,核心流程也逃不出这四步。

4. 新手最常见的坑:环境类、分析类、对抗类问题排查

实操多了就会发现,逆向真正难的不是那些高深算法,而是莫名其妙的坑。我把这些年带学员过程中出现频率最高的问题,给你整理成一张速查表。

4.1 环境与连接问题

问题表现可能原因排查思路
模拟器连不上ADBADB版本与模拟器端口不匹配用adb connect 127.0.0.1:端口手动连接,或换用Android Studio的ADB
frida-ps -U看不到进程frida-server没启动或版本不匹配PC端和手机端的frida版本必须一致,检查/data/local/tmp/frida-server是否存在
Frida提示架构错误So库或frida-server架构与手机不符adb shell getprop ro.product.cpu.abi查看架构,下载对应的frida-server
抓包工具看不到HTTPS内容证书没装好或证书校验未绕过重新安装证书到系统信任区,或先用objection关闭SSL Pinning

frida-server版本不匹配这个问题特别隐蔽,很多人以为脚本写错了,折腾一下午最后发现是版本号差了一位。建议在PC端执行pip show frida查看版本,下载完全相同的frida-server版本,不要用“最新版”三个字糊弄自己。

4.2 分析与脱壳问题

问题表现可能原因排查思路
jadx里搜不到关键字符串字符串被加密或存放在So库用strings命令查So文件,用objection内存搜索
脱壳后Dex无法打开Dump时机不对或Dump不完整换用FART或BlackDex重新Dump,确认Dex文件头部是dex\n035
重打包后App闪退存在签名校验或完整性校验用apktool查看是否存在校验逻辑,或放弃重打包改用Frida动态注入
jadx打开加固App只看到壳入口App未脱壳先运行App直到核心代码加载进内存,再用frida-dexdump dump在内存中的Dex

我见过太多新手把一半时间耗在“怎么绕过签名校验”上。其实现在的商业App基本不会允许你重打包运行,与其死磕重打包,不如直接上动态Hook,这反而更接近真实工作场景。

4.3 对抗逻辑问题

问题表现可能原因排查思路
Frida一运行App就退出存在反Frida检测搜索frida、ptrace等关键词定位检测代码,用Magisk Hide或修改检测特征绕过
模拟器上运行App直接提示“设备不支持”存在模拟器检测在Native层或Java层搜索Build.FINGERPRINT、/dev/qemu_pipe等特征
算法还原后请求失败校验字段不止当前分析的参数,或存在时间戳校验还原完整请求头,对比抓包中的header逐一补齐
Hook不生效代码可能在Native层,或经过混淆与加固用frida-trace跟踪So函数,必要时动态Dump内存数据

反调试和反Frida检测近几年升级很快。遇到这类问题,我的建议是不要一上来就硬刚,先看看App有没有把关键检测做在启动早期的Native层。如果做在Native层,通常需要配合IDA动态调试才能找到准确的检测点,这个复杂度已经属于进阶范畴了。

4.4 我的通用排查心法

除了具体问题,我想分享一个适用性很强的排查思路:先确认链路是否通。

比如抓包内容看不到,先确认代理是否配置成功,能不能打开一个HTTP网站;Frida Hook不生效,先试试frida-ps -U能不能看到进程,再写一个setTimeout打印日志看注入是否成功;jadx搜索不到方法,先确认APK是否脱壳、方法名是否被混淆。把这些基线检查一遍,很多“玄学问题”都会变成“低级问题”。

另一个心法是“对比旧版与新版”。分析目标App时,如果新版加了壳或混淆严重,去下载一个几个月前的旧版本,很多时候旧版的逻辑和新版几乎一样,只是加了个壳。先分析清楚旧版,再回来分析新版,你会轻松很多。因为App迭代过程中,核心业务代码并不会频繁重写,变的主要是外围对抗策略。这也是我在实际项目里最常用的降维打击手段。

5. 进阶方向与资源推荐

如果你已经把上面这条路线走通了,接下来方向就很清晰了:要么往深度走,要么往广度走。

往深度走,就是死磕Native层与反混淆。推荐几个高质量方向:学习ARM64逆向与IDA脚本编写、研究OLLVM控制流平坦化的还原技巧、分析VMP虚拟化保护的So库。这些内容难度大,但一旦掌握,你就属于金字塔顶端那一小撮人了。

往广度走,就是把逆向能力迁移到其他平台。安卓逆向与iOS逆向在思路上高度相通,只是工具链不同;安卓逆向与Web/JS逆向更是有大量重叠,比如App内嵌WebView的请求,本质上就是JS逆向;再往底层走,还有IoT固件逆向、Windows恶意软件分析等方向。你会发现自己学的不是“安卓逆向”,而是一套通用的“解剖未知系统”的方法论。

学习资源方面,我的建议是:

  • 入门书籍看《Android软件安全与逆向分析》,内容老但架构完整,适合搭框架。
  • 勤刷CTF平台上的逆向题,比如看雪、攻防世界、BUUCTF里的Reverse题目,特别是babyre这种题,题目小而精,练手效率极高。
  • 看开源工具源码,比如jadx、Frida、objection的GitHub仓库,读代码比看教程学得快。
  • 多写分析笔记。我自己的经验是,每次逆向完一个目标,都把流程、工具、脚本、踩坑记录整理成文档。半年后回头看,这就是你最好的知识库。

说到底,逆向学习没有捷径,唯一的捷径就是把基础打牢、把工具用熟、把案例做透。卡在某个点上的时候,不要焦虑,放下键盘去跑跑步、睡一觉,思路很可能就通了。这行拼的不是爆发力,而是持久力,只要你不放弃,遇到的问题都会变成你的经验值。

返回列表