Lazy loaded image
《Android 系统安全攻防:从启动到风控的博弈艺术》
Words 8389Read Time 21 min
2026-7-15
2026-7-15
type
Post
status
Published
date
Jul 15, 2026
slug
summary
手册定位:本书旨在打造一本“逆向工程领域的《新华字典》”,从零基础的语言工具,到高阶的内核攻防与反取证对抗,构建完整的知识闭环。既适合新手系统爬升,也适合老手案头速查。
tags
Android
圣经
必看精选
逆向工程
推荐
category
Android逆向
icon
password
网址
上次编辑时间
Jul 15, 2026 09:46 AM
comment
AI 总结

—— 终极七卷总纲

手册定位:本书旨在打造一本“逆向工程领域的《新华字典》”,从零基础的语言工具,到高阶的内核攻防与反取证对抗,构建完整的知识闭环。既适合新手系统爬升,也适合老手案头速查。

卷零:筑基篇 —— 逆向工程的“内功心法”

本卷目标:彻底扫清语言、汇编与工具环境障碍,为后续所有章节打下坚实基础。如果你是初学者,请务必通读本卷;如果你是老手,可作为工具书随时查阅。

第零章:开发环境与作战准备

0.1 操作系统选择

  • 0.1.1 Windows Subsystem for Linux (WSL2) vs 原生 Ubuntu
  • 0.1.2 macOS 环境的配置与取舍

0.2 必备 SDK/NDK 环境变量配置

  • 0.2.1 JAVA_HOMEANDROID_HOMENDK_HOME 的配置原理
  • 0.2.2 adb 与 fastboot 常用命令大全
    • adb logcat 日志过滤技巧
    • adb shell 提权与 su 切换
    • adb pull/push 文件传输
    • fastboot flash 刷机命令详解

0.3 源码同步

  • 0.3.1 repo init 与 repo sync 拉取 AOSP 百万级代码
  • 0.3.2 源码分支切换与标签管理
  • 0.3.3 常见网络问题与镜像源配置

0.4 刷机救砖

  • 0.4.1 fastboot flash 分区表详解(bootsystemvbmetauserdata
  • 0.4.2 9008 深度刷机模式(高通平台)
  • 0.4.3 MTK BROM 刷机模式
  • 0.4.4 救砖实战:从变砖到恢复

第一章:Java / Kotlin 逆向必备基础

1.1 Java 字节码与内存模型

  • 1.1.1 栈(Stack)与堆(Heap)的区别:局部变量表与对象实例存储位置
  • 1.1.2 synchronized 与 volatile 的底层实现(monitor 指令与内存屏障)

1.2 反射(Reflection)—— 逆向的第一把钥匙

  • 1.2.1 Class.forName() 动态加载类绕过 ProGuard 混淆
  • 1.2.2 setAccessible(true) 暴力访问私有成员变量和方法
  • 1.2.3 反射调用 hide API(如 ServiceManager.getService()

1.3 类加载器(ClassLoader)—— Hook 的结构性死穴

  • 1.3.1 BootClassLoaderPathClassLoaderDexClassLoader 的双亲委派模型
  • 1.3.2 为什么 Xposed/LSPosed 注入后,多出来的 ClassLoader 是致命检测点

1.4 JNI(Java Native Interface)—— Java 与 C/C++ 的桥梁

  • 1.4.1 native 方法的注册方式:静态注册(Java_pkg_cls_method)与动态注册(RegisterNatives
  • 1.4.2 JNIEnv 与 jobject / jclass 指针的线程绑定原理
  • 1.4.3 JNI_OnLoad 的执行时机与逆向分析价值

第二章:C / C++ 与编译链接原理

2.1 指针与内存地址(Native 世界的灵魂)

  • 2.1.1 指针的步长(int *p vs char *p 加减运算差异)
  • 2.1.2 函数指针(void (*func)(int))—— 这是 PLT Hook 和 Inline Hook 的操作对象

2.2 内存布局与结构体对齐(Struct Alignment)

  • 2.2.1 为什么 ARM 平台结构体默认 4/8 字节对齐(__attribute__((packed)) 的利与弊)
  • 2.2.2 虚函数表(vtable)在 C++ 对象内存中的位置(偏移 0 处)

2.3 编译链接过程

  • 2.3.1 预处理(E)→ 编译(S 生成汇编)→ 汇编(生成 .o)→ 链接(ld
  • 2.3.2 extern "C" 的作用:防止 C++ Name Mangling(名字修饰),保证 dlsym 能找到符号

第三章:Smali 与 Dalvik 字节码

3.1 Smali 语法基础(Dalvik 可读文本表示)

  • 3.1.1 基本类型映射:V(void)、Z(boolean)、B(byte)、S(short)、C(char)、I(int)、J(long)、F(float)、D(double)
  • 3.1.2 引用类型:Ljava/lang/String; 与数组 [I

3.2 常用指令集

  • 3.2.1 数据操作:constmoveiput/iget(实例字段)、sput/sget(静态字段)
  • 3.2.2 方法调用:invoke-virtual(普通)、invoke-static(静态)、invoke-super(父类)、invoke-interface(接口)
  • 3.2.3 条件跳转:if-eqzif-nezcmp-long 与 switch 指令
  • 3.2.4 返回指令:returnreturn-voidreturn-wide

3.3 实战 Smali 插桩

  • 3.3.1 修改 smali 文件插入 Log.d 打印参数
  • 3.3.2 修改条件跳转绕过 VIP 校验
  • 3.3.3 重打包签名绕过简单校验

第四章:ARM64 / Thumb-2 汇编速成

4.1 寄存器别名与用途

  • 4.1.1 X0-X7:参数传递(前 8 个参数)与返回值(X0
  • 4.1.2 X29 (FP):帧指针(栈基址)、X30 (LR):返回地址、SP:栈顶指针

4.2 寻址模式

  • 4.2.1 立即数寻址(MOV X0, #0x10
  • 4.2.2 寄存器间接寻址(LDR X0, [X1])—— 解引用指针
  • 4.2.3 PC 相对寻址(ADR X0, label)—— 逆向定位全局变量的关键

4.3 函数序言与尾声(Prologue & Epilogue)

  • 4.3.1 标准栈帧构建:stp x29, x30, [sp, #-32]!(压栈保存,分配栈空间)
  • 4.3.2 对比 x86 的 push ebp / mov ebp, esp 的异同

4.4 关键指令速查

  • 4.4.1 跳转指令:BBLBRBLR
  • 4.4.2 加载/存储:LDRSTRLDPSTP
  • 4.4.3 算术逻辑:ADDSUBEORANDORR
  • 4.4.4 系统调用:SVC #0(x8 存放系统调用号)
  • 4.4.5 断点指令:BRK #0(机器码 0xD4200000

第五章:核心工具链使用手册(全流程图解)

5.1 Android Studio 与 GDB(动态调试基础)

  • 5.1.1 使用 lldb 附加 debuggable 进程,断点打在 art::Method 入口
  • 5.1.2 jdb 调试 Java 层:suspend 挂起与 watch 变量
  • 5.1.3 调试非 debuggable 应用的绕过方法

5.2 Jadx / JD-GUI(静态反编译利器)

  • 5.2.1 如何快速搜索字符串(Search -> Text)定位关键加密逻辑
  • 5.2.2 利用 Show Bytecode 功能对照 Smali 与 Java 逻辑
  • 5.2.3 导出所有资源与 res 目录结构分析

5.3 IDA Pro / Ghidra(Native 杀手锏)

  • 5.3.1 反汇编视图(Graph View)与反编译(F5)的使用时机
  • 5.3.2 常用快捷键:G(跳转地址)、X(交叉引用)、P(创建函数)
  • 5.3.3 导入 .so 时要注意的基址(Load Address)与 ARM/Thumb 模式切换(ALT+G 修改 T 位)
  • 5.3.4 Ghidra 的 DEX 反编译插件配置

5.4 Frida(动态插桩与 Hook)

  • 5.4.1 Python 接口与 JS 脚本交互:Java.perform 与 Interceptor.attach
  • 5.4.2 frida-ps -U 查看进程,frida-trace 自动追踪系统 API
  • 5.4.3 常用 Frida 脚本模板:Hook 构造函数、方法重载、修改返回值

5.5 Apktool / Uber APK Signer(重打包与签名)

  • 5.5.1 解码:apktool d app.apk → 修改 Smali/资源 → apktool b 回编译
  • 5.5.2 zipalign 对齐优化
  • 5.5.3 apksigner 签名(v1/v2/v3 签名方案的区别)
  • 5.5.4 绕过签名校验的初级思路:核心破解(禁用 SignatureChecker

卷一:硬件复位到系统启动 —— 从摁下电源键到 Launcher 显示

本卷目标:理解 Android 从通电到桌面的完整链路。这是所有逆向工程的基础 —— 只有理解系统“本该如此”,才能发现“哪里可以被修改”。

第六章:BootROM 与 Bootloader —— 硬件的“接生婆”

6.1 BootROM(启动只读存储器)

  • 6.1.1 硬件复位向量(Reset Vector)与 PC 寄存器的初始值
  • 6.1.2 BootROM 的职责:初始化时钟、SRAM、加载 Bootloader
  • 6.1.3 SoC 厂商差异:高通(PBL/SBL)vs MTK(BROM)

6.2 Bootloader(引导加载程序)

  • 6.2.1 设备树(Device Tree Blob, DTB)的传递
  • 6.2.2 Fastboot 协议详解:fastboot flashing unlock 的底层指令交互
  • 6.2.3 LK(Little Kernel)与 ABL(Android Bootloader)的差异

6.3 Android 验证启动(AVB 2.0)

  • 6.3.1 信任链(Chain of Trust):从 BootROM 签名验签公钥哈希
  • 6.3.2 vbmeta 分区结构:公钥、哈希树根(dm-verity root hash)、标志位
  • 6.3.3 回滚保护(Rollback Protection):防止刷回有漏洞的老版本

6.4 攻防对抗

  • 6.4.1 攻击手段:Bootloader 漏洞利用(如 CVE-2019-2215)提权
  • 6.4.2 封控手段:锁定 Bootloader(flashing lock)与熔断 Q-fuse
  • 6.4.3 对抗检测:Magisk 如何利用 init_boot 分区实现无系统修改 Root

6.5 关键术语速查

  • BootROM:SoC 芯片内置固件,通电执行的第一段代码,相当于芯片 BIOS。
  • bootloader:引导加载器,作用是加载 kernel 和 ramdisk。
  • AVB:Android Verified Boot,全程校验分区文件完整性。
  • vbmeta flags:0=严格校验,3=关闭校验。

第七章:Linux Kernel 与 Init 进程 —— 王国的宪法与国王

7.1 Linux 内核启动

  • 7.1.1 start_kernel():进程调度、内存管理、VFS 的初始化
  • 7.1.2 init/main.c:内核载入 initramfs 并执行 /init

7.2 Init 进程(PID=1)

  • 7.2.1 init.rc 脚本语法详解:on 触发器、serviceaction 的执行顺序
  • 7.2.2 属性服务(Property Service):/dev/__properties__ 与 system_property_set
  • 7.2.3 init 的三阶段启动:First-StageMain → SetupSelinux → SecondStageMain

7.3 SELinux 的加载

  • 7.3.1 plat_sepolicy.cil 与 vendor_sepolicy.cil 的编译与加载
  • 7.3.2 enforcing vs permissive 模式对注入的影响
  • 7.3.3 SELinux 策略的编译期校验(neverallow

7.4 攻防对抗

  • 7.4.1 攻击手段:内核模块(LKM)提权加载(如 KernelSU)
  • 7.4.2 检测手段:检查 uname -r/proc/version 是否与官方指纹匹配
  • 7.4.3 封控对抗:SELinux 的 neverallow 规则如何阻止非法 ptrace 和 binder 调用

7.5 关键术语速查

  • init:PID=1 的一号进程,所有进程的源头。
  • init.rc:init 进程专属配置脚本,支持 on 触发条件、services 服务。
  • SELinux:Linux 强制访问控制(MAC),root 也不能绕过。
  • enforcing / permissive:enforcing 拦截违规;permissive 仅记录日志。

第八章:Zygote 与 SystemServer —— 女娲造人与宰相府

8.1 Zygote 进程

  • 8.1.1 app_process 可执行文件的作用(替换原生 app_process 就是 Xposed 的老路)
  • 8.1.2 AndroidRuntime.cpp 的 startVm():ART 虚拟机实例化
  • 8.1.3 预加载资源(Preload):classresourceopenGLshared_lib
  • 8.1.4 Zygote 的 Socket(/dev/socket/zygote)通信协议

8.2 SystemServer 进程

  • 8.2.1 forkSystemServer() 的调用链路
  • 8.2.2 系统服务的启动顺序(Bootstrap → Core → Other)
  • 8.2.3 Watchdog 机制:如何防止主线程死锁(Blocked)导致 ANR
  • 8.2.4 system_server 崩溃的后果与 bootloop 的关联

8.3 攻防对抗(注入起源)

  • 8.3.1 攻击手段(旧):替换 /system/bin/app_process
  • 8.3.2 攻击手段(新):Native Bridge 劫持(Zygisk 原理)
  • 8.3.3 封控手段:检测 Zygote 进程的 maps 文件是否存在异常 .so

8.4 关键术语速查

  • zygote:APP 和 system_server 的父进程,通过 fork 复制自身。
  • system_server:系统核心进程,PMS、AMS 等运行在这里;崩溃即重启。
  • ServiceManager:Binder 服务的注册中心,addService / getService
  • binder:Android 独有的 IPC 进程间通信机制。

卷二:编译、加载与运行时 —— Native 与 Java 世界的地基

本卷目标:回答“代码是怎么跑起来的”以及“内存里长什么样”。理解 DEX、ELF、ART 和 Binder,是理解所有 Hook 技术的前提。

第九章:DEX 与 ART 虚拟机 —— Java 字节码的“翻译官”

9.1 DEX 文件格式解剖

  • 9.1.1 dex_header:Magic(dex\n035\0)、校验和、偏移表
  • 9.1.2 string_ids / type_ids / proto_ids / field_ids / method_ids 结构体详解
  • 9.1.3 class_def 与 data 区:如何通过偏移定位方法字节码
  • 9.1.4 方法数 65536 限制的原因与 MultiDex 解决方案

9.2 ART 运行时(Android Runtime)

  • 9.2.1 Dalvik 与 ART 的区别:JIT(即时编译)vs AOT(预编译)vs 混合编译模式
  • 9.2.2 oat 文件格式:在 ELF 中嵌入 DEX,以及 oatdata / oatexec 段
  • 9.2.3 vdex 与 art 文件:验证缓存与 APK 的优化副产品

9.3 ArtMethod 结构体

  • 9.3.1 ArtMethod 在 ART 内部的关键字段(entry_point_dex_cache_resolved_methods_
  • 9.3.2 如何通过内存偏移定位 ArtMethod 指针
  • 9.3.3 修改 entry_point 实现 Java 方法 Hook(LSPlant 原理)

9.4 攻防对抗(脱壳与加固)

  • 9.4.1 攻击手段:内存 Dump(FART 脱壳原理)—— 主动调用 Class.forName 触发解密
  • 9.4.2 检测手段:检测 ART 中的 dex_files 是否被抽空(方法体为 nop 或 goto
  • 9.4.3 封控对抗:指令抽取(DexProtector)与 VMP(基于解释器的虚拟机保护)

9.5 关键术语速查

  • DEX:Dalvik Executable,Android 字节码文件格式。
  • ART:Android Runtime,JIT/AOT 混合编译模式。
  • CodeItem:DEX 中存放方法字节码的结构体,函数抽取壳替换的目标。
  • FART:基于主动调用的全自动脱壳机,函数抽取壳的克星。

第十章:ARM64 与 ELF 文件 —— 底层执行的“二进制圣经”

10.1 ELF(可执行与可链接格式)结构

  • 10.1.1 ELF Header:e_ident(魔数 7f 45 4c 46)、e_entry 入口点、e_phnum / e_shnum
  • 10.1.2 Program Header(段):PT_LOAD(可加载段)、PT_DYNAMIC(动态链接信息)
  • 10.1.3 Section Header(节):.text.rodata.data.bss.init_array

10.2 动态链接(Dynamic Linking)

  • 10.2.1 Linker(/system/bin/linker64)加载 SO 的流程:__dl__ZN6soinfo13prelink_imageEv
  • 10.2.2 重定位表(.rela.dyn 与 .rela.plt):R_AARCH64_JUMP_SLOT 与 R_AARCH64_GLOB_DAT
  • 10.2.3 DT_NEEDED 依赖解析与库加载顺序

10.3 关键机制

  • 10.3.1 PLT(过程链接表)与 GOT(全局偏移表)的作用与内存布局
  • 10.3.2 延迟绑定(Lazy Binding)与 BIND_NOW 立即绑定
  • 10.3.3 dlopen / dlsym 的实现原理

10.4 攻防对抗

  • 10.4.1 攻击手段:解析 .dynamic 段,通过 dlsym 获取函数地址进行调用
  • 10.4.2 检测手段:检查 ELF 头部的 e_flags 是否被篡改(如 UPX 加壳)

10.5 关键术语速查

  • ELF:Android 可执行文件格式(.so 库)。
  • PLT / GOT:过程链接表与全局偏移表,PLT-Hook 的目标。
  • Linker/system/bin/linker64,动态链接器,负责加载共享库。
  • Trampoline(跳板):Inline Hook 中用于中转的代码片段。

第十一章:Binder 与 ServiceManager —— 跨进程通信的“快递网络”

11.1 Binder 驱动原理(/dev/binder

  • 11.1.1 open() / mmap() / ioctl() 标准流程
  • 11.1.2 内存映射与一次拷贝(One-Copy)原理:内核缓冲区与用户态地址映射
  • 11.1.3 Binder 事务(Transaction):BC_TRANSACTION 与 BR_TRANSACTION_COMPLETE 协议

11.2 ServiceManager 服务注册与获取

  • 11.2.1 IServiceManager 接口:addService() 与 getService() 的调用栈
  • 11.2.2 plat_service_contexts 与 vendor_service_contexts 的 SELinux 上下文映射
  • 11.2.3 service list 命令查看全部注册服务

11.3 AIDL 与 Binder 通信

  • 11.3.1 AIDL 文件的编译产物与 Binder 代理类的生成
  • 11.3.2 Binder 事务码(Transaction Code)的含义

11.4 攻防对抗

  • 11.4.1 攻击手段:Hook ServiceManager.getService() 返回伪造的 Binder 代理(Proxy)对象
  • 11.4.2 检测手段:检测 Binder 调用延迟(反射调用耗时突变)

卷三:核心兵器库 —— Hook 与注入原理全解析

本卷目标:深入讲解“如何让别人的进程执行我的代码”。这是逆向工程的核心兵器库,也是所有注入工具的理论基础。

第十二章:PLT / GOT Hook —— 修改通讯录的“间谍”

12.1 原理深度剖析

  • 12.1.1 为什么导入函数必须经过 GOT(因为地址编译时未知)
  • 12.1.2 延迟绑定(Lazy Binding)机制:dl_runtime_resolve 的触发条件

12.2 技术实现

  • 12.2.1 解析 Elf32/64_Rela 结构获取 GOT 表地址
  • 12.2.2 修改 mprotect 为 PROT_READ | PROT_WRITE,替换函数地址
  • 12.2.3 还原内存保护属性防止崩溃

12.3 攻防对抗

  • 12.3.1 检测手段:检查 GOT 表地址是否落在正常 SO 范围内(远程扫描)
  • 12.3.2 封控对抗BIND_NOW 编译选项(立即绑定),减少运行期 GOT 写权限

第十三章:Inline Hook —— 修改路标的“强拆队”

13.1 ARM64 下的实现细节

  • 13.1.1 跳转指令选择:LDR X16, [PC, #8] + BR X16(绝对跳转)vs B(相对跳转)
  • 13.1.2 指令修复(Instruction Fixup):如何备份被覆盖的原始指令并在跳板(Trampoline)中执行

13.2 稳定性生死线

  • 13.2.1 指令长度对齐:为什么必须至少备份 2-4 条指令(防止 PC 相对寻址被破坏)
  • 13.2.2 __clear_cache 刷指令缓存(ICache)与数据缓存(DCache)的一致性

13.3 攻防对抗

  • 13.3.1 检测手段:CRC 校验代码段前 16/32 字节;检测页属性(/proc/pid/smaps 中的 rwxp 异常段)
  • 13.3.2 反检测:使用 mprotect + PAGE_SIZE 对齐,避开基于字节的扫描

第十四章:Zygisk / Riru 注入 —— 被官方认可的“特洛伊木马”

14.1 Native Bridge 机制劫持

  • 14.1.1 属性 ro.dalvik.vm.native.bridge 的生效时机(AndroidRuntime.cpp 的 startVm 之后)
  • 14.1.2 libnativebridge.so 的 NativeBridgeLoad 和 NativeBridgePreInitialize 回调链路

14.2 代码分发机制

  • 14.2.1 Zygisk 如何通过 fork 的 copy-on-write 让子进程继承 so 加载
  • 14.2.2 模块加载顺序:zygisk_module 的 onLoad 与 onAppCreate 回调

14.3 vs ptrace:为什么 Zygisk 取代了传统注入

  • 14.3.1 ptrace 的内核级痕迹(auditd 日志、TracerPid 残留)
  • 14.3.2 Zygisk 的“合规性”优势:利用系统合法机制,无侵入痕迹

14.4 攻防对抗

  • 14.4.1 检测手段(静态):扫描 ro.dalvik.vm.native.bridge 的字符串值
  • 14.4.2 检测手段(动态):检查 Zygote 进程中多出来的匿名 mmap 段
  • 14.4.3 封控对抗:隐藏 native_bridge 属性(通过 Hook __system_property_read

14.5 关键术语速查

  • Zygisk:Magisk 官方 zygote 注入方案,借助 native-bridge。
  • Riru:早期 zygote 注入方案,已淘汰。
  • native bridge:指令集翻译桥,Zygisk 利用其入口注入。
  • carrier:将 so 送入目标进程的载体机制,Zygisk / ptrace / native-bridge 都属于 carrier。

第十五章:LSPlant / Xposed —— ART 内部的“结构工程师”

15.1 Dalvik 时代的 Xposed

  • 15.1.1 将 Java 方法标记为 native,替换 dalvik_multi_dlopen
  • 15.1.2 替换 /system/bin/app_process 的经典方案

15.2 ART 时代的 LSPlant(LSPosed 核心)

  • 15.2.1 获取 ArtMethod 结构体指针(kRuntimePointerSize 对齐)
  • 15.2.2 替换 ArtMethod 的 entry_point_from_quick_compiled_code_
  • 15.2.3 内联反优化(Deoptimization):使 JIT 编译的代码回退到解释执行确保 Hook 生效

15.3 攻防对抗(结构性死穴)

  • 15.3.1 检测手段(降维打击):扫描 ART 全局 class_loaders_ 链表,统计 ClassLoader 数量(正常 App 仅 2-3 个)
  • 15.3.2 检测手段:检查 ArtMethod 的 dex_cache_resolved_methods 是否指向异常地址

15.4 关键术语速查

  • Xposed:老牌 Java 层 Hook 框架,替换 app_process。
  • LSPosed:Xposed 升级版,基于 Zygisk + LSPlant。
  • LSPlant:ART-Hook 引擎,修改 ArtMethod 结构体。
  • Deoptimization:反优化,使 JIT 编译的方法回退到解释执行。

卷四:隐身术 —— 擦除“入侵基因”

本卷目标:回答“为什么我注入成功了,应用还是闪退/检测到环境异常?”—— 因为你的“痕迹”没擦干净。

第十六章:文件系统痕迹清理(Maps、FD、Proc)

16.1 /proc/self/maps 过滤

  • 16.1.1 用户态 Hook open / fread 动态修改返回流数据
  • 16.1.2 内核态过滤:基于 LSM(Linux Security Module)Hook get_proc_pid_maps

16.2 /proc/self/fd 目录隐藏

  • 16.2.1 关闭注入过程中打开的 mem 或 pagemap 文件句柄

16.3 攻防对抗

  • 16.3.1 检测手段(绕过过滤):风控直接使用 mincore() 或 process_vm_readv 绕过文件系统路径扫描
  • 16.3.2 封控对抗:使用 dlopen 加载的 SO 主动调用 munmap 解除内存映射(需配合 mremap 迁移重定位)

16.4 关键术语速查

  • maps hide:Hook openat/read 过滤 /proc/self/maps 内容。
  • scrub(denylist hide):Zygisk 卸载自身 so 并清理内存痕迹。

第十七章:属性伪造与栈帧清洗

17.1 系统属性(Property)伪造

  • 17.1.1 Hook __system_property_get / __system_property_read_callback
  • 17.1.2 常见伪造清单:ro.debuggablero.build.tagsro.build.typero.boot.flash.locked

17.2 栈回溯(Unwind)清洗

  • 17.2.1 原理:_Unwind_Backtrace 遍历 __libc_unwind 的调用链
  • 17.2.2 实现 unwind_cloak:在检测库的 dl_iterate_phdr 回调中过滤特定 so 帧

17.3 攻防对抗

  • 17.3.1 检测手段:利用 libart 的 GetStackFrames 方法从 Java 层向下回溯 Native,绕过 Native 层的 Hook
  • 17.3.2 封控对抗:伪造 oat 帧,让栈看起来像是执行正常的 ART 编译代码

17.4 关键术语速查

  • props hook:Hook 属性读取函数返回伪造值。
  • stack hiding:拦截 Throwable 堆栈,清除 Hook 产生的栈帧。
  • dexFile 伪装:修改 dexElement.mFileName 伪装为系统文件。

第十八章:TracerPid 与 Ptrace 痕迹清除(绝地求生)

18.1 ptrace 系统调用的审计痕迹

  • 18.1.1 /proc/pid/status 中的 TracerPid 字段含义
  • 18.1.2 detach 后为何 TracerPid 归零但内核 task_struct 仍有 parent 指针残留

18.2 清除技术的极限

  • 18.2.1 Hook 文件读取(只能欺骗用户态)
  • 18.2.2 无法清除内核审计日志(auditd)和 dmesg 中的 ptrace_attach 记录

18.3 攻防对抗

  • 18.3.1 检测手段(终局):风控自研内核模块直接读取当前线程的 real_parent 进程名
  • 18.3.2 结论:Zygisk 之所以取代 ptrace,正是因为内核级痕迹的不可清洗性

18.4 关键术语速查

  • TracerPid/proc/self/status 中的调试器 PID,正常值为 0。
  • ptrace:Linux 原生调试调用,特征明显,易被检测。

第十九章:Crash 清扫、日志清洗与 Failsafe 自毁

19.1 Tombstone / 崩溃日志清理

  • 19.1.1 /data/tombstones/ 目录监控与主动删除
  • 19.1.2 Hook log_write 拦截 FATAL 级别的日志输出

19.2 Failsafe(故障保险)机制

  • 19.2.1 心跳线程(Heartbeat):检测应用是否被挂起调试
  • 19.2.2 紧急预案:检测到风控扫描时,触发干净的系统重启(sync(); reboot())而非崩溃,掩盖现场

19.3 关键术语速查

  • crash 清扫:主动删除崩溃日志和 xlog 日志。
  • Tombstone:Native 层崩溃堆栈快照,取证的重要来源。

卷五:降维打击 —— 源码定制、硬件信任与混淆对抗

本卷目标:从“应用层黑客”晋升为“系统层架构师”,探讨终极对抗手段。

第二十章:系统源码定制与 Bootloop 的艺术(ROM 级对抗)

20.1 添加系统级服务(addService

  • 20.1.1 修改 frameworks/base/services/java/com/android/server/SystemServer.java
  • 20.1.2 修改 plat_service_contexts 与 service.te(SELinux 策略)
  • 20.1.3 audit2allow 生成 SELinux 策略

20.2 避免 Bootloop 的关键设计模式

  • 20.2.1 服务依赖图分析:避免循环依赖(Circular Dependency)
  • 20.2.2 核心实操:使用 SystemServiceManager.startBootPhase 异步启动非关键服务,防止阻塞 main 线程触发 Watchdog

20.3 白名单机制

  • 20.3.1 在 PackageManagerService 中绕过 Signature 校验(PackageParser 修改)
  • 20.3.2 将特定 App 提升为 shell 或 system 权限(grantRuntimePermission 强制授权)

第二十一章:Play Integrity 与硬件信任根(TEE / StrongBox)

21.1 Google Play Integrity API 深度拆解

  • 21.1.1 Basic、Device、Strong 三级认证的触发条件
  • 21.1.2 认证令牌(JWT)的 payload 字段解析:ctsProfileMatchbasicIntegrity

21.2 硬件可信执行环境(TEE)

  • 21.2.1 Keymaster TA(Trusted Application)与 Gatekeeper 的签名过程
  • 21.2.2 attestation key 如何被熔丝(fuse)保护

21.3 攻防对抗

  • 21.3.1 攻击手段:Magisk 模块 Play Integrity Fix 原理(劫持 keystore 返回预计算的有效签名)
  • 21.3.2 检测手段:后端校验 nonce 与时间戳,杜绝重放攻击(Replay Attack)

21.4 关键术语速查

  • SafetyNet / Play Integrity:Google 设备完整性检测服务。
  • verifiedbootstate:green(官方)/ orange(解锁)/ red(损坏)。
  • device_state:locked / unlocked。

第二十二章:OLLVM、VMP 与代码混淆的“抽象宇宙”

22.1 OLLVM(基于 LLVM 的混淆)

  • 22.1.1 控制流平坦化(Flattening):基本块分发器(Dispatcher)与状态变量(State Variable)
  • 22.1.2 虚假控制流(Bogus):插入永不执行的 JMP 增加路径爆炸
  • 22.1.3 指令替换(Substitution):add 变 sub + xor 组合

22.2 VMP(虚拟机保护)

  • 22.2.1 自定义字节码解析:Handler 表与 switch-case 解释器循环
  • 22.2.2 基于栈式(Stack-Based)与寄存器式(Register-Based)虚拟机的区分

22.3 反混淆技术与动态还原

  • 22.3.1 符号执行(Angr):通过路径约束求解还原原始语义
  • 22.3.2 动态二进制翻译(Unicorn Engine):模拟执行去平坦化
  • 22.3.3 检测手段:风控检测 CPU 运行时指令解释延迟(时间侧信道攻击)

卷六:拓展与实战 —— 网络、密码、加固与逆向 SOP

本卷目标:覆盖逆向工程中除系统底层外的应用层实战,包括网络协议、密码识别、商业加固和标准作业流程。

第二十三章:网络协议拦截与密码学识别

23.1 SSL / TLS 抓包

  • 23.1.1 Charles / mitmproxy 安装 CA 证书
  • 23.1.2 Android 7.0 以上用户证书信任问题与解决方案(Network Security Config)
  • 23.1.3 系统级 CA 证书安装(Magisk 模块)

23.2 SSL Pinning(证书绑定)绕过

  • 23.2.1 Hook TrustManager / X509TrustManager 的 checkServerTrusted
  • 23.2.2 Frida 脚本 Universal-android-ssl-pinning-bypass
  • 23.2.3 双向认证的绕过:提取客户端证书与私钥

23.3 WebSocket / Protobuf 逆向

  • 23.3.1 利用 gRPC 反射或 Hook CodedInputStream 解析二进制协议
  • 23.3.2 Protobuf 的 .proto 文件还原

23.4 常见加密算法特征速查

  • 23.4.1 哈希类:MD5(0x67452301 初始向量)、SHA256(0x6a09e667
  • 23.4.2 对称加密:AES 的 S 盒(0x63, 0x7c...)、TEA/XTEA 的黄金分割常数(0x9E3779B9
  • 23.4.3 非对称加密:RSA 的 0x10001(65537 公钥指数)特征
  • 23.4.4 编码类:Base64 编码表、Hex 编码

23.5 关键术语速查

  • SSL Pinning:证书绑定,将服务器证书硬编码在 App 内校验。
  • AES S 盒0x63, 0x7c, 0x77...,IDA 中搜索可快速定位 AES。
  • TEA 常数0x9E3779B9,黄金分割数,搜索可定位 TEA/XTEA 加密。

第二十四章:调试器原理与高级反调试对抗

24.1 软件断点(Software Breakpoint)

  • 24.1.1 ARM64 的 BRK #00xD4200000)与 x86 的 INT 30xCC)指令
  • 24.1.2 断点指令如何引发 SIGTRAP 信号

24.2 硬件断点(Hardware Breakpoint)

  • 24.2.1 ARM 的 DBGBVR(调试断点值寄存器)与 DBGBCR(控制寄存器)原理
  • 24.2.2 检测 ptrace 的 PTRACE_GETHBPREGS

24.3 反调试手段合集

  • 24.3.1 检测 TracerPid/proc/self/status
  • 24.3.2 检测 ro.debuggable 属性
  • 24.3.3 检测 /proc/self/fd 中的 ptrace 附着文件
  • 24.3.4 利用 inotify 监控 /proc/self/maps 的变动(检测 frida-agent 加载)

24.4 绕过思路

  • 24.4.1 Frida 的 gum-js 的 Process.setExceptionHandler 捕获断点
  • 24.4.2 使用 ld_preload 抢占 ptrace 先机

24.5 关键术语速查

  • 软件断点BRK #0(ARM64)/ INT 3(x86),触发 SIGTRAP。
  • 硬件断点:利用 CPU 调试寄存器,无需修改指令。
  • inotify:文件系统事件监控,可检测 so 加载。

第二十五章:商业加固壳与脱壳实战

25.1 壳的发展史

  • 25.1.1 整体加壳(DEX 加密)→ 函数抽取(Code Dump)→ VMP(解释器)

25.2 加固厂商特征识别

  • 25.2.1 爱加密:StubApplicationassets/ijm_lib 目录
  • 25.2.2 360 加固:EntryWrapperlibjiagu.so
  • 25.2.3 梆梆加固:Bangclelibsecexe.so
  • 25.2.4 腾讯加固:libtup.sotss_sdk

25.3 DEX 整体脱壳(内存 Dump)

  • 25.3.1 利用 memfd 或 Frida 遍历 DexFile 对象
  • 25.3.2 内存中 Dump 出解密后的 .dex

25.4 函数抽取壳还原(FART 框架原理)

  • 25.4.1 主动调用(Active Call)触发 CodeItem 填充
  • 25.4.2 拦截 Class 加载瞬间内存快照

25.5 修复 DEX

  • 25.5.1 将内存中的 CodeItem 回填到 DEX 文件
  • 25.5.2 修复 checksum 和 signature

25.6 关键术语速查

  • 整体加壳:整个 DEX 加密,运行时内存解密。
  • 函数抽取壳:CodeItem 替换为 nop,运行时逐個解密。
  • VMP 壳:自定义字节码 + 解释器,反编译器无法还原。
  • FART:全自动脱壳机,函数抽取壳的克星。

第二十六章:逆向工程标准作业流程(SOP)与企业级对抗

26.1 第一阶段(信息收集)

  • 26.1.1 抓包看 API 接口
  • 26.1.2 查 AndroidManifest 看四大组件、权限声明
  • 26.1.3 检视 lib/ 下的 SO 库数量与名称

26.2 第二阶段(静态分析)

  • 26.2.1 Jadx 打开搜索 encrypt / key / check / verify / sign
  • 26.2.2 IDA 加载 SO 查看 JNI_OnLoad 和导出函数
  • 26.2.3 识别加固壳类型

26.3 第三阶段(动态验证)

  • 26.3.1 Frida 跟踪关键函数入参出参
  • 26.3.2 Xposed/LSPosed 编写模块验证 Hook 点
  • 26.3.3 动态调试(gdb / lldb)定位关键逻辑

26.4 第四阶段(Patch 与重打包)

  • 26.4.1 修改 Smali 跳转绕过 VIP 校验
  • 26.4.2 zipalign 对齐,apksigner 签名
  • 26.4.3 绕过签名校验的几种思路

26.5 企业级风控对抗决策树

  • 26.5.1 判断服务器校验(改 Response)还是本地校验(改 Smali)
  • 26.5.2 有硬核反调试(如爱加密)则优先静态 Patch
  • 26.5.3 有 Play Integrity 检测则优先 Magisk 隐藏

卷七:终极之眼 —— 反取证、取证对抗与未来

本卷目标:从“攻击者”视角延伸至“防御者/取证者”视角,理解如何消除痕迹以及如何对抗痕迹消除。

第二十七章:反取证导论 —— 定义、范畴与思维模型

27.1 什么是反取证?

  • 27.1.1 定义:阻碍、混淆、破坏数字取证调查的技术集合
  • 27.1.2 本质:打破取证的“可靠性”与“完整性”原则

27.2 反取证技术的四大分类

  • 27.2.1 数据清除(Data Wiping):覆写、消磁,让数据彻底消失
  • 27.2.2 数据隐藏(Data Hiding):隐写术、加密、隐藏分区
  • 27.2.3 痕迹混淆(Trail Obfuscation):伪造日志、时间戳篡改
  • 27.2.4 攻击取证工具:向取证软件注入恶意代码

第二十八章:数据销毁与痕迹清除的艺术

28.1 文件粉碎(File Wiping)

  • 28.1.1 普通删除 vs 多次覆写
  • 28.1.2 覆写标准:Gutmann(35 次)、DoD 5220.22-M(3 次)、随机数覆写
  • 28.1.3 Android 实践与闪存磨损均衡(Wear Leveling)问题

28.2 系统级擦除:恢复出厂设置(Factory Reset)

  • 28.2.1 文件系统级擦除 vs 块设备级擦除
  • 28.2.2 “密码学擦除”:丢弃 dm-crypt 加密密钥

28.3 日志与临时文件的清扫(Log & Cache Scrubbing)

  • 28.3.1 logcat 缓冲区、/data/tombstones/、应用缓存目录
  • 28.3.2 内存式运行(RAM-only Execution):tmpfs 挂载

第二十九章:数据隐藏与欺骗性环境构建

29.1 加密(Encryption)

  • 29.1.1 全盘加密 / 文件级加密(FBE)
  • 29.1.2 应用级加密与 Android Keystore
  • 29.1.3 可拒绝加密(Plausible Deniable Encryption):隐藏卷

29.2 隐写术(Steganography)

  • 29.2.1 图片 LSB 隐写
  • 29.2.2 音频/视频隐写
  • 29.2.3 隐写与加密结合

29.3 伪装与混淆(Camouflage & Obfuscation)

  • 29.3.1 进程/文件伪装:恶意进程命名伪装为系统进程
  • 29.3.2 时间戳混淆(Timestamp Manipulation):touch 修改 MAC 时间
  • 29.3.3 内存造假:Hook 系统调用返回伪造的 maps / status

第三十章:对抗新型取证技术

30.1 传统取证技术的弱点

  • 30.1.1 依赖“偶然”痕迹(logcat 环形缓冲区)
  • 30.1.2 静态分析易被加密/混淆迷惑

30.2 新型主动取证:Android 入侵日志记录

  • 30.2.1 加密存储与用户控制:Google 无法读取
  • 30.2.2 防篡改设计:12 个月内用户无法删除
  • 30.2.3 记录的三大类事件:安全事件、应用生命周期、系统异常

30.3 机器学习在取证与反取证中的应用

  • 30.3.1 AI 辅助取证:异常模式识别
  • 30.3.2 AI 辅助反取证:生成虚假日志和网络流量污染数据

📎 附录(全书实战速查字典)

附录 A:AOSP 关键源码路径索引

  • /frameworks/base/:Framework 核心代码
  • /art/:ART 虚拟机源码
  • /system/core/:init、adb、logcat 等核心组件
  • /system/sepolicy/:SELinux 策略源码

附录 B:ARM64 / Thumb 常用指令机器码对照表

  • BRK #00xD4200000(软件断点)
  • NOP0xD503201F
  • B 指令偏移量计算方式
  • LDR BR 跳转序列的 Hex 特征

附录 C:SELinux avc: denied 日志分析与策略添加速查

  • audit2allow 实战:将 avc 日志转换为 allow 规则
  • 常用 allow 规则模板
  • neverallow 常见陷阱

附录 D:Frida / Xposed / LSPosed 常用 API 速查表

  • Frida:Java.performInterceptor.attachProcess.setExceptionHandler
  • Xposed:XposedHelpers.findAndHookMethodXposedBridge.log
  • LSPosed:模块入口 handleLoadPackage、作用域配置

附录 E:加固厂商 AndroidManifest 入口特征表

  • 爱加密:StubApplication
  • 360 加固:EntryWrapper
  • 梆梆加固:Bangcle
  • 腾讯加固:tss_sdk

附录 F:逆向常用正则与 Hex 特征搜索模板

  • 搜索 0x9E3779B9 定位 TEA/XTEA
  • 搜索 0x67452301 定位 MD5
  • 搜索 0x6a09e667 定位 SHA256
  • 搜索 0x63, 0x7c, 0x77 定位 AES S 盒
  • 搜索 0x10001 定位 RSA 公钥指数

附录 G:各厂商(小米、华为、三星)分区布局差异对比表

  • 小米:init_boot 分区(Magisk 修补目标)
  • 华为:recovery_ramdisk 分区
  • 三星:vbmeta + dtbo 分区结构
上一篇
爬虫数据采集加密算法全景指南
下一篇
【原创】Android 底层核心术语通俗详解|启动流程、SELinux、Hook、反取证体系梳理

Comments
Loading...
Catalog