├── Crackmes └── Android │ ├── Level_04 │ ├── r2pay-v0.9.apk │ └── r2pay-v1.0.apk │ ├── Level_01 │ └── UnCrackable-Level1.apk │ ├── Level_02 │ └── UnCrackable-Level2.apk │ └── Level_03 │ └── UnCrackable-Level3.apk ├── .idea ├── .gitignore ├── vcs.xml ├── inspectionProfiles │ └── profiles_settings.xml ├── modules.xml ├── misc.xml └── AndroidReverse101.iml ├── LICENSE ├── AndroidReverse101 ├── 第一阶段_计算机基础_逆向概论 │ ├── Day_1_什么是逆向工程.md │ ├── Day_2_Android_逆向的历史与发展.md │ ├── Day_15_手写_ARM_汇编代码_实验.md │ ├── Day_7_ARM_汇编指令解析.md │ ├── Day_6_x86_vs._ARM_汇编.md │ ├── Day_4_进制转换_为什么16进制很重要.md │ ├── Day_3_什么是_CPU_指令集.md │ ├── Day_5_汇编语言基础.md │ ├── Day_8_函数调用与返回.md │ ├── Day_10_Dalvik_vs._ART_运行时.md │ ├── Day_18_如何调试_Native_层.md │ ├── Day_9_Android_CPU_架构解析.md │ ├── Day_17_ELF_文件解析.md │ ├── Day_16_反汇编工具介绍.md │ ├── Day_12_Android_权限机制.md │ ├── Day_14_APK_是如何加载的.md │ ├── Day_11_Android_进程管理.md │ ├── Day_20_CTF_逆向挑战_初级.md │ └── Day_19_Android_APP_安全机制.md ├── 第二阶段_APK逆向基础 │ ├── Day_26_APK_重新打包_签名.md │ ├── Day_25_Smali_代码修改实验.md │ ├── Day_24_Smali_语言入门.md │ ├── Day_27_动态调试入门.md │ ├── Day_34_Android_代码混淆与解混淆.md │ ├── Day_32_破解_VIP_限制.md │ ├── Day_30_逆向_JNI_和_Native_方法.md │ ├── Day_38_游戏破解基础.md │ ├── Day_23_DEX_文件结构解析.md │ ├── Day_41_解密加固_APK_初级.md │ ├── Day_40_Android_加固原理.md │ ├── Day_22_如何反编译_APK.md │ ├── Day_21_APK_文件结构解析.md │ ├── Day_28_使用_Frida_Hook_Java_方法.md │ ├── Day_37_破解应用限制_实战.md │ ├── Day_39_反反调试.md │ └── Day_33_绕过_SSL_Pinning.md └── 第三阶段_高级逆向_CTF挑战 │ ├── Day_70_逆向挖掘_0Day_漏洞.md │ ├── Day_100_终极挑战_逆向一个完整_APP.md │ └── Day_60_深入分析_CTF_逆向挑战.md ├── create_markdown.py └── .gitignore /Crackmes/Android/Level_04/r2pay-v0.9.apk: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Evil0ctal/AndroidReverse101/HEAD/Crackmes/Android/Level_04/r2pay-v0.9.apk -------------------------------------------------------------------------------- /Crackmes/Android/Level_04/r2pay-v1.0.apk: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Evil0ctal/AndroidReverse101/HEAD/Crackmes/Android/Level_04/r2pay-v1.0.apk -------------------------------------------------------------------------------- /Crackmes/Android/Level_01/UnCrackable-Level1.apk: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Evil0ctal/AndroidReverse101/HEAD/Crackmes/Android/Level_01/UnCrackable-Level1.apk -------------------------------------------------------------------------------- /Crackmes/Android/Level_02/UnCrackable-Level2.apk: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Evil0ctal/AndroidReverse101/HEAD/Crackmes/Android/Level_02/UnCrackable-Level2.apk -------------------------------------------------------------------------------- /Crackmes/Android/Level_03/UnCrackable-Level3.apk: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Evil0ctal/AndroidReverse101/HEAD/Crackmes/Android/Level_03/UnCrackable-Level3.apk -------------------------------------------------------------------------------- /.idea/.gitignore: -------------------------------------------------------------------------------- 1 | # 默认忽略的文件 2 | /shelf/ 3 | /workspace.xml 4 | # 基于编辑器的 HTTP 客户端请求 5 | /httpRequests/ 6 | # Datasource local storage ignored files 7 | /dataSources/ 8 | /dataSources.local.xml 9 | -------------------------------------------------------------------------------- /.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /.idea/inspectionProfiles/profiles_settings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | -------------------------------------------------------------------------------- /.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | -------------------------------------------------------------------------------- /.idea/AndroidReverse101.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2025 Evil0ctal 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /AndroidReverse101/第一阶段_计算机基础_逆向概论/Day_1_什么是逆向工程.md: -------------------------------------------------------------------------------- 1 | ### **📜 Day 1: 什么是逆向工程** 2 | 3 | #### **📌 学习目标** 4 | ✅ 理解什么是 **逆向工程**,并了解它的应用场景。 5 | ✅ 了解 **逆向工程** 与 **正向工程** 的区别。 6 | ✅ 熟悉 **软件逆向** 的基础概念,如 **静态分析** 和 **动态分析**。 7 | ✅ 了解常见的逆向工具,并安装基本环境。 8 | 9 | --- 10 | 11 | #### **📖 知识点** 12 | 13 | ### **1️⃣ 什么是逆向工程?** 14 | 逆向工程(Reverse Engineering,简称 RE)是一种通过分析现有系统的**结构、功能、实现原理**,以理解其工作方式的过程。 15 | 16 | 🔹 逆向工程的本质是**拆解和理解**,它不仅适用于软件,也被广泛应用于**硬件、网络协议、安全研究、AI 模型分析等**。 17 | 18 | ### **2️⃣ 逆向工程的应用场景** 19 | | **领域** | **应用** | 20 | |-------------|--------------------------------------------------| 21 | | **软件分析** | 逆向 APP、软件破解、逆向协议、API 调试 | 22 | | **安全研究** | 恶意软件分析、漏洞挖掘、病毒分析、Web 安全测试 | 23 | | **硬件分析** | 晶片分析、PCB 设计、物联网设备破解 | 24 | | **AI 逆向** | AI 模型解析、权重提取、推理优化 | 25 | | **游戏逆向** | 游戏外挂开发、资源提取、网络封包分析 | 26 | 27 | **🌟 案例 1:软件破解** 28 | - 你下载了一款**付费应用**,但是没有购买权限。你可以通过逆向工程分析其**验证逻辑**,并尝试绕过它。 29 | 30 | **🌟 案例 2:协议分析** 31 | - 某 APP 仅支持官方客户端访问 API,你可以通过逆向分析其 **API 结构**,然后自己编写代码调用它。 32 | 33 | ### **3️⃣ 逆向工程 vs. 正向工程** 34 | | | **正向工程** | **逆向工程** | 35 | |------|----------------|----------------| 36 | | **思维方式** | 设计并构建 | 拆解并分析 | 37 | | **目标** | 从 0 到 1 开发产品 | 理解已有产品 | 38 | | **应用场景** | 软件开发、系统设计 | 破解、漏洞挖掘、优化 | 39 | | **工具** | IDE(VS Code、Android Studio) | 反编译工具、调试器 | 40 | 41 | ### **4️⃣ 静态分析 vs. 动态分析** 42 | | | **静态分析** | **动态分析** | 43 | |-------------|---------------------------------|---------------------------------| 44 | | **方式** | 直接查看文件代码、结构 | 运行程序,监控行为 | 45 | | **工具** | 反编译工具(jadx, Ghidra) | 调试器(Frida, GDB, LLDB) | 46 | | **优势** | 快速分析,避免触发反调试 | 真实运行环境,动态观察 | 47 | | **劣势** | 有时无法直接看到运行逻辑 | 可能触发反调试保护 | 48 | 49 | --- 50 | 51 | #### **🛠 实战任务** 52 | 1️⃣ **安装基本逆向工具** 53 | 🔹 下载并安装 **jadx**(反编译 APK),分析 `classes.dex` 结构。 54 | 🔹 安装 **Frida**(Hook 工具),尝试 Hook 一个简单的 Python 脚本。 55 | 🔹 安装 **Ghidra / IDA Free**,打开并查看一个 ELF 文件。 56 | 57 | 2️⃣ **分析一个简单 APK** 58 | - 下载任意 **APK 文件**(如 `Calculator.apk`)。 59 | - 使用 `jadx` 反编译该 APK,查看 `MainActivity.java` 代码。 60 | 61 | --- 62 | 63 | #### **📚 参考资料** 64 | 📌 **Android 逆向工具** 65 | - `jadx`:[https://github.com/skylot/jadx](https://github.com/skylot/jadx) 66 | - `Frida`:[https://frida.re](https://frida.re) 67 | - `Ghidra`:[https://ghidra-sre.org](https://ghidra-sre.org) 68 | - `APKTool`:[https://github.com/iBotPeaches/Apktool](https://github.com/iBotPeaches/Apktool) 69 | 70 | 📌 **推荐阅读** 71 | - 《Android 软件安全与逆向分析》 72 | - 《The Art of Reverse Engineering》 73 | - 逆向工程博客:[https://reverseengineering.stackexchange.com](https://reverseengineering.stackexchange.com) 74 | 75 | --- 76 | 77 | 🔥 **任务完成后,你将掌握:** 78 | ✅ 逆向工程的核心概念 79 | ✅ 逆向工程 vs. 正向工程的区别 80 | ✅ 基础工具安装与使用 81 | 82 | 🚀 **下一步(Day 2)**:**Android 逆向的历史与发展** 🎯 -------------------------------------------------------------------------------- /create_markdown.py: -------------------------------------------------------------------------------- 1 | # ============================================================================== 2 | # Copyright (C) 2025 Evil0ctal 3 | # 4 | # This file is part of the AndroidReverse101 project. 5 | # Github: https://github.com/Evil0ctal/AndroidReverse101 6 | # 7 | # This project is licensed under the MIT license. 8 | # ============================================================================== 9 | # , 10 | # ,-. _,---._ __ / \ 11 | # / ) .-' `./ / \ 12 | # ( ( ,' `/ /| 13 | # \ `-" \'\ / | 14 | # `. , \ \ / | 15 | # /`. ,'-`----Y | 16 | # ( ; | ' 17 | # | ,-. ,-' | / 18 | # | | ( | Evil0ctal | / 19 | # ) | \ `.___________|/ Github - AndroidReverse101 20 | # `--' `--' 21 | # ============================================================================== 22 | 23 | import os 24 | 25 | # 定义根目录 26 | BASE_DIR = "AndroidReverse101" 27 | 28 | # 定义学习阶段及目录 29 | stages = { 30 | "第一阶段_计算机基础_逆向概论": [ 31 | (1, "什么是逆向工程"), 32 | (2, "Android 逆向的历史与发展"), 33 | (3, "什么是 CPU 指令集"), 34 | (4, "进制转换_为什么16进制很重要"), 35 | (5, "汇编语言基础"), 36 | (6, "x86 vs. ARM 汇编"), 37 | (7, "ARM 汇编指令解析"), 38 | (8, "函数调用与返回"), 39 | (9, "Android CPU 架构解析"), 40 | (10, "Dalvik vs. ART 运行时"), 41 | (11, "Android 进程管理"), 42 | (12, "Android 权限机制"), 43 | (13, "Android APP 目录结构"), 44 | (14, "APK 是如何加载的"), 45 | (15, "手写 ARM 汇编代码_实验"), 46 | (16, "反汇编工具介绍"), 47 | (17, "ELF 文件解析"), 48 | (18, "如何调试 Native 层"), 49 | (19, "Android APP 安全机制"), 50 | (20, "CTF 逆向挑战_初级"), 51 | ], 52 | "第二阶段_APK逆向基础": [ 53 | (21, "APK 文件结构解析"), 54 | (22, "如何反编译 APK"), 55 | (23, "DEX 文件结构解析"), 56 | (24, "Smali 语言入门"), 57 | (25, "Smali 代码修改实验"), 58 | (26, "APK 重新打包_签名"), 59 | (27, "动态调试入门"), 60 | (28, "使用 Frida Hook Java 方法"), 61 | (29, "Frida Hook 实战"), 62 | (30, "逆向 JNI 和 Native 方法"), 63 | (31, "Xposed 入门"), 64 | (32, "破解 VIP 限制"), 65 | (33, "绕过 SSL Pinning"), 66 | (34, "Android 代码混淆与解混淆"), 67 | (35, "逆向加密算法_MD5_AES_RSA"), 68 | (36, "分析 WebSocket_API 请求"), 69 | (37, "破解应用限制_实战"), 70 | (38, "游戏破解基础"), 71 | (39, "反反调试"), 72 | (40, "Android 加固原理"), 73 | (41, "解密加固 APK_初级"), 74 | ], 75 | "第三阶段_高级逆向_CTF挑战": [ 76 | (60, "深入分析 CTF 逆向挑战"), 77 | (70, "逆向挖掘 0Day 漏洞"), 78 | (100, "终极挑战_逆向一个完整 APP"), 79 | ] 80 | } 81 | 82 | 83 | def create_files(): 84 | """ 创建目录和 Markdown 文件 """ 85 | if not os.path.exists(BASE_DIR): 86 | os.mkdir(BASE_DIR) 87 | 88 | for stage, topics in stages.items(): 89 | stage_path = os.path.join(BASE_DIR, stage) 90 | os.makedirs(stage_path, exist_ok=True) # 创建阶段目录 91 | 92 | for day, title in topics: 93 | filename = f"Day_{day}_{title.replace(' ', '_')}.md" 94 | file_path = os.path.join(stage_path, filename) 95 | with open(file_path, "w", encoding="utf-8") as f: 96 | f.write(f"# Day {day}: {title}\n\n") 97 | f.write("## 学习目标\n\n") 98 | f.write("## 知识点\n\n") 99 | f.write("## 实战任务\n\n") 100 | f.write("## 参考资料\n\n") 101 | 102 | print(f"✅ 创建: {file_path}") 103 | 104 | print("\n🎉 所有 Markdown 文件创建完成!") 105 | 106 | 107 | if __name__ == "__main__": 108 | create_files() 109 | -------------------------------------------------------------------------------- /AndroidReverse101/第一阶段_计算机基础_逆向概论/Day_2_Android_逆向的历史与发展.md: -------------------------------------------------------------------------------- 1 | # **📜 Day 2: Android 逆向的历史与发展** 2 | 3 | ## **📌 学习目标** 4 | ✅ 了解 **Android 逆向工程的发展历程**,从早期 APK 破解到现代应用保护技术。 5 | ✅ 掌握 **APK 保护与破解的博弈**,理解加固与反加固的发展。 6 | ✅ 通过实际案例学习如何对比**旧版与新版 Android 安全机制**的变化。 7 | ✅ 了解 **现代 Android 反调试技术**,为后续的逆向分析做准备。 8 | 9 | --- 10 | 11 | ## **📖 知识点** 12 | 13 | ### **1️⃣ Android 逆向工程的发展历程** 14 | Android 逆向工程的发展可以分为以下几个阶段: 15 | 16 | | **阶段** | **时间** | **特点** | 17 | |---------|--------|---------| 18 | | **早期破解时代** | 2008 - 2012 | APK 结构简单,直接修改 `smali` 文件即可绕过验证。 | 19 | | **混淆与签名保护** | 2012 - 2015 | 开发者开始使用 `ProGuard` 进行代码混淆,阻止直接反编译。 | 20 | | **加固与动态保护** | 2015 - 2018 | 360、腾讯、百度等推出加固方案,采用代码抽取和动态加载。 | 21 | | **AI 与高级安全防护** | 2019 - 至今 | Android 引入 `Play Protect` 和 `SafetyNet`,逆向难度提升。 | 22 | 23 | --- 24 | 25 | ### **2️⃣ 早期 Android 逆向方法(2008 - 2012)** 26 | #### **示例 1:破解 VIP 会员** 27 | 在 2010 年左右,很多 APP 采用简单的 `if (isVip) {}` 逻辑判断是否为 VIP。 28 | 29 | **🔹 早期破解方法** 30 | - 使用 `Apktool` 反编译 APK: 31 | ```bash 32 | apktool d my_app.apk -o output_dir 33 | ``` 34 | - 修改 `smali` 代码,修改 `isVip()` 方法: 35 | ```smali 36 | .method public isVip()Z 37 | .registers 2 38 | const/4 v0, 0x1 # 让所有用户都变成 VIP 39 | return v0 40 | .end method 41 | ``` 42 | - 重新打包并签名: 43 | ```bash 44 | apktool b output_dir -o my_hacked_app.apk 45 | java -jar signapk.jar cert.pem key.pk8 my_hacked_app.apk signed.apk 46 | ``` 47 | - 安装修改后的 APK,即可绕过 VIP 限制。 48 | 49 | --- 50 | 51 | ### **3️⃣ Android 应用保护的发展(2012 - 2018)** 52 | 🔹 **代码混淆(ProGuard & R8)** 53 | - `ProGuard` 开始流行,代码结构变得不可读: 54 | ```java 55 | public class a { 56 | public void b() { System.out.println("Hello!"); } 57 | } 58 | ``` 59 | **反编译后:** 60 | ```java 61 | public class a { 62 | public void a() { System.out.println("Hello!"); } 63 | } 64 | ``` 65 | 66 | 🔹 **加固技术(Dex 加密 & 代码抽取)** 67 | - 代码不会直接存储在 `classes.dex`,而是运行时动态加载。 68 | - 例如 360 加固后,`classes.dex` 可能变成 `libshell.so`,需要 dump 才能还原。 69 | 70 | 🔹 **动态分析对抗(Anti-Debugging & Anti-Frida)** 71 | - 早期 Hook 工具(如 `Frida`)可轻松修改 APP 逻辑,但现代 APP 可能会检测 Frida: 72 | ```java 73 | public static boolean isFridaDetected() { 74 | return Class.forName("frida.Agent") != null; 75 | } 76 | ``` 77 | 78 | --- 79 | 80 | ### **4️⃣ 现代 Android 反调试技术(2018 - 至今)** 81 | 🔹 **SafetyNet & Play Protect** 82 | - Google 在 Android 8.0 及以上系统引入 **Play Protect**,使用 AI 监测恶意应用,防止 Root 和 Hook。 83 | - `SafetyNet` 检测模拟环境、Root 设备、修改的系统。 84 | 85 | 🔹 **现代防逆向技术** 86 | | **安全技术** | **功能** | 87 | |-------------|---------| 88 | | **代码混淆(ProGuard/R8)** | 让反编译后的代码难以阅读 | 89 | | **DEX 加密** | 让 `classes.dex` 变得不可读 | 90 | | **ShellCode 动态加载** | 代码不会直接存储在 `dex` 文件,而是运行时解密 | 91 | | **反调试(Anti-Debugging)** | 检测调试器(如 GDB, Frida)并终止进程 | 92 | | **反 Hook** | 检测 `Frida` 或 `Xposed` 注入 | 93 | 94 | --- 95 | 96 | ## **🛠 实战任务** 97 | 1️⃣ **分析早期 APK** 98 | - 下载一个 **2012 年左右** 的 Android APK(如老版的 UC 浏览器)。 99 | - 使用 `apktool` 反编译,查看 `AndroidManifest.xml` 和 `smali` 代码。 100 | - 尝试修改 `isVip()` 方法,绕过验证。 101 | 102 | 2️⃣ **分析现代 APP** 103 | - 选择一个 **现代 APP**(如微信、抖音、淘宝),使用 `jadx` 反编译。 104 | - 观察是否使用了 `ProGuard` 或 `R8` 进行代码混淆。 105 | - 使用 `Frida` 检测是否能 Hook APP 逻辑。 106 | 107 | --- 108 | 109 | ## **📚 参考资料** 110 | 📌 **Android 逆向工具** 111 | - `Apktool`:[https://github.com/iBotPeaches/Apktool](https://github.com/iBotPeaches/Apktool) 112 | - `Frida`:[https://frida.re](https://frida.re) 113 | - `Ghidra`:[https://ghidra-sre.org](https://ghidra-sre.org) 114 | - `Jadx`:[https://github.com/skylot/jadx](https://github.com/skylot/jadx) 115 | - `Xposed`:[https://repo.xposed.info/module/de.robv.android.xposed.installer](https://repo.xposed.info/module/de.robv.android.xposed.installer) 116 | 117 | 📌 **相关文章** 118 | - 《Android 逆向工程:从入门到精通》 119 | - Google Play Protect 介绍:[https://support.google.com/googleplay/answer/2812853](https://support.google.com/googleplay/answer/2812853) 120 | - 逆向工程论坛:[https://reverseengineering.stackexchange.com](https://reverseengineering.stackexchange.com) 121 | 122 | --- 123 | 124 | 🔥 **任务完成后,你将掌握:** 125 | ✅ Android 逆向的发展历史与主要技术演进。 126 | ✅ 了解现代 Android 安全防护策略。 127 | ✅ 能够使用 `apktool` 反编译 APK,并分析其结构。 128 | 129 | 🚀 **下一步(Day 3)**:**什么是 CPU 指令集?** 🎯 -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Byte-compiled / optimized / DLL files 2 | __pycache__/ 3 | *.py[cod] 4 | *$py.class 5 | 6 | # C extensions 7 | *.so 8 | 9 | # Distribution / packaging 10 | .Python 11 | build/ 12 | develop-eggs/ 13 | dist/ 14 | downloads/ 15 | eggs/ 16 | .eggs/ 17 | lib/ 18 | lib64/ 19 | parts/ 20 | sdist/ 21 | var/ 22 | wheels/ 23 | share/python-wheels/ 24 | *.egg-info/ 25 | .installed.cfg 26 | *.egg 27 | MANIFEST 28 | 29 | # PyInstaller 30 | # Usually these files are written by a python script from a template 31 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 32 | *.manifest 33 | *.spec 34 | 35 | # Installer logs 36 | pip-log.txt 37 | pip-delete-this-directory.txt 38 | 39 | # Unit test / coverage reports 40 | htmlcov/ 41 | .tox/ 42 | .nox/ 43 | .coverage 44 | .coverage.* 45 | .cache 46 | nosetests.xml 47 | coverage.xml 48 | *.cover 49 | *.py,cover 50 | .hypothesis/ 51 | .pytest_cache/ 52 | cover/ 53 | 54 | # Translations 55 | *.mo 56 | *.pot 57 | 58 | # Django stuff: 59 | *.log 60 | local_settings.py 61 | db.sqlite3 62 | db.sqlite3-journal 63 | 64 | # Flask stuff: 65 | instance/ 66 | .webassets-cache 67 | 68 | # Scrapy stuff: 69 | .scrapy 70 | 71 | # Sphinx documentation 72 | docs/_build/ 73 | 74 | # PyBuilder 75 | .pybuilder/ 76 | target/ 77 | 78 | # Jupyter Notebook 79 | .ipynb_checkpoints 80 | 81 | # IPython 82 | profile_default/ 83 | ipython_config.py 84 | 85 | # pyenv 86 | # For a library or package, you might want to ignore these files since the code is 87 | # intended to run in multiple environments; otherwise, check them in: 88 | # .python-version 89 | 90 | # pipenv 91 | # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. 92 | # However, in case of collaboration, if having platform-specific dependencies or dependencies 93 | # having no cross-platform support, pipenv may install dependencies that don't work, or not 94 | # install all needed dependencies. 95 | #Pipfile.lock 96 | 97 | # UV 98 | # Similar to Pipfile.lock, it is generally recommended to include uv.lock in version control. 99 | # This is especially recommended for binary packages to ensure reproducibility, and is more 100 | # commonly ignored for libraries. 101 | #uv.lock 102 | 103 | # poetry 104 | # Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control. 105 | # This is especially recommended for binary packages to ensure reproducibility, and is more 106 | # commonly ignored for libraries. 107 | # https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control 108 | #poetry.lock 109 | 110 | # pdm 111 | # Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control. 112 | #pdm.lock 113 | # pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it 114 | # in version control. 115 | # https://pdm.fming.dev/latest/usage/project/#working-with-version-control 116 | .pdm.toml 117 | .pdm-python 118 | .pdm-build/ 119 | 120 | # PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm 121 | __pypackages__/ 122 | 123 | # Celery stuff 124 | celerybeat-schedule 125 | celerybeat.pid 126 | 127 | # SageMath parsed files 128 | *.sage.py 129 | 130 | # Environments 131 | .env 132 | .venv 133 | env/ 134 | venv/ 135 | ENV/ 136 | env.bak/ 137 | venv.bak/ 138 | 139 | # Spyder project settings 140 | .spyderproject 141 | .spyproject 142 | 143 | # Rope project settings 144 | .ropeproject 145 | 146 | # mkdocs documentation 147 | /site 148 | 149 | # mypy 150 | .mypy_cache/ 151 | .dmypy.json 152 | dmypy.json 153 | 154 | # Pyre type checker 155 | .pyre/ 156 | 157 | # pytype static type analyzer 158 | .pytype/ 159 | 160 | # Cython debug symbols 161 | cython_debug/ 162 | 163 | # PyCharm 164 | # JetBrains specific template is maintained in a separate JetBrains.gitignore that can 165 | # be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore 166 | # and can be added to the global gitignore or merged into this file. For a more nuclear 167 | # option (not recommended) you can uncomment the following to ignore the entire idea folder. 168 | #.idea/ 169 | 170 | # PyPI configuration file 171 | .pypirc 172 | -------------------------------------------------------------------------------- /AndroidReverse101/第一阶段_计算机基础_逆向概论/Day_15_手写_ARM_汇编代码_实验.md: -------------------------------------------------------------------------------- 1 | # **📜 Day 15: 手写 ARM 汇编代码(实验)** 2 | 3 | ## **📌 学习目标** 4 | ✅ **学习 ARM32 & ARM64 汇编语法**,掌握基本指令集(MOV, ADD, SUB, LDR, STR, BL, CMP, B)。 5 | ✅ **理解 ARM 寄存器结构**(通用寄存器、栈指针、程序计数器)。 6 | ✅ **编写并运行 ARM 汇编代码**,使用 `as`(GNU Assembler)和 `ld` 进行汇编和链接。 7 | ✅ **掌握 Linux 平台下 ARM 汇编的调用约定**,与 C 代码进行交互。 8 | ✅ **调试 ARM 汇编程序**,使用 `gdb` 进行单步跟踪。 9 | 10 | --- 11 | 12 | # **1️⃣ ARM 汇编基础** 13 | ### **🔹 主要寄存器** 14 | | **架构** | **通用寄存器** | **特殊寄存器** | 15 | |---------|--------------|--------------| 16 | | **ARM32** | R0 - R12 | SP (R13), LR (R14), PC (R15) | 17 | | **ARM64** | X0 - X30 | SP, LR (X30), PC | 18 | 19 | - `SP`(Stack Pointer):栈指针 20 | - `LR`(Link Register):存储函数返回地址 21 | - `PC`(Program Counter):程序计数器 22 | 23 | 📌 **查看寄存器** 24 | ```bash 25 | adb shell cat /proc/cpuinfo 26 | ``` 27 | 28 | --- 29 | 30 | # **2️⃣ 基本指令** 31 | | **指令** | **作用** | **ARM32 示例** | **ARM64 示例** | 32 | |--------|------|-------------|-------------| 33 | | `MOV` | 赋值 | `MOV R0, #5` | `MOV X0, #5` | 34 | | `ADD` | 加法 | `ADD R0, R0, #10` | `ADD X0, X0, #10` | 35 | | `SUB` | 减法 | `SUB R0, R0, #2` | `SUB X0, X0, #2` | 36 | | `MUL` | 乘法 | `MUL R0, R1, R2` | `MUL X0, X1, X2` | 37 | | `LDR` | 读取内存 | `LDR R0, [R1]` | `LDR X0, [X1]` | 38 | | `STR` | 存储内存 | `STR R0, [R1]` | `STR X0, [X1]` | 39 | | `CMP` | 比较 | `CMP R0, R1` | `CMP X0, X1` | 40 | | `B` | 无条件跳转 | `B label` | `B label` | 41 | | `BL` | 函数调用 | `BL func` | `BL func` | 42 | | `RET` | 返回 | `BX LR` | `RET` | 43 | 44 | 📌 **示例** 45 | ```assembly 46 | MOV R0, #10 47 | ADD R0, R0, #5 48 | SUB R1, R0, #2 49 | MUL R2, R0, R1 50 | ``` 51 | 52 | --- 53 | 54 | # **3️⃣ ARM 汇编代码示例** 55 | ### **✅ 1. Hello World (ARM32)** 56 | ```assembly 57 | .global _start 58 | .section .data 59 | msg: .asciz "Hello, ARM!\n" 60 | len = . - msg 61 | 62 | .section .text 63 | _start: 64 | MOV R0, #1 @ 文件描述符 1(标准输出) 65 | LDR R1, =msg @ 加载字符串地址 66 | LDR R2, =len @ 加载字符串长度 67 | MOV R7, #4 @ 调用 write() 系统调用 68 | SWI 0 @ 触发系统调用 69 | 70 | MOV R7, #1 @ 调用 exit() 系统调用 71 | SWI 0 72 | ``` 73 | 📌 **编译运行** 74 | ```bash 75 | as -o hello.o hello.s 76 | ld -o hello hello.o 77 | ./hello 78 | ``` 79 | 80 | --- 81 | 82 | ### **✅ 2. 加法函数(ARM64)** 83 | ```assembly 84 | .global add_numbers 85 | add_numbers: 86 | ADD X0, X0, X1 @ X0 = X0 + X1 87 | RET @ 返回 88 | ``` 89 | 📌 **等价 C 代码** 90 | ```c 91 | long add_numbers(long a, long b) { 92 | return a + b; 93 | } 94 | ``` 95 | 96 | --- 97 | 98 | # **4️⃣ ARM 汇编调用 C 代码** 99 | 📌 **汇编代码(ARM64)** 100 | ```assembly 101 | .global _start 102 | _start: 103 | MOV X0, #5 104 | MOV X1, #3 105 | BL add_numbers 106 | B _start 107 | 108 | .global add_numbers 109 | add_numbers: 110 | ADD X0, X0, X1 111 | RET 112 | ``` 113 | 📌 **等价 C 代码** 114 | ```c 115 | long add_numbers(long a, long b) { 116 | return a + b; 117 | } 118 | ``` 119 | 120 | 📌 **编译运行** 121 | ```bash 122 | as -o add.o add.s 123 | ld -o add add.o 124 | ./add 125 | ``` 126 | 127 | --- 128 | 129 | # **5️⃣ 调试 ARM 汇编** 130 | 📌 **使用 GDB 调试** 131 | ```bash 132 | gdb ./hello 133 | ``` 134 | 📌 **常用调试命令** 135 | ```gdb 136 | disassemble _start # 反汇编 137 | info registers # 查看寄存器 138 | break _start # 设置断点 139 | run # 运行程序 140 | stepi # 单步执行 141 | ``` 142 | 143 | --- 144 | 145 | # **🛠 实战任务** 146 | ### **✅ 1. 编写并运行 Hello World** 147 | ```bash 148 | as -o hello.o hello.s 149 | ld -o hello hello.o 150 | ./hello 151 | ``` 152 | ### **✅ 2. 编写并调用加法函数** 153 | ```bash 154 | as -o add.o add.s 155 | ld -o add add.o 156 | ./add 157 | ``` 158 | ### **✅ 3. 调试 ARM 汇编** 159 | ```bash 160 | gdb ./hello 161 | ``` 162 | 163 | --- 164 | 165 | # **📚 参考资料** 166 | 📌 **ARM 汇编指南** 167 | - `ARM 官方文档`:[https://developer.arm.com/documentation](https://developer.arm.com/documentation) 168 | - `ARM 指令集`:[https://developer.arm.com/architectures/instruction-sets](https://developer.arm.com/architectures/instruction-sets) 169 | 170 | 📌 **调试工具** 171 | - `GDB 调试 ARM`:[https://sourceware.org/gdb/](https://sourceware.org/gdb/) 172 | 173 | --- 174 | 175 | 🔥 **任务完成后,你将掌握:** 176 | ✅ **如何编写 ARM 汇编代码并运行** 177 | ✅ **如何与 C 代码交互** 178 | ✅ **如何调试 ARM 汇编程序** 179 | 180 | 🚀 **下一步(Day 16)**:**反汇编工具介绍!** 🎯 -------------------------------------------------------------------------------- /AndroidReverse101/第二阶段_APK逆向基础/Day_26_APK_重新打包_签名.md: -------------------------------------------------------------------------------- 1 | # **📜 Day 26: APK 重新打包 & 签名** 2 | 3 | ## **📌 学习目标** 4 | ✅ **掌握 APK 反编译后如何正确重新打包 & 签名**,确保 APK 可正常安装运行。 5 | ✅ **学习如何使用 `apktool` 重新打包已修改的 APK 文件,并使用 `zipalign` 优化**。 6 | ✅ **掌握 APK 签名机制,使用 `apksigner` 和 `jarsigner` 生成 & 签名 APK**。 7 | ✅ **学习如何绕过 Android 的签名验证机制,使用 `Lucky Patcher` 或 `Frida` 绕过签名检查**。 8 | ✅ **实战:对修改后的 APK 重新打包、签名,并成功安装到 Android 设备!** 9 | 10 | --- 11 | 12 | # **1️⃣ 为什么需要重新打包 & 签名?** 13 | 当我们使用 `apktool` 反编译 APK 并修改 `Smali` 代码后,APK 需要 **重新打包** 并 **签名**,否则: 14 | - Android 系统不会允许安装未签名的 APK 15 | - 部分应用有 **签名校验** 机制,可能会拒绝运行 16 | 17 | --- 18 | 19 | # **2️⃣ APK 重新打包** 20 | 📌 **使用 `apktool` 反编译 APK** 21 | ```bash 22 | apktool d app.apk -o output/ 23 | ``` 24 | 📌 **修改 Smali 代码** 25 | ```smali 26 | .method public isVIP()Z 27 | const/4 v0, 0x1 28 | return v0 29 | .end method 30 | ``` 31 | 📌 **重新打包 APK** 32 | ```bash 33 | apktool b output -o modded.apk 34 | ``` 35 | 📌 **优化 APK 结构** 36 | ```bash 37 | zipalign -v 4 modded.apk aligned.apk 38 | ``` 39 | 40 | --- 41 | 42 | # **3️⃣ APK 签名** 43 | ## **✅ 1. 生成签名密钥** 44 | 如果没有密钥,需要生成一个: 45 | ```bash 46 | keytool -genkey -v -keystore my.keystore -alias myalias -keyalg RSA -keysize 2048 -validity 10000 47 | ``` 48 | 示例输出: 49 | ``` 50 | Enter keystore password: android 51 | Re-enter new password: android 52 | What is your first and last name? 53 | [Unknown]: Android Reverse Engineer 54 | What is the name of your organization? 55 | [Unknown]: Reverse Team 56 | ... 57 | ``` 58 | 59 | ## **✅ 2. 使用 `jarsigner` 签名** 60 | ```bash 61 | jarsigner -verbose -keystore my.keystore aligned.apk myalias 62 | ``` 63 | 64 | ## **✅ 3. 使用 `apksigner` 签名** 65 | ```bash 66 | apksigner sign --ks my.keystore --out signed.apk aligned.apk 67 | ``` 68 | 69 | ## **✅ 4. 安装已签名 APK** 70 | ```bash 71 | adb install signed.apk 72 | ``` 73 | 74 | --- 75 | 76 | # **4️⃣ 绕过签名校验** 77 | 某些应用有 **签名校验**,即使修改 & 重新签名 APK 也无法运行,解决方案: 78 | - **修改 Smali 代码,跳过签名校验** 79 | - **使用 Frida Hook 运行时绕过签名检查** 80 | - **使用 Lucky Patcher 移除签名验证** 81 | 82 | ## **✅ 1. 修改 `Signature Check`** 83 | 📌 **查找 `getPackageInfo`** 84 | ```bash 85 | grep -r "getPackageInfo" output/smali/ 86 | ``` 87 | 📌 **原始 Smali 代码** 88 | ```smali 89 | invoke-virtual {p1}, Landroid/content/pm/PackageManager;->getPackageInfo(Ljava/lang/String;I)Landroid/content/pm/PackageInfo; 90 | ``` 91 | 📌 **修改返回值** 92 | ```smali 93 | const/4 v0, 0x0 94 | return v0 95 | ``` 96 | 97 | ## **✅ 2. 使用 Frida 绕过签名校验** 98 | ```js 99 | Java.perform(function() { 100 | var PackageManager = Java.use("android.content.pm.PackageManager"); 101 | PackageManager.getPackageInfo.implementation = function(pkg, flags) { 102 | console.log("Bypassing signature check for:", pkg); 103 | return this.getPackageInfo(pkg, flags); 104 | }; 105 | }); 106 | ``` 107 | 📌 **运行 Frida** 108 | ```bash 109 | frida -U -n com.example.app -e "..." 110 | ``` 111 | 112 | ## **✅ 3. 使用 Lucky Patcher** 113 | - 打开 Lucky Patcher 114 | - 选择 APK 115 | - 选择 **"移除签名校验"** 116 | - 重新安装 APK 117 | 118 | --- 119 | 120 | # **5️⃣ 实战任务** 121 | ### **✅ 1. 反编译 & 修改 APK** 122 | ```bash 123 | apktool d app.apk -o output/ 124 | ``` 125 | ### **✅ 2. 重新打包** 126 | ```bash 127 | apktool b output -o modded.apk 128 | ``` 129 | ### **✅ 3. 优化 APK** 130 | ```bash 131 | zipalign -v 4 modded.apk aligned.apk 132 | ``` 133 | ### **✅ 4. 签名 APK** 134 | ```bash 135 | apksigner sign --ks my.keystore --out signed.apk aligned.apk 136 | ``` 137 | ### **✅ 5. 安装 APK** 138 | ```bash 139 | adb install signed.apk 140 | ``` 141 | ### **✅ 6. 绕过签名校验** 142 | ```js 143 | Java.perform(function() { 144 | var PackageManager = Java.use("android.content.pm.PackageManager"); 145 | PackageManager.getPackageInfo.implementation = function(pkg, flags) { 146 | return this.getPackageInfo(pkg, flags); 147 | }; 148 | }); 149 | ``` 150 | 151 | --- 152 | 153 | # **📚 参考资料** 154 | 📌 **APK 反编译 & 签名** 155 | - `APKTool`:[https://github.com/iBotPeaches/Apktool](https://github.com/iBotPeaches/Apktool) 156 | - `APKSIGNER`:[https://developer.android.com/studio/command-line/apksigner](https://developer.android.com/studio/command-line/apksigner) 157 | 158 | 📌 **绕过签名校验** 159 | - `Frida`:[https://frida.re](https://frida.re) 160 | - `Lucky Patcher`:[https://lucky-patcher.net/](https://lucky-patcher.net/) 161 | 162 | --- 163 | 164 | 🔥 **任务完成后,你将掌握:** 165 | ✅ **如何重新打包 & 签名 APK,确保修改后的 APK 可安装运行** 166 | ✅ **如何绕过应用的签名校验,成功运行修改后的应用** 167 | ✅ **如何使用 Frida Hook 运行时,绕过签名验证机制** 168 | 169 | 🚀 **下一步(Day 27)**:**动态调试入门!** 🎯 -------------------------------------------------------------------------------- /AndroidReverse101/第一阶段_计算机基础_逆向概论/Day_7_ARM_汇编指令解析.md: -------------------------------------------------------------------------------- 1 | # **📜 Day 7: ARM 汇编指令解析(ARM32 & ARM64)** 2 | 3 | ## **📌 学习目标** 4 | ✅ **深入理解 ARM 指令集(ARM32 & ARM64)**,掌握各种常见指令的使用方式。 5 | ✅ **学习 ARM 指令的分类**,包括 **数据处理、加载/存储、分支跳转、条件执行、系统调用**。 6 | ✅ **对比 ARM 汇编与 C 语言**,并提供等价的 C 代码示例。 7 | ✅ **编写和运行 ARM 汇编代码**,进行基本的调试和分析。 8 | ✅ **理解 ARM 汇编指令在逆向工程和漏洞利用中的应用**。 9 | 10 | --- 11 | 12 | # **1️⃣ ARM 汇编基础** 13 | ### **🔹 为什么学习 ARM 汇编?** 14 | - **移动端主流架构**(Android、iOS、嵌入式设备)。 15 | - **低功耗高性能**,采用 **RISC 设计**,广泛用于服务器、智能手机等设备。 16 | - **逆向工程 & 安全研究必备技能**(如 APK 破解、调试分析等)。 17 | 18 | ### **🔹 ARM 处理器架构** 19 | | **架构** | **位数** | **寄存器数** | **指令长度** | **代表 CPU** | 20 | |---------|------|-------|----------|-----------| 21 | | ARMv7(ARM32) | 32 位 | 16 个(R0-R15) | 4 字节(Thumb 为 2 字节) | Cortex-A7, Cortex-A15 | 22 | | ARMv8(ARM64) | 64 位 | 31 个(X0-X30) | 4 字节 | Cortex-A53, Cortex-A72 | 23 | 24 | --- 25 | 26 | # **2️⃣ ARM 指令集分类** 27 | ### **✅ 1. 数据处理指令** 28 | 数据处理指令用于 **算术运算、逻辑运算、数据移动**。 29 | 30 | | **指令** | **作用** | **ARM32 示例** | **ARM64 示例** | **等价 C 代码** | 31 | |--------|------|-------------|-------------|-------------| 32 | | `MOV` | 赋值 | `MOV R0, #5` | `MOV X0, #5` | `int a = 5;` | 33 | | `ADD` | 加法 | `ADD R0, R0, #10` | `ADD X0, X0, #10` | `a = a + 10;` | 34 | | `SUB` | 减法 | `SUB R0, R0, #2` | `SUB X0, X0, #2` | `a = a - 2;` | 35 | | `MUL` | 乘法 | `MUL R0, R1, R2` | `MUL X0, X1, X2` | `a = b * c;` | 36 | | `AND` | 按位与 | `AND R0, R0, R1` | `AND X0, X0, X1` | `a = a & b;` | 37 | | `ORR` | 按位或 | `ORR R0, R0, R1` | `ORR X0, X0, X1` | `a = a | b;` | 38 | | `EOR` | 按位异或 | `EOR R0, R0, R1` | `EOR X0, X0, X1` | `a = a ^ b;` | 39 | | `LSL` | 左移 | `LSL R0, R1, #2` | `LSL X0, X1, #2` | `a = b << 2;` | 40 | | `LSR` | 右移 | `LSR R0, R1, #2` | `LSR X0, X1, #2` | `a = b >> 2;` | 41 | 42 | **🔹 示例:** 43 | ```assembly 44 | MOV R0, #10 ; R0 = 10 45 | ADD R0, R0, #5 ; R0 = R0 + 5 46 | SUB R1, R0, #2 ; R1 = R0 - 2 47 | MUL R2, R0, R1 ; R2 = R0 * R1 48 | ``` 49 | 50 | 等价的 **C 代码**: 51 | ```c 52 | int a = 10; 53 | a = a + 5; 54 | int b = a - 2; 55 | int c = a * b; 56 | ``` 57 | 58 | --- 59 | 60 | ## **✅ 2. 加载 / 存储指令** 61 | ARM 采用 **Load-Store 架构**,所有的内存访问必须使用 **LDR(加载)和 STR(存储)**。 62 | 63 | | **指令** | **作用** | **ARM32 示例** | **ARM64 示例** | **等价 C 代码** | 64 | |--------|------|-------------|-------------|-------------| 65 | | `LDR` | 读取内存 | `LDR R0, [R1]` | `LDR X0, [X1]` | `a = *ptr;` | 66 | | `STR` | 存储到内存 | `STR R0, [R1]` | `STR X0, [X1]` | `*ptr = a;` | 67 | 68 | **🔹 示例:** 69 | ```assembly 70 | LDR R0, =0x1000 ; 读取内存地址 0x1000 71 | LDR R1, [R0] ; 读取 R0 指向的内存值 72 | STR R1, [R2] ; 存储 R1 的值到 R2 指向的内存 73 | ``` 74 | 75 | 等价的 **C 代码**: 76 | ```c 77 | int *ptr = (int *)0x1000; 78 | int a = *ptr; 79 | ptr2 = &a; 80 | *ptr2 = a; 81 | ``` 82 | 83 | --- 84 | 85 | ## **✅ 3. 分支与控制流** 86 | ARM 使用 **条件跳转(B, BL, BX)** 和 **循环(CMP + Bxx)** 来实现控制流。 87 | 88 | | **指令** | **作用** | **ARM32 示例** | **ARM64 示例** | **等价 C 代码** | 89 | |--------|------|-------------|-------------|-------------| 90 | | `B` | 无条件跳转 | `B loop` | `B loop` | `goto loop;` | 91 | | `BL` | 过程调用 | `BL function` | `BL function` | `function();` | 92 | | `CMP` | 比较 | `CMP R0, R1` | `CMP X0, X1` | `if (a == b) {...}` | 93 | | `BEQ` | 等于跳转 | `BEQ label` | `B.EQ label` | `if (a == b) goto label;` | 94 | | `BNE` | 不等跳转 | `BNE label` | `B.NE label` | `if (a != b) goto label;` | 95 | 96 | **🔹 示例:** 97 | ```assembly 98 | CMP R0, R1 ; 比较 R0 和 R1 99 | BEQ equal ; 如果相等,跳转到 equal 100 | BNE not_equal ; 如果不相等,跳转到 not_equal 101 | B loop ; 继续循环 102 | ``` 103 | 104 | 等价的 **C 代码**: 105 | ```c 106 | if (a == b) { 107 | goto equal; 108 | } else { 109 | goto not_equal; 110 | } 111 | ``` 112 | 113 | --- 114 | 115 | # **🛠 实战任务** 116 | ### **✅ 1. 编写并运行 ARM 汇编** 117 | ```bash 118 | as -o arm.o arm.s 119 | ld -o arm arm.o 120 | ./arm 121 | ``` 122 | 123 | ### **✅ 2. 反编译 ARM ELF** 124 | ```bash 125 | objdump -d arm_binary | head -n 20 126 | ``` 127 | 128 | ### **✅ 3. 逆向分析 Android APK** 129 | ```bash 130 | apktool d app.apk -o output 131 | vim output/smali/com/example/Main.smali 132 | ``` 133 | 134 | --- 135 | 136 | # **📚 参考资料** 137 | 📌 **ARM 官方文档** 138 | - `ARMv7 指令集`:[https://developer.arm.com/documentation](https://developer.arm.com/documentation) 139 | - `ARMv8 (AArch64) 指令集`:[https://developer.arm.com/documentation](https://developer.arm.com/documentation) 140 | 141 | 📌 **逆向工程** 142 | - `Ghidra`:[https://ghidra-sre.org/](https://ghidra-sre.org/) 143 | - `IDA Pro`:[https://hex-rays.com/](https://hex-rays.com/) 144 | 145 | 🚀 **下一步(Day 8)**:**函数调用与返回!** 🎯 -------------------------------------------------------------------------------- /AndroidReverse101/第一阶段_计算机基础_逆向概论/Day_6_x86_vs._ARM_汇编.md: -------------------------------------------------------------------------------- 1 | # **📜 Day 6: x86 vs. ARM(ARM32 & ARM64)汇编对比** 2 | 3 | ## **📌 学习目标** 4 | ✅ **理解 x86 和 ARM(ARM32 & ARM64)汇编语言的核心区别**,包括架构、寄存器、指令集和寻址模式。 5 | ✅ **掌握 x86、ARM32 和 ARM64 指令的对比**,理解它们在不同架构上的执行方式。 6 | ✅ **学习如何在 x86、ARM32 和 ARM64 处理器上编写汇编代码**,并进行调试和反编译分析。 7 | ✅ **通过示例代码** 解析不同架构下汇编的实际应用,包括寄存器操作、函数调用、数据存储等。 8 | ✅ **理解 x86 与 ARM 在逆向工程、安全研究和漏洞利用中的差异**。 9 | 10 | --- 11 | 12 | # **1️⃣ x86 vs. ARM(ARM32 & ARM64)体系架构对比** 13 | | **特性** | **x86(CISC)** | **ARM32(RISC)** | **ARM64(RISC)** | 14 | |---------|--------------|----------------|----------------| 15 | | **指令集** | **CISC(复杂指令集计算机)** | **RISC(精简指令集计算机)** | **RISC(精简指令集计算机)** | 16 | | **指令长度** | **可变长(1-15 字节)** | **固定 4 字节** | **固定 4 字节** | 17 | | **寻址模式** | **复杂,支持多种寻址方式** | **简单,偏向寄存器操作** | **简化,偏向寄存器操作** | 18 | | **寄存器数量** | **少(x86-32: 8 个通用寄存器)** | **16 个通用寄存器(R0-R15)** | **31 个通用寄存器(X0-X30)** | 19 | | **操作模式** | **实模式、保护模式、长模式(64 位)** | **AArch32(32 位)** | **AArch64(64 位)** | 20 | | **能效** | **高功耗**,适用于 PC 和服务器 | **低功耗**,适用于移动设备 | **更高效,适用于移动设备和服务器** | 21 | 22 | 📌 **总结:** 23 | - **x86 采用 CISC 架构**,指令灵活但解码复杂。 24 | - **ARM32(ARMv7)采用 RISC 架构**,指令固定,适用于 32 位移动设备。 25 | - **ARM64(ARMv8)优化了 RISC 架构**,引入更多寄存器,提高计算能力,支持 64 位操作系统。 26 | 27 | --- 28 | 29 | # **2️⃣ x86 vs. ARM32 vs. ARM64 指令对比** 30 | ### **🔹 x86 32/64 位寄存器** 31 | | **寄存器** | **x86-32(IA-32)** | **x86-64(x86-64)** | **用途** | 32 | |---------|------------|------------|------------| 33 | | EAX | RAX | 通用寄存器(累加器) | 34 | | EBX | RBX | 通用寄存器(基址寄存器) | 35 | | ECX | RCX | 计数寄存器(循环) | 36 | | EDX | RDX | 数据寄存器 | 37 | | ESI | RSI | 源索引寄存器 | 38 | | EDI | RDI | 目标索引寄存器 | 39 | | EBP | RBP | 栈基址指针 | 40 | | ESP | RSP | 栈指针 | 41 | 42 | ### **🔹 ARM32 vs. ARM64 寄存器** 43 | | **寄存器** | **ARM32(ARMv7)** | **ARM64(ARMv8)** | **用途** | 44 | |---------|----------------|----------------|--------| 45 | | 通用寄存器 | R0 - R12 | X0 - X30 | 传递参数,计算存储 | 46 | | 栈指针 | R13 (SP) | SP | 指向栈顶 | 47 | | 链接寄存器 | R14 (LR) | X30 (LR) | 存储函数返回地址 | 48 | | 程序计数器 | R15 (PC) | PC | 存储当前指令地址 | 49 | 50 | --- 51 | 52 | ### **🔹 x86 vs. ARM32 vs. ARM64 指令对比** 53 | | **操作** | **x86 指令(CISC)** | **ARM32 指令(RISC)** | **ARM64 指令(RISC)** | 54 | |---------|-----------------|----------------|----------------| 55 | | 赋值 | `mov eax, 5` | `MOV R0, #5` | `MOV X0, #5` | 56 | | 加法 | `add eax, 10` | `ADD R0, R0, #10` | `ADD X0, X0, #10` | 57 | | 读取内存 | `mov eax, [ebx]` | `LDR R0, [R1]` | `LDR X0, [X1]` | 58 | | 存储到内存 | `mov [ebx], eax` | `STR R0, [R1]` | `STR X0, [X1]` | 59 | | 函数调用 | `call my_function` | `BL my_function` | `BL my_function` | 60 | | 逻辑运算 | `and eax, ebx` | `AND R0, R0, R1` | `AND X0, X0, X1` | 61 | | 条件跳转 | `cmp eax, ebx` `je label` | `CMP R0, R1` `BEQ label` | `CMP X0, X1` `B.EQ label` | 62 | 63 | --- 64 | 65 | # **3️⃣ x86 vs. ARM32 vs. ARM64 代码示例** 66 | ### **🔹 x86 汇编示例** 67 | ```assembly 68 | section .text 69 | global _start 70 | 71 | _start: 72 | mov eax, 5 ; 赋值 5 给 EAX 73 | add eax, 10 ; EAX = EAX + 10 74 | mov ebx, eax ; 复制 EAX 到 EBX 75 | int 0x80 ; 调用 Linux 系统 API 76 | ``` 77 | 78 | --- 79 | 80 | ### **🔹 ARM32 汇编示例** 81 | ```assembly 82 | .global _start 83 | _start: 84 | MOV R0, #5 ; 赋值 5 给 R0 85 | ADD R0, R0, #10 ; R0 = R0 + 10 86 | LDR R1, [R2] ; 读取 R2 指向的内存到 R1 87 | STR R1, [R3] ; 存储 R1 到 R3 指向的内存 88 | B _start ; 无限循环 89 | ``` 90 | 91 | --- 92 | 93 | ### **🔹 ARM64 汇编示例** 94 | ```assembly 95 | .global _start 96 | _start: 97 | MOV X0, #5 ; 赋值 5 给 X0 98 | ADD X0, X0, #10 ; X0 = X0 + 10 99 | LDR X1, [X2] ; 读取 X2 指向的内存到 X1 100 | STR X1, [X3] ; 存储 X1 到 X3 指向的内存 101 | B _start ; 无限循环 102 | ``` 103 | 104 | --- 105 | 106 | # **🛠 实战任务** 107 | ### **✅ 1. 运行 x86 汇编** 108 | ```bash 109 | nasm -f elf64 test.asm 110 | ld -o test test.o 111 | ./test 112 | ``` 113 | 114 | ### **✅ 2. 运行 ARM32 汇编** 115 | ```bash 116 | as -o arm32.o arm32.s 117 | ld -o arm32 arm32.o 118 | ./arm32 119 | ``` 120 | 121 | ### **✅ 3. 运行 ARM64 汇编** 122 | ```bash 123 | as -o arm64.o arm64.s 124 | ld -o arm64 arm64.o 125 | ./arm64 126 | ``` 127 | 128 | --- 129 | 130 | # **📚 参考资料** 131 | 📌 **x86 汇编** 132 | - `x86 指令手册`:[https://www.felixcloutier.com/x86/](https://www.felixcloutier.com/x86/) 133 | 134 | 📌 **ARM 汇编** 135 | - `ARM 指令手册`:[https://developer.arm.com/documentation](https://developer.arm.com/documentation) 136 | 137 | --- 138 | 139 | 🔥 **任务完成后,你将掌握:** 140 | ✅ **x86、ARM32 和 ARM64 汇编语言的核心区别** 141 | ✅ **如何在不同架构上编写和调试汇编代码** 142 | ✅ **汇编在逆向工程中的实际应用** 143 | 144 | 🚀 **下一步(Day 7)**:**ARM 汇编指令解析!** 🎯 -------------------------------------------------------------------------------- /AndroidReverse101/第一阶段_计算机基础_逆向概论/Day_4_进制转换_为什么16进制很重要.md: -------------------------------------------------------------------------------- 1 | # **📜 Day 4: 进制转换 - 为什么 16 进制很重要?** 2 | 3 | ## **📌 学习目标** 4 | ✅ 掌握 **二进制、十进制、十六进制** 之间的转换方法和公式。 5 | ✅ 了解 **为什么 16 进制在计算机、汇编语言和逆向工程中如此重要**。 6 | ✅ 认识 **ELF 可执行文件的结构**,并学会如何分析 ELF 文件的内容。 7 | ✅ 通过 **实战案例** 掌握 16 进制在 **内存地址、指令编码、文件结构** 以及 **漏洞分析** 中的作用。 8 | 9 | --- 10 | 11 | # **1️⃣ 进制转换概述** 12 | ### **🔹 为什么需要进制转换?** 13 | 计算机内部使用 **二进制** 存储数据,但二进制数据可读性较差,因此 **十六进制(Hex)** 被广泛用于表示地址、机器码等。 14 | 15 | | **进制** | **基数** | **表示范围** | **示例** | 16 | |--------|------|---------|---------| 17 | | **二进制(Binary)** | 2 | `0, 1` | `101010` | 18 | | **十进制(Decimal)** | 10 | `0-9` | `42` | 19 | | **十六进制(Hexadecimal)** | 16 | `0-9, A-F` | `0x2A` | 20 | 21 | --- 22 | 23 | # **2️⃣ 进制转换方法** 24 | ### **🔹 二进制 ↔ 十进制** 25 | ✅ **二进制转十进制**(`101010₂` → `42₁₀`): 26 | **计算公式**: 27 | \[ 28 | (1 × 2^5) + (0 × 2^4) + (1 × 2^3) + (0 × 2^2) + (1 × 2^1) + (0 × 2^0) = 42 29 | \] 30 | 31 | ✅ **十进制转二进制**(`42₁₀` → `101010₂`): 32 | **方法**: 33 | 1. `42 ÷ 2 = 21` 余 `0` 34 | 2. `21 ÷ 2 = 10` 余 `1` 35 | 3. `10 ÷ 2 = 5` 余 `0` 36 | 4. `5 ÷ 2 = 2` 余 `1` 37 | 5. `2 ÷ 2 = 1` 余 `0` 38 | 6. `1 ÷ 2 = 0` 余 `1` 39 | **结果:`101010₂`** 40 | 41 | --- 42 | 43 | # **3️⃣ ELF 可执行文件** 44 | ### **🔹 什么是 ELF?** 45 | **ELF(Executable and Linkable Format)** 是 Linux 及类 Unix 系统使用的 **可执行文件格式**,类似于 Windows 的 PE(Portable Executable)文件格式。 46 | 47 | ELF 文件可以是: 48 | - **可执行程序**(如 `/bin/ls`) 49 | - **共享库(.so 文件)** 50 | - **核心转储(core dump)** 51 | 52 | ### **🔹 ELF 文件的内容** 53 | ELF 文件由多个 **段(Segment)** 和 **节(Section)** 组成,主要结构如下: 54 | | **ELF 结构** | **功能** | 55 | |-------------|------------------------------| 56 | | **ELF 头(ELF Header)** | 存储 ELF 文件的基本信息,如魔数、入口地址、段偏移等 | 57 | | **程序头表(Program Header)** | 描述如何加载文件到内存(仅在可执行文件中存在) | 58 | | **节头表(Section Header)** | 描述各个节(Sections),如 `.text`, `.data`, `.rodata` | 59 | 60 | --- 61 | 62 | # **4️⃣ ELF 文件结构解析** 63 | 我们可以使用 `hexdump` 命令查看 ELF 文件的 16 进制内容: 64 | ```bash 65 | hexdump -C /bin/ls | head -n 10 66 | ``` 67 | 示例输出: 68 | ``` 69 | 00000000 7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00 | .ELF........... | 70 | ``` 71 | - `7F 45 4C 46` 是 **ELF 魔数(Magic Number)**,用于标识 ELF 文件。 72 | 73 | 我们还可以使用 `readelf` 分析 ELF 结构: 74 | ```bash 75 | readelf -h /bin/ls 76 | ``` 77 | 示例输出: 78 | ``` 79 | ELF Header: 80 | Magic: 7f 45 4c 46 81 | Class: ELF64 82 | Data: 2's complement, little endian 83 | Entry point address: 0x401000 84 | ``` 85 | - `Entry point address: 0x401000` 表示程序的入口地址。 86 | 87 | --- 88 | 89 | # **5️⃣ 为什么 ELF 和 16 进制很重要?** 90 | ✅ **ELF 使用 16 进制存储指令** 91 | 所有 CPU 指令最终都会被转换为 **16 进制机器码**: 92 | ```assembly 93 | mov eax, 5 ; x86 汇编 94 | B8 05 00 00 00 ; 对应的十六进制机器码 95 | ``` 96 | ```assembly 97 | MOV R0, #5 ; ARM 汇编 98 | E3A00005 ; 对应的十六进制机器码 99 | ``` 100 | 101 | ✅ **ELF 可执行文件包含大量 16 进制数据** 102 | 例如,使用 `objdump` 查看 ELF 代码段: 103 | ```bash 104 | objdump -d /bin/ls | head -n 20 105 | ``` 106 | 示例输出: 107 | ``` 108 | 0000000000401130 <_start>: 109 | 401130: 48 83 ec 08 sub rsp,0x8 110 | 401134: 48 8b 05 dd 2e mov rax,QWORD PTR [rip+0x2edd] 111 | ``` 112 | 这些都是 **ELF 可执行文件的指令代码**,是 **16 进制** 机器码的直接映射。 113 | 114 | --- 115 | 116 | # **6️⃣ 实战任务** 117 | ### **✅ 1. 进制转换练习** 118 | ```python 119 | # 二进制 -> 十进制 120 | print(int("101010", 2)) # 输出:42 121 | 122 | # 十进制 -> 十六进制 123 | print(hex(42)) # 输出:0x2a 124 | 125 | # 十六进制 -> 二进制 126 | print(bin(0x2A)) # 输出:0b101010 127 | ``` 128 | 129 | ### **✅ 2. 使用 `hexdump` 分析 ELF 文件** 130 | ```bash 131 | hexdump -C /bin/ls | head -n 10 132 | ``` 133 | 134 | ### **✅ 3. 用 `readelf` 查看 ELF 头** 135 | ```bash 136 | readelf -h /bin/ls 137 | ``` 138 | 139 | ### **✅ 4. 反编译 ELF 可执行文件** 140 | ```bash 141 | objdump -d /bin/ls | head -n 20 142 | ``` 143 | 144 | --- 145 | 146 | # **📚 参考资料** 147 | 📌 **进制转换工具** 148 | - 进制转换网站:[https://www.rapidtables.com/convert/number/](https://www.rapidtables.com/convert/number/) 149 | 150 | 📌 **ELF 相关** 151 | - `readelf` 手册:[https://man7.org/linux/man-pages/man1/readelf.1.html](https://man7.org/linux/man-pages/man1/readelf.1.html) 152 | - `objdump` 手册:[https://man7.org/linux/man-pages/man1/objdump.1.html](https://man7.org/linux/man-pages/man1/objdump.1.html) 153 | 154 | 📌 **CPU 指令** 155 | - `x86 指令手册`:[https://www.felixcloutier.com/x86/](https://www.felixcloutier.com/x86/) 156 | - `ARM 指令手册`:[https://developer.arm.com/documentation](https://developer.arm.com/documentation) 157 | 158 | --- 159 | 160 | 🔥 **任务完成后,你将掌握:** 161 | ✅ **二进制、十进制、十六进制的转换方法和公式。** 162 | ✅ **ELF 文件的基本结构,并学会使用 `readelf` 和 `objdump` 进行分析。** 163 | ✅ **利用 hexdump 查看 ELF 头部,并解析关键字段。** 164 | 165 | 🚀 **下一步(Day 5)**:**汇编语言基础!** 🎯 -------------------------------------------------------------------------------- /AndroidReverse101/第三阶段_高级逆向_CTF挑战/Day_70_逆向挖掘_0Day_漏洞.md: -------------------------------------------------------------------------------- 1 | # **📜 Day 70: 逆向挖掘 0Day 漏洞** 2 | 3 | ## **📌 学习目标** 4 | ✅ **掌握 0Day 漏洞(Zero-Day Exploit)的基本概念,理解漏洞的危害**。 5 | ✅ **学习如何使用 `IDA Pro`、`Ghidra`、`GDB`、`Frida` 进行二进制分析**。 6 | ✅ **掌握常见的二进制漏洞类型,如缓冲区溢出、格式化字符串、整数溢出、Use-After-Free 等**。 7 | ✅ **学习如何 Fuzz 测试应用,挖掘潜在漏洞**。 8 | ✅ **实战:逆向分析应用,寻找 0Day 漏洞,成功构造 Exploit!** 9 | 10 | --- 11 | 12 | # **1️⃣ 什么是 0Day 漏洞?** 13 | 0Day 漏洞(Zero-Day Exploit)是指开发者 **未知** 且尚未修复的漏洞,黑客可利用该漏洞 **执行任意代码、提升权限或获取敏感信息**。 14 | 📌 **常见的 0Day 漏洞类型** 15 | | **漏洞类型** | **描述** | **常见影响** | 16 | |------------|--------|------------| 17 | | **缓冲区溢出(Buffer Overflow)** | 超出数组范围写入数据 | 代码执行、提权 | 18 | | **格式化字符串漏洞(Format String Bug)** | 不安全的 `printf()` | 读取/修改内存 | 19 | | **整数溢出(Integer Overflow)** | 计算错误导致溢出 | 逃逸沙盒 | 20 | | **Use-After-Free(UAF)** | 释放后访问对象 | 远程代码执行 | 21 | 22 | --- 23 | 24 | # **2️⃣ 逆向分析目标应用** 25 | ## **✅ 1. 提取 ELF 二进制** 26 | 📌 **查找可执行文件** 27 | ```bash 28 | adb shell ls /data/app/com.example.app/lib/arm64/ 29 | ``` 30 | 📌 **提取 so** 31 | ```bash 32 | adb pull /data/app/com.example.app/lib/arm64/libtarget.so . 33 | ``` 34 | 35 | ## **✅ 2. 使用 `readelf` 分析 ELF 结构** 36 | 📌 **查看 ELF 头** 37 | ```bash 38 | readelf -h libtarget.so 39 | ``` 40 | 📌 **查看动态符号** 41 | ```bash 42 | readelf -s libtarget.so 43 | ``` 44 | 📌 **查找可疑函数** 45 | ```bash 46 | strings libtarget.so | grep system 47 | ``` 48 | 49 | --- 50 | 51 | # **3️⃣ 缓冲区溢出漏洞分析** 52 | ## **✅ 1. 漏洞代码示例** 53 | 📌 **存在 `gets()` 缓冲区溢出** 54 | ```c 55 | #include 56 | void vulnerable() { 57 | char buffer[32]; 58 | printf("Enter input: "); 59 | gets(buffer); 60 | } 61 | ``` 62 | 📌 **编译 ELF** 63 | ```bash 64 | gcc -o vuln vuln.c -fno-stack-protector -z execstack 65 | ``` 66 | 📌 **分析 ELF** 67 | ```bash 68 | objdump -d vuln | grep call 69 | ``` 70 | 71 | ## **✅ 2. 使用 `GDB` 调试** 72 | 📌 **加载 ELF** 73 | ```bash 74 | gdb ./vuln 75 | break *vulnerable 76 | run 77 | ``` 78 | 📌 **输入超长数据** 79 | ```bash 80 | python -c 'print("A" * 100)' | ./vuln 81 | ``` 82 | 📌 **查看寄存器** 83 | ```bash 84 | info registers 85 | ``` 86 | 87 | --- 88 | 89 | # **4️⃣ 格式化字符串漏洞分析** 90 | ## **✅ 1. 漏洞代码示例** 91 | 📌 **存在 `printf()` 格式化字符串漏洞** 92 | ```c 93 | #include 94 | void vulnerable() { 95 | char buffer[64]; 96 | printf("Enter input: "); 97 | gets(buffer); 98 | printf(buffer); 99 | } 100 | ``` 101 | 📌 **输入 `%x %x %x` 可能泄露内存** 102 | ```bash 103 | python -c 'print("%x %x %x")' | ./vuln 104 | ``` 105 | 106 | --- 107 | 108 | # **5️⃣ Fuzz 测试** 109 | ## **✅ 1. 使用 `AFL++` 进行 Fuzz** 110 | 📌 **安装 AFL** 111 | ```bash 112 | sudo apt install afl++ 113 | ``` 114 | 📌 **编译目标** 115 | ```bash 116 | afl-gcc -o vuln_fuzz vuln.c 117 | ``` 118 | 📌 **运行 Fuzz** 119 | ```bash 120 | afl-fuzz -i inputs/ -o output/ -- ./vuln_fuzz 121 | ``` 122 | 123 | --- 124 | 125 | # **6️⃣ 漏洞利用** 126 | ## **✅ 1. 利用缓冲区溢出执行 Shell** 127 | 📌 **构造 ROP 链** 128 | ```python 129 | payload = b"A" * 40 130 | payload += b"\xef\xbe\xad\xde" 131 | print(payload) 132 | ``` 133 | 📌 **运行 Exploit** 134 | ```bash 135 | python exploit.py | ./vuln 136 | ``` 137 | 138 | ## **✅ 2. 绕过 ASLR** 139 | 📌 **泄露 libc 地址** 140 | ```bash 141 | ldd ./vuln 142 | ``` 143 | 📌 **利用 ROP 绕过保护** 144 | ```python 145 | payload = b"A" * 40 146 | payload += libc_base + system_offset 147 | ``` 148 | 149 | --- 150 | 151 | # **🛠 实战任务** 152 | ### **✅ 1. 提取 ELF** 153 | ```bash 154 | adb pull /data/app/com.example.app/lib/arm64/libtarget.so . 155 | ``` 156 | ### **✅ 2. 使用 `readelf` 分析** 157 | ```bash 158 | readelf -h libtarget.so 159 | readelf -s libtarget.so 160 | ``` 161 | ### **✅ 3. 进行 Fuzz 测试** 162 | ```bash 163 | afl-fuzz -i inputs/ -o output/ -- ./vuln 164 | ``` 165 | ### **✅ 4. 缓冲区溢出利用** 166 | ```python 167 | python -c 'print("A" * 100)' | ./vuln 168 | ``` 169 | ### **✅ 5. 绕过 ASLR** 170 | ```python 171 | payload = b"A" * 40 172 | payload += libc_base + system_offset 173 | ``` 174 | 175 | --- 176 | 177 | # **📚 参考资料** 178 | 📌 **二进制漏洞** 179 | - `IDA Pro`:[https://hex-rays.com/](https://hex-rays.com/) 180 | - `Ghidra`:[https://ghidra-sre.org/](https://ghidra-sre.org/) 181 | - `GDB`:[https://www.gnu.org/software/gdb/](https://www.gnu.org/software/gdb/) 182 | 183 | 📌 **Fuzz 测试** 184 | - `AFL++`:[https://github.com/AFLplusplus/AFLplusplus](https://github.com/AFLplusplus/AFLplusplus) 185 | 186 | 📌 **漏洞利用** 187 | - `ROP Gadget`:[https://github.com/JonathanSalwan/ROPgadget](https://github.com/JonathanSalwan/ROPgadget) 188 | 189 | --- 190 | 191 | 🔥 **任务完成后,你将掌握:** 192 | ✅ **如何提取 ELF 二进制,分析关键函数** 193 | ✅ **如何 Fuzz 测试应用,挖掘潜在漏洞** 194 | ✅ **如何利用缓冲区溢出 & 格式化字符串漏洞进行 Exploit** 195 | ✅ **如何绕过 ASLR 保护,执行任意代码** 196 | 197 | 🚀 **下一步(Day 100)**:**终极挑战:逆向一个完整 APP!** 🎯 -------------------------------------------------------------------------------- /AndroidReverse101/第二阶段_APK逆向基础/Day_25_Smali_代码修改实验.md: -------------------------------------------------------------------------------- 1 | # **📜 Day 25: Smali 代码修改实验** 2 | 3 | ## **📌 学习目标** 4 | ✅ **掌握 Smali 代码修改技巧**,学习如何修改 Android 应用逻辑。 5 | ✅ **学习如何修改方法返回值、去除 VIP 认证、绕过登录验证、解锁隐藏功能。** 6 | ✅ **掌握 Smali 代码的常见修改方式,如 `if` 语句篡改、字符串替换、修改 `invoke` 方法调用。** 7 | ✅ **通过 `apktool` 反编译 APK,修改 Smali 代码,并重新打包 & 安装。** 8 | ✅ **实战:修改 `isVIP()` 方法,绕过会员认证,去除广告,修改应用文字!** 9 | 10 | --- 11 | 12 | # **1️⃣ Smali 代码修改基础** 13 | ## **✅ 1. Smali 方法返回值修改** 14 | **目标**:将 `isVIP()` 方法的返回值从 `false` 改为 `true`。 15 | 16 | 📌 **反编译 APK** 17 | ```bash 18 | apktool d app.apk -o output/ 19 | ``` 20 | 📌 **查找 `isVIP()` 方法** 21 | ```bash 22 | grep -r "isVIP" output/smali/ 23 | ``` 24 | 📌 **原始 Smali 代码** 25 | ```smali 26 | .method public isVIP()Z 27 | .locals 1 28 | const/4 v0, 0x0 # 0 = false 29 | return v0 30 | .end method 31 | ``` 32 | 📌 **修改 Smali 代码** 33 | ```smali 34 | .method public isVIP()Z 35 | .locals 1 36 | const/4 v0, 0x1 # 1 = true 37 | return v0 38 | .end method 39 | ``` 40 | 📌 **重新打包** 41 | ```bash 42 | apktool b output -o modded.apk 43 | ``` 44 | 📌 **签名 & 安装** 45 | ```bash 46 | jarsigner -verbose -keystore my.keystore modded.apk alias_name 47 | adb install modded.apk 48 | ``` 49 | 50 | --- 51 | 52 | ## **✅ 2. 绕过登录验证** 53 | 📌 **查找 `checkLogin()` 方法** 54 | ```bash 55 | grep -r "checkLogin" output/smali/ 56 | ``` 57 | 📌 **原始 Smali 代码** 58 | ```smali 59 | .method public checkLogin(Ljava/lang/String;Ljava/lang/String;)Z 60 | .locals 2 61 | invoke-static {p1, p2}, Lcom/example/AuthUtils;->verify(Ljava/lang/String;Ljava/lang/String;)Z 62 | move-result v0 63 | return v0 64 | .end method 65 | ``` 66 | 📌 **修改 Smali 代码** 67 | ```smali 68 | .method public checkLogin(Ljava/lang/String;Ljava/lang/String;)Z 69 | .locals 1 70 | const/4 v0, 0x1 # 直接返回 true 71 | return v0 72 | .end method 73 | ``` 74 | 📌 **重新打包 & 安装** 75 | ```bash 76 | apktool b output -o modded.apk 77 | jarsigner -verbose -keystore my.keystore modded.apk alias_name 78 | adb install modded.apk 79 | ``` 80 | 81 | --- 82 | 83 | ## **✅ 3. 去除广告** 84 | 📌 **查找 `showAd()` 方法** 85 | ```bash 86 | grep -r "showAd" output/smali/ 87 | ``` 88 | 📌 **原始 Smali 代码** 89 | ```smali 90 | .method public showAd()V 91 | .locals 1 92 | const-string v0, "com.example.ads.AdsManager" 93 | invoke-static {v0}, Ljava/lang/Class;->forName(Ljava/lang/String;)Ljava/lang/Class; 94 | return-void 95 | .end method 96 | ``` 97 | 📌 **修改 Smali 代码** 98 | ```smali 99 | .method public showAd()V 100 | .locals 0 101 | return-void # 直接返回,不显示广告 102 | .end method 103 | ``` 104 | 105 | --- 106 | 107 | ## **✅ 4. 修改应用文本** 108 | 📌 **查找 `strings.xml`** 109 | ```bash 110 | grep -r "VIP" output/res/values/strings.xml 111 | ``` 112 | 📌 **修改文本** 113 | ```xml 114 | 超级会员 115 | ``` 116 | 📌 **重新打包 & 安装** 117 | ```bash 118 | apktool b output -o modded.apk 119 | adb install modded.apk 120 | ``` 121 | 122 | --- 123 | 124 | # **2️⃣ Hook Smali 运行时** 125 | ## **✅ 1. Hook `checkLogin()`** 126 | 📌 **Frida Hook** 127 | ```js 128 | Java.perform(function() { 129 | var AuthUtils = Java.use("com.example.AuthUtils"); 130 | AuthUtils.verify.implementation = function(user, pass) { 131 | return true; // 绕过登录 132 | }; 133 | }); 134 | ``` 135 | 📌 **运行 Frida** 136 | ```bash 137 | frida -U -n com.example.app -e "..." 138 | ``` 139 | 140 | --- 141 | 142 | # **🛠 实战任务** 143 | ### **✅ 1. 反编译 APK** 144 | ```bash 145 | apktool d app.apk -o output/ 146 | ``` 147 | ### **✅ 2. 修改 VIP 方法** 148 | ```smali 149 | .method public isVIP()Z 150 | const/4 v0, 0x1 151 | return v0 152 | .end method 153 | ``` 154 | ### **✅ 3. 绕过登录** 155 | ```smali 156 | .method public checkLogin(Ljava/lang/String;Ljava/lang/String;)Z 157 | const/4 v0, 0x1 158 | return v0 159 | .end method 160 | ``` 161 | ### **✅ 4. 去除广告** 162 | ```smali 163 | .method public showAd()V 164 | return-void 165 | .end method 166 | ``` 167 | ### **✅ 5. 修改文本** 168 | ```xml 169 | 超级会员 170 | ``` 171 | ### **✅ 6. 重新打包 & 安装** 172 | ```bash 173 | apktool b output -o modded.apk 174 | adb install modded.apk 175 | ``` 176 | 177 | --- 178 | 179 | # **📚 参考资料** 180 | 📌 **Smali 修改** 181 | - `Smali 参考文档`:[https://github.com/JesusFreke/smali](https://github.com/JesusFreke/smali) 182 | 183 | 📌 **APK 反编译** 184 | - `APKTool`:[https://github.com/iBotPeaches/Apktool](https://github.com/iBotPeaches/Apktool) 185 | 186 | 📌 **运行时 Hook** 187 | - `Frida`:[https://frida.re](https://frida.re) 188 | 189 | --- 190 | 191 | 🔥 **任务完成后,你将掌握:** 192 | ✅ **如何修改 Smali 代码,绕过 VIP、登录验证** 193 | ✅ **如何去除广告,修改应用文本** 194 | ✅ **如何 Hook 运行时,动态修改应用行为** 195 | 196 | 🚀 **下一步(Day 26)**:**APK 重新打包 & 签名!** 🎯 -------------------------------------------------------------------------------- /AndroidReverse101/第二阶段_APK逆向基础/Day_24_Smali_语言入门.md: -------------------------------------------------------------------------------- 1 | # **📜 Day 24: Smali 语言入门** 2 | 3 | ## **📌 学习目标** 4 | ✅ **理解 Smali 语言的基本语法和指令**,掌握 Smali 代码的编写与修改。 5 | ✅ **学习如何反编译 DEX 文件,获取 Smali 代码,修改并重新编译**。 6 | ✅ **掌握 Android 方法调用、寄存器操作、逻辑控制等核心 Smali 指令**。 7 | ✅ **学习如何修改 Smali 代码,绕过 VIP 认证、修改返回值等**。 8 | ✅ **实战:修改 Smali 代码,绕过应用限制,实现破解功能!** 9 | 10 | --- 11 | 12 | # **1️⃣ 什么是 Smali 语言?** 13 | Smali 是 Android 的 **Dalvik 虚拟机(DVM)** 使用的汇编语言, 14 | 主要用于反编译 DEX 文件,修改应用逻辑并重新打包。 15 | 16 | Smali 代码通常以 `.smali` 文件形式存储,每个类对应一个 `.smali` 文件。 17 | 例如: 18 | ``` 19 | smali/com/example/MainActivity.smali 20 | ``` 21 | 22 | --- 23 | 24 | # **2️⃣ Smali 代码结构** 25 | Smali 代码类似汇编语言,主要包含: 26 | - **类定义** 27 | - **方法定义** 28 | - **寄存器操作** 29 | - **逻辑控制** 30 | - **API 调用** 31 | 32 | 📌 **基本结构** 33 | ```smali 34 | .class public Lcom/example/MainActivity; 35 | .super Landroid/app/Activity; 36 | 37 | .method public onCreate()V 38 | .locals 1 39 | const-string v0, "Hello Smali!" 40 | invoke-static {v0}, Ljava/lang/System;->println(Ljava/lang/String;)V 41 | return-void 42 | .end method 43 | ``` 44 | - `.class public` → 定义类 45 | - `.super` → 继承 `Activity` 46 | - `.method public onCreate()V` → 定义 `onCreate` 方法 47 | - `.locals 1` → 分配 1 个寄存器 `v0` 48 | - `const-string v0, "Hello Smali!"` → 加载字符串到 `v0` 49 | - `invoke-static {v0}, Ljava/lang/System;->println(Ljava/lang/String;)V` → 调用 `System.out.println` 50 | - `return-void` → 返回 51 | 52 | --- 53 | 54 | # **3️⃣ Smali 关键指令** 55 | ## **✅ 1. 变量与寄存器** 56 | Smali 使用 `v` 开头的变量存储数据: 57 | ```smali 58 | .locals 2 59 | const/4 v0, 1 60 | const/16 v1, 100 61 | ``` 62 | - `v0 = 1` 63 | - `v1 = 100` 64 | 65 | ## **✅ 2. 方法调用** 66 | 📌 **调用静态方法** 67 | ```smali 68 | invoke-static {}, Lcom/example/Utils;->getFlag()Ljava/lang/String; 69 | ``` 70 | 📌 **调用实例方法** 71 | ```smali 72 | invoke-virtual {p0}, Lcom/example/User;->getName()Ljava/lang/String; 73 | ``` 74 | 📌 **调用构造方法** 75 | ```smali 76 | invoke-direct {p0}, Lcom/example/MainActivity;->()V 77 | ``` 78 | 79 | ## **✅ 3. 条件判断** 80 | 📌 **等于判断** 81 | ```smali 82 | if-eq v0, v1, :label_true 83 | ``` 84 | 📌 **大于判断** 85 | ```smali 86 | if-gt v0, v1, :label_greater 87 | ``` 88 | 📌 **跳转** 89 | ```smali 90 | :label_true 91 | const-string v0, "True!" 92 | goto :label_end 93 | 94 | :label_greater 95 | const-string v0, "Greater!" 96 | 97 | :label_end 98 | return-void 99 | ``` 100 | 101 | --- 102 | 103 | # **4️⃣ 反编译 APK,修改 Smali** 104 | ## **✅ 1. 反编译 APK** 105 | ```bash 106 | apktool d app.apk -o output/ 107 | ``` 108 | ## **✅ 2. 查找 VIP 方法** 109 | ```bash 110 | grep -r "isVIP" output/smali/ 111 | ``` 112 | 📌 **修改 `isVIP()`** 113 | ```smali 114 | .method public isVIP()Z 115 | .locals 1 116 | const/4 v0, 0x1 117 | return v0 118 | .end method 119 | ``` 120 | ## **✅ 3. 重新打包** 121 | ```bash 122 | apktool b output -o modded.apk 123 | ``` 124 | ## **✅ 4. 重新签名** 125 | ```bash 126 | jarsigner -verbose -keystore my.keystore modded.apk alias_name 127 | adb install modded.apk 128 | ``` 129 | 130 | --- 131 | 132 | # **5️⃣ Hook Smali 运行时** 133 | ## **✅ 1. Hook `isVIP()`** 134 | ```js 135 | Java.perform(function() { 136 | var MainActivity = Java.use("com.example.MainActivity"); 137 | MainActivity.isVIP.implementation = function() { 138 | return true; 139 | }; 140 | }); 141 | ``` 142 | ## **✅ 2. 运行 Frida** 143 | ```bash 144 | frida -U -n com.example.app -e "..." 145 | ``` 146 | 147 | --- 148 | 149 | # **🛠 实战任务** 150 | ### **✅ 1. 反编译 APK** 151 | ```bash 152 | apktool d app.apk -o output/ 153 | ``` 154 | ### **✅ 2. 修改 VIP 方法** 155 | ```smali 156 | .method public isVIP()Z 157 | const/4 v0, 0x1 158 | return v0 159 | .end method 160 | ``` 161 | ### **✅ 3. 重新打包 & 安装** 162 | ```bash 163 | apktool b output -o modded.apk 164 | jarsigner -verbose -keystore my.keystore modded.apk alias_name 165 | adb install modded.apk 166 | ``` 167 | ### **✅ 4. Hook Smali 方法** 168 | ```js 169 | Java.perform(function() { 170 | var MainActivity = Java.use("com.example.MainActivity"); 171 | MainActivity.isVIP.implementation = function() { 172 | return true; 173 | }; 174 | }); 175 | ``` 176 | 177 | --- 178 | 179 | # **📚 参考资料** 180 | 📌 **Smali 语法** 181 | - `Smali 参考文档`:[https://github.com/JesusFreke/smali](https://github.com/JesusFreke/smali) 182 | - `Smali 逆向指南`:[https://www.androidreversing.com/smali](https://www.androidreversing.com/smali) 183 | 184 | 📌 **APK 反编译** 185 | - `APKTool`:[https://github.com/iBotPeaches/Apktool](https://github.com/iBotPeaches/Apktool) 186 | 187 | 📌 **运行时 Hook** 188 | - `Frida`:[https://frida.re](https://frida.re) 189 | 190 | --- 191 | 192 | 🔥 **任务完成后,你将掌握:** 193 | ✅ **如何编写和修改 Smali 代码,修改 Android 应用逻辑** 194 | ✅ **如何反编译 APK,修改 Smali 代码并重新打包** 195 | ✅ **如何 Hook 运行时 Smali 方法,实现动态修改** 196 | 197 | 🚀 **下一步(Day 25)**:**Smali 代码修改实验!** 🎯 -------------------------------------------------------------------------------- /AndroidReverse101/第二阶段_APK逆向基础/Day_27_动态调试入门.md: -------------------------------------------------------------------------------- 1 | # **📜 Day 27: 动态调试入门** 2 | 3 | ## **📌 学习目标** 4 | ✅ **掌握动态调试(Dynamic Debugging)的基本概念**,了解与静态分析的区别。 5 | ✅ **学习如何使用 `adb logcat` 监控应用日志,分析应用行为。** 6 | ✅ **掌握 `gdb`、`lldb`、`Frida`、`Xposed` 等调试工具,动态修改应用逻辑。** 7 | ✅ **学习如何设置断点、Hook 关键方法、修改函数返回值、绕过反调试保护。** 8 | ✅ **实战:使用 Frida Hook 目标方法,动态修改返回值 & 绕过登录认证!** 9 | 10 | --- 11 | 12 | # **1️⃣ 什么是动态调试?** 13 | 动态调试(Dynamic Debugging)是一种 **在应用运行时分析和修改代码行为** 的技术, 14 | 不同于静态分析(直接反编译代码),它通过 **Hook 方法、设置断点、监控日志** 等方式实时修改代码执行。 15 | 16 | 📌 **动态调试 vs. 静态分析** 17 | | **方法** | **优点** | **缺点** | 18 | |---------|--------|-------| 19 | | **静态分析** | 直接查看代码结构 | 不能实时修改行为 | 20 | | **动态调试** | 运行时修改代码逻辑 | 需要附加调试器,部分应用有反调试机制 | 21 | 22 | --- 23 | 24 | # **2️⃣ 监控 Android 应用日志** 25 | ## **✅ 1. 使用 `adb logcat`** 26 | 📌 **过滤特定应用日志** 27 | ```bash 28 | adb logcat -s "com.example.app" 29 | ``` 30 | 📌 **查看 `System.out.println()` 输出** 31 | ```bash 32 | adb logcat | grep "Hello Debugging" 33 | ``` 34 | 📌 **查看崩溃日志** 35 | ```bash 36 | adb logcat *:E 37 | ``` 38 | 39 | ## **✅ 2. 使用 `logcat` 监控函数调用** 40 | 📌 **插入 `Log.d` 语句** 41 | ```smali 42 | invoke-static {}, Landroid/util/Log;->d(Ljava/lang/String;Ljava/lang/String;)I 43 | ``` 44 | 📌 **过滤特定关键字** 45 | ```bash 46 | adb logcat -s "LoginActivity" 47 | ``` 48 | 49 | --- 50 | 51 | # **3️⃣ 使用 Frida 进行动态调试** 52 | ## **✅ 1. 安装 Frida** 53 | 📌 **在 Android 设备上安装 Frida** 54 | ```bash 55 | adb push frida-server /data/local/tmp/ 56 | adb shell chmod +x /data/local/tmp/frida-server 57 | adb shell /data/local/tmp/frida-server & 58 | ``` 59 | 📌 **在 PC 端连接 Frida** 60 | ```bash 61 | frida -U -n com.example.app -i 62 | ``` 63 | 64 | ## **✅ 2. Hook 方法 & 修改返回值** 65 | 📌 **Hook `isVIP()`** 66 | ```js 67 | Java.perform(function() { 68 | var MainActivity = Java.use("com.example.MainActivity"); 69 | MainActivity.isVIP.implementation = function() { 70 | console.log("Bypassing VIP check..."); 71 | return true; 72 | }; 73 | }); 74 | ``` 75 | 📌 **运行** 76 | ```bash 77 | frida -U -n com.example.app -e "..." 78 | ``` 79 | 80 | ## **✅ 3. Hook `getPackageInfo()` 绕过签名校验** 81 | ```js 82 | Java.perform(function() { 83 | var PackageManager = Java.use("android.content.pm.PackageManager"); 84 | PackageManager.getPackageInfo.implementation = function(pkg, flags) { 85 | console.log("Bypassing signature check for:", pkg); 86 | return this.getPackageInfo(pkg, flags); 87 | }; 88 | }); 89 | ``` 90 | 91 | --- 92 | 93 | # **4️⃣ 使用 GDB / LLDB 调试 Native 层** 94 | ## **✅ 1. 附加到进程** 95 | 📌 **获取进程 ID** 96 | ```bash 97 | adb shell ps | grep com.example.app 98 | ``` 99 | 📌 **附加 GDB** 100 | ```bash 101 | gdb -p 102 | ``` 103 | 104 | ## **✅ 2. 设置断点** 105 | 📌 **设置 `strcmp()` 断点** 106 | ```gdb 107 | b strcmp 108 | ``` 109 | 📌 **继续执行** 110 | ```gdb 111 | c 112 | ``` 113 | 114 | --- 115 | 116 | # **5️⃣ 绕过反调试** 117 | 某些应用会检测调试器(GDB / Frida),常见绕过方法: 118 | - **修改 `ptrace()` 调用** 119 | - **Patch 反调试 Smali 代码** 120 | - **使用 `Frida` Patch `anti-debug` 方法** 121 | 122 | 📌 **Hook `ptrace()` 绕过调试检测** 123 | ```js 124 | Interceptor.attach(Module.findExportByName(null, "ptrace"), { 125 | onEnter: function(args) { 126 | console.log("Bypassing ptrace anti-debugging"); 127 | args[0] = 0; 128 | } 129 | }); 130 | ``` 131 | 132 | --- 133 | 134 | # **🛠 实战任务** 135 | ### **✅ 1. 监控应用日志** 136 | ```bash 137 | adb logcat -s "com.example.app" 138 | ``` 139 | ### **✅ 2. Hook `isVIP()`** 140 | ```js 141 | Java.perform(function() { 142 | var MainActivity = Java.use("com.example.MainActivity"); 143 | MainActivity.isVIP.implementation = function() { 144 | return true; 145 | }; 146 | }); 147 | ``` 148 | ### **✅ 3. Hook `getPackageInfo()` 绕过签名校验** 149 | ```js 150 | Java.perform(function() { 151 | var PackageManager = Java.use("android.content.pm.PackageManager"); 152 | PackageManager.getPackageInfo.implementation = function(pkg, flags) { 153 | return this.getPackageInfo(pkg, flags); 154 | }; 155 | }); 156 | ``` 157 | ### **✅ 4. 绕过 `ptrace()` 反调试** 158 | ```js 159 | Interceptor.attach(Module.findExportByName(null, "ptrace"), { 160 | onEnter: function(args) { 161 | args[0] = 0; 162 | } 163 | }); 164 | ``` 165 | 166 | --- 167 | 168 | # **📚 参考资料** 169 | 📌 **动态调试** 170 | - `Frida`:[https://frida.re](https://frida.re) 171 | - `GDB`:[https://sourceware.org/gdb/](https://sourceware.org/gdb/) 172 | - `LLDB`:[https://lldb.llvm.org/](https://lldb.llvm.org/) 173 | 174 | 📌 **绕过反调试** 175 | - `Android Anti-Debugging`:[https://www.androidreversing.com/](https://www.androidreversing.com/) 176 | 177 | --- 178 | 179 | 🔥 **任务完成后,你将掌握:** 180 | ✅ **如何使用 `adb logcat` 监控日志,分析应用行为** 181 | ✅ **如何使用 Frida Hook 目标方法,动态修改返回值** 182 | ✅ **如何使用 GDB/LLDB 进行 Native 调试,分析 C/C++ 代码** 183 | ✅ **如何绕过反调试机制,成功 Hook 关键方法** 184 | 185 | 🚀 **下一步(Day 28)**:**使用 Frida Hook Java 方法!** 🎯 -------------------------------------------------------------------------------- /AndroidReverse101/第一阶段_计算机基础_逆向概论/Day_3_什么是_CPU_指令集.md: -------------------------------------------------------------------------------- 1 | # **📜 Day 3: 什么是 CPU 指令集?** 2 | 3 | ## **📌 学习目标** 4 | ✅ 了解 **CPU 指令集** 的概念,及其在不同架构(x86、ARM、Smali)中的应用。 5 | ✅ 掌握 **x86(CISC)vs. ARM(RISC)vs. Smali(Android DEX 指令)** 的不同特点。 6 | ✅ 掌握 **ARMv7 (ARM32) vs. ARMv8 (ARM64)** 指令的区别。 7 | ✅ 理解 **C 语言与汇编语言(x86、ARM、Smali)的转换关系**。 8 | ✅ 通过实际代码示例,熟悉不同 CPU 指令集的基本用法。 9 | 10 | --- 11 | 12 | # **1️⃣ 什么是 CPU 指令集?** 13 | **CPU 指令集(Instruction Set Architecture, ISA)** 是 CPU 运行的软件指令集合,决定了 CPU 如何解析和执行二进制代码。 14 | 15 | 🔹 主要作用: 16 | - 控制 **数据存取、运算、逻辑操作** 等计算任务。 17 | - 影响 CPU 的**性能、功耗、兼容性**。 18 | - 各大 CPU 制造商采用不同的 **指令架构**。 19 | 20 | 🔹 **三种主要 CPU 指令集** 21 | | **架构** | **特点** | **应用场景** | 22 | |---------|--------|------------| 23 | | **x86(CISC)** | 复杂指令集,可变长指令,支持强大的寻址模式 | PC、服务器(Intel、AMD) | 24 | | **ARM(RISC)** | 精简指令集,固定指令长度,低功耗高性能 | 移动设备、嵌入式(高通、苹果、华为) | 25 | | **Smali(DEX 字节码)** | Android DEX 虚拟机指令,面向 Java/ART | Android 逆向工程 | 26 | 27 | --- 28 | 29 | # **2️⃣ x86 指令集** 30 | **x86(CISC)** 是 **Intel 和 AMD** 推动的架构,主要用于 PC 和服务器。 31 | 🔹 **特点:** 32 | - **指令长度不固定**(1-15 字节),比 ARM 复杂。 33 | - **多模式寻址**,支持更复杂的操作。 34 | 35 | ### **🔹 x86 汇编示例** 36 | ```assembly 37 | section .text 38 | global _start 39 | 40 | _start: 41 | mov eax, 5 ; 把 5 赋值给 eax 42 | add eax, 10 ; eax = eax + 10 43 | sub eax, 2 ; eax = eax - 2 44 | mov ebx, eax ; 把 eax 复制到 ebx 45 | int 0x80 ; 触发系统调用 46 | ``` 47 | 48 | 🔹 **特点:** 49 | - `mov eax, 5`:数据传输指令。 50 | - `add eax, 10`:加法运算。 51 | - `int 0x80`:Linux 下的系统调用。 52 | 53 | --- 54 | 55 | # **3️⃣ ARM 指令集** 56 | **ARM(RISC)** 适用于移动设备,采用 **精简指令集(RISC)**。 57 | 58 | 🔹 **ARM 特点** 59 | - **指令长度固定**(4 字节)。 60 | - **寄存器数量多**(减少对内存访问,提高性能)。 61 | - **低功耗高效能**,适用于移动设备。 62 | 63 | ### **🔹 ARM 指令 vs. x86 指令** 64 | | **操作** | **x86 指令(CISC)** | **ARM 指令(RISC)** | 65 | |---------|-----------------|----------------| 66 | | 赋值 | `mov eax, 5` | `MOV R0, #5` | 67 | | 加法 | `add eax, 10` | `ADD R0, R0, #10` | 68 | | 读取内存 | `mov eax, [ebx]` | `LDR R0, [R1]` | 69 | | 存储到内存 | `mov [ebx], eax` | `STR R0, [R1]` | 70 | 71 | --- 72 | 73 | # **4️⃣ ARMv7 (32 位) vs. ARMv8 (64 位)** 74 | 🔹 **ARMv7(ARM32)** 75 | ```assembly 76 | .global _start 77 | _start: 78 | MOV R0, #5 ; 赋值 5 给 R0 79 | ADD R0, R0, #3 ; R0 = R0 + 3 80 | LDR R1, [R2] ; 读取 R2 指向的内存到 R1 81 | STR R1, [R3] ; 存储 R1 到 R3 指向的内存 82 | B _start ; 无限循环 83 | ``` 84 | 85 | 🔹 **ARMv8(ARM64)** 86 | ```assembly 87 | .global _start 88 | _start: 89 | MOV X0, #5 ; 赋值 5 给 X0 90 | ADD X0, X0, #3 ; X0 = X0 + 3 91 | LDR X1, [X2] ; 读取 X2 指向的内存到 X1 92 | STR X1, [X3] ; 存储 X1 到 X3 指向的内存 93 | B _start ; 无限循环 94 | ``` 95 | 96 | 📌 **区别:** 97 | - ARMv7 使用 `R0-R15`,ARMv8 使用 `X0-X30`。 98 | - ARMv8 指令支持 64 位数据计算,提高计算能力。 99 | 100 | --- 101 | 102 | # **5️⃣ Smali 汇编语言(Android DEX 指令)** 103 | **Smali 是 Android DEX 的汇编语言,相当于 Java 字节码的汇编版本。** 104 | 105 | ### **🔹 Smali 代码示例** 106 | ```smali 107 | .method public static sum(II)I 108 | .registers 3 109 | add-int v0, p0, p1 110 | return v0 111 | .end method 112 | ``` 113 | 114 | 🔹 **Smali 关键点** 115 | | **指令** | **作用** | 116 | |---------|--------| 117 | | `add-int v0, p0, p1` | p0 + p1 结果存入 v0 | 118 | | `return v0` | 返回计算结果 | 119 | 120 | ### **🔹 Smali 破解示例** 121 | ```smali 122 | .method public isVip()Z 123 | .registers 2 124 | const/4 v0, 0x1 # 让所有用户变成 VIP 125 | return v0 126 | .end method 127 | ``` 128 | 129 | --- 130 | 131 | # **6️⃣ C 语言 vs. 汇编(x86/ARM/Smali)** 132 | ### **🔹 C 代码** 133 | ```c 134 | int sum(int a, int b) { 135 | return a + b; 136 | } 137 | ``` 138 | 139 | ### **🔹 x86 汇编** 140 | ```assembly 141 | sum: 142 | mov eax, edi 143 | add eax, esi 144 | ret 145 | ``` 146 | 147 | ### **🔹 ARM 汇编** 148 | ```assembly 149 | sum: 150 | ADD R0, R0, R1 151 | BX LR 152 | ``` 153 | 154 | ### **🔹 Smali 代码** 155 | ```smali 156 | .method public static sum(II)I 157 | .registers 3 158 | add-int v0, p0, p1 159 | return v0 160 | .end method 161 | ``` 162 | 163 | --- 164 | 165 | # **🛠 实战任务** 166 | 1️⃣ **检查 Android 设备的 CPU 架构** 167 | ```bash 168 | cat /proc/cpuinfo 169 | ``` 170 | 171 | 2️⃣ **运行 x86 汇编** 172 | ```bash 173 | nasm -f elf64 test.asm 174 | ld -o test test.o 175 | ./test 176 | ``` 177 | 178 | 3️⃣ **反编译 Android APK** 179 | ```bash 180 | apktool d myapp.apk -o output_dir 181 | ``` 182 | 183 | --- 184 | 185 | # **📚 参考资料** 186 | 📌 **ARM 指令集** 187 | - ARM 官方文档:[https://developer.arm.com/documentation](https://developer.arm.com/documentation) 188 | 189 | 📌 **x86 指令集** 190 | - Intel 手册:[https://software.intel.com/en-us/articles/intel-sdm](https://software.intel.com/en-us/articles/intel-sdm) 191 | 192 | 📌 **Smali 教程** 193 | - Smali 指南:[https://github.com/JesusFreke/smali](https://github.com/JesusFreke/smali) 194 | 195 | --- 196 | 197 | 🔥 **任务完成后,你将掌握:** 198 | ✅ x86、ARM、Smali 指令集的区别。 199 | ✅ ARM32 vs. ARM64 的演变。 200 | ✅ 运行和修改 Smali 代码。 201 | 202 | 🚀 **下一步(Day 4)**:**进制转换:为什么 16 进制很重要?** 🎯 -------------------------------------------------------------------------------- /AndroidReverse101/第一阶段_计算机基础_逆向概论/Day_5_汇编语言基础.md: -------------------------------------------------------------------------------- 1 | # **📜 Day 5: 汇编语言基础** 2 | 3 | ## **📌 学习目标** 4 | ✅ 了解 **汇编语言** 的基本概念及其在计算机体系结构中的作用。 5 | ✅ 学习 **x86 汇编、ARM 汇编、Smali(DEX 字节码)** 三种汇编语言的基础。 6 | ✅ 掌握 **寄存器、指令格式、数据传输、算术运算、控制流** 等汇编语言核心概念。 7 | ✅ 通过 **实际示例** 学习汇编如何与 C 语言进行交互,并实现简单的汇编程序。 8 | ✅ 学习 **汇编在逆向工程和漏洞利用中的作用**,并进行简单的调试和分析。 9 | 10 | --- 11 | 12 | # **1️⃣ 什么是汇编语言?** 13 | **汇编语言(Assembly Language)** 是 **低级编程语言**,它使用 **助记符(Mnemonic)** 代替二进制指令,使得程序员可以更方便地控制计算机硬件。 14 | 15 | | **语言层级** | **示例** | 16 | |---------|----------------------| 17 | | **高级语言(C、Python)** | `int a = 5;` | 18 | | **汇编语言(x86、ARM)** | `MOV R0, #5` | 19 | | **机器码(16 进制指令)** | `B8 05 00 00 00` | 20 | 21 | 汇编语言与特定 CPU 指令集紧密相关,如: 22 | - **x86 汇编**(Intel、AMD 处理器) 23 | - **ARM 汇编**(移动设备、嵌入式设备) 24 | - **Smali 汇编**(Android DEX 字节码) 25 | 26 | --- 27 | 28 | # **2️⃣ x86 汇编基础** 29 | ### **🔹 x86 处理器架构** 30 | x86 采用 **CISC(复杂指令集计算机)**,支持 **可变长指令** 和 **丰富的寻址模式**。 31 | 32 | **x86 32 位(IA-32)寄存器** 33 | | **寄存器** | **用途** | 34 | |---------|------------| 35 | | EAX | 累加器(运算/返回值) | 36 | | EBX | 基址寄存器 | 37 | | ECX | 计数寄存器(循环) | 38 | | EDX | 数据寄存器 | 39 | | ESI | 源索引寄存器 | 40 | | EDI | 目标索引寄存器 | 41 | | EBP | 栈基址指针 | 42 | | ESP | 栈指针 | 43 | 44 | ### **🔹 x86 指令示例** 45 | ```assembly 46 | section .text 47 | global _start 48 | 49 | _start: 50 | mov eax, 5 ; EAX = 5 51 | add eax, 10 ; EAX = EAX + 10 52 | sub eax, 2 ; EAX = EAX - 2 53 | int 0x80 ; 系统调用 54 | ``` 55 | 📌 **特点**: 56 | - `mov eax, 5`:将 5 赋值给 `eax`。 57 | - `add eax, 10`:对 `eax` 进行加法运算。 58 | - `int 0x80`:调用 Linux 系统 API。 59 | 60 | --- 61 | 62 | # **3️⃣ ARM 汇编基础** 63 | ### **🔹 ARM 处理器架构** 64 | ARM 采用 **RISC(精简指令集计算机)**,指令长度固定,执行效率更高,广泛用于 **移动设备和嵌入式系统**。 65 | 66 | **ARMv7(ARM32)寄存器** 67 | | **寄存器** | **用途** | 68 | |---------|--------| 69 | | R0-R3 | 传递函数参数 | 70 | | R4-R11 | 通用寄存器 | 71 | | R12 | 过程调用寄存器 | 72 | | R13 | 栈指针(SP) | 73 | | R14 | 链接寄存器(LR) | 74 | | R15 | 程序计数器(PC) | 75 | 76 | **ARMv8(ARM64)寄存器** 77 | | **寄存器** | **用途** | 78 | |---------|--------| 79 | | X0-X7 | 传递参数和返回值 | 80 | | X8 | 系统调用 | 81 | | X9-X15 | 临时变量 | 82 | | X19-X30 | 通用寄存器 | 83 | | X30 (LR) | 链接寄存器 | 84 | 85 | ### **🔹 ARM 指令示例** 86 | ```assembly 87 | .global _start 88 | _start: 89 | MOV R0, #5 ; 赋值 5 给 R0 90 | ADD R0, R0, #3 ; R0 = R0 + 3 91 | LDR R1, [R2] ; 读取 R2 指向的内存到 R1 92 | STR R1, [R3] ; 存储 R1 到 R3 指向的内存 93 | B _start ; 无限循环 94 | ``` 95 | 96 | --- 97 | 98 | # **4️⃣ Smali(Android DEX 汇编)** 99 | **Smali 是 Android DEX(Dalvik Executable)文件的汇编语言**,相当于 Java 字节码的汇编版本。 100 | 101 | ### **🔹 Smali 代码示例** 102 | ```smali 103 | .method public static sum(II)I 104 | .registers 3 105 | add-int v0, p0, p1 106 | return v0 107 | .end method 108 | ``` 109 | 110 | ### **🔹 Smali 破解示例** 111 | ```smali 112 | .method public isVip()Z 113 | .registers 2 114 | const/4 v0, 0x1 # 让所有用户变成 VIP 115 | return v0 116 | .end method 117 | ``` 118 | 📌 **修改 Smali 代码可用于绕过 Android 应用的 VIP 限制**。 119 | 120 | --- 121 | 122 | # **5️⃣ 汇编与 C 语言的交互** 123 | ### **🔹 C 语言调用 x86 汇编** 124 | ```c 125 | #include 126 | 127 | int add(int a, int b) { 128 | int result; 129 | __asm__ ( 130 | "addl %%ebx, %%eax;" 131 | : "=a" (result) 132 | : "a" (a), "b" (b) 133 | ); 134 | return result; 135 | } 136 | 137 | int main() { 138 | printf("Result: %d\n", add(5, 10)); 139 | return 0; 140 | } 141 | ``` 142 | 143 | ### **🔹 C 语言调用 ARM 汇编** 144 | ```c 145 | int add(int a, int b) { 146 | int result; 147 | __asm__ ( 148 | "ADD %0, %1, %2" 149 | : "=r" (result) 150 | : "r" (a), "r" (b) 151 | ); 152 | return result; 153 | } 154 | ``` 155 | 156 | --- 157 | 158 | # **🛠 实战任务** 159 | ### **✅ 1. 编写并运行 x86 汇编** 160 | ```bash 161 | nasm -f elf64 test.asm 162 | ld -o test test.o 163 | ./test 164 | ``` 165 | 166 | ### **✅ 2. 运行 ARM 汇编** 167 | ```assembly 168 | .global _start 169 | _start: 170 | MOV R0, #1 171 | LDR R1, =message 172 | MOV R2, #13 173 | MOV R7, #4 174 | SWI 0 175 | MOV R7, #1 176 | SWI 0 177 | 178 | .section .data 179 | message: .ascii "Hello, ARM!\n" 180 | ``` 181 | 182 | ### **✅ 3. 反编译 APK 并修改 Smali** 183 | ```bash 184 | apktool d app.apk -o output 185 | vim output/smali/com/example/Main.smali 186 | ``` 187 | 188 | --- 189 | 190 | # **📚 参考资料** 191 | 📌 **x86 汇编** 192 | - `x86 指令手册`:[https://www.felixcloutier.com/x86/](https://www.felixcloutier.com/x86/) 193 | - `NASM 手册`:[https://nasm.us](https://nasm.us) 194 | 195 | 📌 **ARM 汇编** 196 | - `ARM 指令手册`:[https://developer.arm.com/documentation](https://developer.arm.com/documentation) 197 | - `AArch64 汇编指南`:[https://azeria-labs.com/](https://azeria-labs.com/) 198 | 199 | 📌 **Smali** 200 | - `Smali 教程`:[https://github.com/JesusFreke/smali](https://github.com/JesusFreke/smali) 201 | 202 | --- 203 | 204 | 🔥 **任务完成后,你将掌握:** 205 | ✅ **x86、ARM、Smali 汇编语言的基础知识。** 206 | ✅ **汇编如何与 C 语言交互。** 207 | ✅ **运行、修改和调试汇编代码。** 208 | 209 | 🚀 **下一步(Day 6)**:**x86 vs. ARM 汇编对比!** 🎯 -------------------------------------------------------------------------------- /AndroidReverse101/第一阶段_计算机基础_逆向概论/Day_8_函数调用与返回.md: -------------------------------------------------------------------------------- 1 | # **📜 Day 8: 函数调用与返回(ARM32 & ARM64)** 2 | 3 | ## **📌 学习目标** 4 | ✅ **理解 ARM32 和 ARM64 体系架构下的函数调用与返回机制**。 5 | ✅ **掌握 ARM 函数调用的参数传递方式**(寄存器 & 栈)。 6 | ✅ **学习如何在汇编中调用和返回函数**,并与 C 语言进行交互。 7 | ✅ **掌握 ARM 过程调用约定(AAPCS)**,理解 `BL`, `BX`, `RET` 指令的作用。 8 | ✅ **通过调试和反汇编分析 ARM 汇编中的函数调用方式**。 9 | 10 | --- 11 | 12 | # **1️⃣ 函数调用的基本原理** 13 | ### **🔹 什么是函数调用?** 14 | 函数调用(Function Call)是程序执行过程中 **跳转到另一个代码段执行特定任务,并在执行完毕后返回** 的过程。 15 | 在 ARM 体系结构中,函数调用主要涉及: 16 | 1. **传递参数(Registers & Stack)** 17 | 2. **保存返回地址(Link Register, LR)** 18 | 3. **执行函数代码** 19 | 4. **返回到调用方** 20 | 21 | --- 22 | 23 | # **2️⃣ ARM32 vs. ARM64 函数调用约定** 24 | ### **🔹 ARM32(AAPCS 约定)** 25 | 在 ARM32(AArch32)下: 26 | - **前 4 个参数存放在 R0-R3 寄存器**,剩余参数存放在栈中。 27 | - **返回值存放在 R0(整数)或 R0-R1(64 位整数 / 浮点数)**。 28 | - **调用函数前,`BL` 指令会自动存储返回地址到 `LR(R14)`**。 29 | 30 | ### **🔹 ARM64(AAPCS 约定)** 31 | 在 ARM64(AArch64)下: 32 | - **前 8 个参数存放在 X0-X7 寄存器**,其余参数存入栈中。 33 | - **返回值存放在 X0(整数)或 X0-X1(64 位整数 / 浮点数)**。 34 | - **调用函数时,`BL` 指令会自动存储返回地址到 `X30(LR)`**。 35 | 36 | --- 37 | 38 | # **3️⃣ 函数调用指令** 39 | | **指令** | **作用** | **ARM32 示例** | **ARM64 示例** | **等价 C 代码** | 40 | |--------|------|-------------|-------------|-------------| 41 | | `BL` | 调用子函数 | `BL func` | `BL func` | `func();` | 42 | | `BX` | 返回调用者 | `BX LR` | N/A | `return;` | 43 | | `RET` | 返回调用者 | N/A | `RET` | `return;` | 44 | 45 | --- 46 | 47 | # **4️⃣ ARM32 & ARM64 函数调用示例** 48 | ### **🔹 ARM32 示例** 49 | ```assembly 50 | .global _start 51 | 52 | _start: 53 | MOV R0, #5 ; 传递参数 a = 5 54 | MOV R1, #3 ; 传递参数 b = 3 55 | BL add_numbers ; 调用 add_numbers(R0, R1) 56 | B _start ; 无限循环 57 | 58 | add_numbers: 59 | ADD R0, R0, R1 ; R0 = R0 + R1 60 | BX LR ; 返回调用者 61 | ``` 62 | 63 | **等价 C 代码**: 64 | ```c 65 | int add_numbers(int a, int b) { 66 | return a + b; 67 | } 68 | 69 | int main() { 70 | int result = add_numbers(5, 3); 71 | while (1); 72 | } 73 | ``` 74 | 75 | --- 76 | 77 | ### **🔹 ARM64 示例** 78 | ```assembly 79 | .global _start 80 | 81 | _start: 82 | MOV X0, #5 ; 传递参数 a = 5 83 | MOV X1, #3 ; 传递参数 b = 3 84 | BL add_numbers ; 调用 add_numbers(X0, X1) 85 | B _start ; 无限循环 86 | 87 | add_numbers: 88 | ADD X0, X0, X1 ; X0 = X0 + X1 89 | RET ; 返回调用者 90 | ``` 91 | 92 | **等价 C 代码**: 93 | ```c 94 | long add_numbers(long a, long b) { 95 | return a + b; 96 | } 97 | 98 | int main() { 99 | long result = add_numbers(5, 3); 100 | while (1); 101 | } 102 | ``` 103 | 104 | --- 105 | 106 | # **5️⃣ 复杂函数调用示例** 107 | ### **🔹 传递多个参数** 108 | ARM32: 109 | ```assembly 110 | MOV R0, #5 111 | MOV R1, #3 112 | MOV R2, #2 113 | MOV R3, #4 114 | BL complex_func 115 | ``` 116 | 117 | ARM64: 118 | ```assembly 119 | MOV X0, #5 120 | MOV X1, #3 121 | MOV X2, #2 122 | MOV X3, #4 123 | BL complex_func 124 | ``` 125 | 126 | 等价 C 代码: 127 | ```c 128 | int complex_func(int a, int b, int c, int d); 129 | complex_func(5, 3, 2, 4); 130 | ``` 131 | 132 | --- 133 | 134 | ### **🔹 递归函数调用(阶乘)** 135 | **ARM32** 136 | ```assembly 137 | .global factorial 138 | 139 | factorial: 140 | CMP R0, #1 141 | BLE end_factorial 142 | PUSH {R0, LR} 143 | SUB R0, R0, #1 144 | BL factorial 145 | POP {R1, LR} 146 | MUL R0, R0, R1 147 | end_factorial: 148 | BX LR 149 | ``` 150 | 151 | **ARM64** 152 | ```assembly 153 | .global factorial 154 | 155 | factorial: 156 | CMP X0, #1 157 | BLE end_factorial 158 | STP X0, LR, [SP, #-16]! 159 | SUB X0, X0, #1 160 | BL factorial 161 | LDP X1, LR, [SP], #16 162 | MUL X0, X0, X1 163 | end_factorial: 164 | RET 165 | ``` 166 | 167 | 等价 C 代码: 168 | ```c 169 | int factorial(int n) { 170 | if (n <= 1) return 1; 171 | return n * factorial(n - 1); 172 | } 173 | ``` 174 | 175 | --- 176 | 177 | # **6️⃣ 栈管理** 178 | **ARM32** 179 | ```assembly 180 | PUSH {R4, LR} ; 保存寄存器 181 | POP {R4, PC} ; 还原并返回 182 | ``` 183 | 184 | **ARM64** 185 | ```assembly 186 | STP X29, X30, [SP, #-16]! ; 保护 X29, X30 187 | LDP X29, X30, [SP], #16 ; 恢复 X29, X30 188 | ``` 189 | 190 | --- 191 | 192 | # **🛠 实战任务** 193 | ### **✅ 1. 编写并运行 ARM 汇编** 194 | ```bash 195 | as -o arm.o arm.s 196 | ld -o arm arm.o 197 | ./arm 198 | ``` 199 | 200 | ### **✅ 2. 反编译 ARM ELF** 201 | ```bash 202 | objdump -d arm_binary | head -n 20 203 | ``` 204 | 205 | ### **✅ 3. 逆向分析 Android APK** 206 | ```bash 207 | apktool d app.apk -o output 208 | vim output/smali/com/example/Main.smali 209 | ``` 210 | 211 | --- 212 | 213 | # **📚 参考资料** 214 | 📌 **ARM 官方文档** 215 | - `ARMv7 指令集`:[https://developer.arm.com/documentation](https://developer.arm.com/documentation) 216 | - `ARMv8 (AArch64) 指令集`:[https://developer.arm.com/documentation](https://developer.arm.com/documentation) 217 | 218 | 📌 **逆向工程** 219 | - `Ghidra`:[https://ghidra-sre.org/](https://ghidra-sre.org/) 220 | - `IDA Pro`:[https://hex-rays.com/](https://hex-rays.com/) 221 | 222 | --- 223 | 224 | 🔥 **任务完成后,你将掌握:** 225 | ✅ **ARM32 & ARM64 函数调用和返回机制** 226 | ✅ **如何在 ARM 平台编写和调试函数调用** 227 | ✅ **ARM 汇编在逆向工程中的实际应用** 228 | 229 | 🚀 **下一步(Day 9)**:**Android CPU 架构解析!** 🎯 -------------------------------------------------------------------------------- /AndroidReverse101/第一阶段_计算机基础_逆向概论/Day_10_Dalvik_vs._ART_运行时.md: -------------------------------------------------------------------------------- 1 | # **📜 Day 10: Dalvik vs. ART 运行时解析** 2 | 3 | ## **📌 学习目标** 4 | ✅ 理解 **Dalvik VM** 和 **ART(Android Runtime)** 的区别及其对 Android 应用的影响。 5 | ✅ 掌握 **DEX(Dalvik Executable)文件格式**,理解 **字节码执行方式**。 6 | ✅ 学习 **ART 运行时如何优化 Android 性能**,如 **AOT(Ahead-Of-Time)编译** 和 **JIT(Just-In-Time)编译**。 7 | ✅ 通过 **分析 Dalvik & ART 运行时的行为**,理解它们对逆向工程和性能优化的影响。 8 | ✅ 实践 **Dalvik 与 ART 运行时的调试与逆向分析**。 9 | 10 | --- 11 | 12 | # **1️⃣ 什么是 Dalvik 和 ART?** 13 | Android 应用的代码通常以 **Java/Kotlin** 编写,编译后生成 **DEX(Dalvik Executable)** 文件,在 Android 设备上运行。 14 | **运行 DEX 代码的环境** 就是 **Dalvik VM 或 ART 运行时**。 15 | 16 | | **运行时** | **特性** | **Android 版本** | 17 | |---------|----------------|----------------| 18 | | **Dalvik VM** | 解释执行,JIT 编译,基于寄存器 | **Android 2.2 - 4.4** | 19 | | **ART(Android Runtime)** | AOT + JIT 编译,运行时优化,减少 CPU 负担 | **Android 5.0+** | 20 | 21 | 📌 **简而言之**: 22 | - **Dalvik**:类似传统 Java 虚拟机,每次运行都需要解释代码,影响性能。 23 | - **ART**:引入 **AOT 编译**(安装时编译为机器码),大幅提升性能。 24 | 25 | --- 26 | 27 | # **2️⃣ Dalvik 与 ART 的核心区别** 28 | | **特性** | **Dalvik VM** | **ART 运行时** | 29 | |---------|------------|------------| 30 | | **代码执行方式** | 解释执行 + JIT 编译 | AOT 编译 + JIT 编译 | 31 | | **启动速度** | 快(直接执行 DEX) | 稍慢(首次安装时编译 OAT) | 32 | | **运行时性能** | 低(每次运行需解释代码) | 高(已编译为本机代码) | 33 | | **内存占用** | 低(仅加载需要的字节码) | 高(额外存储 OAT 文件) | 34 | | **电池消耗** | 较高(频繁解释代码) | 较低(减少运行时编译) | 35 | | **GC(垃圾回收)** | 分步 GC(影响 UI 流畅度) | 并发 GC(更流畅) | 36 | | **调试支持** | Smali 级 Hook | 机器码级 Hook(更难调试) | 37 | 38 | --- 39 | 40 | # **3️⃣ Dalvik 运行原理** 41 | ### **🔹 DEX(Dalvik Executable)格式** 42 | Dalvik 运行时执行 **DEX 字节码**,与传统 Java `.class` 文件不同: 43 | - **寄存器架构**(不像 JVM 的栈架构)。 44 | - **更少的指令集**,更适合移动设备。 45 | 46 | 📌 **反编译 DEX** 47 | ```bash 48 | dexdump classes.dex 49 | ``` 50 | 示例输出: 51 | ``` 52 | Dex file version 035 53 | magic: dex\n035 54 | class_defs_size: 5 55 | ``` 56 | 57 | 📌 **反汇编 Smali** 58 | ```bash 59 | baksmali d classes.dex -o output/ 60 | ``` 61 | 62 | --- 63 | 64 | # **4️⃣ ART 运行原理** 65 | ### **🔹 AOT(Ahead-of-Time 编译)** 66 | ART 运行时在 **安装应用时** 预编译 `.dex → .oat`(本机代码),减少运行时开销。 67 | 68 | 📌 **查看 OAT 文件** 69 | ```bash 70 | ls /data/dalvik-cache/ 71 | ``` 72 | 73 | 📌 **反编译 OAT** 74 | ```bash 75 | oatdump --oat-file=/data/dalvik-cache/arm64/system@framework@boot.art 76 | ``` 77 | 78 | ### **🔹 JIT(Just-In-Time 编译)** 79 | - Android 7.0+ 在 **AOT 基础上增加 JIT**,动态优化热点代码,提高运行效率。 80 | - 代码执行过程中,根据 **运行情况** 进行 **热点优化**,提升应用响应速度。 81 | 82 | --- 83 | 84 | # **5️⃣ 逆向工程中的影响** 85 | ### **🔹 Dalvik 逆向分析** 86 | - Dalvik **基于 DEX**,可直接反编译 **Smali** 代码。 87 | - 通过 `smali/baksmali` 轻松修改 `.dex` 代码: 88 | ```bash 89 | apktool d myapp.apk 90 | vim smali/com/example/MainActivity.smali 91 | ``` 92 | - 修改后重新打包: 93 | ```bash 94 | apktool b myapp 95 | jarsigner -verbose -keystore my.keystore myapp/dist/myapp.apk alias_name 96 | ``` 97 | 98 | ### **🔹 ART 逆向分析** 99 | - ART **直接执行 OAT 机器码**,无法简单修改 Smali 代码。 100 | - 需要使用 **Frida / GDB / IDA Pro** 进行动态调试: 101 | ```bash 102 | frida -U -n myapp -e "Interceptor.attach(Module.findExportByName(null, 'open'), {onEnter: function(args) { console.log('open called'); }})" 103 | ``` 104 | - ART 使用 **AOT 编译**,脱壳更困难: 105 | ```bash 106 | dd if=/data/app/com.example-1/oat/arm64/base.odex of=/sdcard/base.odex 107 | ``` 108 | 109 | --- 110 | 111 | # **6️⃣ Android 设备上的 Dalvik vs. ART** 112 | 📌 **检查 Android 设备使用的运行时** 113 | ```bash 114 | adb shell getprop persist.sys.dalvik.vm.lib.2 115 | ``` 116 | 输出: 117 | ``` 118 | libart.so 119 | ``` 120 | 👉 说明该设备使用 **ART 运行时**。 121 | 122 | 📌 **查看 OAT 目录** 123 | ```bash 124 | adb shell ls /data/dalvik-cache 125 | ``` 126 | 示例输出: 127 | ``` 128 | arm64/data@app@com.example-1@base.apk@classes.dex 129 | ``` 130 | 📌 **检查应用的执行模式** 131 | ```bash 132 | adb shell getprop dalvik.vm.execution-mode 133 | ``` 134 | 可能的输出: 135 | ``` 136 | jit 137 | aot 138 | ``` 139 | 140 | --- 141 | 142 | # **🛠 实战任务** 143 | ### **✅ 1. 检查 Android 设备使用的运行时** 144 | ```bash 145 | adb shell getprop persist.sys.dalvik.vm.lib.2 146 | ``` 147 | ### **✅ 2. 解析 DEX 文件** 148 | ```bash 149 | dexdump classes.dex 150 | baksmali d classes.dex -o output/ 151 | ``` 152 | ### **✅ 3. 反编译 ART OAT 文件** 153 | ```bash 154 | oatdump --oat-file=/data/dalvik-cache/arm64/system@framework@boot.art 155 | ``` 156 | ### **✅ 4. Hook ART 运行时** 157 | ```bash 158 | frida -U -n myapp -e "Interceptor.attach(Module.findExportByName(null, 'open'), {onEnter: function(args) { console.log('open called'); }})" 159 | ``` 160 | 161 | --- 162 | 163 | # **📚 参考资料** 164 | 📌 **Android 运行时** 165 | - `ART 介绍`:[https://source.android.com/devices/tech/dalvik](https://source.android.com/devices/tech/dalvik) 166 | - `DEX 结构`:[https://source.android.com/devices/tech/dalvik/dex-format](https://source.android.com/devices/tech/dalvik/dex-format) 167 | 168 | 📌 **逆向工程** 169 | - `Smali / Baksmali`:[https://github.com/JesusFreke/smali](https://github.com/JesusFreke/smali) 170 | - `Frida`:[https://frida.re](https://frida.re) 171 | - `oatdump`:[https://developer.android.com/ndk/guides/other_build_systems](https://developer.android.com/ndk/guides/other_build_systems) 172 | 173 | --- 174 | 175 | 🔥 **任务完成后,你将掌握:** 176 | ✅ **Dalvik 和 ART 运行时的核心区别** 177 | ✅ **如何解析 DEX、OAT 文件,进行应用逆向分析** 178 | ✅ **如何检查 Android 设备的运行时环境** 179 | ✅ **如何利用 Frida / GDB Hook ART 运行时** 180 | 181 | 🚀 **下一步(Day 11)**:**Android 进程管理解析!** 🎯 -------------------------------------------------------------------------------- /AndroidReverse101/第一阶段_计算机基础_逆向概论/Day_18_如何调试_Native_层.md: -------------------------------------------------------------------------------- 1 | # **📜 Day 18: 如何调试 Native 层** 2 | 3 | ## **📌 学习目标** 4 | ✅ **掌握 Android Native 层的调试方法**,包括 GDB、LLDB、Frida 远程调试。 5 | ✅ **学习如何加载、分析和调试 Native 共享库(.so)**。 6 | ✅ **掌握使用 GDB 进行 Native 断点调试的方法**,追踪 JNI 调用流程。 7 | ✅ **理解 Frida 在 Native Hook 中的应用**,动态修改程序行为。 8 | ✅ **实战:使用 GDB + Frida Hook `libnative.so`,调试 Native 方法调用**。 9 | 10 | --- 11 | 12 | # **1️⃣ 为什么需要调试 Native 层?** 13 | Android 应用通常包含 Native 代码(C/C++ 编写),这些代码以 **共享库(.so)** 形式存在。 14 | Native 代码通常用于: 15 | - **JNI(Java Native Interface)调用**(如音视频处理、算法库)。 16 | - **反调试 & 反 Hook**(常见于加固应用)。 17 | - **高性能计算(如加密/解密、数学运算)**。 18 | 19 | --- 20 | 21 | # **2️⃣ 准备工作** 22 | 📌 **获取目标应用的进程 ID(PID)** 23 | ```bash 24 | adb shell ps -A | grep com.example.app 25 | ``` 26 | 示例输出: 27 | ``` 28 | u0_a123 1234 ... com.example.app 29 | ``` 30 | 👉 **记住 `1234` 这个进程 ID!** 31 | 32 | 📌 **获取应用的 Native 库** 33 | ```bash 34 | adb shell ls /data/app/com.example.app/lib/arm64/ 35 | ``` 36 | 示例输出: 37 | ``` 38 | libnative.so 39 | ``` 40 | 📌 **将 `libnative.so` 拷贝到本地** 41 | ```bash 42 | adb pull /data/app/com.example.app/lib/arm64/libnative.so . 43 | ``` 44 | 45 | --- 46 | 47 | # **3️⃣ 使用 GDB 进行 Native 调试** 48 | ### **✅ 1. 安装 `gdbserver`** 49 | ```bash 50 | adb shell "cp /system/bin/gdbserver /data/local/tmp/" 51 | adb shell chmod +x /data/local/tmp/gdbserver 52 | ``` 53 | 54 | ### **✅ 2. 让 `gdbserver` 附加到目标进程** 55 | ```bash 56 | adb shell su -c "/data/local/tmp/gdbserver :12345 --attach 1234" 57 | ``` 58 | (`1234` 为目标进程 ID) 59 | 60 | 📌 **确认 `gdbserver` 在监听** 61 | ```bash 62 | adb shell netstat -tulnp | grep 12345 63 | ``` 64 | 65 | --- 66 | 67 | ### **✅ 3. 在本地启动 GDB** 68 | 📌 **将 Android NDK 提供的 GDB 拷贝到本地** 69 | ```bash 70 | export PATH=$PATH:/path/to/android-ndk/prebuilt/linux-x86_64/bin 71 | ``` 72 | 73 | 📌 **连接远程 `gdbserver`** 74 | ```bash 75 | gdb-multiarch 76 | ``` 77 | 然后在 GDB 中执行: 78 | ```gdb 79 | target remote <设备 IP>:12345 80 | ``` 81 | 82 | 📌 **加载目标库** 83 | ```gdb 84 | add-symbol-file libnative.so 0x0000000000001000 85 | ``` 86 | 87 | --- 88 | 89 | # **4️⃣ 设置断点并调试** 90 | 📌 **列出所有符号** 91 | ```gdb 92 | info functions 93 | ``` 94 | 95 | 📌 **在 `native_func` 处设置断点** 96 | ```gdb 97 | break native_func 98 | ``` 99 | 100 | 📌 **开始调试** 101 | ```gdb 102 | continue 103 | ``` 104 | 105 | 📌 **查看寄存器** 106 | ```gdb 107 | info registers 108 | ``` 109 | 110 | 📌 **单步执行** 111 | ```gdb 112 | stepi 113 | ``` 114 | 115 | 📌 **打印内存** 116 | ```gdb 117 | x/10xw $sp 118 | ``` 119 | 120 | --- 121 | 122 | # **5️⃣ 使用 Frida 进行动态调试** 123 | ### **✅ 1. Hook Native 函数** 124 | 📌 **Hook `libnative.so` 中的 `native_func`** 125 | ```js 126 | var lib = Module.findExportByName("libnative.so", "native_func"); 127 | Interceptor.attach(lib, { 128 | onEnter: function(args) { 129 | console.log("native_func called!"); 130 | console.log("Arg1: " + args[0].toInt32()); 131 | }, 132 | onLeave: function(retval) { 133 | console.log("native_func returned: " + retval.toInt32()); 134 | } 135 | }); 136 | ``` 137 | 138 | 📌 **执行 Frida** 139 | ```bash 140 | frida -U -n com.example.app -e "..." 141 | ``` 142 | 143 | --- 144 | 145 | ### **✅ 2. 修改返回值** 146 | 📌 **改变 `native_func` 的返回值** 147 | ```js 148 | Interceptor.attach(lib, { 149 | onLeave: function(retval) { 150 | retval.replace(999); 151 | } 152 | }); 153 | ``` 154 | 155 | 📌 **执行** 156 | ```bash 157 | frida -U -n com.example.app -e "..." 158 | ``` 159 | 160 | --- 161 | 162 | # **6️⃣ 逆向 JNI 调用** 163 | 📌 **查看 JNI 方法表** 164 | ```bash 165 | readelf -s libnative.so | grep Java_ 166 | ``` 167 | 示例输出: 168 | ``` 169 | 00001234 FUNC GLOBAL DEFAULT Java_com_example_app_NativeLib_nativeMethod 170 | ``` 171 | 172 | 📌 **动态 Hook JNI** 173 | ```js 174 | var nativeMethod = Module.findExportByName("libnative.so", "Java_com_example_app_NativeLib_nativeMethod"); 175 | Interceptor.attach(nativeMethod, { 176 | onEnter: function(args) { 177 | console.log("JNI nativeMethod called!"); 178 | } 179 | }); 180 | ``` 181 | 182 | --- 183 | 184 | # **🛠 实战任务** 185 | ### **✅ 1. 启动 `gdbserver`** 186 | ```bash 187 | adb shell su -c "/data/local/tmp/gdbserver :12345 --attach 1234" 188 | ``` 189 | ### **✅ 2. 连接 GDB** 190 | ```bash 191 | gdb-multiarch 192 | target remote <设备 IP>:12345 193 | ``` 194 | ### **✅ 3. Hook `native_func`** 195 | ```js 196 | Interceptor.attach(Module.findExportByName("libnative.so", "native_func"), { 197 | onEnter: function(args) { 198 | console.log("Called!"); 199 | } 200 | }); 201 | ``` 202 | ### **✅ 4. 修改返回值** 203 | ```js 204 | Interceptor.attach(Module.findExportByName("libnative.so", "native_func"), { 205 | onLeave: function(retval) { 206 | retval.replace(999); 207 | } 208 | }); 209 | ``` 210 | 211 | --- 212 | 213 | # **📚 参考资料** 214 | 📌 **GDB 调试** 215 | - `GDB 官方文档`:[https://sourceware.org/gdb/](https://sourceware.org/gdb/) 216 | 217 | 📌 **Frida 动态调试** 218 | - `Frida 官方文档`:[https://frida.re](https://frida.re) 219 | 220 | 📌 **Android Native 逆向** 221 | - `Android NDK 调试`:[https://developer.android.com/ndk](https://developer.android.com/ndk) 222 | 223 | --- 224 | 225 | 🔥 **任务完成后,你将掌握:** 226 | ✅ **如何使用 GDB 调试 Android Native 代码** 227 | ✅ **如何使用 Frida Hook Native 层函数** 228 | ✅ **如何修改 ELF 运行时行为** 229 | 230 | 🚀 **下一步(Day 19)**:**Android APP 安全机制解析!** 🎯 -------------------------------------------------------------------------------- /AndroidReverse101/第二阶段_APK逆向基础/Day_34_Android_代码混淆与解混淆.md: -------------------------------------------------------------------------------- 1 | # **📜 Day 34: Android 代码混淆与解混淆** 2 | 3 | ## **📌 学习目标** 4 | ✅ **掌握 Android 代码混淆(Obfuscation)的基本概念,理解为什么应用进行混淆**。 5 | ✅ **学习 ProGuard、R8、DexGuard 等混淆工具的工作原理**,分析其对逆向的影响。 6 | ✅ **掌握代码解混淆技术,包括 `jadx`、`procyon`、`bytecode viewer` 等工具**。 7 | ✅ **学习如何手动还原混淆代码、恢复类/方法/变量名,并进行代码重构分析**。 8 | ✅ **实战:分析一个混淆后的 APK,进行解混淆并恢复可读的代码!** 9 | 10 | --- 11 | 12 | # **1️⃣ 什么是 Android 代码混淆?** 13 | Android 开发者通常使用 **混淆工具** 对代码进行保护,使逆向分析变得困难,主要目的: 14 | - **防止逆向分析** 15 | - **提高应用安全性** 16 | - **减少 APK 体积** 17 | - **保护核心算法** 18 | 19 | 📌 **常见的混淆工具** 20 | | **工具** | **特点** | **是否默认启用** | 21 | |---------|--------|------------| 22 | | **ProGuard** | 代码缩减 & 重命名 | ✅ 默认启用 | 23 | | **R8** | 代替 ProGuard,支持 D8 | ✅ 默认启用 | 24 | | **DexGuard** | 付费,支持加密 & 动态混淆 | ❌ 需要单独购买 | 25 | | **Jiagu (360加固)** | 国内常见的加固方案 | ❌ 需手动配置 | 26 | 27 | 📌 **混淆对代码的影响** 28 | | **原始代码** | **混淆后代码** | 29 | |------------|------------| 30 | | `public void checkLogin()` | `public void a()` | 31 | | `private boolean isVIP()` | `private boolean b()` | 32 | | `String username = "admin";` | `String a = "admin";` | 33 | 34 | --- 35 | 36 | # **2️⃣ 检测 APK 是否混淆** 37 | ## **✅ 1. 使用 `jadx` 反编译** 38 | 📌 **反编译 APK** 39 | ```bash 40 | jadx -d output/ app.apk 41 | ``` 42 | 📌 **查看类 & 方法名** 43 | ```bash 44 | ls output/sources/com/example/ 45 | ``` 46 | 如果类名是 `a`, `b`, `c`,则表示已被混淆。 47 | 48 | --- 49 | 50 | # **3️⃣ 代码解混淆** 51 | ## **✅ 1. 还原 ProGuard 混淆** 52 | ProGuard & R8 会生成 `mapping.txt` 文件,存储混淆映射关系。 53 | 54 | 📌 **示例 `mapping.txt`** 55 | ``` 56 | com.example.MainActivity -> a 57 | checkLogin() -> b 58 | isVIP() -> c 59 | ``` 60 | 📌 **还原代码** 61 | ```bash 62 | proguard retrace mapping.txt stacktrace.txt 63 | ``` 64 | 65 | --- 66 | 67 | ## **✅ 2. 使用 `bytecode viewer` 进行解混淆** 68 | 📌 **步骤** 69 | 1. 下载 `Bytecode Viewer`:[https://github.com/Konloch/bytecode-viewer](https://github.com/Konloch/bytecode-viewer) 70 | 2. 打开 APK,选择 `Procyon` 反编译器 71 | 3. **查看混淆后的代码** 72 | 4. **自动恢复部分变量 & 方法名** 73 | 74 | --- 75 | 76 | ## **✅ 3. 手动恢复类 & 方法名** 77 | 📌 **示例:混淆后的 Smali 代码** 78 | ```smali 79 | .method public b()V 80 | .locals 1 81 | const-string v0, "Login Success" 82 | invoke-static {v0}, Landroid/util/Log;->d(Ljava/lang/String;Ljava/lang/String;)V 83 | return-void 84 | .end method 85 | ``` 86 | 📌 **手动修改 & 还原** 87 | ```smali 88 | .method public checkLogin()V 89 | .locals 1 90 | const-string v0, "Login Success" 91 | invoke-static {v0}, Landroid/util/Log;->d(Ljava/lang/String;Ljava/lang/String;)V 92 | return-void 93 | .end method 94 | ``` 95 | 96 | --- 97 | 98 | ## **✅ 4. 使用 `deobfuscator` 进行自动解混淆** 99 | 📌 **运行 `deobfuscator`** 100 | ```bash 101 | java -jar deobfuscator.jar -input app.apk -output output.apk 102 | ``` 103 | 📌 **自动分析 & 还原类名** 104 | ```bash 105 | grep -r "MainActivity" output/ 106 | ``` 107 | 108 | --- 109 | 110 | # **4️⃣ 逆向 ProGuard 混淆代码** 111 | ## **✅ 1. 获取 `mapping.txt`** 112 | 如果 `mapping.txt` 不可用,可尝试使用 **`deobfuscator`** 进行自动分析: 113 | ```bash 114 | java -jar deobfuscator.jar -input app.apk -output output.apk 115 | ``` 116 | 117 | ## **✅ 2. 使用 `jadx` 分析代码** 118 | ```bash 119 | jadx -d output/ app.apk 120 | grep -r "a()" output/ 121 | ``` 122 | 123 | ## **✅ 3. 手动恢复类名** 124 | ```bash 125 | mv output/sources/a.java output/sources/MainActivity.java 126 | ``` 127 | 128 | --- 129 | 130 | # **5️⃣ 绕过 R8/DexGuard 加密** 131 | ## **✅ 1. 分析 Dex 文件** 132 | 📌 **使用 `dexdump` 查看 Dex 结构** 133 | ```bash 134 | dexdump -d classes.dex | grep "MainActivity" 135 | ``` 136 | 📌 **手动解混淆** 137 | ```bash 138 | baksmali disassemble classes.dex -o smali/ 139 | ``` 140 | 141 | --- 142 | 143 | # **6️⃣ 破解 360 加固 & 其他保护** 144 | 某些应用使用 **360 加固**,导致无法直接反编译: 145 | 📌 **查找 360 加固签名** 146 | ```bash 147 | grep -r "qihoo" output/ 148 | ``` 149 | 📌 **使用 `unpackers` 工具** 150 | ```bash 151 | java -jar Qihoo360Unpacker.jar -i app.apk -o unpacked.apk 152 | ``` 153 | 📌 **重新反编译** 154 | ```bash 155 | jadx -d output/ unpacked.apk 156 | ``` 157 | 158 | --- 159 | 160 | # **🛠 实战任务** 161 | ### **✅ 1. 反编译 APK** 162 | ```bash 163 | jadx -d output/ app.apk 164 | ls output/sources/com/example/ 165 | ``` 166 | ### **✅ 2. 查找混淆代码** 167 | ```bash 168 | grep -r "a()" output/ 169 | ``` 170 | ### **✅ 3. 还原 `mapping.txt`** 171 | ```bash 172 | proguard retrace mapping.txt stacktrace.txt 173 | ``` 174 | ### **✅ 4. 使用 `bytecode viewer`** 175 | - 打开 `app.apk` 176 | - 选择 `Procyon` 177 | - 自动恢复代码 178 | ### **✅ 5. 破解 360 加固** 179 | ```bash 180 | java -jar Qihoo360Unpacker.jar -i app.apk -o unpacked.apk 181 | jadx -d output/ unpacked.apk 182 | ``` 183 | 184 | --- 185 | 186 | # **📚 参考资料** 187 | 📌 **代码解混淆** 188 | - `jadx`:[https://github.com/skylot/jadx](https://github.com/skylot/jadx) 189 | - `bytecode viewer`:[https://github.com/Konloch/bytecode-viewer](https://github.com/Konloch/bytecode-viewer) 190 | 191 | 📌 **绕过 ProGuard** 192 | - `ProGuard Retrace`:[https://www.guardsquare.com/en/products/proguard](https://www.guardsquare.com/en/products/proguard) 193 | 194 | 📌 **破解加固** 195 | - `360加固 Unpacker`:[https://github.com/bunq/xposed-anti360](https://github.com/bunq/xposed-anti360) 196 | 197 | --- 198 | 199 | 🔥 **任务完成后,你将掌握:** 200 | ✅ **如何检测 APK 是否被混淆** 201 | ✅ **如何使用 `jadx`、`bytecode viewer` 进行解混淆** 202 | ✅ **如何还原 `mapping.txt`,恢复原始类名 & 方法名** 203 | ✅ **如何破解 360 加固,提取未加密的 DEX 文件** 204 | 205 | 🚀 **下一步(Day 35)**:**逆向加密算法(MD5、AES、RSA)!** 🎯 -------------------------------------------------------------------------------- /AndroidReverse101/第一阶段_计算机基础_逆向概论/Day_9_Android_CPU_架构解析.md: -------------------------------------------------------------------------------- 1 | # **📜 Day 9: Android CPU 架构解析** 2 | 3 | ## **📌 学习目标** 4 | ✅ 了解 **Android 设备的 CPU 架构**,包括 **ARM32、ARM64、x86、RISC-V**。 5 | ✅ 掌握 **ARMv7、ARMv8(AArch64)及其主要特性**,理解 **big.LITTLE** 架构。 6 | ✅ 熟悉 **Android 设备的 CPU 兼容性**,学习如何判断 APK 适用于哪种架构。 7 | ✅ 通过 **实战分析 Android 设备 CPU 信息**,获取 `/proc/cpuinfo` 解析设备架构。 8 | ✅ 理解不同 CPU 架构的 **逆向工程、性能优化、漏洞分析的影响**。 9 | 10 | --- 11 | 12 | # **1️⃣ Android 平台的主流 CPU 架构** 13 | 目前,Android 设备主要采用以下 CPU 架构: 14 | | **架构** | **指令集** | **常见处理器** | **适用设备** | 15 | |---------|----------|--------------|------------| 16 | | **ARMv7 (32-bit)** | ARM32 | Cortex-A7, Cortex-A15 | 旧款 Android 手机、IoT 设备 | 17 | | **ARMv8 (64-bit)** | ARM64 (AArch64) | Cortex-A53, Cortex-A76 | 现代 Android 旗舰手机 | 18 | | **x86 / x86_64** | CISC | Intel Atom, AMD Ryzen Embedded | Android 模拟器、少量平板 | 19 | | **RISC-V** | RISC | 未来趋势 | 低功耗设备、实验性 Android 平台 | 20 | 21 | --- 22 | 23 | # **2️⃣ ARMv7 vs. ARMv8 (AArch64)** 24 | | **特性** | **ARMv7 (32-bit)** | **ARMv8 (64-bit)** | 25 | |---------|----------------|----------------| 26 | | **指令集** | ARM32 (AArch32) | ARM64 (AArch64) | 27 | | **最大内存支持** | 4GB | 16EB(大幅提升) | 28 | | **通用寄存器** | 16 个(R0-R15) | 31 个(X0-X30) | 29 | | **指令集优化** | 依赖 `Thumb-2` | 精简、提高能效 | 30 | | **NEON SIMD 支持** | 可选 | 内置支持 | 31 | | **性能** | 低功耗,较慢 | 高效,高吞吐量 | 32 | | **兼容性** | 不能运行 64 位应用 | 向下兼容 ARMv7 代码 | 33 | 34 | **🔹 示例:ARM32 vs. ARM64 汇编** 35 | ```assembly 36 | ; ARM32 版本 37 | MOV R0, #5 38 | ADD R0, R0, #3 39 | 40 | ; ARM64 版本 41 | MOV X0, #5 42 | ADD X0, X0, #3 43 | ``` 44 | 📌 **ARM64 版本的寄存器更宽,计算能力更强!** 45 | 46 | --- 47 | 48 | # **3️⃣ big.LITTLE 架构** 49 | ### **🔹 什么是 big.LITTLE?** 50 | big.LITTLE 是 ARM 开发的一种 **异构多核架构**,将 **高性能核心(big)** 与 **节能核心(LITTLE)** 结合,达到 **性能与功耗的平衡**。 51 | 52 | | **核心类型** | **特点** | **常见核心** | 53 | |------------|--------|-------------| 54 | | **big 核心** | 高性能,适合重负载任务 | Cortex-A76, Cortex-X1 | 55 | | **LITTLE 核心** | 低功耗,适合后台任务 | Cortex-A55 | 56 | 57 | 📌 **常见 big.LITTLE 组合** 58 | | **CPU 组合** | **示例处理器** | 59 | |------------|------------| 60 | | 4× big + 4× LITTLE | Snapdragon 865 (4× Cortex-A77 + 4× Cortex-A55) | 61 | | 1× big + 3× middle + 4× LITTLE | Snapdragon 8 Gen 1 (1× Cortex-X2 + 3× Cortex-A710 + 4× Cortex-A510) | 62 | 63 | **🔹 big.LITTLE 如何工作?** 64 | - 当 **设备空闲** 时,任务运行在 **LITTLE 核心**,节省功耗。 65 | - 当 **用户运行大型应用** 时,任务切换到 **big 核心**,提高性能。 66 | 67 | **💡 逆向工程影响**: 68 | - **不同核心运行不同任务**,调试时要注意 CPU 负载的变化。 69 | - **big 核心更适合跑高负载逆向分析,如 Frida、Ghidra。** 70 | 71 | --- 72 | 73 | # **4️⃣ Android APK 架构兼容性** 74 | Android 平台上的 APK 需要匹配设备 CPU 架构。APK 支持的 CPU 架构信息存储在 `lib/` 目录,例如: 75 | ``` 76 | lib/arm64-v8a/ # 64-bit ARM 77 | lib/armeabi-v7a/ # 32-bit ARM 78 | lib/x86/ # 32-bit x86 79 | lib/x86_64/ # 64-bit x86 80 | ``` 81 | 📌 **判断 Android 设备支持的 CPU 架构** 82 | ```bash 83 | adb shell getprop ro.product.cpu.abi 84 | ``` 85 | 示例输出: 86 | ``` 87 | arm64-v8a 88 | ``` 89 | 📌 **查看 Android `/proc/cpuinfo`** 90 | ```bash 91 | adb shell cat /proc/cpuinfo 92 | ``` 93 | 示例输出: 94 | ``` 95 | Processor : ARMv8 Processor rev 3 96 | BogoMIPS : 38.40 97 | Features : fp asimd evtstrm aes pmull sha1 sha2 crc32 98 | CPU architecture: 8 99 | ``` 100 | 101 | 📌 **逆向分析 APK 目标架构** 102 | ```bash 103 | unzip -l myapp.apk | grep lib/ 104 | ``` 105 | 示例输出: 106 | ``` 107 | lib/arm64-v8a/libnative.so 108 | lib/armeabi-v7a/libnative.so 109 | ``` 110 | 👉 说明此 APK **同时支持 ARM64 和 ARM32 设备**。 111 | 112 | --- 113 | 114 | # **5️⃣ 逆向工程 & 漏洞分析** 115 | 不同 CPU 架构影响逆向分析: 116 | 1. **ARM64 指令更简洁**,但 **寄存器 X0-X30 增加复杂性**。 117 | 2. **big.LITTLE 调度影响动态分析**,调试时需关注 CPU 核心的任务分配情况。 118 | 3. **漏洞利用**: 119 | - **ROP 攻击(Return Oriented Programming)**:x86 上常见,ARM64 由于 `PAC` 保护难度更大。 120 | - **指令集转换**:ARM 支持 **AArch32 & AArch64**,部分应用仍使用 ARM32 指令,可导致兼容性问题。 121 | 122 | 📌 **示例:使用 GDB 读取 `/proc/cpuinfo`** 123 | ```bash 124 | adb shell su 125 | gdbserver :5039 --attach 126 | ``` 127 | 然后在 GDB 中: 128 | ```gdb 129 | p *(char(*)[100])0x7ffd8c3b0000 130 | ``` 131 | 📌 **分析 CPU 指令** 132 | ```bash 133 | objdump -d libnative.so | head -n 20 134 | ``` 135 | --- 136 | 137 | # **🛠 实战任务** 138 | ### **✅ 1. 检查 Android 设备 CPU 架构** 139 | ```bash 140 | adb shell getprop ro.product.cpu.abi 141 | ``` 142 | ### **✅ 2. 解析 `/proc/cpuinfo`** 143 | ```bash 144 | adb shell cat /proc/cpuinfo 145 | ``` 146 | ### **✅ 3. 检查 APK 兼容的 CPU 架构** 147 | ```bash 148 | unzip -l myapp.apk | grep lib/ 149 | ``` 150 | ### **✅ 4. 反编译 Android 共享库** 151 | ```bash 152 | objdump -d libnative.so | head -n 20 153 | ``` 154 | --- 155 | 156 | # **📚 参考资料** 157 | 📌 **ARM 官方文档** 158 | - `ARMv7 指令集`:[https://developer.arm.com/documentation](https://developer.arm.com/documentation) 159 | - `ARMv8 (AArch64) 指令集`:[https://developer.arm.com/documentation](https://developer.arm.com/documentation) 160 | 161 | 📌 **big.LITTLE 参考** 162 | - `ARM big.LITTLE 技术`:[https://developer.arm.com/solutions/mobile](https://developer.arm.com/solutions/mobile) 163 | 164 | 📌 **Android 逆向工程** 165 | - `Ghidra`:[https://ghidra-sre.org/](https://ghidra-sre.org/) 166 | - `IDA Pro`:[https://hex-rays.com/](https://hex-rays.com/) 167 | 168 | --- 169 | 170 | 🔥 **任务完成后,你将掌握:** 171 | ✅ **Android 设备 CPU 架构(ARM32, ARM64, x86, RISC-V)** 172 | ✅ **如何分析 Android 设备的 `/proc/cpuinfo` 获取 CPU 信息** 173 | ✅ **如何判断 APK 适用于哪种 CPU 架构** 174 | ✅ **big.LITTLE 架构的工作原理及其影响** 175 | 176 | 🚀 **下一步(Day 10)**:**Dalvik vs. ART 运行时解析!** 🎯 -------------------------------------------------------------------------------- /AndroidReverse101/第二阶段_APK逆向基础/Day_32_破解_VIP_限制.md: -------------------------------------------------------------------------------- 1 | # **📜 Day 32: 破解 VIP 限制** 2 | 3 | ## **📌 学习目标** 4 | ✅ **掌握如何通过静态 & 动态分析破解 Android 应用的 VIP 限制**。 5 | ✅ **学习如何使用 `jadx`、`apktool` 反编译 APK,查找 VIP 认证逻辑**。 6 | ✅ **学习如何使用 `Frida`、`Xposed` Hook VIP 方法,动态修改应用逻辑**。 7 | ✅ **掌握修改 Smali 代码 & 重新打包签名,实现永久 VIP 破解**。 8 | ✅ **实战:破解 VIP 会员系统,解锁高级功能!** 9 | 10 | --- 11 | 12 | # **1️⃣ 分析 VIP 限制** 13 | 大多数 Android 应用的 VIP 认证逻辑有以下几种方式: 14 | - **本地存储判断** 15 | - 直接在 SharedPreferences / SQLite 数据库中存储 VIP 状态。 16 | - **API 请求服务器验证** 17 | - 服务器返回 `is_vip=true`,应用根据返回值解锁 VIP。 18 | - **JNI / SO 层认证** 19 | - VIP 逻辑被隐藏在 `libnative.so`,通过 JNI 调用。 20 | - **License Key 校验** 21 | - 应用需要输入 Key 或 Token 进行验证。 22 | 23 | --- 24 | 25 | # **2️⃣ 静态分析 VIP 方法** 26 | ## **✅ 1. 反编译 APK** 27 | 📌 **使用 `apktool` 反编译** 28 | ```bash 29 | apktool d app.apk -o output/ 30 | ``` 31 | 📌 **查找 VIP 相关关键字** 32 | ```bash 33 | grep -r "vip" output/smali/ 34 | ``` 35 | 📌 **示例 VIP 方法** 36 | ```smali 37 | .method public isVIP()Z 38 | .locals 1 39 | const/4 v0, 0x0 # 0 = false (非 VIP) 40 | return v0 41 | .end method 42 | ``` 43 | 📌 **修改 VIP 逻辑** 44 | ```smali 45 | .method public isVIP()Z 46 | .locals 1 47 | const/4 v0, 0x1 # 1 = true (VIP) 48 | return v0 49 | .end method 50 | ``` 51 | 📌 **重新打包 & 签名** 52 | ```bash 53 | apktool b output -o modded.apk 54 | apksigner sign --ks my.keystore --out signed.apk modded.apk 55 | adb install signed.apk 56 | ``` 57 | 58 | --- 59 | 60 | # **3️⃣ 动态 Hook VIP 方法** 61 | ## **✅ 1. Hook `isVIP()` 方法** 62 | 📌 **使用 Frida** 63 | ```js 64 | Java.perform(function() { 65 | var MainActivity = Java.use("com.example.MainActivity"); 66 | MainActivity.isVIP.implementation = function() { 67 | console.log("[*] Hooked isVIP(), returning true"); 68 | return true; 69 | }; 70 | }); 71 | ``` 72 | 📌 **运行 Frida** 73 | ```bash 74 | frida -U -n com.example.app -e "..." 75 | ``` 76 | 77 | --- 78 | 79 | ## **✅ 2. 使用 Xposed Hook VIP** 80 | 📌 **Xposed Hook** 81 | ```java 82 | XposedHelpers.findAndHookMethod("com.example.MainActivity", lpparam.classLoader, "isVIP", 83 | new XC_MethodReplacement() { 84 | @Override 85 | protected Object replaceHookedMethod(MethodHookParam param) { 86 | return true; 87 | } 88 | }); 89 | ``` 90 | 📌 **启用 Xposed 模块 & 重启** 91 | 92 | --- 93 | 94 | # **4️⃣ 绕过服务器 VIP 校验** 95 | 📌 **分析 API** 96 | ```bash 97 | adb logcat -s "OkHttp" | grep "vip" 98 | ``` 99 | 📌 **Hook `HttpURLConnection`,修改返回值** 100 | ```js 101 | Java.perform(function() { 102 | var URL = Java.use("java.net.URL"); 103 | URL.openConnection.implementation = function() { 104 | console.log("[*] Intercepted HTTP request to: " + this.toString()); 105 | return this.openConnection(); 106 | }; 107 | }); 108 | ``` 109 | 📌 **拦截 API 响应** 110 | ```js 111 | Interceptor.attach(Module.findExportByName("libokhttp.so", "ssl_read"), { 112 | onLeave: function(retval) { 113 | console.log("[*] Original Response: " + Memory.readUtf8String(retval)); 114 | var fakeResponse = '{"is_vip": true}'; 115 | Memory.writeUtf8String(retval, fakeResponse); 116 | } 117 | }); 118 | ``` 119 | 120 | --- 121 | 122 | # **5️⃣ 绕过 JNI 层 VIP 校验** 123 | 📌 **查找 JNI 方法** 124 | ```bash 125 | objdump -T libnative.so | grep "Java_com_example" 126 | ``` 127 | 📌 **Frida Hook JNI** 128 | ```js 129 | Interceptor.attach(Module.findExportByName("libnative.so", "Java_com_example_NativeLib_isVIP"), { 130 | onLeave: function(retval) { 131 | retval.replace(1); 132 | } 133 | }); 134 | ``` 135 | 136 | --- 137 | 138 | # **🛠 实战任务** 139 | ### **✅ 1. 反编译 & 修改 APK** 140 | ```bash 141 | apktool d app.apk -o output/ 142 | grep -r "vip" output/smali/ 143 | apktool b output -o modded.apk 144 | apksigner sign --ks my.keystore --out signed.apk modded.apk 145 | adb install signed.apk 146 | ``` 147 | ### **✅ 2. Hook `isVIP()`** 148 | ```js 149 | Java.perform(function() { 150 | var MainActivity = Java.use("com.example.MainActivity"); 151 | MainActivity.isVIP.implementation = function() { 152 | return true; 153 | }; 154 | }); 155 | ``` 156 | ### **✅ 3. Hook API VIP 认证** 157 | ```js 158 | Interceptor.attach(Module.findExportByName("libokhttp.so", "ssl_read"), { 159 | onLeave: function(retval) { 160 | var fakeResponse = '{"is_vip": true}'; 161 | Memory.writeUtf8String(retval, fakeResponse); 162 | } 163 | }); 164 | ``` 165 | ### **✅ 4. Hook JNI VIP 校验** 166 | ```js 167 | Interceptor.attach(Module.findExportByName("libnative.so", "Java_com_example_NativeLib_isVIP"), { 168 | onLeave: function(retval) { 169 | retval.replace(1); 170 | } 171 | }); 172 | ``` 173 | 174 | --- 175 | 176 | # **📚 参考资料** 177 | 📌 **APK 反编译** 178 | - `APKTool`:[https://github.com/iBotPeaches/Apktool](https://github.com/iBotPeaches/Apktool) 179 | - `JADX`:[https://github.com/skylot/jadx](https://github.com/skylot/jadx) 180 | 181 | 📌 **动态 Hook** 182 | - `Frida`:[https://frida.re](https://frida.re) 183 | - `Xposed`:[http://repo.xposed.info/](http://repo.xposed.info/) 184 | 185 | 📌 **JNI 逆向** 186 | - `IDA Pro`:[https://hex-rays.com/](https://hex-rays.com/) 187 | - `Ghidra`:[https://ghidra-sre.org/](https://ghidra-sre.org/) 188 | 189 | --- 190 | 191 | 🔥 **任务完成后,你将掌握:** 192 | ✅ **如何分析 & 破解 VIP 限制,解锁高级功能** 193 | ✅ **如何使用 Smali 代码修改 VIP 认证逻辑** 194 | ✅ **如何使用 Frida / Xposed Hook VIP 方法,动态绕过 VIP 校验** 195 | ✅ **如何拦截 & 修改服务器返回的 VIP 认证信息** 196 | ✅ **如何绕过 JNI 层 VIP 逻辑,实现完全破解** 197 | 198 | 🚀 **下一步(Day 33)**:**绕过 SSL Pinning!** 🎯 -------------------------------------------------------------------------------- /AndroidReverse101/第二阶段_APK逆向基础/Day_30_逆向_JNI_和_Native_方法.md: -------------------------------------------------------------------------------- 1 | # **📜 Day 30: 逆向 JNI 和 Native 方法** 2 | 3 | ## **📌 学习目标** 4 | ✅ **掌握 Android 中 JNI(Java Native Interface)的工作原理**,理解 Java 调用 C/C++ 代码的方式。 5 | ✅ **学习如何逆向分析 Native 层(so 文件)代码,掌握 `Ghidra`、`IDA Pro`、`objdump` 等工具。** 6 | ✅ **学习如何 Hook JNI 方法,修改参数、拦截返回值、绕过安全校验。** 7 | ✅ **掌握 `Frida` 进行动态分析,修改 Native 方法返回值、绕过反调试机制。** 8 | ✅ **实战:逆向分析 `libnative.so`,修改 `checkLicense()` 方法,绕过应用授权验证!** 9 | 10 | --- 11 | 12 | # **1️⃣ 什么是 JNI(Java Native Interface)?** 13 | JNI(Java Native Interface)是 **Java 和 C/C++ 之间的桥梁**,Android APP 通过 JNI 调用 **Native 层(C/C++)代码**,通常用于: 14 | - **提高性能**(计算密集型任务) 15 | - **调用系统 API** 16 | - **代码加密保护**(防止直接反编译 Java 代码) 17 | - **使用第三方库** 18 | 19 | 📌 **JNI 调用流程** 20 | ```java 21 | public native boolean checkLicense(String key); 22 | static { 23 | System.loadLibrary("native-lib"); 24 | } 25 | ``` 26 | 📌 **C 代码** 27 | ```c 28 | JNIEXPORT jboolean JNICALL 29 | Java_com_example_NativeLib_checkLicense(JNIEnv *env, jobject thiz, jstring key) { 30 | const char* key_str = (*env)->GetStringUTFChars(env, key, 0); 31 | if (strcmp(key_str, "VALID_LICENSE") == 0) { 32 | return JNI_TRUE; 33 | } 34 | return JNI_FALSE; 35 | } 36 | ``` 37 | 38 | --- 39 | 40 | # **2️⃣ 提取 Native 库** 41 | ## **✅ 1. 提取 `libnative.so`** 42 | 📌 **查找 SO 文件** 43 | ```bash 44 | adb shell ls /data/app/com.example.app/lib/arm64/ 45 | ``` 46 | 📌 **提取 SO** 47 | ```bash 48 | adb pull /data/app/com.example.app/lib/arm64/libnative.so . 49 | ``` 50 | 📌 **查看文件信息** 51 | ```bash 52 | file libnative.so 53 | ``` 54 | 示例输出: 55 | ``` 56 | libnative.so: ELF 64-bit LSB shared object, ARM aarch64 57 | ``` 58 | 59 | --- 60 | 61 | # **3️⃣ 反编译 Native 层** 62 | ## **✅ 1. 使用 `objdump` 查看 SO 符号** 63 | ```bash 64 | objdump -T libnative.so | grep "Java_com_example" 65 | ``` 66 | 示例输出: 67 | ``` 68 | 0000000000001120 T Java_com_example_NativeLib_checkLicense 69 | ``` 70 | 71 | ## **✅ 2. 使用 `strings` 查找关键字符串** 72 | ```bash 73 | strings libnative.so | grep "VALID_LICENSE" 74 | ``` 75 | 示例输出: 76 | ``` 77 | VALID_LICENSE 78 | INVALID_LICENSE 79 | ``` 80 | 81 | ## **✅ 3. 使用 `IDA Pro` 逆向 SO** 82 | 📌 **步骤** 83 | 1. **打开 IDA Pro** 84 | 2. **选择 `libnative.so` 并设置架构(ARM64)** 85 | 3. **找到 `checkLicense` 函数** 86 | 4. **查看字符串 `VALID_LICENSE` 交叉引用** 87 | 5. **修改 `strcmp()` 逻辑** 88 | 89 | 📌 **修改 `strcmp()`** 90 | ```c 91 | if (strcmp(key, "VALID_LICENSE") == 0) { 92 | return JNI_TRUE; 93 | } 94 | ``` 95 | 📌 **Patch 修改** 96 | - **直接改为 `return JNI_TRUE`** 97 | - **绕过密钥验证** 98 | 99 | --- 100 | 101 | # **4️⃣ 使用 Frida Hook JNI** 102 | ## **✅ 1. Hook `checkLicense()` 方法** 103 | 📌 **Frida Hook** 104 | ```js 105 | Interceptor.attach(Module.findExportByName("libnative.so", "Java_com_example_NativeLib_checkLicense"), { 106 | onEnter: function(args) { 107 | console.log("[*] Hooked JNI function - License Key: " + Memory.readUtf8String(args[2])); 108 | args[2] = Memory.allocUtf8String("VALID_LICENSE"); 109 | }, 110 | onLeave: function(retval) { 111 | console.log("[*] Modifying return value!"); 112 | retval.replace(1); 113 | } 114 | }); 115 | ``` 116 | 📌 **运行 Frida** 117 | ```bash 118 | frida -U -n com.example.app -e "..." 119 | ``` 120 | 121 | --- 122 | 123 | # **5️⃣ 绕过 Native 反调试** 124 | 某些应用会检测调试器(GDB / Frida),常见绕过方法: 125 | - **Hook `ptrace()`** 126 | - **修改 `anti_debug` 逻辑** 127 | 128 | 📌 **Hook `ptrace()`** 129 | ```js 130 | Interceptor.attach(Module.findExportByName(null, "ptrace"), { 131 | onEnter: function(args) { 132 | console.log("[*] Bypassing ptrace anti-debugging"); 133 | args[0] = 0; 134 | } 135 | }); 136 | ``` 137 | 138 | 📌 **绕过 `isDebuggerConnected()`** 139 | ```js 140 | Java.perform(function() { 141 | var Debug = Java.use("android.os.Debug"); 142 | Debug.isDebuggerConnected.implementation = function() { 143 | return false; 144 | }; 145 | }); 146 | ``` 147 | 148 | --- 149 | 150 | # **🛠 实战任务** 151 | ### **✅ 1. 提取 SO** 152 | ```bash 153 | adb pull /data/app/com.example.app/lib/arm64/libnative.so . 154 | ``` 155 | ### **✅ 2. 使用 `objdump` 查看符号** 156 | ```bash 157 | objdump -T libnative.so | grep "Java_com_example" 158 | ``` 159 | ### **✅ 3. 逆向 `checkLicense()`** 160 | ```bash 161 | strings libnative.so | grep "VALID_LICENSE" 162 | ``` 163 | ### **✅ 4. 使用 Frida Hook `checkLicense()`** 164 | ```js 165 | Interceptor.attach(Module.findExportByName("libnative.so", "Java_com_example_NativeLib_checkLicense"), { 166 | onEnter: function(args) { 167 | args[2] = Memory.allocUtf8String("VALID_LICENSE"); 168 | }, 169 | onLeave: function(retval) { 170 | retval.replace(1); 171 | } 172 | }); 173 | ``` 174 | ### **✅ 5. 绕过反调试** 175 | ```js 176 | Interceptor.attach(Module.findExportByName(null, "ptrace"), { 177 | onEnter: function(args) { 178 | args[0] = 0; 179 | } 180 | }); 181 | ``` 182 | ### **✅ 6. 运行 Frida** 183 | ```bash 184 | frida -U -n com.example.app -e "..." 185 | ``` 186 | 187 | --- 188 | 189 | # **📚 参考资料** 190 | 📌 **Native 逆向** 191 | - `IDA Pro`:[https://hex-rays.com/](https://hex-rays.com/) 192 | - `Ghidra`:[https://ghidra-sre.org/](https://ghidra-sre.org/) 193 | 194 | 📌 **Frida Hook** 195 | - `Frida`:[https://frida.re](https://frida.re) 196 | 197 | 📌 **绕过反调试** 198 | - `Frida Anti-Debugging Bypass`:[https://frida.re/docs/android/](https://frida.re/docs/android/) 199 | 200 | --- 201 | 202 | 🔥 **任务完成后,你将掌握:** 203 | ✅ **如何提取 & 逆向分析 Native SO 代码** 204 | ✅ **如何使用 Frida Hook JNI 方法,修改应用逻辑** 205 | ✅ **如何绕过 Native 反调试,成功 Hook 目标应用** 206 | 207 | 🚀 **下一步(Day 31)**:**Xposed 入门!** 🎯 -------------------------------------------------------------------------------- /AndroidReverse101/第一阶段_计算机基础_逆向概论/Day_17_ELF_文件解析.md: -------------------------------------------------------------------------------- 1 | # **📜 Day 17: ELF 文件解析** 2 | 3 | ## **📌 学习目标** 4 | ✅ **理解 ELF(Executable and Linkable Format)文件格式**,掌握其头部结构、节(Section)、程序头(Program Header)。 5 | ✅ **掌握如何解析 ELF 文件**,使用 `readelf`、`objdump`、`hexdump` 等工具进行分析。 6 | ✅ **学习如何从 ELF 文件提取符号表、函数地址、动态链接信息**,理解 SO 共享库的结构。 7 | ✅ **掌握 ELF 逆向分析技术**,包括静态分析和动态调试(GDB, Frida Hook)。 8 | ✅ **分析 Android 中的 ELF(`libnative.so`)文件,掌握 Hook 和劫持技巧**。 9 | 10 | --- 11 | 12 | # **1️⃣ ELF 文件基础** 13 | ### **🔹 什么是 ELF?** 14 | ELF(Executable and Linkable Format)是一种 **Linux 和 Android** 下的可执行文件格式,包括: 15 | - **可执行文件(Executable)** 16 | - **共享库(Shared Object, .so)** 17 | - **核心转储(Core Dump)** 18 | 19 | 📌 **查看 ELF 文件** 20 | ```bash 21 | file libnative.so 22 | ``` 23 | 示例输出: 24 | ``` 25 | libnative.so: ELF 64-bit LSB shared object, ARM aarch64 26 | ``` 27 | 28 | 📌 **解析 ELF 结构** 29 | ```bash 30 | readelf -h libnative.so 31 | ``` 32 | 33 | --- 34 | 35 | # **2️⃣ ELF 头部解析** 36 | ### **🔹 ELF 头部(ELF Header)** 37 | ELF 头部包含 ELF 文件的基本信息,如 **架构、入口点、段表位置** 等。 38 | 39 | 📌 **查看 ELF 头** 40 | ```bash 41 | readelf -h libnative.so 42 | ``` 43 | 示例输出: 44 | ``` 45 | ELF Header: 46 | Magic: 7f 45 4c 46 ... 47 | Class: ELF64 48 | Data: 2's complement, little endian 49 | Entry point address: 0x0000000000001234 50 | ``` 51 | 52 | 📌 **关键字段** 53 | | **字段** | **含义** | 54 | |---------|---------| 55 | | `Magic` | ELF 文件标识(7F 45 4C 46 -> .ELF) | 56 | | `Class` | ELF32 / ELF64 | 57 | | `Data` | 小端/大端存储 | 58 | | `Entry point` | 程序入口地址 | 59 | 60 | --- 61 | 62 | # **3️⃣ 程序头(Program Header)** 63 | 程序头(Program Header)定义了 **可执行文件的加载方式**,指定 **代码段、数据段、动态链接信息**。 64 | 65 | 📌 **查看程序头** 66 | ```bash 67 | readelf -l libnative.so 68 | ``` 69 | 示例输出: 70 | ``` 71 | Program Headers: 72 | Type Offset VirtAddr PhysAddr FileSiz MemSiz Flags Align 73 | LOAD 0x000000 0x000000 0x000000 0x1234 0x2000 R E 0x1000 74 | ``` 75 | 76 | 📌 **关键字段** 77 | | **字段** | **含义** | 78 | |---------|---------| 79 | | `Type` | LOAD(可加载段), DYNAMIC(动态段), NOTE(调试信息) | 80 | | `VirtAddr` | 代码段/数据段的虚拟地址 | 81 | | `Flags` | R(读), W(写), X(执行) | 82 | 83 | --- 84 | 85 | # **4️⃣ 节表(Section Header)** 86 | 节表(Section Header)描述了 ELF 文件的 **各个节(代码段、数据段、符号表等)**。 87 | 88 | 📌 **查看节表** 89 | ```bash 90 | readelf -S libnative.so 91 | ``` 92 | 示例输出: 93 | ``` 94 | Section Headers: 95 | [Nr] Name Type Addr Off Size ES Flg Lk Inf Al 96 | [ 1] .text PROGBITS 0x000010 0x0010 0x1000 00 AX 0 0 16 97 | [ 2] .data PROGBITS 0x002000 0x2000 0x2000 00 WA 0 0 16 98 | ``` 99 | 100 | 📌 **关键段** 101 | | **节名** | **作用** | 102 | |---------|---------| 103 | | `.text` | 代码段(只读、可执行) | 104 | | `.data` | 数据段(读写) | 105 | | `.rodata` | 只读数据段 | 106 | | `.bss` | 未初始化数据 | 107 | 108 | --- 109 | 110 | # **5️⃣ 符号表(Symbol Table)** 111 | 符号表(Symbol Table)存储了 **函数名、变量名与地址映射关系**,用于调试和动态链接。 112 | 113 | 📌 **查看符号表** 114 | ```bash 115 | readelf -s libnative.so | grep " func" 116 | ``` 117 | 示例输出: 118 | ``` 119 | 1234: 00000000 123 FUNC GLOBAL DEFAULT UND printf 120 | ``` 121 | 122 | 📌 **反查符号** 123 | ```bash 124 | nm -D libnative.so 125 | ``` 126 | 127 | --- 128 | 129 | # **6️⃣ 动态链接信息** 130 | 📌 **查看共享库依赖** 131 | ```bash 132 | ldd libnative.so 133 | ``` 134 | 示例输出: 135 | ``` 136 | libc.so => /lib/libc.so 137 | libm.so => /lib/libm.so 138 | ``` 139 | 140 | 📌 **查看动态段** 141 | ```bash 142 | readelf -d libnative.so 143 | ``` 144 | 145 | --- 146 | 147 | # **7️⃣ 逆向 ELF** 148 | ## **✅ 1. 解析 ELF 头** 149 | ```bash 150 | readelf -h libnative.so 151 | ``` 152 | ## **✅ 2. 解析符号表** 153 | ```bash 154 | nm -D libnative.so 155 | ``` 156 | ## **✅ 3. 反汇编 ELF** 157 | ```bash 158 | objdump -d libnative.so | head -n 20 159 | ``` 160 | ## **✅ 4. Hook ELF 运行时** 161 | 📌 **使用 Frida Hook `open()`** 162 | ```js 163 | Java.perform(function() { 164 | var libc = Module.findExportByName(null, "open"); 165 | Interceptor.attach(libc, { 166 | onEnter: function(args) { 167 | console.log("File Opened: " + Memory.readUtf8String(args[0])); 168 | } 169 | }); 170 | }); 171 | ``` 172 | 173 | --- 174 | 175 | # **🛠 实战任务** 176 | ### **✅ 1. 提取 ELF** 177 | ```bash 178 | adb shell run-as com.example.app cat /data/app/com.example.app/lib/arm64/libnative.so > libnative.so 179 | ``` 180 | ### **✅ 2. 解析 ELF** 181 | ```bash 182 | readelf -h libnative.so 183 | readelf -S libnative.so 184 | readelf -s libnative.so 185 | ``` 186 | ### **✅ 3. 反汇编** 187 | ```bash 188 | objdump -d libnative.so | head -n 20 189 | ``` 190 | ### **✅ 4. Hook `open()`** 191 | ```js 192 | Java.perform(function() { 193 | var libc = Module.findExportByName(null, "open"); 194 | Interceptor.attach(libc, { 195 | onEnter: function(args) { 196 | console.log("File Opened: " + Memory.readUtf8String(args[0])); 197 | } 198 | }); 199 | }); 200 | ``` 201 | 202 | --- 203 | 204 | # **📚 参考资料** 205 | 📌 **ELF 解析** 206 | - `ELF 格式官方文档`:[https://man7.org/linux/man-pages/man5/elf.5.html](https://man7.org/linux/man-pages/man5/elf.5.html) 207 | - `readelf 手册`:[https://sourceware.org/binutils/docs/binutils/readelf.html](https://sourceware.org/binutils/docs/binutils/readelf.html) 208 | 209 | 📌 **逆向分析** 210 | - `Frida Hook ELF`:[https://frida.re](https://frida.re) 211 | - `objdump`:[https://sourceware.org/binutils/docs/binutils/](https://sourceware.org/binutils/docs/binutils/) 212 | 213 | --- 214 | 215 | 🔥 **任务完成后,你将掌握:** 216 | ✅ **如何解析 ELF 头、程序头、符号表** 217 | ✅ **如何反汇编 ELF 并分析 Native 代码** 218 | ✅ **如何使用 Frida/Xposed Hook ELF 运行时行为** 219 | 220 | 🚀 **下一步(Day 18)**:**如何调试 Native 层?** 🎯 -------------------------------------------------------------------------------- /AndroidReverse101/第三阶段_高级逆向_CTF挑战/Day_100_终极挑战_逆向一个完整_APP.md: -------------------------------------------------------------------------------- 1 | ## **📜 Day 100: 终极挑战 - 逆向一个完整 APP** 2 | 3 | ## **📌 学习目标** 4 | ✅ **掌握 Android 逆向工程的三大核心技能:静态分析、抓包分析、动态分析**。 5 | ✅ **学会使用 `jadx`、`IDA Pro`、`Frida`、`Xposed`、`Wireshark`、`Mitmproxy` 等工具进行完整逆向分析**。 6 | ✅ **学习如何绕过登录认证、Hook 关键方法、解密存储数据、拦截 API 通信、破解 VIP 限制**。 7 | ✅ **深入分析 Native 层,提取 `libnative.so`,绕过 `ptrace()` 反调试**。 8 | ✅ **最终成功提取 `Flag`,完成 Android 逆向 100 天的终极挑战!** 9 | 10 | --- 11 | 12 | ## **📜 1. 逆向三板斧** 13 | 在 Android 逆向分析中,**最常用的方法有三种**: 14 | 1. **静态分析(Static Analysis)** 15 | - 通过 **反编译 APK**,直接阅读代码,找到关键逻辑,例如 **登录验证、加密算法、API URL**。 16 | 2. **抓包分析(Network Analysis)** 17 | - 通过 **Wireshark、Burp Suite、Mitmproxy** 监控和拦截网络通信,伪造 API 响应,分析 `Token` 机制。 18 | 3. **动态调试(Dynamic Analysis)** 19 | - 通过 **Frida/Xposed Hook**,修改运行时逻辑,例如 **绕过登录验证、伪造 VIP 会员、修改 SharedPreferences**。 20 | 21 | 📌 **完整逆向流程** 22 | 1. **提取目标 APP** 23 | 2. **静态分析:解包 APK,阅读代码** 24 | 3. **抓包分析:拦截 API 通信** 25 | 4. **动态分析:Hook 关键方法,修改应用行为** 26 | 5. **绕过安全机制,提取最终 `Flag`** 27 | 6. **验证 & 复盘,撰写完整 `Writeup`** 28 | 29 | --- 30 | 31 | ## **📜 2. 静态分析:提取 & 反编译 APK** 32 | ### **✅ 1. 获取目标 APK** 33 | 📌 **从设备提取 APK** 34 | ```bash 35 | adb shell pm list packages | grep target.app 36 | adb shell pm path com.example.target.app 37 | adb pull /data/app/com.example.target.app/base.apk . 38 | ``` 39 | 📌 **解压 APK** 40 | ```bash 41 | unzip base.apk -d output/ 42 | ``` 43 | 📌 **检查 APK 目录结构** 44 | ```bash 45 | tree output/ 46 | ``` 47 | **关键文件** 48 | - `AndroidManifest.xml` → **权限 & 入口点** 49 | - `classes.dex` → **DEX 字节码** 50 | - `res/` → **资源文件** 51 | - `assets/` → **可能存储加密数据** 52 | - `lib/` → **可能包含 Native SO 库** 53 | 54 | --- 55 | 56 | ### **✅ 2. 反编译 APK** 57 | 📌 **使用 `jadx` 反编译 DEX** 58 | ```bash 59 | jadx -d decompiled/ base.apk 60 | ``` 61 | 📌 **搜索关键代码** 62 | ```bash 63 | grep -r "login" decompiled/ 64 | grep -r "encrypt" decompiled/ 65 | grep -r "Flag{" decompiled/ 66 | ``` 67 | 📌 **分析代码** 68 | - 找到 `checkLogin()` 方法,分析登录逻辑 69 | - 查找 `AES 加密算法`,尝试解密存储数据 70 | - 发现 `API 请求 URL`,为抓包做准备 71 | 72 | --- 73 | 74 | ### **✅ 3. 逆向加密算法** 75 | 📌 **示例 AES 加密代码** 76 | ```java 77 | public static byte[] encryptAES(String key, String data) throws Exception { 78 | SecretKeySpec secretKey = new SecretKeySpec(key.getBytes(), "AES"); 79 | Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding"); 80 | cipher.init(Cipher.ENCRYPT_MODE, secretKey); 81 | return cipher.doFinal(data.getBytes()); 82 | } 83 | ``` 84 | 📌 **Python 解密** 85 | ```python 86 | from Crypto.Cipher import AES 87 | import base64 88 | 89 | key = b'Sixteen byte key' 90 | cipher = AES.new(key, AES.MODE_ECB) 91 | encrypted = cipher.encrypt(b"hello world!!!") 92 | print(base64.b64encode(encrypted)) 93 | ``` 94 | 95 | --- 96 | 97 | ## **📜 3. 抓包分析:拦截 & 伪造 API** 98 | ### **✅ 1. 设置代理** 99 | 📌 **使用 Burp Suite 监听流量** 100 | ```bash 101 | adb shell settings put global http_proxy 192.168.1.2:8080 102 | ``` 103 | 📌 **安装 Burp 证书** 104 | ```bash 105 | adb push burp_cert.der /sdcard/ 106 | ``` 107 | 108 | ### **✅ 2. 绕过 SSL Pinning** 109 | 📌 **Frida Hook** 110 | ```js 111 | Java.perform(function() { 112 | var CertificatePinner = Java.use("okhttp3.CertificatePinner"); 113 | CertificatePinner.check.overload("java.lang.String", "java.util.List").implementation = function(hostname, peerCertificates) { 114 | console.log("[*] Bypassing SSL Pinning for: " + hostname); 115 | return; 116 | }; 117 | }); 118 | ``` 119 | 120 | ### **✅ 3. 拦截 API 请求** 121 | 📌 **分析 `OkHttp`** 122 | ```bash 123 | grep -r "okhttp3" decompiled/ 124 | ``` 125 | 📌 **Frida Hook** 126 | ```js 127 | Java.perform(function() { 128 | var Request = Java.use("okhttp3.Request"); 129 | Request.body.implementation = function() { 130 | console.log("[*] Intercepted API Request: " + this.body()); 131 | return this.body(); 132 | }; 133 | }); 134 | ``` 135 | 136 | --- 137 | 138 | ## **📜 4. 动态分析:Hook 关键方法** 139 | ### **✅ 1. 绕过登录认证** 140 | 📌 **查找 `checkLogin()`** 141 | ```bash 142 | grep -r "checkLogin" decompiled/ 143 | ``` 144 | 📌 **Frida Hook** 145 | ```js 146 | Java.perform(function() { 147 | var Auth = Java.use("com.example.app.Auth"); 148 | Auth.checkLogin.implementation = function(username, password) { 149 | console.log("[*] Bypassing checkLogin()"); 150 | return true; 151 | }; 152 | }); 153 | ``` 154 | 155 | ### **✅ 2. 破解 VIP 功能** 156 | 📌 **Hook `isVip()`** 157 | ```js 158 | Java.perform(function() { 159 | var User = Java.use("com.example.app.User"); 160 | User.isVip.implementation = function() { 161 | console.log("[*] Unlocking VIP features"); 162 | return true; 163 | }; 164 | }); 165 | ``` 166 | 167 | ### **✅ 3. 修改 SharedPreferences** 168 | 📌 **Frida Hook** 169 | ```js 170 | Java.perform(function() { 171 | var SharedPreferences = Java.use("android.content.SharedPreferences"); 172 | SharedPreferences.getBoolean.implementation = function(key, defValue) { 173 | console.log("[*] Bypassing VIP check"); 174 | return true; 175 | }; 176 | }); 177 | ``` 178 | 179 | --- 180 | 181 | ## **📜 5. 逆向 Native 层 & 提取 Flag** 182 | ### **✅ 1. 反编译 `libnative.so`** 183 | 📌 **使用 IDA Pro** 184 | 1. **加载 `libnative.so`** 185 | 2. **搜索 `flag{}`** 186 | 3. **修改 `strcmp()` 比较逻辑** 187 | 188 | ### **✅ 2. Hook `getFlag()`** 189 | 📌 **Frida Hook** 190 | ```js 191 | Java.perform(function() { 192 | var Challenge = Java.use("com.example.app.Challenge"); 193 | Challenge.getFlag.implementation = function() { 194 | console.log("[*] Extracting Flag!"); 195 | return "FLAG{Final_Challenge_Solved}"; 196 | }; 197 | }); 198 | ``` 199 | 200 | --- 201 | 202 | # **🎯 挑战完成!你已成功掌握 Android 逆向工程!** 🚀 -------------------------------------------------------------------------------- /AndroidReverse101/第一阶段_计算机基础_逆向概论/Day_16_反汇编工具介绍.md: -------------------------------------------------------------------------------- 1 | # **📜 Day 16: 反汇编工具介绍** 2 | 3 | ## **📌 学习目标** 4 | ✅ **理解反汇编的基本概念**,掌握如何将二进制文件转换为可读的汇编代码。 5 | ✅ **熟悉主流反汇编工具**(IDA Pro、Ghidra、Radare2、objdump)的功能与使用场景。 6 | ✅ **学习如何分析 Android ELF 文件、DEX 文件、Native 共享库(.so)**。 7 | ✅ **掌握基于 Frida / Xposed 的动态分析方法**,Hook 关键函数。 8 | ✅ **通过实际操作,提取、反编译、分析 Android 应用的二进制代码**。 9 | 10 | --- 11 | 12 | # **1️⃣ 反汇编基础** 13 | ### **🔹 什么是反汇编?** 14 | 反汇编(Disassembly)是指将 **机器码(Binary Code)转换为汇编代码(Assembly Code)**,从而理解程序的运行逻辑。 15 | 16 | 📌 **示例** 17 | | **二进制指令** | **ARM 汇编** | **等价 C 代码** | 18 | |-------------|-----------|-----------| 19 | | `E3A00005` | `MOV R0, #5` | `int a = 5;` | 20 | | `E0801001` | `ADD R1, R0, R1` | `b = a + b;` | 21 | | `EB000001` | `BL function` | `function();` | 22 | 23 | 📌 **查看 ELF 文件架构** 24 | ```bash 25 | file libnative.so 26 | ``` 27 | 示例输出: 28 | ``` 29 | libnative.so: ELF 64-bit LSB shared object, ARM aarch64 30 | ``` 31 | 32 | --- 33 | 34 | # **2️⃣ 反汇编工具** 35 | ## **✅ 1. objdump(Linux 自带)** 36 | 📌 **反汇编 ELF 文件** 37 | ```bash 38 | objdump -d libnative.so | head -n 20 39 | ``` 40 | 📌 **解析 ELF 段信息** 41 | ```bash 42 | readelf -h libnative.so 43 | ``` 44 | 45 | --- 46 | 47 | ## **✅ 2. IDA Pro(交互式反汇编器)** 48 | 📌 **安装 IDA Free** 49 | ```bash 50 | wget https://out7.hex-rays.com/files/idafree83_linux.run 51 | chmod +x idafree83_linux.run 52 | ./idafree83_linux.run 53 | ``` 54 | 📌 **打开 ELF 文件** 55 | 1. **File → Open → 选择 `libnative.so`** 56 | 2. **选择 CPU 架构(ARM/ARM64)** 57 | 3. **开始分析,查看函数表、字符串、交叉引用(XREF)** 58 | 59 | 📌 **快捷键** 60 | | **操作** | **快捷键** | 61 | |---------|---------| 62 | | 交叉引用 | `X` | 63 | | 切换汇编/C 代码 | `F5` | 64 | | 查找字符串 | `Shift + F12` | 65 | 66 | --- 67 | 68 | ## **✅ 3. Ghidra(NSA 开源工具)** 69 | 📌 **安装 Ghidra** 70 | ```bash 71 | wget https://ghidra-sre.org/ghidra_10.1.5_PUBLIC_20231005.zip 72 | unzip ghidra_10.1.5_PUBLIC_20231005.zip 73 | cd ghidra_10.1.5 74 | ./ghidraRun 75 | ``` 76 | 📌 **分析 ELF 文件** 77 | 1. **File → New Project → Import `libnative.so`** 78 | 2. **选择 ARM 处理器** 79 | 3. **双击函数,查看反汇编结果** 80 | 4. **使用 `Decompiler` 还原 C 代码** 81 | 82 | 📌 **Ghidra 常用快捷键** 83 | | **操作** | **快捷键** | 84 | |---------|---------| 85 | | 查找字符串 | `Ctrl + Shift + F` | 86 | | 交叉引用 | `Ctrl + Shift + X` | 87 | | 反编译 | `F4` | 88 | 89 | --- 90 | 91 | ## **✅ 4. Radare2(开源 CLI 反汇编工具)** 92 | 📌 **安装 Radare2** 93 | ```bash 94 | git clone https://github.com/radareorg/radare2.git 95 | cd radare2 96 | sys/install.sh 97 | ``` 98 | 📌 **反汇编 ELF** 99 | ```bash 100 | r2 -AA libnative.so 101 | ``` 102 | 📌 **常用命令** 103 | | **命令** | **作用** | 104 | |---------|---------| 105 | | `aa` | 自动分析 | 106 | | `afl` | 显示所有函数 | 107 | | `pdf @ main` | 反汇编 `main()` | 108 | | `izz` | 查找字符串 | 109 | 110 | --- 111 | 112 | # **3️⃣ 逆向分析 Android ELF** 113 | ## **✅ 1. 提取 libnative.so** 114 | ```bash 115 | adb shell run-as com.example.app cat /data/app/com.example.app/lib/arm64/libnative.so > libnative.so 116 | ``` 117 | 118 | ## **✅ 2. 解析 ELF 头** 119 | ```bash 120 | readelf -h libnative.so 121 | ``` 122 | 123 | ## **✅ 3. 反汇编** 124 | ```bash 125 | objdump -d libnative.so | head -n 20 126 | ``` 127 | 128 | ## **✅ 4. Hook ELF 运行时行为** 129 | 📌 **使用 Frida Hook `open()`** 130 | ```js 131 | Java.perform(function() { 132 | var libc = Module.findExportByName(null, "open"); 133 | Interceptor.attach(libc, { 134 | onEnter: function(args) { 135 | console.log("File Opened: " + Memory.readUtf8String(args[0])); 136 | } 137 | }); 138 | }); 139 | ``` 140 | 📌 **执行** 141 | ```bash 142 | frida -U -n com.example.app -e "..." 143 | ``` 144 | 145 | --- 146 | 147 | # **4️⃣ Hook DEX 代码** 148 | 📌 **使用 Frida Hook DEX 运行时** 149 | ```js 150 | Java.perform(function() { 151 | var DexClassLoader = Java.use("dalvik.system.DexClassLoader"); 152 | DexClassLoader.loadClass.implementation = function(name) { 153 | console.log("Hooked Dex Load: " + name); 154 | return this.loadClass(name); 155 | }; 156 | }); 157 | ``` 158 | 159 | 📌 **执行** 160 | ```bash 161 | frida -U -n com.example.app -e "..." 162 | ``` 163 | 164 | --- 165 | 166 | # **🛠 实战任务** 167 | ### **✅ 1. 使用 `objdump` 反汇编 ELF** 168 | ```bash 169 | objdump -d libnative.so | head -n 20 170 | ``` 171 | ### **✅ 2. 使用 IDA Pro/Ghidra 反编译 ELF** 172 | 1. **导入 `libnative.so`** 173 | 2. **查找字符串** 174 | 3. **分析关键函数** 175 | ### **✅ 3. Hook `open()` 调用** 176 | ```js 177 | Java.perform(function() { 178 | var libc = Module.findExportByName(null, "open"); 179 | Interceptor.attach(libc, { 180 | onEnter: function(args) { 181 | console.log("File Opened: " + Memory.readUtf8String(args[0])); 182 | } 183 | }); 184 | }); 185 | ``` 186 | ### **✅ 4. Hook `DexClassLoader`** 187 | ```js 188 | Java.perform(function() { 189 | var DexClassLoader = Java.use("dalvik.system.DexClassLoader"); 190 | DexClassLoader.loadClass.implementation = function(name) { 191 | console.log("Hooked Dex Load: " + name); 192 | return this.loadClass(name); 193 | }; 194 | }); 195 | ``` 196 | 197 | --- 198 | 199 | # **📚 参考资料** 200 | 📌 **反汇编工具** 201 | - `IDA Pro`:[https://hex-rays.com/](https://hex-rays.com/) 202 | - `Ghidra`:[https://ghidra-sre.org/](https://ghidra-sre.org/) 203 | - `Radare2`:[https://github.com/radareorg/radare2](https://github.com/radareorg/radare2) 204 | 205 | 📌 **Android ELF 逆向** 206 | - `Frida`:[https://frida.re](https://frida.re/) 207 | - `objdump`:[https://sourceware.org/binutils/docs/binutils/](https://sourceware.org/binutils/docs/binutils/) 208 | 209 | --- 210 | 211 | 🔥 **任务完成后,你将掌握:** 212 | ✅ **主流反汇编工具的使用(IDA, Ghidra, objdump, Radare2)** 213 | ✅ **如何解析 ELF 文件,分析 Android Native 代码** 214 | ✅ **如何使用 Frida/Xposed 进行动态分析** 215 | 216 | 🚀 **下一步(Day 17)**:**ELF 文件解析!** 🎯 -------------------------------------------------------------------------------- /AndroidReverse101/第二阶段_APK逆向基础/Day_38_游戏破解基础.md: -------------------------------------------------------------------------------- 1 | # **📜 Day 38: 游戏破解基础** 2 | 3 | ## **📌 学习目标** 4 | ✅ **掌握 Android 游戏的基本架构,理解游戏的内存管理 & 反作弊机制**。 5 | ✅ **学习如何使用 `Frida`、`Cheat Engine`、`GameGuardian` 进行游戏修改**。 6 | ✅ **学习如何 Hook 关键函数,如 `金币系统`、`攻击力计算`,实现游戏修改**。 7 | ✅ **掌握如何分析 `libgame.so`,逆向游戏逻辑,修改关键变量**。 8 | ✅ **实战:修改游戏内金币数量、攻击力、解锁 VIP 角色!** 9 | 10 | --- 11 | 12 | # **1️⃣ Android 游戏的架构** 13 | 📌 **常见游戏引擎** 14 | | **游戏引擎** | **特点** | **使用案例** | 15 | |------------|--------|--------| 16 | | **Unity3D** | 使用 `C#`,核心代码在 `libil2cpp.so` | 王者荣耀、崩坏3 | 17 | | **Unreal Engine** | 使用 `C++`,代码在 `libUE4.so` | PUBG Mobile | 18 | | **Cocos2d-x** | 使用 `C++`,代码在 `libgame.so` | 小型 2D 游戏 | 19 | | **原生 Android** | 直接使用 `Java/Kotlin` | 休闲类小游戏 | 20 | 21 | 📌 **游戏内常见变量** 22 | | **变量** | **用途** | **存储位置** | 23 | |--------|--------|--------| 24 | | `金币` | 影响游戏内购买 | 存储在 `SharedPreferences` 或 `内存` | 25 | | `攻击力` | 影响战斗伤害 | 存储在 `内存` | 26 | | `血量` | 影响角色生存 | 存储在 `内存` | 27 | | `经验值` | 用于升级 | 存储在 `内存` | 28 | 29 | --- 30 | 31 | # **2️⃣ 修改游戏数据** 32 | ## **✅ 1. 使用 GameGuardian 修改金币** 33 | 📌 **步骤** 34 | 1. **安装 GameGuardian** 35 | 2. **运行游戏,打开 GameGuardian** 36 | 3. **搜索金币数值** 37 | 4. **修改为 `9999999`** 38 | 5. **验证修改是否生效** 39 | 40 | 📌 **注意** 41 | - **浮点数修改**:部分游戏使用 `float` 代替 `int`,搜索时需尝试 `float`。 42 | - **加密存储**:部分游戏会对数据进行加密,如 `金币 = (真实值 + 1234) * 2`。 43 | 44 | --- 45 | 46 | ## **✅ 2. 使用 Cheat Engine 修改攻击力** 47 | 📌 **步骤** 48 | 1. **在 PC 上运行 Android 模拟器** 49 | 2. **使用 Cheat Engine 连接模拟器** 50 | 3. **搜索当前攻击力** 51 | 4. **修改攻击力为 `9999`** 52 | 5. **在游戏中攻击敌人,观察是否生效** 53 | 54 | --- 55 | 56 | ## **✅ 3. 使用 Frida Hook 修改游戏逻辑** 57 | ### **📌 Hook 金币增加方法** 58 | 📌 **游戏原始代码** 59 | ```java 60 | public void addCoins(int amount) { 61 | this.coins += amount; 62 | } 63 | ``` 64 | 📌 **Frida Hook** 65 | ```js 66 | Java.perform(function() { 67 | var GameClass = Java.use("com.example.game.GameManager"); 68 | GameClass.addCoins.implementation = function(amount) { 69 | console.log("[*] Hooked addCoins, original: " + amount); 70 | this.addCoins(9999999); 71 | }; 72 | }); 73 | ``` 74 | 📌 **运行 Frida** 75 | ```bash 76 | frida -U -n com.example.game -e "..." 77 | ``` 78 | 79 | --- 80 | 81 | # **3️⃣ 逆向 `libgame.so` 进行修改** 82 | ## **✅ 1. 提取 `libgame.so`** 83 | 📌 **查找 so 文件** 84 | ```bash 85 | adb shell ls /data/app/com.example.game/lib/arm64/ 86 | ``` 87 | 📌 **提取 so** 88 | ```bash 89 | adb pull /data/app/com.example.game/lib/arm64/libgame.so . 90 | ``` 91 | 92 | ## **✅ 2. 反编译 so 文件** 93 | 📌 **使用 IDA Pro** 94 | 1. **加载 `libgame.so`** 95 | 2. **搜索 `金币相关函数`** 96 | 3. **找到 `ADD COINS` 相关逻辑** 97 | 4. **修改 `MOV R0, #9999999`** 98 | 99 | 📌 **使用 Ghidra** 100 | 1. **加载 `libgame.so`** 101 | 2. **查看 `gameManager` 相关函数** 102 | 3. **修改 `金币增加逻辑`** 103 | 104 | --- 105 | 106 | # **4️⃣ 绕过游戏的反作弊** 107 | ## **✅ 1. 绕过 `ptrace()` 反调试** 108 | 📌 **Frida Hook** 109 | ```js 110 | Interceptor.attach(Module.findExportByName(null, "ptrace"), { 111 | onEnter: function(args) { 112 | console.log("[*] Bypassing ptrace anti-debugging"); 113 | args[0] = 0; 114 | } 115 | }); 116 | ``` 117 | 118 | ## **✅ 2. 绕过 `isRooted()` 检测** 119 | 📌 **Frida Hook** 120 | ```js 121 | Java.perform(function() { 122 | var SecurityUtils = Java.use("com.example.game.SecurityUtils"); 123 | SecurityUtils.isRooted.implementation = function() { 124 | console.log("[*] Bypassing root detection"); 125 | return false; 126 | }; 127 | }); 128 | ``` 129 | 130 | --- 131 | 132 | # **5️⃣ 伪造服务器数据** 133 | ## **✅ 1. 拦截 & 修改 API 响应** 134 | 📌 **修改金币 API 返回值** 135 | ```js 136 | Interceptor.attach(Module.findExportByName("libokhttp.so", "ssl_read"), { 137 | onLeave: function(retval) { 138 | console.log("[*] Intercepted API response: " + Memory.readUtf8String(retval)); 139 | var fakeResponse = '{"coins": 9999999}'; 140 | Memory.writeUtf8String(retval, fakeResponse); 141 | } 142 | }); 143 | ``` 144 | 145 | --- 146 | 147 | # **🛠 实战任务** 148 | ### **✅ 1. 提取 `libgame.so`** 149 | ```bash 150 | adb pull /data/app/com.example.game/lib/arm64/libgame.so . 151 | ``` 152 | ### **✅ 2. 使用 GameGuardian 修改金币** 153 | 1. **搜索当前金币数量** 154 | 2. **修改为 `9999999`** 155 | ### **✅ 3. 使用 Frida Hook 金币系统** 156 | ```js 157 | Java.perform(function() { 158 | var GameClass = Java.use("com.example.game.GameManager"); 159 | GameClass.addCoins.implementation = function(amount) { 160 | this.addCoins(9999999); 161 | }; 162 | }); 163 | ``` 164 | ### **✅ 4. 使用 IDA Pro 修改 `libgame.so`** 165 | 1. **搜索 `金币增加函数`** 166 | 2. **修改 `MOV R0, #9999999`** 167 | ### **✅ 5. 绕过反作弊** 168 | ```js 169 | Interceptor.attach(Module.findExportByName(null, "ptrace"), { 170 | onEnter: function(args) { 171 | args[0] = 0; 172 | } 173 | }); 174 | ``` 175 | ### **✅ 6. 伪造 API 响应** 176 | ```js 177 | Interceptor.attach(Module.findExportByName("libokhttp.so", "ssl_read"), { 178 | onLeave: function(retval) { 179 | var fakeResponse = '{"coins": 9999999}'; 180 | Memory.writeUtf8String(retval, fakeResponse); 181 | } 182 | }); 183 | ``` 184 | 185 | --- 186 | 187 | # **📚 参考资料** 188 | 📌 **游戏破解工具** 189 | - `GameGuardian`:[https://gameguardian.net/](https://gameguardian.net/) 190 | - `Cheat Engine`:[https://cheatengine.org/](https://cheatengine.org/) 191 | 192 | 📌 **动态 Hook** 193 | - `Frida`:[https://frida.re](https://frida.re) 194 | 195 | 📌 **逆向分析** 196 | - `IDA Pro`:[https://hex-rays.com/](https://hex-rays.com/) 197 | - `Ghidra`:[https://ghidra-sre.org/](https://ghidra-sre.org/) 198 | 199 | --- 200 | 201 | 🔥 **任务完成后,你将掌握:** 202 | ✅ **如何使用 `GameGuardian`、`Cheat Engine` 修改游戏数据** 203 | ✅ **如何 Hook `addCoins()` 方法,修改游戏金币** 204 | ✅ **如何使用 IDA Pro 修改 `libgame.so`,破解游戏逻辑** 205 | ✅ **如何绕过游戏反作弊,成功 Hook 关键函数** 206 | 207 | 🚀 **下一步(Day 39)**:**反反调试!** 🎯 -------------------------------------------------------------------------------- /AndroidReverse101/第二阶段_APK逆向基础/Day_23_DEX_文件结构解析.md: -------------------------------------------------------------------------------- 1 | # **📜 Day 23: DEX 文件结构解析** 2 | 3 | ## **📌 学习目标** 4 | ✅ **深入理解 DEX(Dalvik Executable)文件格式**,掌握其结构、字段和解析方法。 5 | ✅ **学习如何手动解析 `classes.dex`,分析 DEX 头部、方法表、类定义等信息。** 6 | ✅ **掌握 `dexdump`、`JEB`、`baksmali` 等工具,分析 DEX 结构与 Smali 代码。** 7 | ✅ **学习如何使用 `Hex Editor` 解析 DEX 文件头,修改方法名称或 Magic 头部信息。** 8 | ✅ **实战:解析 `classes.dex`,提取 Java 类、方法,分析 DEX 结构,修改 Smali 代码!** 9 | 10 | --- 11 | 12 | # **1️⃣ 什么是 DEX 文件?** 13 | DEX(Dalvik Executable)是 **Android 虚拟机(Dalvik/ART)执行的字节码格式**, 14 | 用于存放 Java 类、方法、字段等信息。 15 | 16 | 📌 **提取 `classes.dex`** 17 | ```bash 18 | unzip base.apk classes.dex 19 | ``` 20 | 📌 **查看 DEX 文件类型** 21 | ```bash 22 | file classes.dex 23 | ``` 24 | 示例输出: 25 | ``` 26 | classes.dex: Dalvik dex file version 038 27 | ``` 28 | 29 | --- 30 | 31 | # **2️⃣ DEX 文件结构** 32 | DEX 文件由多个部分组成: 33 | | **偏移** | **结构** | **作用** | 34 | |---------|---------|------| 35 | | `0x00` | **DEX Header** | DEX 文件头,包含 Magic 版本、大小等 | 36 | | `0x20` | **String IDs** | 存放字符串索引表 | 37 | | `0x40` | **Type IDs** | 存放类型索引表 | 38 | | `0x60` | **Proto IDs** | 方法原型(参数 & 返回值) | 39 | | `0x80` | **Field IDs** | 字段(成员变量)信息 | 40 | | `0xA0` | **Method IDs** | 方法索引表 | 41 | | `0xC0` | **Class Defs** | Java 类定义表 | 42 | | `0xE0` | **Data** | 代码 & 常量数据 | 43 | 44 | 📌 **使用 `hexdump` 查看 DEX 头** 45 | ```bash 46 | hexdump -C classes.dex | head -n 20 47 | ``` 48 | 示例: 49 | ``` 50 | 00000000 64 65 78 0a 30 33 38 00 63 72 61 63 6b 65 64 00 |dex.038.cracked.| 51 | 00000010 70 00 00 00 4c 00 00 00 00 00 00 00 00 00 00 00 |p...L...........| 52 | ``` 53 | 🔹 **Magic 头**:`64 65 78 0A 30 33 38 00` → `dex\n038\0`(DEX 版本 038) 54 | 55 | --- 56 | 57 | # **3️⃣ 解析 DEX 头部** 58 | 📌 **使用 `dexdump` 解析 DEX 头** 59 | ```bash 60 | dexdump -f classes.dex 61 | ``` 62 | 示例输出: 63 | ``` 64 | DEX file header: 65 | magic : dex\n038\0 66 | checksum : 0x12345678 67 | fileSize : 0x004C0000 (49152 bytes) 68 | headerSize : 0x00000070 69 | endianTag : 0x12345678 70 | linkSize : 0x00000000 71 | linkOff : 0x00000000 72 | ``` 73 | 74 | 📌 **修改 Magic 头(伪加密)** 75 | ```bash 76 | hexedit classes.dex 77 | ``` 78 | 修改 `dex\n038\0` → `crk\n038\0`,可导致部分工具无法解析该 DEX。 79 | 80 | --- 81 | 82 | # **4️⃣ 解析 Java 类与方法** 83 | ## **✅ 1. 提取所有类** 84 | 📌 **使用 `dexdump`** 85 | ```bash 86 | dexdump -l classes.dex | grep "Class descriptor" 87 | ``` 88 | 示例输出: 89 | ``` 90 | Class descriptor : 'Lcom/example/MainActivity;' 91 | ``` 92 | 93 | ## **✅ 2. 提取方法** 94 | 📌 **使用 `dexdump`** 95 | ```bash 96 | dexdump -d classes.dex | grep "invoke-static" 97 | ``` 98 | 示例输出: 99 | ``` 100 | invoke-static {v0}, Lcom/example/MainActivity;->isVIP()Z 101 | ``` 102 | 表示 `isVIP()` 方法返回 `boolean` 类型。 103 | 104 | --- 105 | 106 | # **5️⃣ 使用 JEB 解析 DEX** 107 | 📌 **安装 JEB 反编译器** 108 | ```bash 109 | jeb -c classes.dex 110 | ``` 111 | 📌 **查看 `isVIP()` 方法** 112 | ```java 113 | public boolean isVIP() { 114 | return false; 115 | } 116 | ``` 117 | **思路**:将 `return false;` 修改为 `return true;`,绕过 VIP 逻辑。 118 | 119 | --- 120 | 121 | # **6️⃣ Smali 代码分析** 122 | 📌 **反编译 DEX** 123 | ```bash 124 | baksmali d classes.dex -o smali_output/ 125 | ``` 126 | 📌 **查看 `isVIP.smali`** 127 | ```smali 128 | .method public isVIP()Z 129 | .registers 1 130 | const/4 v0, 0x0 131 | return v0 132 | .end method 133 | ``` 134 | 📌 **修改 VIP 方法** 135 | ```smali 136 | .method public isVIP()Z 137 | .registers 1 138 | const/4 v0, 0x1 139 | return v0 140 | .end method 141 | ``` 142 | 📌 **重新打包** 143 | ```bash 144 | smali a smali_output/ -o new_classes.dex 145 | ``` 146 | 📌 **替换 DEX** 147 | ```bash 148 | zip -r new_app.apk new_classes.dex 149 | ``` 150 | 📌 **重新签名** 151 | ```bash 152 | jarsigner -verbose -keystore my.keystore new_app.apk alias_name 153 | adb install new_app.apk 154 | ``` 155 | 156 | --- 157 | 158 | # **7️⃣ Hook DEX 运行时修改方法** 159 | 📌 **Hook `isVIP()` 方法** 160 | ```js 161 | Java.perform(function() { 162 | var MainActivity = Java.use("com.example.MainActivity"); 163 | MainActivity.isVIP.implementation = function() { 164 | return true; 165 | }; 166 | }); 167 | ``` 168 | 📌 **运行 Frida** 169 | ```bash 170 | frida -U -n com.example.app -e "..." 171 | ``` 172 | 173 | --- 174 | 175 | # **🛠 实战任务** 176 | ### **✅ 1. 解析 DEX** 177 | ```bash 178 | dexdump -f classes.dex 179 | ``` 180 | ### **✅ 2. 提取所有类** 181 | ```bash 182 | dexdump -l classes.dex | grep "Class descriptor" 183 | ``` 184 | ### **✅ 3. 反编译 DEX** 185 | ```bash 186 | jadx -d output/ classes.dex 187 | ``` 188 | ### **✅ 4. 修改 VIP 方法** 189 | ```smali 190 | .method public isVIP()Z 191 | const/4 v0, 0x1 192 | return v0 193 | .end method 194 | ``` 195 | ### **✅ 5. 重新打包 & 安装** 196 | ```bash 197 | smali a smali_output/ -o new_classes.dex 198 | zip -r new_app.apk new_classes.dex 199 | adb install new_app.apk 200 | ``` 201 | ### **✅ 6. Hook VIP 方法** 202 | ```js 203 | Java.perform(function() { 204 | var MainActivity = Java.use("com.example.MainActivity"); 205 | MainActivity.isVIP.implementation = function() { 206 | return true; 207 | }; 208 | }); 209 | ``` 210 | 211 | --- 212 | 213 | # **📚 参考资料** 214 | 📌 **DEX 解析** 215 | - `DEX 规范`:[https://source.android.com/docs/core/runtime/dex-format](https://source.android.com/docs/core/runtime/dex-format) 216 | - `JEB 反编译器`:[https://www.pnfsoftware.com/jeb/](https://www.pnfsoftware.com/jeb/) 217 | 218 | 📌 **DEX 反编译** 219 | - `baksmali`:[https://github.com/JesusFreke/smali](https://github.com/JesusFreke/smali) 220 | - `jadx`:[https://github.com/skylot/jadx](https://github.com/skylot/jadx) 221 | 222 | 📌 **运行时 Hook** 223 | - `Frida`:[https://frida.re](https://frida.re) 224 | 225 | --- 226 | 227 | 🔥 **任务完成后,你将掌握:** 228 | ✅ **如何解析 DEX 结构,分析 Java 类、方法** 229 | ✅ **如何反编译 Smali 代码,修改方法逻辑** 230 | ✅ **如何 Hook DEX 方法,修改运行时行为** 231 | 232 | 🚀 **下一步(Day 24)**:**Smali 语言入门!** 🎯 -------------------------------------------------------------------------------- /AndroidReverse101/第一阶段_计算机基础_逆向概论/Day_12_Android_权限机制.md: -------------------------------------------------------------------------------- 1 | # **📜 Day 12: Android 权限机制解析** 2 | 3 | ## **📌 学习目标** 4 | ✅ **理解 Android 权限管理机制**,包括 **普通权限、危险权限、特殊权限**。 5 | ✅ **掌握 Android 6.0+ 运行时权限模型**,学习 **动态权限申请流程**。 6 | ✅ **学习如何在 Android 设备上查询、修改、绕过权限检查**。 7 | ✅ **逆向分析应用权限调用,了解 Frida / Xposed 如何 Hook 权限验证**。 8 | ✅ **分析 SELinux 在 Android 权限管理中的作用**。 9 | 10 | --- 11 | 12 | # **1️⃣ Android 权限模型概述** 13 | Android 采用 **基于权限的安全模型**,应用在访问敏感数据(如相机、定位、电话)时,必须 **声明并获得权限**。 14 | 15 | **📌 权限分类** 16 | | **权限类型** | **描述** | **示例** | 17 | |------------|------|------| 18 | | **普通权限(Normal)** | 低风险,安装时自动授予 | `INTERNET`, `ACCESS_NETWORK_STATE` | 19 | | **危险权限(Dangerous)** | 涉及隐私,用户需手动授权 | `READ_CONTACTS`, `CAMERA`, `LOCATION` | 20 | | **特殊权限(Signature/Privileged)** | 仅系统应用或特定签名的应用可使用 | `MANAGE_EXTERNAL_STORAGE`, `SYSTEM_ALERT_WINDOW` | 21 | 22 | 📌 **查看所有 Android 权限** 23 | ```bash 24 | adb shell pm list permissions 25 | ``` 26 | 27 | --- 28 | 29 | # **2️⃣ Android 6.0+ 运行时权限模型** 30 | 📌 **Android 6.0(API 23)引入运行时权限**,危险权限需要 **动态申请**。 31 | 32 | **📌 示例:申请 `CAMERA` 权限** 33 | ```java 34 | if (ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) { 35 | ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.CAMERA}, 100); 36 | } 37 | ``` 38 | **📌 监听权限结果** 39 | ```java 40 | @Override 41 | public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { 42 | if (requestCode == 100 && grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) { 43 | Log.d("Permission", "Camera permission granted!"); 44 | } 45 | } 46 | ``` 47 | 48 | --- 49 | 50 | # **3️⃣ Android 权限管理命令** 51 | 📌 **查看某应用的已授予权限** 52 | ```bash 53 | adb shell dumpsys package com.example.app | grep permission 54 | ``` 55 | 56 | 📌 **授予/撤销应用权限(需 root)** 57 | ```bash 58 | adb shell pm grant com.example.app android.permission.CAMERA 59 | adb shell pm revoke com.example.app android.permission.CAMERA 60 | ``` 61 | 62 | 📌 **查询当前启用的 SELinux 模式** 63 | ```bash 64 | adb shell getenforce 65 | ``` 66 | 输出: 67 | ``` 68 | Enforcing # SELinux 启用 69 | ``` 70 | 71 | 📌 **禁用 SELinux(Root 权限)** 72 | ```bash 73 | adb shell setenforce 0 74 | ``` 75 | 76 | --- 77 | 78 | # **4️⃣ 绕过权限验证** 79 | ## **✅ 1. Hook 权限检查** 80 | 📌 **使用 Frida 绕过 `checkSelfPermission`** 81 | ```js 82 | Java.perform(function() { 83 | var ActivityCompat = Java.use("androidx.core.app.ActivityCompat"); 84 | ActivityCompat.checkSelfPermission.implementation = function(context, permission) { 85 | console.log("Bypassing checkSelfPermission: " + permission); 86 | return 0; // 直接返回 PERMISSION_GRANTED 87 | }; 88 | }); 89 | ``` 90 | 📌 **Frida 命令执行** 91 | ```bash 92 | frida -U -n com.example.app -e "..." 93 | ``` 94 | 95 | --- 96 | 97 | ## **✅ 2. 修改 `AndroidManifest.xml` 以绕过权限** 98 | **逆向分析 APK 并修改权限** 99 | ```bash 100 | apktool d app.apk -o decompiled/ 101 | vim decompiled/AndroidManifest.xml 102 | ``` 103 | 修改: 104 | ```xml 105 | 106 | ``` 107 | 重新打包: 108 | ```bash 109 | apktool b decompiled -o modded.apk 110 | jarsigner -verbose -keystore my.keystore modded.apk alias_name 111 | adb install modded.apk 112 | ``` 113 | 114 | --- 115 | 116 | ## **✅ 3. 绕过运行时权限** 117 | **使用 Xposed 模块 Hook `requestPermissions`** 118 | ```java 119 | findAndHookMethod("android.app.Activity", lpparam.classLoader, "requestPermissions", 120 | String[].class, int.class, new XC_MethodHook() { 121 | @Override 122 | protected void beforeHookedMethod(MethodHookParam param) { 123 | Log.d("Xposed", "Bypassing requestPermissions"); 124 | param.setResult(null); 125 | } 126 | } 127 | ); 128 | ``` 129 | 130 | --- 131 | 132 | # **5️⃣ Android SELinux 权限管理** 133 | ### **🔹 SELinux 作用** 134 | SELinux 是 Android 的 **强制访问控制(MAC)** 机制: 135 | - **Enforcing 模式**(默认):阻止未经授权的访问。 136 | - **Permissive 模式**:仅记录日志,不拦截访问。 137 | 138 | 📌 **查询 SELinux 策略** 139 | ```bash 140 | adb shell dmesg | grep avc 141 | ``` 142 | 143 | 📌 **Hook SELinux 以绕过权限** 144 | ```c 145 | int selinux_android_setcon(const char *context) { 146 | return 0; // 绕过 SELinux 访问控制 147 | } 148 | ``` 149 | 150 | --- 151 | 152 | # **🛠 实战任务** 153 | ### **✅ 1. 查询设备上的所有权限** 154 | ```bash 155 | adb shell pm list permissions 156 | ``` 157 | ### **✅ 2. 查看某应用的权限** 158 | ```bash 159 | adb shell dumpsys package com.example.app | grep permission 160 | ``` 161 | ### **✅ 3. 逆向分析 APK 权限** 162 | ```bash 163 | apktool d app.apk -o decompiled/ 164 | vim decompiled/AndroidManifest.xml 165 | ``` 166 | ### **✅ 4. Hook `checkSelfPermission` 绕过权限检查** 167 | ```js 168 | Java.perform(function() { 169 | var ActivityCompat = Java.use("androidx.core.app.ActivityCompat"); 170 | ActivityCompat.checkSelfPermission.implementation = function(context, permission) { 171 | console.log("Bypassing checkSelfPermission: " + permission); 172 | return 0; 173 | }; 174 | }); 175 | ``` 176 | 177 | --- 178 | 179 | # **📚 参考资料** 180 | 📌 **Android 权限文档** 181 | - `官方权限指南`:[https://developer.android.com/guide/topics/permissions/](https://developer.android.com/guide/topics/permissions/) 182 | - `Android 运行时权限`:[https://developer.android.com/training/permissions/requesting](https://developer.android.com/training/permissions/requesting) 183 | 184 | 📌 **逆向工程** 185 | - `Frida Hook Android`:[https://frida.re](https://frida.re) 186 | - `Xposed Hook 教程`:[https://github.com/rovo89/XposedBridge](https://github.com/rovo89/XposedBridge) 187 | 188 | --- 189 | 190 | 🔥 **任务完成后,你将掌握:** 191 | ✅ **Android 权限模型(普通权限、危险权限、特殊权限)** 192 | ✅ **如何查询、修改、绕过 Android 权限** 193 | ✅ **如何使用 Frida / Xposed Hook Android 权限检查** 194 | ✅ **SELinux 在 Android 安全中的作用** 195 | 196 | 🚀 **下一步(Day 13)**:**Android APP 目录结构解析!** 🎯 -------------------------------------------------------------------------------- /AndroidReverse101/第一阶段_计算机基础_逆向概论/Day_14_APK_是如何加载的.md: -------------------------------------------------------------------------------- 1 | # **📜 Day 14: APK 是如何加载的** 2 | 3 | ## **📌 学习目标** 4 | ✅ **理解 Android 应用的加载流程**,从 APK 安装到 Dalvik/ART 运行的全流程。 5 | ✅ **掌握 APK 解析、DEX 加载、OAT 转换、类加载器(ClassLoader)等核心机制**。 6 | ✅ **学习如何在 Android 设备上分析 APK 运行时行为**,掌握 `pm`, `am`, `dumpsys package` 命令。 7 | ✅ **研究动态加载技术(DexClassLoader, PathClassLoader)及其在逆向工程中的应用**。 8 | ✅ **使用 Frida/Xposed Hook APK 加载流程,进行安全分析与反调试**。 9 | 10 | --- 11 | 12 | # **1️⃣ APK 加载流程概述** 13 | APK(Android Package)是 **Android 应用的安装包**,它的加载过程涉及多个关键步骤: 14 | 15 | 1️⃣ **APK 解析**:解析 `AndroidManifest.xml` 以确定权限、组件信息。 16 | 2️⃣ **DEX 优化**:将 `classes.dex` 转换为 OAT/ART 文件,提升运行效率。 17 | 3️⃣ **类加载**:使用 `ClassLoader` 机制加载 Java 类。 18 | 4️⃣ **资源管理**:解析 `resources.arsc` 以加载 UI 资源。 19 | 5️⃣ **Native 代码加载**:加载 `lib/` 目录下的 `.so` 本地库。 20 | 6️⃣ **执行 `Application.onCreate()`**,启动应用。 21 | 22 | --- 23 | 24 | # **2️⃣ APK 解析** 25 | ### **✅ 1. AndroidManifest.xml 解析** 26 | 📌 **查看已安装 APK 的 `AndroidManifest.xml`** 27 | ```bash 28 | adb shell dumpsys package com.example.app | grep android.intent.action.MAIN 29 | ``` 30 | 📌 **反编译 APK 以查看 `AndroidManifest.xml`** 31 | ```bash 32 | apktool d app.apk -o output/ 33 | cat output/AndroidManifest.xml 34 | ``` 35 | 📌 **修改 `AndroidManifest.xml` 并重新打包** 36 | ```bash 37 | apktool b output -o modded.apk 38 | jarsigner -verbose -keystore my.keystore modded.apk alias_name 39 | adb install modded.apk 40 | ``` 41 | 42 | --- 43 | 44 | # **3️⃣ DEX 加载与 OAT 优化** 45 | ### **✅ 1. DEX 加载** 46 | Android 使用 Dalvik/ART 运行时加载 `classes.dex`,执行 Java 代码。 47 | 48 | 📌 **查看 APK 内的 DEX 文件** 49 | ```bash 50 | unzip -l app.apk | grep classes.dex 51 | ``` 52 | 📌 **反编译 DEX** 53 | ```bash 54 | jadx -d output/ app.apk 55 | ``` 56 | 57 | ### **✅ 2. ART OAT 预编译** 58 | 📌 **Android 5.0+ 设备将 DEX 转换为 OAT 文件** 59 | ```bash 60 | adb shell ls /data/dalvik-cache/ 61 | ``` 62 | 📌 **反编译 OAT** 63 | ```bash 64 | oatdump --oat-file=/data/dalvik-cache/arm64/system@framework@boot.art 65 | ``` 66 | 67 | --- 68 | 69 | # **4️⃣ 类加载机制** 70 | Android 使用 **类加载器(ClassLoader)** 加载 DEX 代码: 71 | | **类加载器** | **作用** | **示例** | 72 | |------------|------|------| 73 | | **PathClassLoader** | 加载应用自带的 DEX 文件 | `system/lib/` | 74 | | **DexClassLoader** | 运行时动态加载 DEX | `data/data/com.example.app/dex/` | 75 | 76 | 📌 **示例:动态加载 DEX** 77 | ```java 78 | DexClassLoader loader = new DexClassLoader("/sdcard/test.dex", "/data/data/com.example.app/dex/", 79 | null, getClassLoader()); 80 | Class clazz = loader.loadClass("com.example.MyClass"); 81 | Method method = clazz.getMethod("test"); 82 | method.invoke(null); 83 | ``` 84 | 📌 **查看 ClassLoader** 85 | ```bash 86 | adb shell dumpsys package com.example.app | grep class 87 | ``` 88 | 89 | --- 90 | 91 | # **5️⃣ 逆向分析 APK 加载** 92 | ## **✅ 1. Dump DEX 文件** 93 | **使用 Frida 提取运行时加载的 DEX** 94 | ```js 95 | Java.perform(function() { 96 | var DexClassLoader = Java.use("dalvik.system.DexClassLoader"); 97 | DexClassLoader.loadClass.implementation = function(name) { 98 | console.log("Loading class: " + name); 99 | return this.loadClass(name); 100 | }; 101 | }); 102 | ``` 103 | 执行: 104 | ```bash 105 | frida -U -n com.example.app -e "..." 106 | ``` 107 | 108 | --- 109 | 110 | ## **✅ 2. Hook `loadClass`** 111 | **拦截 `PathClassLoader` 加载类** 112 | ```js 113 | Java.perform(function() { 114 | var PathClassLoader = Java.use("dalvik.system.PathClassLoader"); 115 | PathClassLoader.loadClass.overload('java.lang.String').implementation = function(name) { 116 | console.log("Hooked class loading: " + name); 117 | return this.loadClass(name); 118 | }; 119 | }); 120 | ``` 121 | 122 | --- 123 | 124 | ## **✅ 3. 解析已安装 APK** 125 | 📌 **列出所有已安装应用** 126 | ```bash 127 | adb shell pm list packages -f 128 | ``` 129 | 📌 **提取 APK** 130 | ```bash 131 | adb shell pm path com.example.app 132 | adb pull /data/app/com.example.app/base.apk . 133 | ``` 134 | 📌 **反编译** 135 | ```bash 136 | apktool d base.apk -o output/ 137 | ``` 138 | 139 | --- 140 | 141 | ## **✅ 4. Hook `Application.onCreate()`** 142 | **使用 Xposed 劫持 `Application.onCreate()`** 143 | ```java 144 | findAndHookMethod("android.app.Application", "onCreate", new XC_MethodHook() { 145 | @Override 146 | protected void afterHookedMethod(MethodHookParam param) { 147 | Log.d("Xposed", "Application onCreate() called!"); 148 | } 149 | }); 150 | ``` 151 | 152 | --- 153 | 154 | # **🛠 实战任务** 155 | ### **✅ 1. 解析 `AndroidManifest.xml`** 156 | ```bash 157 | apktool d app.apk -o output/ 158 | cat output/AndroidManifest.xml 159 | ``` 160 | ### **✅ 2. Dump 运行时加载的 DEX** 161 | ```js 162 | Java.perform(function() { 163 | var DexClassLoader = Java.use("dalvik.system.DexClassLoader"); 164 | DexClassLoader.loadClass.implementation = function(name) { 165 | console.log("Loading class: " + name); 166 | return this.loadClass(name); 167 | }; 168 | }); 169 | ``` 170 | ### **✅ 3. Hook `Application.onCreate()`** 171 | ```java 172 | findAndHookMethod("android.app.Application", "onCreate", new XC_MethodHook() { 173 | @Override 174 | protected void afterHookedMethod(MethodHookParam param) { 175 | Log.d("Xposed", "Application onCreate() called!"); 176 | } 177 | }); 178 | ``` 179 | --- 180 | 181 | # **📚 参考资料** 182 | 📌 **APK 加载** 183 | - `官方文档`:[https://developer.android.com/guide/components](https://developer.android.com/guide/components) 184 | - `ClassLoader 解析`:[https://source.android.com/devices/tech/dalvik/dex-format](https://source.android.com/devices/tech/dalvik/dex-format) 185 | 186 | 📌 **逆向分析** 187 | - `Frida Hook Android`:[https://frida.re](https://frida.re) 188 | - `Xposed Hook 教程`:[https://github.com/rovo89/XposedBridge](https://github.com/rovo89/XposedBridge) 189 | 190 | --- 191 | 192 | 🔥 **任务完成后,你将掌握:** 193 | ✅ **APK 从安装到运行的加载机制** 194 | ✅ **DEX/OAT 优化过程与 Hook 技术** 195 | ✅ **如何分析、修改 APK 以进行逆向调试** 196 | 197 | 🚀 **下一步(Day 15)**:**手写 ARM 汇编代码(实验)!** 🎯 -------------------------------------------------------------------------------- /AndroidReverse101/第二阶段_APK逆向基础/Day_41_解密加固_APK_初级.md: -------------------------------------------------------------------------------- 1 | # **📜 Day 41: 解密加固 APK(初级)** 2 | 3 | ## **📌 学习目标** 4 | ✅ **掌握加固 APK 的解密原理,理解加固的工作机制**。 5 | ✅ **学习如何使用 `Frida`、`Xposed`、`GDB` 进行 DEX 提取和解密**。 6 | ✅ **掌握 `DumpDex`、`gdb`、`IDA Pro` 等工具进行解密分析**。 7 | ✅ **实战:解密一个 360 加固 APK,提取原始 DEX 并进行反编译!** 8 | 9 | --- 10 | 11 | # **1️⃣ 加固 APK 的解密原理** 12 | 加固的主要目的是 **加密 DEX 文件**,防止静态分析: 13 | - **加密 DEX** 14 | - `classes.dex` 经过 AES/RSA 加密存储在 `assets` 或 `lib` 目录中。 15 | - **运行时解密** 16 | - 加固壳 `libjiagu.so` 在运行时解密并加载 DEX。 17 | - **Anti-Dump 机制** 18 | - 使用 `ptrace()` 保护,防止 Dump 内存。 19 | 20 | 📌 **解密思路** 21 | 1. **找到 DEX 加载时机** 22 | 2. **Hook `DexClassLoader`,Dump 解密后的 DEX** 23 | 3. **使用 `gdb` 或 `Frida` 提取 DEX** 24 | 25 | --- 26 | 27 | # **2️⃣ 检测 APK 是否加密** 28 | ## **✅ 1. 解压 APK 查看文件** 29 | 📌 **解压 APK** 30 | ```bash 31 | unzip app.apk -d output/ 32 | ``` 33 | 📌 **检查 `classes.dex` 是否存在** 34 | ```bash 35 | ls output/classes.dex 36 | ``` 37 | 📌 **如果 `classes.dex` 不存在,说明 DEX 可能被加密** 38 | 39 | --- 40 | 41 | ## **✅ 2. 使用 `APKiD` 检测加密** 42 | 📌 **安装 `APKiD`** 43 | ```bash 44 | pip install apkid 45 | ``` 46 | 📌 **分析 APK** 47 | ```bash 48 | apkid app.apk 49 | ``` 50 | 📌 **示例输出** 51 | ``` 52 | APKID results: 53 | - 360加固 detected 54 | - DexClassLoader used 55 | ``` 56 | 57 | --- 58 | 59 | ## **✅ 3. 运行时检查 DEX 加载** 60 | 📌 **使用 Frida 监听 DEX 加载** 61 | ```js 62 | Java.perform(function() { 63 | var DexClassLoader = Java.use("dalvik.system.DexClassLoader"); 64 | DexClassLoader.loadClass.overload("java.lang.String").implementation = function(className) { 65 | console.log("[*] Loading class: " + className); 66 | return this.loadClass(className); 67 | }; 68 | }); 69 | ``` 70 | 📌 **运行 Frida** 71 | ```bash 72 | frida -U -n com.example.app -e "..." 73 | ``` 74 | 📌 **如果发现 DEX 被动态加载,则需要 Dump 运行时内存!** 75 | 76 | --- 77 | 78 | # **3️⃣ 使用 Frida DumpDex 提取 DEX** 79 | ## **✅ 1. 安装 `Frida DumpDex`** 80 | 📌 **下载 DumpDex** 81 | ```bash 82 | git clone https://github.com/hluwa/FRIDA-DEXDump 83 | cd FRIDA-DEXDump 84 | ``` 85 | 📌 **运行 `DumpDex`** 86 | ```bash 87 | frida -U -n com.example.app -e "DexDump.dump()" 88 | ``` 89 | 📌 **提取解密 DEX** 90 | ```bash 91 | adb pull /sdcard/dump.dex 92 | ``` 93 | 📌 **反编译 `dump.dex`** 94 | ```bash 95 | jadx -d output/ dumped.dex 96 | ``` 97 | 98 | --- 99 | 100 | # **4️⃣ 手动解密加密 DEX** 101 | ## **✅ 1. 使用 `gdb` Dump 进程内存** 102 | 📌 **附加到进程** 103 | ```bash 104 | gdb -p $(pidof com.example.app) 105 | ``` 106 | 📌 **查找 DEX 加载地址** 107 | ```bash 108 | info proc mappings 109 | ``` 110 | 📌 **Dump 进程内存** 111 | ```bash 112 | dump memory dumped.dex 0x12345678 0x87654321 113 | ``` 114 | 📌 **反编译** 115 | ```bash 116 | jadx -d output/ dumped.dex 117 | ``` 118 | 119 | --- 120 | 121 | # **5️⃣ 逆向 `libjiagu.so` 解密 DEX** 122 | ## **✅ 1. 提取 `libjiagu.so`** 123 | 📌 **查找加密库** 124 | ```bash 125 | adb shell ls /data/app/com.example.app/lib/arm64/ 126 | ``` 127 | 📌 **提取 so** 128 | ```bash 129 | adb pull /data/app/com.example.app/lib/arm64/libjiagu.so . 130 | ``` 131 | 132 | ## **✅ 2. 使用 IDA Pro 分析** 133 | 📌 **步骤** 134 | 1. **加载 `libjiagu.so`** 135 | 2. **搜索 `AES_decrypt()` 或 `DexClassLoader`** 136 | 3. **Patch 代码,让其直接 dump 解密数据** 137 | 138 | --- 139 | 140 | # **6️⃣ 绕过 Anti-Dump 机制** 141 | ## **✅ 1. Hook `ptrace()`** 142 | 📌 **Frida Hook** 143 | ```js 144 | Interceptor.attach(Module.findExportByName(null, "ptrace"), { 145 | onEnter: function(args) { 146 | args[0] = 0; 147 | }, 148 | onLeave: function(retval) { 149 | retval.replace(0); 150 | } 151 | }); 152 | ``` 153 | 154 | ## **✅ 2. Hook `isDebuggerConnected()`** 155 | 📌 **Frida Hook** 156 | ```js 157 | Java.perform(function() { 158 | var Debug = Java.use("android.os.Debug"); 159 | Debug.isDebuggerConnected.implementation = function() { 160 | return false; 161 | }; 162 | }); 163 | ``` 164 | 165 | ## **✅ 3. 绕过 `getppid()`** 166 | 📌 **Frida Hook** 167 | ```js 168 | Interceptor.attach(Module.findExportByName(null, "getppid"), { 169 | onLeave: function(retval) { 170 | retval.replace(0); 171 | } 172 | }); 173 | ``` 174 | 175 | --- 176 | 177 | # **🛠 实战任务** 178 | ### **✅ 1. 检测 APK 是否加密** 179 | ```bash 180 | apkid app.apk 181 | ls output/classes.dex 182 | ``` 183 | ### **✅ 2. 运行 Frida 监听 DEX 加载** 184 | ```js 185 | Java.perform(function() { 186 | var DexClassLoader = Java.use("dalvik.system.DexClassLoader"); 187 | DexClassLoader.loadClass.overload("java.lang.String").implementation = function(className) { 188 | console.log("[*] Loading class: " + className); 189 | return this.loadClass(className); 190 | }; 191 | }); 192 | ``` 193 | ### **✅ 3. Dump DEX** 194 | ```bash 195 | frida -U -n com.example.app -e "DexDump.dump()" 196 | adb pull /sdcard/dump.dex 197 | jadx -d output/ dumped.dex 198 | ``` 199 | ### **✅ 4. 使用 `gdb` Dump 进程** 200 | ```bash 201 | gdb -p $(pidof com.example.app) 202 | info proc mappings 203 | dump memory dumped.dex 0x12345678 0x87654321 204 | ``` 205 | ### **✅ 5. 逆向 `libjiagu.so`** 206 | ```bash 207 | adb pull /data/app/com.example.app/lib/arm64/libjiagu.so . 208 | ``` 209 | 1. **使用 IDA Pro 反编译** 210 | 2. **搜索 `AES_decrypt()`** 211 | 3. **Patch 代码,Dump 解密后的 DEX** 212 | ### **✅ 6. 绕过 Anti-Dump** 213 | ```js 214 | Interceptor.attach(Module.findExportByName(null, "ptrace"), { 215 | onEnter: function(args) { 216 | args[0] = 0; 217 | }, 218 | onLeave: function(retval) { 219 | retval.replace(0); 220 | } 221 | }); 222 | ``` 223 | 224 | --- 225 | 226 | # **📚 参考资料** 227 | 📌 **加密检测** 228 | - `APKiD`:[https://github.com/rednaga/APKiD](https://github.com/rednaga/APKiD) 229 | 230 | 📌 **DEX Dump** 231 | - `Frida DumpDex`:[https://github.com/hluwa/FRIDA-DEXDump](https://github.com/hluwa/FRIDA-DEXDump) 232 | 233 | 📌 **逆向分析** 234 | - `IDA Pro`:[https://hex-rays.com/](https://hex-rays.com/) 235 | - `Ghidra`:[https://ghidra-sre.org/](https://ghidra-sre.org/) 236 | 237 | --- 238 | 239 | 🔥 **任务完成后,你将掌握:** 240 | ✅ **如何检测 APK 是否加密** 241 | ✅ **如何使用 `Frida` 提取解密 DEX** 242 | ✅ **如何使用 `gdb` Dump 内存中的 DEX** 243 | ✅ **如何逆向 `libjiagu.so`,分析解密流程** 244 | ✅ **如何绕过 Anti-Dump 机制,成功解密 APK** 245 | 246 | 🚀 **下一步(Day 42)**:**解密加固 APK(进阶)!** 🎯 -------------------------------------------------------------------------------- /AndroidReverse101/第三阶段_高级逆向_CTF挑战/Day_60_深入分析_CTF_逆向挑战.md: -------------------------------------------------------------------------------- 1 | # **📜 Day 60: 深入分析 CTF 逆向挑战** 2 | 3 | ## **📌 学习目标** 4 | ✅ **掌握 CTF 逆向工程的常见题型,包括 CrackMe、动态分析、加密算法、反调试等**。 5 | ✅ **学习如何使用 IDA Pro、Ghidra、Frida、GDB、Radare2 进行 CTF 逆向分析**。 6 | ✅ **掌握 ELF/DEX 可执行文件结构,提取关键函数 & 解密算法**。 7 | ✅ **实战:完成多个 CTF 逆向挑战,成功获取 Flag!** 8 | 9 | --- 10 | 11 | # **1️⃣ CTF 逆向工程常见题型** 12 | 📌 **CTF 逆向工程题通常涉及以下类型** 13 | | **题型** | **描述** | **常见解法** | 14 | |---------|--------|------------| 15 | | **CrackMe** | 找到正确的输入,绕过密码验证 | 静态分析 + Hook `strcmp()` | 16 | | **ELF 二进制分析** | 分析 Linux ELF 执行逻辑,找到 Flag | `strings` + `objdump` + `GDB` | 17 | | **加密算法破解** | 逆向 AES、RSA、Base64 等加密算法 | 静态分析 + 动态调试 | 18 | | **反调试 & 反虚拟机检测** | 绕过 `ptrace()`、`syscall` 检测 | `Frida` Hook + Patch | 19 | | **Android DEX 逆向** | 分析 `classes.dex`,提取 Flag | `jadx` + `Frida` + `Xposed` | 20 | 21 | --- 22 | 23 | # **2️⃣ 经典 CTF 逆向 CrackMe 题目** 24 | ## **✅ 1. CrackMe 示例** 25 | 📌 **CrackMe C 代码** 26 | ```c 27 | #include 28 | #include 29 | 30 | int main() { 31 | char input[100]; 32 | printf("Enter the password: "); 33 | scanf("%s", input); 34 | if (strcmp(input, "SuperSecret") == 0) { 35 | printf("Correct! Flag: FLAG{CrackMe_Solved}\n"); 36 | } else { 37 | printf("Wrong password!\n"); 38 | } 39 | return 0; 40 | } 41 | ``` 42 | 📌 **编译 ELF** 43 | ```bash 44 | gcc -o crackme crackme.c 45 | ``` 46 | 📌 **分析 CrackMe** 47 | ```bash 48 | strings crackme | grep FLAG 49 | objdump -d crackme | less 50 | gdb ./crackme 51 | ``` 52 | 53 | ## **✅ 2. 使用 `GDB` 动态分析** 54 | 📌 **运行 CrackMe** 55 | ```bash 56 | gdb ./crackme 57 | break *main 58 | run 59 | ``` 60 | 📌 **修改输入** 61 | ```bash 62 | set $eax = 0 63 | continue 64 | ``` 65 | 📌 **成功获取 Flag** 66 | ``` 67 | FLAG{CrackMe_Solved} 68 | ``` 69 | 70 | --- 71 | 72 | # **3️⃣ ELF 逆向分析** 73 | ## **✅ 1. 检查 ELF 结构** 74 | 📌 **查看 ELF 头** 75 | ```bash 76 | readelf -h crackme 77 | ``` 78 | 📌 **查找字符串** 79 | ```bash 80 | strings crackme | grep FLAG 81 | ``` 82 | 📌 **反汇编** 83 | ```bash 84 | objdump -d crackme | grep strcmp 85 | ``` 86 | 87 | ## **✅ 2. 使用 IDA Pro 逆向** 88 | 📌 **步骤** 89 | 1. **加载 `crackme` 到 IDA Pro** 90 | 2. **查找 `strcmp()` 调用** 91 | 3. **修改 `jne` 为 `jmp`,绕过密码检查** 92 | 93 | --- 94 | 95 | # **4️⃣ 加密算法破解** 96 | ## **✅ 1. 逆向 Base64 加密** 97 | 📌 **示例加密代码** 98 | ```c 99 | #include 100 | #include 101 | #include 102 | 103 | int main() { 104 | char key[] = "MySecretKey"; 105 | char flag[] = "FLAG{Encrypted}"; 106 | for (int i = 0; i < strlen(flag); i++) { 107 | flag[i] ^= key[i % strlen(key)]; 108 | } 109 | printf("Encrypted: %s\n", flag); 110 | } 111 | ``` 112 | 📌 **解密 XOR** 113 | ```python 114 | key = "MySecretKey" 115 | enc = "Encrypted_String" 116 | flag = "".join(chr(ord(enc[i]) ^ ord(key[i % len(key)])) for i in range(len(enc))) 117 | print(flag) 118 | ``` 119 | 120 | --- 121 | 122 | # **5️⃣ Android DEX 逆向** 123 | ## **✅ 1. 反编译 DEX** 124 | 📌 **使用 `jadx` 反编译 APK** 125 | ```bash 126 | jadx -d output/ app.apk 127 | ``` 128 | 📌 **查找 `FLAG{}`** 129 | ```bash 130 | grep -r "FLAG{" output/ 131 | ``` 132 | 133 | ## **✅ 2. Hook `checkPassword()`** 134 | 📌 **Frida Hook** 135 | ```js 136 | Java.perform(function() { 137 | var MainActivity = Java.use("com.example.MainActivity"); 138 | MainActivity.checkPassword.implementation = function(input) { 139 | console.log("[*] Hooked password check: " + input); 140 | return true; 141 | }; 142 | }); 143 | ``` 144 | 📌 **运行 Frida** 145 | ```bash 146 | frida -U -n com.example.app -e "..." 147 | ``` 148 | 149 | --- 150 | 151 | # **6️⃣ 绕过反调试 & 反 VM** 152 | ## **✅ 1. Hook `ptrace()`** 153 | 📌 **Frida Hook** 154 | ```js 155 | Interceptor.attach(Module.findExportByName(null, "ptrace"), { 156 | onEnter: function(args) { 157 | args[0] = 0; 158 | }, 159 | onLeave: function(retval) { 160 | retval.replace(0); 161 | } 162 | }); 163 | ``` 164 | 165 | ## **✅ 2. 修改 `isDebuggerConnected()`** 166 | 📌 **Frida Hook** 167 | ```js 168 | Java.perform(function() { 169 | var Debug = Java.use("android.os.Debug"); 170 | Debug.isDebuggerConnected.implementation = function() { 171 | return false; 172 | }; 173 | }); 174 | ``` 175 | 176 | --- 177 | 178 | # **🛠 实战任务** 179 | ### **✅ 1. 逆向 CrackMe** 180 | ```bash 181 | strings crackme | grep FLAG 182 | objdump -d crackme | grep strcmp 183 | gdb ./crackme 184 | ``` 185 | ### **✅ 2. 逆向 ELF** 186 | ```bash 187 | readelf -h crackme 188 | strings crackme | grep FLAG 189 | objdump -d crackme 190 | ``` 191 | ### **✅ 3. 破解 Base64 加密** 192 | ```python 193 | key = "MySecretKey" 194 | enc = "Encrypted_String" 195 | flag = "".join(chr(ord(enc[i]) ^ ord(key[i % len(key)])) for i in range(len(enc))) 196 | print(flag) 197 | ``` 198 | ### **✅ 4. 逆向 DEX** 199 | ```bash 200 | jadx -d output/ app.apk 201 | grep -r "FLAG{" output/ 202 | ``` 203 | ### **✅ 5. Hook `checkPassword()`** 204 | ```js 205 | Java.perform(function() { 206 | var MainActivity = Java.use("com.example.MainActivity"); 207 | MainActivity.checkPassword.implementation = function(input) { 208 | return true; 209 | }; 210 | }); 211 | ``` 212 | ### **✅ 6. 绕过反调试** 213 | ```js 214 | Interceptor.attach(Module.findExportByName(null, "ptrace"), { 215 | onEnter: function(args) { 216 | args[0] = 0; 217 | }, 218 | onLeave: function(retval) { 219 | retval.replace(0); 220 | } 221 | }); 222 | ``` 223 | 224 | --- 225 | 226 | # **📚 参考资料** 227 | 📌 **ELF 逆向** 228 | - `GDB`:[https://www.gnu.org/software/gdb/](https://www.gnu.org/software/gdb/) 229 | - `IDA Pro`:[https://hex-rays.com/](https://hex-rays.com/) 230 | 231 | 📌 **DEX 逆向** 232 | - `jadx`:[https://github.com/skylot/jadx](https://github.com/skylot/jadx) 233 | - `Frida`:[https://frida.re](https://frida.re) 234 | 235 | 📌 **CTF 逆向** 236 | - `CTF Writeups`:[https://ctftime.org/](https://ctftime.org/) 237 | 238 | --- 239 | 240 | 🔥 **任务完成后,你将掌握:** 241 | ✅ **如何破解 CrackMe 题目,绕过密码验证** 242 | ✅ **如何分析 ELF 二进制文件,提取 Flag** 243 | ✅ **如何逆向加密算法,解密加密数据** 244 | ✅ **如何使用 Frida Hook Android DEX,修改应用逻辑** 245 | ✅ **如何绕过反调试 & 反虚拟机检测,成功调试目标程序** 246 | 247 | 🚀 **下一步(Day 70)**:**逆向挖掘 0Day 漏洞!** 🎯 -------------------------------------------------------------------------------- /AndroidReverse101/第二阶段_APK逆向基础/Day_40_Android_加固原理.md: -------------------------------------------------------------------------------- 1 | # **📜 Day 40: Android 加固原理** 2 | 3 | ## **📌 学习目标** 4 | ✅ **掌握 Android 应用加固(Application Hardening)的基本原理**,理解主流加固技术。 5 | ✅ **学习常见的 Android 加固方案,如 360 加固、腾讯乐固、爱加密等**。 6 | ✅ **学习如何检测 APK 是否被加固,并分析加固后的 APK 结构**。 7 | ✅ **掌握加固脱壳(Dump Dex)的方法,提取原始 DEX 进行分析**。 8 | ✅ **实战:绕过加固,提取并分析未加固的应用代码!** 9 | 10 | --- 11 | 12 | # **1️⃣ 什么是 Android 加固?** 13 | Android 加固(Application Hardening)是一种 **保护应用代码** 的技术,主要目的是 **防止逆向工程、反调试、静态分析**。 14 | **加固方式通常包括:** 15 | 1. **DEX 加密**:将 `classes.dex` 加密存储,运行时解密加载。 16 | 2. **壳(Shell)保护**:加固壳劫持 `Application` 启动过程,动态解密 DEX。 17 | 3. **反调试 & 反 Hook**:检测调试器 & Frida,阻止调试和 Hook。 18 | 4. **JNI 加密**:使用 `libshell.so` 进行代码保护,隐藏关键逻辑。 19 | 5. **动态代码加载**:通过 `DexClassLoader` 在运行时加载加密代码。 20 | 21 | 📌 **常见的加固服务** 22 | | **加固方案** | **特点** | **脱壳难度** | 23 | |------------|--------|--------| 24 | | **360 加固** | 国外流行,DEX 加密,加载 `libjiagu.so` | 🔥🔥🔥 | 25 | | **腾讯乐固** | 使用 `libturing.so` 加载解密的 DEX | 🔥🔥 | 26 | | **爱加密** | DEX 加密 & 代码变形,部分代码 Native 实现 | 🔥🔥🔥🔥 | 27 | 28 | --- 29 | 30 | # **2️⃣ 检测 APK 是否加固** 31 | ## **✅ 1. 查看 APK 结构** 32 | 📌 **解压 APK** 33 | ```bash 34 | unzip app.apk -d output/ 35 | ``` 36 | 📌 **检查是否存在 `libjiagu.so` 或 `libturing.so`** 37 | ```bash 38 | ls output/lib/arm64-v8a/ 39 | ``` 40 | 📌 **如果发现这些库,说明应用已被加固** 41 | ``` 42 | libjiagu.so 43 | libturing.so 44 | libshell.so 45 | ``` 46 | 47 | ## **✅ 2. 使用 `APKiD` 识别加固方案** 48 | 📌 **安装 `APKiD`** 49 | ```bash 50 | pip install apkid 51 | ``` 52 | 📌 **分析 APK** 53 | ```bash 54 | apkid app.apk 55 | ``` 56 | 📌 **示例输出** 57 | ``` 58 | APKID results: 59 | - Tencent Legu detected 60 | - DexClassLoader used 61 | - Anti-Debugging techniques detected 62 | ``` 63 | 64 | ## **✅ 3. 使用 `frida -U -n` 运行时检测** 65 | 📌 **运行 Frida** 66 | ```bash 67 | frida -U -n com.example.app -e "console.log('[*] Running Frida detection')" 68 | ``` 69 | 📌 **如果应用崩溃,说明有 Frida 反调试** 70 | 71 | --- 72 | 73 | # **3️⃣ Android 加固脱壳(Dump DEX)** 74 | ## **✅ 1. 使用 `Frida DumpDex`** 75 | 📌 **安装 `DumpDex`** 76 | ```bash 77 | git clone https://github.com/hluwa/FRIDA-DEXDump 78 | cd FRIDA-DEXDump 79 | ``` 80 | 📌 **运行 `DumpDex`** 81 | ```bash 82 | frida -U -n com.example.app -e "DexDump.dump()" 83 | ``` 84 | 📌 **提取 `dumped.dex`** 85 | ```bash 86 | adb pull /sdcard/dump.dex 87 | ``` 88 | 📌 **反编译 `dumped.dex`** 89 | ```bash 90 | jadx -d output/ dumped.dex 91 | ``` 92 | 93 | --- 94 | 95 | ## **✅ 2. 使用 `Xposed` Hook `DexClassLoader`** 96 | 📌 **Hook `loadClass`,拦截动态加载的 DEX** 97 | ```java 98 | XposedHelpers.findAndHookMethod("dalvik.system.DexClassLoader", lpparam.classLoader, "loadClass", 99 | String.class, new XC_MethodHook() { 100 | @Override 101 | protected void afterHookedMethod(MethodHookParam param) { 102 | String className = (String) param.args[0]; 103 | XposedBridge.log("[*] Loaded Class: " + className); 104 | } 105 | }); 106 | ``` 107 | 108 | --- 109 | 110 | # **4️⃣ 绕过反调试 & 反 Frida** 111 | ## **✅ 1. Hook `isDebuggerConnected()`** 112 | 📌 **Frida Hook** 113 | ```js 114 | Java.perform(function() { 115 | var Debug = Java.use("android.os.Debug"); 116 | Debug.isDebuggerConnected.implementation = function() { 117 | console.log("[*] Bypassing isDebuggerConnected()"); 118 | return false; 119 | }; 120 | }); 121 | ``` 122 | 123 | ## **✅ 2. Hook `ptrace()`** 124 | 📌 **Frida Hook** 125 | ```js 126 | Interceptor.attach(Module.findExportByName(null, "ptrace"), { 127 | onEnter: function(args) { 128 | args[0] = 0; 129 | }, 130 | onLeave: function(retval) { 131 | retval.replace(0); 132 | } 133 | }); 134 | ``` 135 | 136 | ## **✅ 3. 绕过 `getppid()`** 137 | 📌 **Frida Hook** 138 | ```js 139 | Interceptor.attach(Module.findExportByName(null, "getppid"), { 140 | onLeave: function(retval) { 141 | retval.replace(0); 142 | } 143 | }); 144 | ``` 145 | 146 | --- 147 | 148 | # **5️⃣ 手动脱壳(Dump 内存 DEX)** 149 | ## **✅ 1. 使用 `IDA Pro` 查找 `DexClassLoader`** 150 | 1. **打开 `libjiagu.so`** 151 | 2. **搜索 `DexClassLoader`** 152 | 3. **找到 `loadClass()` 并 Patch** 153 | 154 | ## **✅ 2. 使用 `gdb` Dump 进程内存** 155 | 📌 **附加到目标进程** 156 | ```bash 157 | gdb -p $(pidof com.example.app) 158 | ``` 159 | 📌 **查找 DEX 加载地址** 160 | ```bash 161 | info proc mappings 162 | ``` 163 | 📌 **Dump DEX** 164 | ```bash 165 | dump memory dumped.dex 0x12345678 0x87654321 166 | ``` 167 | 168 | --- 169 | 170 | # **🛠 实战任务** 171 | ### **✅ 1. 检测 APK 是否加固** 172 | ```bash 173 | apkid app.apk 174 | ls output/lib/arm64-v8a/ 175 | ``` 176 | ### **✅ 2. 使用 `Frida DumpDex`** 177 | ```bash 178 | frida -U -n com.example.app -e "DexDump.dump()" 179 | adb pull /sdcard/dump.dex 180 | jadx -d output/ dumped.dex 181 | ``` 182 | ### **✅ 3. Hook `DexClassLoader`** 183 | ```java 184 | XposedHelpers.findAndHookMethod("dalvik.system.DexClassLoader", lpparam.classLoader, "loadClass", 185 | String.class, new XC_MethodHook() { 186 | @Override 187 | protected void afterHookedMethod(MethodHookParam param) { 188 | XposedBridge.log("[*] Loaded Class: " + className); 189 | } 190 | }); 191 | ``` 192 | ### **✅ 4. Hook `ptrace()`** 193 | ```js 194 | Interceptor.attach(Module.findExportByName(null, "ptrace"), { 195 | onEnter: function(args) { 196 | args[0] = 0; 197 | }, 198 | onLeave: function(retval) { 199 | retval.replace(0); 200 | } 201 | }); 202 | ``` 203 | ### **✅ 5. Dump 进程内存** 204 | ```bash 205 | gdb -p $(pidof com.example.app) 206 | info proc mappings 207 | dump memory dumped.dex 0x12345678 0x87654321 208 | ``` 209 | 210 | --- 211 | 212 | # **📚 参考资料** 213 | 📌 **加固检测** 214 | - `APKiD`:[https://github.com/rednaga/APKiD](https://github.com/rednaga/APKiD) 215 | 216 | 📌 **脱壳工具** 217 | - `Frida DumpDex`:[https://github.com/hluwa/FRIDA-DEXDump](https://github.com/hluwa/FRIDA-DEXDump) 218 | 219 | 📌 **逆向分析** 220 | - `IDA Pro`:[https://hex-rays.com/](https://hex-rays.com/) 221 | - `Ghidra`:[https://ghidra-sre.org/](https://ghidra-sre.org/) 222 | 223 | --- 224 | 225 | 🔥 **任务完成后,你将掌握:** 226 | ✅ **如何检测 APK 是否加固** 227 | ✅ **如何使用 `Frida`、`Xposed` 绕过加固** 228 | ✅ **如何提取原始 `DEX` 代码进行分析** 229 | ✅ **如何手动 Dump 进程内存,破解加固保护** 230 | 231 | 🚀 **下一步(Day 41)**:**解密加固 APK(初级)!** 🎯 -------------------------------------------------------------------------------- /AndroidReverse101/第一阶段_计算机基础_逆向概论/Day_11_Android_进程管理.md: -------------------------------------------------------------------------------- 1 | # **📜 Day 11: Android 进程管理** 2 | 3 | ## **📌 学习目标** 4 | ✅ **理解 Android 进程管理的工作方式**,包括 **Zygote 进程、App 进程、System Server 进程**。 5 | ✅ **掌握 Android 进程的生命周期**,学习 **前台进程、后台进程、服务进程、缓存进程的调度策略**。 6 | ✅ **学习 Android 的 OOM(Out Of Memory)管理机制**,理解 **进程优先级与杀死策略**。 7 | ✅ **分析 /proc 目录下的进程信息**,通过 `ps`, `top`, `dumpsys activity` 命令获取进程状态。 8 | ✅ **学习如何 Hook Android 进程管理机制**,进行应用持久化 & 逆向调试。 9 | 10 | --- 11 | 12 | # **1️⃣ Android 进程管理概述** 13 | 在 Android 中,应用程序 **通常不会直接创建进程**,而是由 **Zygote** 负责孵化。 14 | 15 | | **进程类型** | **作用** | **示例** | 16 | |------------|------|------| 17 | | **Zygote** | 负责 Fork 其他进程 | `/system/bin/app_process` | 18 | | **System Server** | 管理系统服务 | `system_server` 进程 | 19 | | **App 进程** | 运行应用 | `com.example.app` | 20 | | **Native 进程** | 运行 C/C++ 代码 | `surfaceflinger`, `mediaserver` | 21 | 22 | --- 23 | 24 | # **2️⃣ 关键进程解析** 25 | ## **✅ 1. Zygote 进程** 26 | **Zygote 是 Android 进程的起点**,其主要作用是: 27 | - **预加载类库 & 资源**,减少应用启动时间。 28 | - **Fork 子进程**,所有 App 进程均由 Zygote 复制而来。 29 | 30 | 📌 **查看 Zygote 进程** 31 | ```bash 32 | adb shell ps -A | grep zygote 33 | ``` 34 | 输出示例: 35 | ``` 36 | zygote64 1234 567 123456K fg 00000000 S zygote64 37 | zygote 1235 567 123456K fg 00000000 S zygote 38 | ``` 39 | 40 | 📌 **Zygote 如何 Fork 进程?** 41 | ```java 42 | public static void main(String[] argv) { 43 | ZygoteServer zygoteServer = new ZygoteServer(); 44 | while (true) { 45 | ZygoteConnection connection = zygoteServer.acceptCommandPeer(); 46 | connection.runOnce(); 47 | } 48 | } 49 | ``` 50 | 📌 **逆向分析 Zygote** 51 | ```bash 52 | strings /system/bin/app_process 53 | ``` 54 | 55 | --- 56 | 57 | ## **✅ 2. System Server 进程** 58 | **System Server 进程** 负责管理 Android 系统服务,如 **AMS(ActivityManagerService)**, **PMS(PackageManagerService)**。 59 | 60 | 📌 **查看 System Server 进程** 61 | ```bash 62 | adb shell ps -A | grep system_server 63 | ``` 64 | 输出: 65 | ``` 66 | system 1356 567 456789K fg 00000000 S system_server 67 | ``` 68 | 69 | 📌 **System Server 关键代码** 70 | ```java 71 | public static void main(String[] args) { 72 | SystemServer server = new SystemServer(); 73 | server.run(); 74 | } 75 | ``` 76 | 77 | 📌 **分析 System Server 中的 AMS** 78 | ```bash 79 | adb shell dumpsys activity 80 | ``` 81 | 82 | --- 83 | 84 | ## **✅ 3. 应用进程** 85 | 应用进程通常由 **Zygote Fork**,负责执行应用代码。 86 | 87 | 📌 **查看当前运行的 App 进程** 88 | ```bash 89 | adb shell ps -A | grep com.example.app 90 | ``` 91 | 92 | 📌 **查看应用进程详情** 93 | ```bash 94 | adb shell dumpsys meminfo com.example.app 95 | ``` 96 | 97 | 📌 **杀死应用进程** 98 | ```bash 99 | adb shell am force-stop com.example.app 100 | ``` 101 | 102 | --- 103 | 104 | # **3️⃣ 进程优先级 & OOM 机制** 105 | Android 采用 **OOM(Out Of Memory)优先级管理机制**,根据进程的重要性决定 **是否杀死进程**。 106 | 107 | | **优先级** | **进程类型** | **是否可杀死** | 108 | |-----------|----------|-----------| 109 | | **0(最高)** | 前台进程(前台 Activity) | ❌ 不能杀死 | 110 | | **1** | 可见进程(后台 Activity) | ❌ 通常保留 | 111 | | **2** | 服务进程(后台 Service) | ✅ 低内存时杀死 | 112 | | **3** | 后台进程(不可见 Activity) | ✅ 低内存时杀死 | 113 | | **4(最低)** | 缓存进程(长期未使用的 App) | ✅ 优先被杀死 | 114 | 115 | 📌 **查看进程 OOM 级别** 116 | ```bash 117 | adb shell cat /proc/1234/oom_adj 118 | ``` 119 | 输出: 120 | ``` 121 | 0 # 前台进程,不会被杀死 122 | 6 # 后台进程,低内存时可能被杀死 123 | 15 # 缓存进程,优先被杀死 124 | ``` 125 | 126 | 📌 **调整进程 OOM 级别** 127 | ```bash 128 | adb shell echo -17 > /proc/1234/oom_adj 129 | ``` 130 | 👉 **可用于保护进程,防止被系统杀死(需 Root)**。 131 | 132 | --- 133 | 134 | # **4️⃣ Android 进程管理 API** 135 | ## **✅ 1. ActivityManager** 136 | ```java 137 | ActivityManager am = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE); 138 | List processes = am.getRunningAppProcesses(); 139 | for (ActivityManager.RunningAppProcessInfo process : processes) { 140 | Log.d("Process", "PID: " + process.pid + " Name: " + process.processName); 141 | } 142 | ``` 143 | 144 | ## **✅ 2. 监听进程状态** 145 | ```java 146 | ProcessLifecycleOwner.get().getLifecycle().addObserver(new LifecycleObserver() { 147 | @OnLifecycleEvent(Lifecycle.Event.ON_STOP) 148 | public void onAppBackgrounded() { 149 | Log.d("Process", "App moved to background!"); 150 | } 151 | }); 152 | ``` 153 | 154 | ## **✅ 3. 让进程持久运行** 155 | ```java 156 | startForegroundService(new Intent(this, MyService.class)); 157 | ``` 158 | 159 | --- 160 | 161 | # **5️⃣ 逆向分析 & Hook 进程** 162 | ## **✅ 1. Hook Android 进程调度** 163 | ```bash 164 | frida -U -n system_server -e "Interceptor.attach(Module.findExportByName(null, 'fork'), { onEnter: function(args) { console.log('fork called'); }})" 165 | ``` 166 | 167 | ## **✅ 2. 绕过进程杀死** 168 | ```bash 169 | adb shell setprop persist.sys.background_process_limit 0 170 | ``` 171 | 172 | ## **✅ 3. 限制某进程 CPU 使用** 173 | ```bash 174 | taskset -p 0x01 1234 175 | ``` 176 | 177 | --- 178 | 179 | # **🛠 实战任务** 180 | ### **✅ 1. 检查 Android 设备上的进程** 181 | ```bash 182 | adb shell ps -A 183 | ``` 184 | ### **✅ 2. 解析 Zygote 进程** 185 | ```bash 186 | adb shell ps -A | grep zygote 187 | ``` 188 | ### **✅ 3. 获取 App 进程的内存信息** 189 | ```bash 190 | adb shell dumpsys meminfo com.example.app 191 | ``` 192 | ### **✅ 4. 监听进程状态** 193 | ```java 194 | ProcessLifecycleOwner.get().getLifecycle().addObserver(new LifecycleObserver() { 195 | @OnLifecycleEvent(Lifecycle.Event.ON_STOP) 196 | public void onAppBackgrounded() { 197 | Log.d("Process", "App moved to background!"); 198 | } 199 | }); 200 | ``` 201 | 202 | --- 203 | 204 | # **📚 参考资料** 205 | 📌 **Android 进程管理** 206 | - `Zygote 进程`:[https://source.android.com/devices/tech/dalvik/zygote](https://source.android.com/devices/tech/dalvik/zygote) 207 | - `AMS 进程调度`:[https://developer.android.com/guide/components/activities/process-lifecycle](https://developer.android.com/guide/components/activities/process-lifecycle) 208 | 209 | 📌 **Android 逆向** 210 | - `Frida`:[https://frida.re](https://frida.re) 211 | - `Android 进程 Hook`:[https://github.com/lasting-yang/AndroidReverseStudy](https://github.com/lasting-yang/AndroidReverseStudy) 212 | 213 | --- 214 | 215 | 🔥 **任务完成后,你将掌握:** 216 | ✅ **Android 进程管理的核心机制** 217 | ✅ **如何查看 & 调试 Android 进程** 218 | ✅ **如何 Hook Android 进程管理,进行持久化与逆向分析** 219 | 220 | 🚀 **下一步(Day 12)**:**Android 权限机制解析!** 🎯 -------------------------------------------------------------------------------- /AndroidReverse101/第二阶段_APK逆向基础/Day_22_如何反编译_APK.md: -------------------------------------------------------------------------------- 1 | # **📜 Day 22: 如何反编译 APK** 2 | 3 | ## **📌 学习目标** 4 | ✅ **理解 Android APK 反编译的核心概念**,掌握不同的反编译工具和方法。 5 | ✅ **学习如何提取 `classes.dex` 并转换回 Java 代码**,掌握 `jadx`、`baksmali`、`dex2jar` 等工具。 6 | ✅ **掌握 `AndroidManifest.xml` 反编译、资源文件提取、Smali 代码分析**。 7 | ✅ **学习 APK 反编译后的修改技巧,包括绕过加密、修改逻辑、重打包**。 8 | ✅ **掌握 SO 共享库(Native 层)的反编译分析,使用 `IDA Pro` 和 `Ghidra` 进行逆向工程**。 9 | ✅ **实战:反编译 APK,提取 Java 代码,分析 SO 文件,修改逻辑,重新打包运行!** 10 | 11 | --- 12 | 13 | # **1️⃣ 什么是 APK 反编译?** 14 | APK 反编译是指将编译后的 APK 文件 **转换回可读代码**,从而: 15 | - 提取 Java 代码(`classes.dex` → `.java`)。 16 | - 查看资源文件(布局 XML、图片、字符串)。 17 | - 分析 `AndroidManifest.xml` 组件和权限信息。 18 | - 逆向分析 SO 共享库(ELF 文件),找出敏感逻辑和加密算法。 19 | - 修改 APP 逻辑,移除广告、破解 VIP 限制等。 20 | 21 | --- 22 | 23 | # **2️⃣ APK 反编译的三种方法** 24 | | **方法** | **适用场景** | **工具** | 25 | |---------|----------|------| 26 | | **Java 反编译** | 还原 Java 代码 | `jadx`, `dex2jar` | 27 | | **Smali 反编译** | 修改 Dalvik 字节码 | `apktool`, `smali` | 28 | | **Native 逆向** | 逆向分析 `.so` 文件 | `IDA Pro`, `Ghidra` | 29 | 30 | --- 31 | 32 | # **3️⃣ 提取 APK 代码** 33 | ## **✅ 1. 提取 APK** 34 | 📌 **获取已安装 APK** 35 | ```bash 36 | adb shell pm list packages | grep example 37 | adb shell pm path com.example.app 38 | adb pull /data/app/com.example.app-1/base.apk . 39 | ``` 40 | 41 | ## **✅ 2. 提取 `classes.dex`** 42 | ```bash 43 | unzip base.apk classes.dex 44 | ``` 45 | 46 | --- 47 | 48 | # **4️⃣ Java 代码反编译** 49 | ## **✅ 1. 使用 `jadx`** 50 | 📌 **安装 `jadx`** 51 | ```bash 52 | git clone https://github.com/skylot/jadx.git 53 | cd jadx 54 | ./gradlew dist 55 | ``` 56 | 📌 **反编译 DEX** 57 | ```bash 58 | jadx -d output/ base.apk 59 | ``` 60 | 📌 **查看反编译代码** 61 | ```bash 62 | cat output/com/example/MainActivity.java 63 | ``` 64 | 示例输出: 65 | ```java 66 | package com.example; 67 | 68 | public class MainActivity { 69 | public void onCreate() { 70 | System.out.println("Hello, Reverse Engineering!"); 71 | } 72 | } 73 | ``` 74 | 75 | --- 76 | 77 | ## **✅ 2. 使用 `dex2jar` + `JD-GUI`** 78 | 📌 **安装 `dex2jar`** 79 | ```bash 80 | wget https://github.com/pxb1988/dex2jar/releases/download/v2.0/dex-tools-2.0.zip 81 | unzip dex-tools-2.0.zip 82 | ``` 83 | 📌 **转换 DEX 为 JAR** 84 | ```bash 85 | ./d2j-dex2jar.sh classes.dex 86 | ``` 87 | 📌 **使用 JD-GUI 打开** 88 | ```bash 89 | jd-gui classes-dex2jar.jar 90 | ``` 91 | 92 | --- 93 | 94 | # **5️⃣ Smali 代码反编译** 95 | ## **✅ 1. 使用 `apktool`** 96 | 📌 **安装 `apktool`** 97 | ```bash 98 | wget https://raw.githubusercontent.com/iBotPeaches/Apktool/master/scripts/linux/apktool 99 | chmod +x apktool 100 | ``` 101 | 📌 **反编译 APK** 102 | ```bash 103 | apktool d base.apk -o output/ 104 | ``` 105 | 📌 **查看 Smali 代码** 106 | ```bash 107 | cat output/smali/com/example/MainActivity.smali 108 | ``` 109 | 示例: 110 | ```smali 111 | .method public onCreate()V 112 | .locals 1 113 | const-string v0, "Hello, Reverse Engineering!" 114 | invoke-static {v0}, Ljava/lang/System;->println(Ljava/lang/String;)V 115 | .end method 116 | ``` 117 | 118 | --- 119 | 120 | ## **✅ 2. 修改 Smali 代码** 121 | 📌 **修改 `MainActivity.smali`** 122 | ```smali 123 | .method public onCreate()V 124 | .locals 1 125 | const-string v0, "Hacked by Reverse Engineer!" 126 | invoke-static {v0}, Ljava/lang/System;->println(Ljava/lang/String;)V 127 | .end method 128 | ``` 129 | 📌 **重新打包** 130 | ```bash 131 | apktool b output -o modded.apk 132 | ``` 133 | 📌 **重新签名** 134 | ```bash 135 | jarsigner -verbose -keystore my.keystore modded.apk alias_name 136 | ``` 137 | 📌 **安装 APK** 138 | ```bash 139 | adb install modded.apk 140 | ``` 141 | 142 | --- 143 | 144 | # **6️⃣ 解析 SO 共享库(Native 层)** 145 | 📌 **提取 SO 文件** 146 | ```bash 147 | adb pull /data/data/com.example.app/lib/arm64/libnative.so . 148 | ``` 149 | 📌 **查看 ELF 结构** 150 | ```bash 151 | readelf -h libnative.so 152 | ``` 153 | 📌 **查看导出函数** 154 | ```bash 155 | nm -D libnative.so 156 | ``` 157 | 158 | --- 159 | 160 | ## **✅ 1. 使用 IDA Pro 分析 SO** 161 | 📌 **步骤** 162 | 1. **打开 IDA Pro** 163 | 2. **选择 `libnative.so` 并设置架构(ARM/ARM64)** 164 | 3. **分析代码,查找关键函数** 165 | 4. **查找字符串** 166 | - `Shift + F12` 查看所有字符串 167 | - `X` 查看交叉引用 168 | 169 | 📌 **示例** 170 | ```c 171 | if (strcmp(input, "SecretKey") == 0) { 172 | return "FLAG{IDA_NATIVE_REVERSE}"; 173 | } 174 | ``` 175 | **思路**:搜索 `"SecretKey"` 字符串,找到关键验证逻辑,修改二进制或 Hook 该函数。 176 | 177 | --- 178 | 179 | ## **✅ 2. 使用 Ghidra 反编译 SO** 180 | 📌 **步骤** 181 | 1. **打开 Ghidra** 182 | 2. **新建工程,导入 `libnative.so`** 183 | 3. **选择处理器架构(ARM/ARM64)** 184 | 4. **使用 `Decompiler` 还原 C 代码** 185 | 5. **查找 `strcmp()` 调用,分析逻辑** 186 | 187 | 📌 **示例** 188 | ```c 189 | bool check_password(char* input) { 190 | return strcmp(input, "SuperSecretKey") == 0; 191 | } 192 | ``` 193 | **思路**:可以使用 Frida 修改 `strcmp()` 返回值,实现绕过验证。 194 | 195 | --- 196 | 197 | ## **✅ 3. Hook SO 运行时修改代码** 198 | 📌 **Hook `check_password()`** 199 | ```js 200 | Java.perform(function() { 201 | var nativeFunc = Module.findExportByName("libnative.so", "check_password"); 202 | Interceptor.attach(nativeFunc, { 203 | onEnter: function(args) { 204 | console.log("check_password called!"); 205 | args[0] = ptr("HackedPassword"); 206 | } 207 | }); 208 | }); 209 | ``` 210 | 📌 **运行 Frida** 211 | ```bash 212 | frida -U -n com.example.app -e "..." 213 | ``` 214 | 215 | --- 216 | 217 | # **🛠 实战任务** 218 | ### **✅ 1. 提取 `classes.dex`** 219 | ```bash 220 | unzip base.apk classes.dex 221 | ``` 222 | ### **✅ 2. 反编译 Java** 223 | ```bash 224 | jadx -d output/ base.apk 225 | ``` 226 | ### **✅ 3. 反编译 Smali** 227 | ```bash 228 | apktool d base.apk -o output/ 229 | cat output/smali/com/example/MainActivity.smali 230 | ``` 231 | ### **✅ 4. 修改 VIP 方法** 232 | ```smali 233 | .method public isVIP()Z 234 | const/4 v0, 0x1 235 | return v0 236 | .end method 237 | ``` 238 | ### **✅ 5. 解析 SO** 239 | ```bash 240 | readelf -h libnative.so 241 | nm -D libnative.so 242 | ``` 243 | ### **✅ 6. 使用 IDA Pro 分析** 244 | - 打开 `libnative.so` 245 | - 查找 `strcmp()` 调用 246 | - 修改返回值 247 | 248 | --- 249 | 250 | # **📚 参考资料** 251 | 📌 **APK 反编译** 252 | - `IDA Pro`:[https://hex-rays.com/](https://hex-rays.com/) 253 | - `Ghidra`:[https://ghidra-sre.org/](https://ghidra-sre.org/) 254 | - `Frida`:[https://frida.re](https://frida.re) 255 | 256 | --- 257 | 258 | 🔥 **任务完成后,你将掌握:** 259 | ✅ **如何反编译 Java & Smali 代码** 260 | ✅ **如何逆向分析 Native SO 代码** 261 | ✅ **如何使用 IDA Pro、Frida Hook、Ghidra 进行逆向调试** 262 | 263 | 🚀 **下一步(Day 23)**:**DEX 文件结构解析!** 🎯 -------------------------------------------------------------------------------- /AndroidReverse101/第一阶段_计算机基础_逆向概论/Day_20_CTF_逆向挑战_初级.md: -------------------------------------------------------------------------------- 1 | # **📜 Day 20: CTF 逆向挑战(初级)** 2 | 3 | ## **📌 学习目标** 4 | ✅ **理解 CTF 逆向工程基本概念**,掌握常见 CTF 逆向题型(CrackMe、Reversing、PWN)。 5 | ✅ **学习如何分析 ELF 可执行文件、Android APK、Native 共享库(.so)**。 6 | ✅ **掌握静态分析(IDA Pro, Ghidra, Radare2)和动态调试(GDB, Frida)的方法**。 7 | ✅ **熟练掌握 CTF 中的常见逆向技巧,如字符串加密、反调试、动态 Hook**。 8 | ✅ **实战:编写并破解自己的 CTF 逆向题目,分析加密算法并获取 flag!** 9 | 10 | --- 11 | 12 | # **1️⃣ 什么是 CTF 逆向挑战?** 13 | CTF(Capture The Flag)是一种信息安全竞赛,其中 **逆向工程(Reversing)** 是常见题型之一。 14 | CTF 逆向主要包括: 15 | - **CrackMe**:分析二进制程序的认证逻辑,绕过密码检查,找到 flag。 16 | - **PWN(漏洞利用)**:分析缓冲区溢出、格式化字符串漏洞等。 17 | - **Android Reversing**:分析 APK、DEX、JNI、Hook 代码,绕过验证或提取敏感数据。 18 | 19 | 本章节提供多个 **CrackMe 题目的源代码**,用户可自行编译 **ELF / APK / SO** 文件, 20 | 练习 **逆向分析、绕过密码验证、解密 flag** 等技能,并提供 **解题思路**。 21 | 22 | --- 23 | 24 | # **2️⃣ ELF CrackMe 逆向挑战** 25 | ## **✅ CrackMe 1 - 简单字符串检查** 26 | 📌 **CrackMe 源代码** 27 | ```c 28 | #include 29 | #include 30 | 31 | void check_password(char *input) { 32 | if (strcmp(input, "SuperSecret123") == 0) { 33 | printf("Correct! Flag is FLAG{ELF_REVERSE_101}\n"); 34 | } else { 35 | printf("Wrong password!\n"); 36 | } 37 | } 38 | 39 | int main() { 40 | char password[32]; 41 | printf("Enter password: "); 42 | scanf("%s", password); 43 | check_password(password); 44 | return 0; 45 | } 46 | ``` 47 | 📌 **编译 ELF** 48 | ```bash 49 | gcc -o crackme1 crackme1.c 50 | ``` 51 | 📌 **解题思路** 52 | 1. **静态分析**: 53 | ```bash 54 | strings crackme1 55 | ``` 56 | 可能输出: 57 | ``` 58 | Enter password: 59 | Wrong password! 60 | Correct! Flag is FLAG{ELF_REVERSE_101} 61 | ``` 62 | 直接获取 flag,无需运行程序。 63 | 64 | 2. **动态调试**: 65 | ```bash 66 | gdb ./crackme1 67 | break check_password 68 | run 69 | ``` 70 | 在 `check_password` 处设置断点,修改输入参数绕过密码检查。 71 | 72 | 📌 **Flag** 73 | ``` 74 | FLAG{ELF_REVERSE_101} 75 | ``` 76 | 77 | --- 78 | 79 | ## **✅ CrackMe 2 - XOR 加密** 80 | 📌 **CrackMe 源代码** 81 | ```c 82 | #include 83 | #include 84 | 85 | void decrypt(char *input) { 86 | char key = 0x55; 87 | char flag[] = {0x12, 0x36, 0x71, 0x55, 0x47, 0x00}; // XOR 加密后的 FLAG 88 | 89 | for (int i = 0; i < strlen(flag); i++) { 90 | flag[i] ^= key; 91 | } 92 | 93 | if (strcmp(input, flag) == 0) { 94 | printf("Correct! Flag is %s\n", flag); 95 | } else { 96 | printf("Wrong password!\n"); 97 | } 98 | } 99 | 100 | int main() { 101 | char password[32]; 102 | printf("Enter password: "); 103 | scanf("%s", password); 104 | decrypt(password); 105 | return 0; 106 | } 107 | ``` 108 | 📌 **编译 ELF** 109 | ```bash 110 | gcc -o crackme2 crackme2.c 111 | ``` 112 | 📌 **解题思路** 113 | 1. **静态分析**: 114 | ```bash 115 | objdump -d crackme2 | less 116 | ``` 117 | 找到 `XOR` 加密部分,发现密钥 `0x55`。 118 | 119 | 2. **Python 解密** 120 | ```python 121 | key = 0x55 122 | cipher = [0x12, 0x36, 0x71, 0x55, 0x47] 123 | print("".join(chr(c ^ key) for c in cipher)) 124 | ``` 125 | 输出: 126 | ``` 127 | FLAG{XOR_BYPASS} 128 | ``` 129 | 130 | 📌 **Flag** 131 | ``` 132 | FLAG{XOR_BYPASS} 133 | ``` 134 | 135 | --- 136 | 137 | # **3️⃣ Android CrackMe 逆向挑战** 138 | ## **✅ Java CrackMe** 139 | 📌 **CrackMe Java 代码** 140 | ```java 141 | package com.example.crackme; 142 | 143 | import android.app.Activity; 144 | import android.os.Bundle; 145 | import android.widget.Button; 146 | import android.widget.EditText; 147 | import android.widget.Toast; 148 | 149 | public class MainActivity extends Activity { 150 | @Override 151 | protected void onCreate(Bundle savedInstanceState) { 152 | super.onCreate(savedInstanceState); 153 | setContentView(R.layout.activity_main); 154 | 155 | EditText input = findViewById(R.id.password); 156 | Button checkBtn = findViewById(R.id.check_btn); 157 | 158 | checkBtn.setOnClickListener(v -> { 159 | String userInput = input.getText().toString(); 160 | if (userInput.equals("SuperSecret123")) { 161 | Toast.makeText(this, "Correct! Flag is FLAG{ANDROID_REVERSE}", Toast.LENGTH_LONG).show(); 162 | } else { 163 | Toast.makeText(this, "Wrong password!", Toast.LENGTH_LONG).show(); 164 | } 165 | }); 166 | } 167 | } 168 | ``` 169 | 📌 **解题思路** 170 | 1. **反编译 APK** 171 | ```bash 172 | apktool d crackme.apk -o output/ 173 | ``` 174 | 2. **查找密码** 175 | ```bash 176 | grep -r "SuperSecret123" output/ 177 | ``` 178 | 找到硬编码密码: 179 | ``` 180 | "SuperSecret123" 181 | ``` 182 | 3. **输入该密码获取 flag** 183 | 184 | 📌 **Flag** 185 | ``` 186 | FLAG{ANDROID_REVERSE} 187 | ``` 188 | 189 | --- 190 | 191 | ## **✅ JNI CrackMe** 192 | 📌 **CrackMe JNI 代码** 193 | ```c 194 | #include 195 | #include 196 | 197 | JNIEXPORT jstring JNICALL 198 | Java_com_example_crackme_NativeLib_check(JNIEnv *env, jobject thiz, jstring input) { 199 | const char *user_input = (*env)->GetStringUTFChars(env, input, 0); 200 | if (strcmp(user_input, "SecretJNI") == 0) { 201 | return (*env)->NewStringUTF(env, "Correct! Flag is FLAG{JNI_BYPASS}"); 202 | } 203 | return (*env)->NewStringUTF(env, "Wrong password!"); 204 | } 205 | ``` 206 | 📌 **解题思路** 207 | 1. **提取 SO** 208 | ```bash 209 | adb pull /data/data/com.example.crackme/lib/arm64/libnative.so . 210 | ``` 211 | 2. **反编译** 212 | ```bash 213 | strings libnative.so | grep FLAG 214 | ``` 215 | 找到: 216 | ``` 217 | FLAG{JNI_BYPASS} 218 | ``` 219 | 220 | 📌 **Flag** 221 | ``` 222 | FLAG{JNI_BYPASS} 223 | ``` 224 | 225 | --- 226 | 227 | # **🛠 实战任务** 228 | ### **✅ 1. 编译并破解 ELF** 229 | ```bash 230 | gcc -o crackme1 crackme1.c 231 | gdb ./crackme1 232 | ``` 233 | ### **✅ 2. 破解 APK** 234 | ```bash 235 | apktool d app-debug.apk -o output/ 236 | grep -r "SuperSecret123" output/ 237 | ``` 238 | ### **✅ 3. Hook JNI** 239 | ```js 240 | Java.perform(function() { 241 | var nativeMethod = Module.findExportByName("libnative.so", "Java_com_example_crackme_NativeLib_check"); 242 | Interceptor.attach(nativeMethod, { 243 | onEnter: function(args) { 244 | console.log("JNI check() called!"); 245 | } 246 | }); 247 | }); 248 | ``` 249 | 250 | --- 251 | 252 | 🔥 **任务完成后,你将掌握:** 253 | ✅ **如何编写 & 逆向 ELF / APK / SO** 254 | ✅ **如何绕过密码验证,修改二进制逻辑** 255 | ✅ **如何使用 Frida/GDB Hook 关键函数** 256 | 257 | 🚀 **下一步(Day 21)**:**APK 文件结构解析!** 🎯 -------------------------------------------------------------------------------- /AndroidReverse101/第二阶段_APK逆向基础/Day_21_APK_文件结构解析.md: -------------------------------------------------------------------------------- 1 | # **📜 Day 21: APK 文件结构解析** 2 | 3 | ## **📌 学习目标** 4 | ✅ **深入理解 APK 文件的结构**,掌握各个组件的作用和解析方法。 5 | ✅ **学习如何使用 `apktool`、`jadx`、`aapt` 解析 APK,查看 AndroidManifest.xml、DEX 文件、资源文件等。** 6 | ✅ **掌握 APK 反编译与重打包技术,学习如何修改代码、绕过安全机制。** 7 | ✅ **分析 `AndroidManifest.xml` 权限声明、入口 Activity、组件结构。** 8 | ✅ **实战:手动拆解 APK,提取 `classes.dex`,反编译 Java 代码,修改资源文件。** 9 | 10 | --- 11 | 12 | # **1️⃣ 什么是 APK 文件?** 13 | APK(Android Package)是 Android 应用的安装包,**本质上是一个 ZIP 压缩包**,包含所有 **应用代码、资源、配置文件**。 14 | 15 | 📌 **查看 APK 文件结构** 16 | ```bash 17 | unzip -l app.apk 18 | ``` 19 | 示例输出: 20 | ``` 21 | Archive: app.apk 22 | Length Date Time Name 23 | --------- ---------- ----- ---- 24 | 123456 2024-02-22 12:34 AndroidManifest.xml 25 | 234567 2024-02-22 12:34 classes.dex 26 | 345678 2024-02-22 12:34 lib/arm64-v8a/libnative.so 27 | 456789 2024-02-22 12:34 res/ 28 | 567890 2024-02-22 12:34 META-INF/ 29 | ``` 30 | --- 31 | 32 | # **2️⃣ APK 主要结构解析** 33 | | **文件** | **作用** | 34 | |---------|---------| 35 | | **AndroidManifest.xml** | 应用的核心配置文件(权限、组件、入口点) | 36 | | **classes.dex** | Dalvik Executable 文件(应用的字节码) | 37 | | **lib/** | 存放 `*.so` 共享库(C/C++ 编写的 Native 代码) | 38 | | **res/** | 存放图片、布局、字符串等资源 | 39 | | **META-INF/** | 存放签名、证书信息 | 40 | | **assets/** | 存放未编译的资源,如字体、数据库、配置文件 | 41 | | **resources.arsc** | 存放资源 ID,优化后的资源文件 | 42 | 43 | --- 44 | 45 | # **3️⃣ 解析 AndroidManifest.xml** 46 | AndroidManifest.xml 是 **Android 应用的配置文件**,包含: 47 | - **应用权限** 48 | - **四大组件(Activity、Service、BroadcastReceiver、ContentProvider)** 49 | - **入口 Activity** 50 | - **签名信息** 51 | 52 | 📌 **使用 `aapt` 查看 Manifest** 53 | ```bash 54 | aapt dump badging app.apk 55 | ``` 56 | 示例输出: 57 | ``` 58 | package: name='com.example.app' versionCode='1' versionName='1.0' 59 | sdkVersion:'29' 60 | targetSdkVersion:'33' 61 | launchable-activity: name='com.example.MainActivity' 62 | uses-permission: name='android.permission.INTERNET' 63 | ``` 64 | 65 | 📌 **使用 `apktool` 反编译 Manifest** 66 | ```bash 67 | apktool d app.apk -o output/ 68 | cat output/AndroidManifest.xml 69 | ``` 70 | 示例: 71 | ```xml 72 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | ``` 85 | 86 | --- 87 | 88 | # **4️⃣ 解析 DEX(Dalvik Executable)** 89 | DEX 文件是 **Android 虚拟机(ART/Dalvik)执行的字节码**,存放 Java 代码编译后的可执行文件。 90 | 91 | 📌 **提取 DEX** 92 | ```bash 93 | unzip app.apk classes.dex 94 | ``` 95 | 📌 **使用 `jadx` 反编译 DEX** 96 | ```bash 97 | jadx -d output/ classes.dex 98 | ``` 99 | 📌 **查看 DEX 结构** 100 | ```bash 101 | dexdump classes.dex | less 102 | ``` 103 | 📌 **反编译 Java 代码** 104 | ```bash 105 | jadx -d output/ app.apk 106 | ``` 107 | 打开 `output/com/example/MainActivity.java`,可以看到: 108 | ```java 109 | package com.example; 110 | 111 | public class MainActivity { 112 | public void onCreate() { 113 | System.out.println("Hello, Android Reverse Engineering!"); 114 | } 115 | } 116 | ``` 117 | 118 | --- 119 | 120 | # **5️⃣ 解析 Native 共享库(lib/*.so)** 121 | 某些 APK **包含 C/C++ 代码**,存放于 `lib/` 目录下。 122 | 123 | 📌 **查看 SO 文件** 124 | ```bash 125 | file lib/arm64-v8a/libnative.so 126 | ``` 127 | 示例输出: 128 | ``` 129 | libnative.so: ELF 64-bit LSB shared object, ARM aarch64 130 | ``` 131 | 📌 **反编译 SO** 132 | ```bash 133 | strings lib/arm64-v8a/libnative.so | less 134 | ``` 135 | 📌 **Hook SO** 136 | ```js 137 | Java.perform(function() { 138 | var nativeFunc = Module.findExportByName("libnative.so", "native_func"); 139 | Interceptor.attach(nativeFunc, { 140 | onEnter: function(args) { 141 | console.log("native_func called!"); 142 | } 143 | }); 144 | }); 145 | ``` 146 | 147 | --- 148 | 149 | # **6️⃣ 修改 APK 并重新打包** 150 | ## **✅ 1. 修改资源文件** 151 | 📌 **替换 APP 图标** 152 | ```bash 153 | cp new_icon.png output/res/drawable/ic_launcher.png 154 | ``` 155 | 📌 **修改 APP 名称** 156 | 编辑 `output/res/values/strings.xml`: 157 | ```xml 158 | Hacked App 159 | ``` 160 | 161 | ## **✅ 2. 修改 Java 代码** 162 | 📌 **反编译并修改 `MainActivity.java`** 163 | ```java 164 | public void onCreate() { 165 | System.out.println("Hacked App Launched!"); 166 | } 167 | ``` 168 | 169 | ## **✅ 3. 重新打包** 170 | ```bash 171 | apktool b output -o modded.apk 172 | ``` 173 | 174 | ## **✅ 4. 重新签名** 175 | ```bash 176 | jarsigner -verbose -keystore my.keystore modded.apk alias_name 177 | ``` 178 | 179 | ## **✅ 5. 安装 APK** 180 | ```bash 181 | adb install modded.apk 182 | ``` 183 | 184 | --- 185 | 186 | # **🛠 实战任务** 187 | ### **✅ 1. 提取 DEX** 188 | ```bash 189 | unzip app.apk classes.dex 190 | ``` 191 | ### **✅ 2. 反编译 Java** 192 | ```bash 193 | jadx -d output/ app.apk 194 | ``` 195 | ### **✅ 3. 查看 AndroidManifest.xml** 196 | ```bash 197 | apktool d app.apk -o output/ 198 | cat output/AndroidManifest.xml 199 | ``` 200 | ### **✅ 4. Hook SO** 201 | ```js 202 | Java.perform(function() { 203 | var nativeFunc = Module.findExportByName("libnative.so", "native_func"); 204 | Interceptor.attach(nativeFunc, { 205 | onEnter: function(args) { 206 | console.log("native_func called!"); 207 | } 208 | }); 209 | }); 210 | ``` 211 | ### **✅ 5. 修改并重新打包** 212 | ```bash 213 | apktool b output -o modded.apk 214 | ``` 215 | ### **✅ 6. 重新签名** 216 | ```bash 217 | jarsigner -verbose -keystore my.keystore modded.apk alias_name 218 | ``` 219 | ### **✅ 7. 安装修改后的 APK** 220 | ```bash 221 | adb install modded.apk 222 | ``` 223 | 224 | --- 225 | 226 | # **📚 参考资料** 227 | 📌 **APK 解析** 228 | - `APKTool`:[https://github.com/iBotPeaches/Apktool](https://github.com/iBotPeaches/Apktool) 229 | - `AAPT`:[https://developer.android.com/studio/command-line/aapt2](https://developer.android.com/studio/command-line/aapt2) 230 | 231 | 📌 **DEX 解析** 232 | - `JADX`:[https://github.com/skylot/jadx](https://github.com/skylot/jadx) 233 | - `smali 代码反编译`:[https://github.com/JesusFreke/smali](https://github.com/JesusFreke/smali) 234 | 235 | 📌 **Native 逆向** 236 | - `Frida`:[https://frida.re](https://frida.re) 237 | - `Ghidra`:[https://ghidra-sre.org/](https://ghidra-sre.org/) 238 | 239 | --- 240 | 241 | 🔥 **任务完成后,你将掌握:** 242 | ✅ **如何解析 APK 文件,分析 Android 代码、资源、Manifest** 243 | ✅ **如何修改 APK 资源、Java 代码,并重新打包** 244 | ✅ **如何 Hook Native SO 文件,修改程序逻辑** 245 | 246 | 🚀 **下一步(Day 22)**:**如何反编译 DEX 文件!** 🎯 -------------------------------------------------------------------------------- /AndroidReverse101/第一阶段_计算机基础_逆向概论/Day_19_Android_APP_安全机制.md: -------------------------------------------------------------------------------- 1 | # **📜 Day 19: Android APP 安全机制** 2 | 3 | ## **📌 学习目标** 4 | ✅ **理解 Android 安全机制**,包括 **应用沙盒(Sandbox)、SELinux、签名验证、Root 检测** 等。 5 | ✅ **掌握 Android APP 代码保护方式**,如 **混淆(ProGuard)、加固、动态调试检测**。 6 | ✅ **学习 Android 存储安全**,避免 **数据泄露(SharedPreferences、SQLite、文件存储)**。 7 | ✅ **掌握动态分析技巧**,绕过 **Root 检测、反调试、加固保护**,提高逆向能力。 8 | ✅ **实战:分析并绕过 Android APP 的安全防护**。 9 | 10 | --- 11 | 12 | # **1️⃣ Android 应用沙盒(Sandbox)** 13 | **🔹 什么是应用沙盒?** 14 | - 每个 Android APP 运行在 **独立的 Linux 进程** 中,具有 **独立的 UID/GID**。 15 | - **不同应用的文件、数据、进程默认不能互相访问**。 16 | 17 | 📌 **查看某应用的 UID** 18 | ```bash 19 | adb shell dumpsys package com.example.app | grep userId= 20 | ``` 21 | 示例输出: 22 | ``` 23 | userId=10123 24 | ``` 25 | 👉 **每个 APP 都有唯一的 UID,防止数据泄露。** 26 | 27 | 📌 **尝试访问其他 APP 目录** 28 | ```bash 29 | adb shell ls /data/data/com.other.app/ 30 | ``` 31 | **如果未 Root,访问会被拒绝!** 32 | 33 | --- 34 | 35 | # **2️⃣ SELinux(强制访问控制)** 36 | SELinux(Security-Enhanced Linux)用于限制 **进程间通信、访问系统资源**。 37 | 38 | 📌 **查看 SELinux 状态** 39 | ```bash 40 | adb shell getenforce 41 | ``` 42 | 示例输出: 43 | ``` 44 | Enforcing # 说明 SELinux 已启用 45 | ``` 46 | 📌 **禁用 SELinux(Root 权限)** 47 | ```bash 48 | adb shell setenforce 0 49 | ``` 50 | 51 | 📌 **查看 SELinux 拒绝的访问** 52 | ```bash 53 | adb shell dmesg | grep avc 54 | ``` 55 | 56 | --- 57 | 58 | # **3️⃣ Android 签名验证** 59 | Android APP 在安装时需要 **数字签名** 以确保应用完整性。 60 | 61 | 📌 **检查 APK 签名** 62 | ```bash 63 | apksigner verify --print-certs app.apk 64 | ``` 65 | 示例输出: 66 | ``` 67 | Signer #1 certificate DN: CN=Developer, O=Example Corp, C=US 68 | ``` 69 | 📌 **绕过签名校验** 70 | 在 `AndroidManifest.xml` 添加: 71 | ```xml 72 | 73 | ``` 74 | 然后重新签名: 75 | ```bash 76 | zipalign -v 4 modded.apk aligned.apk 77 | apksigner sign --ks my.keystore --out signed.apk aligned.apk 78 | adb install signed.apk 79 | ``` 80 | 81 | --- 82 | 83 | # **4️⃣ Root 检测** 84 | 许多应用 **检测设备是否 Root** 以防止被逆向分析。 85 | 86 | 📌 **常见 Root 检测方法** 87 | 1. **检查 su** 88 | ```java 89 | File f = new File("/system/bin/su"); 90 | if (f.exists()) { 91 | Log.d("RootCheck", "Device is Rooted!"); 92 | } 93 | ``` 94 | 95 | 2. **检测 Root 进程** 96 | ```bash 97 | adb shell ps -A | grep magiskd 98 | ``` 99 | 示例输出: 100 | ``` 101 | magiskd 1023 567 123456K fg 00000000 S magiskd 102 | ``` 103 | 104 | 📌 **绕过 Root 检测** 105 | **使用 Frida Hook `File.exists()`** 106 | ```js 107 | Java.perform(function() { 108 | var File = Java.use("java.io.File"); 109 | File.exists.implementation = function() { 110 | return false; 111 | }; 112 | }); 113 | ``` 114 | 115 | 📌 **执行 Frida** 116 | ```bash 117 | frida -U -n com.example.app -e "..." 118 | ``` 119 | 120 | --- 121 | 122 | # **5️⃣ 代码混淆 & 加固** 123 | ### **✅ 1. ProGuard 混淆** 124 | ```proguard 125 | -dontobfuscate 126 | -keep class com.example.** { *; } 127 | ``` 128 | 📌 **反混淆 DEX** 129 | ```bash 130 | jadx -d output/ app.apk 131 | ``` 132 | 133 | ### **✅ 2. 加固** 134 | 加固(如 `360加固`, `腾讯加固`)用于 **隐藏代码逻辑,防止逆向**。 135 | 136 | 📌 **检查 APK 是否加固** 137 | ```bash 138 | unzip -l app.apk | grep classes 139 | ``` 140 | 如果 `classes.dex` 被拆分或替换,则 **APK 可能被加固**。 141 | 142 | 📌 **绕过加固(Frida Dump DEX)** 143 | ```bash 144 | frida -U -n com.example.app -e "Java.perform(function() { 145 | Java.use('dalvik.system.BaseDexClassLoader').loadClass.implementation = function(name) { 146 | console.log('Load Class: ' + name); 147 | }; 148 | });" 149 | ``` 150 | 151 | --- 152 | 153 | # **6️⃣ Android 存储安全** 154 | ### **✅ 1. 避免明文存储** 155 | ❌ **不安全** 156 | ```java 157 | SharedPreferences prefs = getSharedPreferences("settings", MODE_PRIVATE); 158 | prefs.edit().putString("password", "123456").apply(); 159 | ``` 160 | 📌 **查看存储数据** 161 | ```bash 162 | adb shell cat /data/data/com.example.app/shared_prefs/settings.xml 163 | ``` 164 | **✅ 解决方案:使用加密存储** 165 | ```java 166 | EncryptedSharedPreferences encryptedPrefs = EncryptedSharedPreferences.create( 167 | "settings", 168 | MasterKeys.getOrCreate(MasterKeys.AES256_GCM_SPEC), 169 | context, 170 | EncryptedSharedPreferences.PrefKeyEncryptionScheme.AES256_SIV, 171 | EncryptedSharedPreferences.PrefValueEncryptionScheme.AES256_GCM 172 | ); 173 | encryptedPrefs.edit().putString("password", "123456").apply(); 174 | ``` 175 | 176 | --- 177 | 178 | # **7️⃣ 逆向绕过安全机制** 179 | ## **✅ 1. 绕过 Root 检测** 180 | ```js 181 | Java.perform(function() { 182 | var File = Java.use("java.io.File"); 183 | File.exists.implementation = function() { 184 | return false; 185 | }; 186 | }); 187 | ``` 188 | 189 | ## **✅ 2. 绕过反调试** 190 | ```js 191 | Java.perform(function() { 192 | var Debug = Java.use("android.os.Debug"); 193 | Debug.isDebuggerConnected.implementation = function() { 194 | return false; 195 | }; 196 | }); 197 | ``` 198 | 199 | ## **✅ 3. Dump DEX** 200 | ```js 201 | Java.perform(function() { 202 | var DexClassLoader = Java.use("dalvik.system.DexClassLoader"); 203 | DexClassLoader.loadClass.implementation = function(name) { 204 | console.log("Hooked Dex Load: " + name); 205 | return this.loadClass(name); 206 | }; 207 | }); 208 | ``` 209 | 210 | --- 211 | 212 | # **🛠 实战任务** 213 | ### **✅ 1. 检查应用的 UID** 214 | ```bash 215 | adb shell dumpsys package com.example.app | grep userId= 216 | ``` 217 | ### **✅ 2. 禁用 SELinux** 218 | ```bash 219 | adb shell setenforce 0 220 | ``` 221 | ### **✅ 3. Hook `File.exists()` 绕过 Root 检测** 222 | ```js 223 | Java.perform(function() { 224 | var File = Java.use("java.io.File"); 225 | File.exists.implementation = function() { 226 | return false; 227 | }; 228 | }); 229 | ``` 230 | ### **✅ 4. Dump DEX** 231 | ```js 232 | Java.perform(function() { 233 | var DexClassLoader = Java.use("dalvik.system.DexClassLoader"); 234 | DexClassLoader.loadClass.implementation = function(name) { 235 | console.log("Hooked Dex Load: " + name); 236 | return this.loadClass(name); 237 | }; 238 | }); 239 | ``` 240 | 241 | --- 242 | 243 | # **📚 参考资料** 244 | 📌 **Android 安全机制** 245 | - `SELinux`:[https://source.android.com/security/selinux](https://source.android.com/security/selinux) 246 | - `ProGuard`:[https://developer.android.com/studio/build/shrink-code](https://developer.android.com/studio/build/shrink-code) 247 | - `Android 签名机制`:[https://developer.android.com/studio/publish/app-signing](https://developer.android.com/studio/publish/app-signing) 248 | 249 | 📌 **逆向分析** 250 | - `Frida`:[https://frida.re](https://frida.re) 251 | - `Xposed Hook 教程`:[https://github.com/rovo89/XposedBridge](https://github.com/rovo89/XposedBridge) 252 | 253 | --- 254 | 255 | 🔥 **任务完成后,你将掌握:** 256 | ✅ **Android 沙盒机制、SELinux、安全存储方法** 257 | ✅ **如何绕过 Root 检测、签名校验、反调试** 258 | ✅ **如何 Dump DEX、分析代码混淆与加固** 259 | 260 | 🚀 **下一步(Day 20)**:**CTF 逆向挑战(初级)!** 🎯 -------------------------------------------------------------------------------- /AndroidReverse101/第二阶段_APK逆向基础/Day_28_使用_Frida_Hook_Java_方法.md: -------------------------------------------------------------------------------- 1 | # **📜 Day 28: 使用 Frida Hook Java 方法** 2 | 3 | ## **📌 学习目标** 4 | ✅ **掌握 Frida Hook Java 方法的基本原理**,实现动态修改应用行为。 5 | ✅ **学习如何 Hook Java 方法,修改返回值、打印函数参数、绕过安全校验。** 6 | ✅ **掌握 `Java.use`、`Java.choose`、`Interceptor.attach` 等 Frida API 进行 Hook**。 7 | ✅ **学习如何动态修改应用逻辑,如绕过 VIP 认证、拦截网络请求、查看敏感数据。** 8 | ✅ **实战:使用 Frida Hook Android 方法,动态修改应用逻辑!** 9 | 10 | --- 11 | 12 | # **1️⃣ 什么是 Frida Hook?** 13 | Frida 是一种 **动态调试工具**,可用于 **Hook Java / Native 方法**,修改应用逻辑。 14 | Frida 允许 **在应用运行时注入代码**,拦截方法调用,甚至 **修改方法参数 & 返回值**。 15 | 16 | 📌 **常见 Hook 场景** 17 | - **绕过 VIP 认证**(`isVIP()` 方法) 18 | - **绕过登录校验**(修改 `checkLogin()` 方法) 19 | - **拦截网络请求**(修改 `HttpURLConnection` 方法) 20 | - **解密数据**(Hook `decrypt()` 方法) 21 | 22 | --- 23 | 24 | # **2️⃣ 安装 & 运行 Frida** 25 | ## **✅ 1. 安装 Frida** 26 | 📌 **在 PC 端安装 Frida** 27 | ```bash 28 | pip install frida 29 | pip install frida-tools 30 | ``` 31 | 📌 **在 Android 设备上安装 Frida Server** 32 | ```bash 33 | adb push frida-server /data/local/tmp/ 34 | adb shell chmod +x /data/local/tmp/frida-server 35 | adb shell /data/local/tmp/frida-server & 36 | ``` 37 | 📌 **确认 Frida 运行正常** 38 | ```bash 39 | frida -U -n com.example.app 40 | ``` 41 | --- 42 | 43 | # **3️⃣ Hook Java 方法** 44 | ## **✅ 1. Hook `isVIP()` 绕过会员认证** 45 | 📌 **原始 Java 代码** 46 | ```java 47 | public boolean isVIP() { 48 | return false; 49 | } 50 | ``` 51 | 📌 **Frida Hook** 52 | ```js 53 | Java.perform(function() { 54 | var MainActivity = Java.use("com.example.MainActivity"); 55 | MainActivity.isVIP.implementation = function() { 56 | console.log("[*] Hooked isVIP(), returning true"); 57 | return true; 58 | }; 59 | }); 60 | ``` 61 | 📌 **运行 Frida** 62 | ```bash 63 | frida -U -n com.example.app -e "..." 64 | ``` 65 | 66 | --- 67 | 68 | ## **✅ 2. Hook `checkLogin()` 绕过登录验证** 69 | 📌 **原始 Java 代码** 70 | ```java 71 | public boolean checkLogin(String username, String password) { 72 | return username.equals("admin") && password.equals("123456"); 73 | } 74 | ``` 75 | 📌 **Frida Hook** 76 | ```js 77 | Java.perform(function() { 78 | var Auth = Java.use("com.example.Auth"); 79 | Auth.checkLogin.implementation = function(username, password) { 80 | console.log("[*] Intercepted login attempt - Username: " + username + ", Password: " + password); 81 | return true; 82 | }; 83 | }); 84 | ``` 85 | 📌 **运行 Frida** 86 | ```bash 87 | frida -U -n com.example.app -e "..." 88 | ``` 89 | 90 | --- 91 | 92 | ## **✅ 3. Hook 网络请求** 93 | 📌 **原始 Java 代码** 94 | ```java 95 | URL url = new URL("https://api.example.com"); 96 | HttpURLConnection conn = (HttpURLConnection) url.openConnection(); 97 | ``` 98 | 📌 **Frida Hook** 99 | ```js 100 | Java.perform(function() { 101 | var URL = Java.use("java.net.URL"); 102 | URL.openConnection.implementation = function() { 103 | console.log("[*] Intercepted HTTP request to: " + this.toString()); 104 | return this.openConnection(); 105 | }; 106 | }); 107 | ``` 108 | 109 | --- 110 | 111 | ## **✅ 4. Hook AES 解密** 112 | 📌 **原始 Java 代码** 113 | ```java 114 | public String decrypt(String ciphertext) { 115 | return AES.decrypt(ciphertext, "secret_key"); 116 | } 117 | ``` 118 | 📌 **Frida Hook** 119 | ```js 120 | Java.perform(function() { 121 | var Crypto = Java.use("com.example.Crypto"); 122 | Crypto.decrypt.implementation = function(ciphertext) { 123 | console.log("[*] Intercepted decryption - Ciphertext: " + ciphertext); 124 | var result = this.decrypt(ciphertext); 125 | console.log("[*] Decryption result: " + result); 126 | return result; 127 | }; 128 | }); 129 | ``` 130 | 📌 **运行 Frida** 131 | ```bash 132 | frida -U -n com.example.app -e "..." 133 | ``` 134 | 135 | --- 136 | 137 | # **4️⃣ 遍历 Java 类 & 方法** 138 | 📌 **查找 Java 类** 139 | ```js 140 | Java.enumerateLoadedClasses({ 141 | onMatch: function(className) { 142 | console.log(className); 143 | }, 144 | onComplete: function() { 145 | console.log("Done!"); 146 | } 147 | }); 148 | ``` 149 | 📌 **查找方法** 150 | ```js 151 | Java.perform(function() { 152 | var MainActivity = Java.use("com.example.MainActivity"); 153 | console.log(MainActivity.class.getDeclaredMethods()); 154 | }); 155 | ``` 156 | 157 | --- 158 | 159 | # **5️⃣ 绕过反 Hook 机制** 160 | 部分应用有 **Frida 检测 & 反 Hook 机制**,常见绕过方式: 161 | - **Hook `detectFrida()`** 162 | - **Hook `ptrace()` 反调试** 163 | - **Patch `Frida` 检测代码** 164 | 165 | 📌 **Hook `detectFrida()`** 166 | ```js 167 | Java.perform(function() { 168 | var AntiFrida = Java.use("com.example.AntiFrida"); 169 | AntiFrida.detectFrida.implementation = function() { 170 | console.log("[*] Bypassing Frida detection"); 171 | return false; 172 | }; 173 | }); 174 | ``` 175 | 176 | 📌 **Hook `ptrace()` 反调试** 177 | ```js 178 | Interceptor.attach(Module.findExportByName(null, "ptrace"), { 179 | onEnter: function(args) { 180 | console.log("[*] Bypassing ptrace anti-debugging"); 181 | args[0] = 0; 182 | } 183 | }); 184 | ``` 185 | 186 | --- 187 | 188 | # **🛠 实战任务** 189 | ### **✅ 1. Hook `isVIP()`** 190 | ```js 191 | Java.perform(function() { 192 | var MainActivity = Java.use("com.example.MainActivity"); 193 | MainActivity.isVIP.implementation = function() { 194 | return true; 195 | }; 196 | }); 197 | ``` 198 | ### **✅ 2. Hook `checkLogin()`** 199 | ```js 200 | Java.perform(function() { 201 | var Auth = Java.use("com.example.Auth"); 202 | Auth.checkLogin.implementation = function(username, password) { 203 | return true; 204 | }; 205 | }); 206 | ``` 207 | ### **✅ 3. Hook AES 解密** 208 | ```js 209 | Java.perform(function() { 210 | var Crypto = Java.use("com.example.Crypto"); 211 | Crypto.decrypt.implementation = function(ciphertext) { 212 | console.log("[*] Decryption result: " + this.decrypt(ciphertext)); 213 | return this.decrypt(ciphertext); 214 | }; 215 | }); 216 | ``` 217 | ### **✅ 4. 绕过 Frida 检测** 218 | ```js 219 | Java.perform(function() { 220 | var AntiFrida = Java.use("com.example.AntiFrida"); 221 | AntiFrida.detectFrida.implementation = function() { 222 | return false; 223 | }; 224 | }); 225 | ``` 226 | ### **✅ 5. 运行 Frida** 227 | ```bash 228 | frida -U -n com.example.app -e "..." 229 | ``` 230 | 231 | --- 232 | 233 | # **📚 参考资料** 234 | 📌 **Frida 官方文档** 235 | - `Frida`:[https://frida.re](https://frida.re) 236 | 237 | 📌 **Frida Hook 教程** 238 | - `Android Hook 教程`:[https://www.androidreversing.com/](https://www.androidreversing.com/) 239 | 240 | 📌 **绕过 Frida 检测** 241 | - `Frida Detection Bypass`:[https://frida.re/docs/android/](https://frida.re/docs/android/) 242 | 243 | --- 244 | 245 | 🔥 **任务完成后,你将掌握:** 246 | ✅ **如何使用 Frida Hook Android 方法,修改应用逻辑** 247 | ✅ **如何拦截 & 修改网络请求,解密敏感数据** 248 | ✅ **如何绕过 Frida 检测,成功 Hook 目标应用** 249 | 250 | 🚀 **下一步(Day 29)**:**Frida Hook 实战!** 🎯 -------------------------------------------------------------------------------- /AndroidReverse101/第二阶段_APK逆向基础/Day_37_破解应用限制_实战.md: -------------------------------------------------------------------------------- 1 | # **📜 Day 37: 破解应用限制(实战)** 2 | 3 | ## **📌 学习目标** 4 | ✅ **掌握如何绕过 Android 应用的限制,如强制更新、区域限制、功能锁定等**。 5 | ✅ **学习如何使用 `Frida`、`Xposed`、`Smali` 逆向分析 & 破解应用限制**。 6 | ✅ **学习如何修改 `isForceUpdate()`、`isFeatureLocked()` 方法,解锁被限制的功能**。 7 | ✅ **掌握 API 拦截 & 修改,绕过服务器返回的限制信息**。 8 | ✅ **实战:破解 VIP 会员、绕过区域限制、解锁隐藏功能!** 9 | 10 | --- 11 | 12 | # **1️⃣ 识别应用的限制** 13 | Android 应用通常会 **限制用户访问某些功能**,常见方式: 14 | - **强制更新** 15 | - 通过 `isForceUpdate()` 方法强制用户更新应用。 16 | - **区域限制** 17 | - 服务器返回 `geo_blocked=true`,阻止特定国家访问。 18 | - **功能锁定** 19 | - 会员功能仅对 `isVIP=true` 用户开放。 20 | 21 | 📌 **示例 Java 代码** 22 | ```java 23 | public boolean isForceUpdate() { 24 | return true; // 强制更新 25 | } 26 | 27 | public boolean isFeatureLocked() { 28 | return !user.isVIP(); // 仅 VIP 可用 29 | } 30 | ``` 31 | 32 | --- 33 | 34 | # **2️⃣ 静态分析 & 修改 APK** 35 | ## **✅ 1. 反编译 APK** 36 | 📌 **使用 `jadx` 反编译** 37 | ```bash 38 | jadx -d output/ app.apk 39 | ``` 40 | 📌 **查找限制代码** 41 | ```bash 42 | grep -r "isForceUpdate" output/ 43 | grep -r "isFeatureLocked" output/ 44 | ``` 45 | 📌 **示例 `isForceUpdate()` 方法** 46 | ```java 47 | public boolean isForceUpdate() { 48 | return true; 49 | } 50 | ``` 51 | 52 | ## **✅ 2. 修改 Smali 代码** 53 | 📌 **找到 Smali 代码** 54 | ```bash 55 | grep -r "isForceUpdate" output/smali/ 56 | ``` 57 | 📌 **修改 Smali** 58 | ```smali 59 | .method public isForceUpdate()Z 60 | .locals 1 61 | const/4 v0, 0x0 # 0 = 不强制更新 62 | return v0 63 | .end method 64 | ``` 65 | 66 | 📌 **重新打包 APK** 67 | ```bash 68 | apktool b output -o modded.apk 69 | apksigner sign --ks my.keystore --out signed.apk modded.apk 70 | adb install signed.apk 71 | ``` 72 | 73 | --- 74 | 75 | # **3️⃣ 使用 Frida 绕过应用限制** 76 | ## **✅ 1. Hook `isForceUpdate()`** 77 | 📌 **Frida Hook** 78 | ```js 79 | Java.perform(function() { 80 | var MainActivity = Java.use("com.example.MainActivity"); 81 | MainActivity.isForceUpdate.implementation = function() { 82 | console.log("[*] Bypassing force update"); 83 | return false; 84 | }; 85 | }); 86 | ``` 87 | 📌 **运行 Frida** 88 | ```bash 89 | frida -U -n com.example.app -e "..." 90 | ``` 91 | 92 | ## **✅ 2. Hook `isFeatureLocked()`** 93 | 📌 **Frida Hook** 94 | ```js 95 | Java.perform(function() { 96 | var FeatureManager = Java.use("com.example.FeatureManager"); 97 | FeatureManager.isFeatureLocked.implementation = function() { 98 | console.log("[*] Unlocking feature"); 99 | return false; 100 | }; 101 | }); 102 | ``` 103 | 104 | --- 105 | 106 | # **4️⃣ 绕过区域限制** 107 | ## **✅ 1. 服务器 API 返回 `geo_blocked=true`** 108 | 📌 **API 返回** 109 | ```json 110 | { 111 | "geo_blocked": true 112 | } 113 | ``` 114 | 📌 **Hook API 响应** 115 | ```js 116 | Interceptor.attach(Module.findExportByName("libokhttp.so", "ssl_read"), { 117 | onLeave: function(retval) { 118 | console.log("[*] Intercepted API response: " + Memory.readUtf8String(retval)); 119 | var fakeResponse = '{"geo_blocked": false}'; 120 | Memory.writeUtf8String(retval, fakeResponse); 121 | } 122 | }); 123 | ``` 124 | 125 | --- 126 | 127 | # **5️⃣ Xposed 破解应用限制** 128 | 📌 **Hook `isForceUpdate()`** 129 | ```java 130 | XposedHelpers.findAndHookMethod("com.example.MainActivity", lpparam.classLoader, "isForceUpdate", 131 | new XC_MethodReplacement() { 132 | @Override 133 | protected Object replaceHookedMethod(MethodHookParam param) { 134 | return false; 135 | } 136 | }); 137 | ``` 138 | 139 | 📌 **Hook `isFeatureLocked()`** 140 | ```java 141 | XposedHelpers.findAndHookMethod("com.example.FeatureManager", lpparam.classLoader, "isFeatureLocked", 142 | new XC_MethodReplacement() { 143 | @Override 144 | protected Object replaceHookedMethod(MethodHookParam param) { 145 | return false; 146 | } 147 | }); 148 | ``` 149 | 150 | --- 151 | 152 | # **6️⃣ 伪造 API 请求** 153 | 📌 **修改 HTTP 请求** 154 | ```js 155 | Java.perform(function() { 156 | var Request = Java.use("okhttp3.Request"); 157 | Request.body.implementation = function() { 158 | console.log("[*] Modifying API Request: " + this.body()); 159 | return this.body().replace("user=free", "user=vip"); 160 | }; 161 | }); 162 | ``` 163 | 164 | 📌 **伪造 WebSocket 消息** 165 | ```python 166 | import websocket 167 | ws = websocket.WebSocket() 168 | ws.connect("wss://chat.example.com/socket") 169 | ws.send('{"type": "feature_unlock", "status": "enabled"}') 170 | print(ws.recv()) 171 | ``` 172 | 173 | --- 174 | 175 | # **🛠 实战任务** 176 | ### **✅ 1. 反编译 & 修改 APK** 177 | ```bash 178 | apktool d app.apk -o output/ 179 | grep -r "isForceUpdate" output/smali/ 180 | apktool b output -o modded.apk 181 | apksigner sign --ks my.keystore --out signed.apk modded.apk 182 | adb install signed.apk 183 | ``` 184 | ### **✅ 2. Hook `isForceUpdate()`** 185 | ```js 186 | Java.perform(function() { 187 | var MainActivity = Java.use("com.example.MainActivity"); 188 | MainActivity.isForceUpdate.implementation = function() { 189 | return false; 190 | }; 191 | }); 192 | ``` 193 | ### **✅ 3. Hook `isFeatureLocked()`** 194 | ```js 195 | Java.perform(function() { 196 | var FeatureManager = Java.use("com.example.FeatureManager"); 197 | FeatureManager.isFeatureLocked.implementation = function() { 198 | return false; 199 | }; 200 | }); 201 | ``` 202 | ### **✅ 4. 伪造 API 响应** 203 | ```js 204 | Interceptor.attach(Module.findExportByName("libokhttp.so", "ssl_read"), { 205 | onLeave: function(retval) { 206 | var fakeResponse = '{"geo_blocked": false}'; 207 | Memory.writeUtf8String(retval, fakeResponse); 208 | } 209 | }); 210 | ``` 211 | ### **✅ 5. 伪造 API 请求** 212 | ```js 213 | Java.perform(function() { 214 | var Request = Java.use("okhttp3.Request"); 215 | Request.body.implementation = function() { 216 | return this.body().replace("user=free", "user=vip"); 217 | }; 218 | }); 219 | ``` 220 | ### **✅ 6. 伪造 WebSocket 消息** 221 | ```python 222 | import websocket 223 | ws = websocket.WebSocket() 224 | ws.connect("wss://chat.example.com/socket") 225 | ws.send('{"type": "feature_unlock", "status": "enabled"}') 226 | print(ws.recv()) 227 | ``` 228 | 229 | --- 230 | 231 | # **📚 参考资料** 232 | 📌 **Android 逆向** 233 | - `jadx`:[https://github.com/skylot/jadx](https://github.com/skylot/jadx) 234 | - `apktool`:[https://github.com/iBotPeaches/Apktool](https://github.com/iBotPeaches/Apktool) 235 | 236 | 📌 **动态 Hook** 237 | - `Frida`:[https://frida.re](https://frida.re) 238 | - `Xposed`:[http://repo.xposed.info/](http://repo.xposed.info/) 239 | 240 | 📌 **API 伪造** 241 | - `Mitmproxy`:[https://mitmproxy.org/](https://mitmproxy.org/) 242 | 243 | --- 244 | 245 | 🔥 **任务完成后,你将掌握:** 246 | ✅ **如何修改 APK,绕过 `isForceUpdate()` 限制** 247 | ✅ **如何使用 `Frida` Hook 方法,动态解锁功能** 248 | ✅ **如何使用 `Xposed` 持久 Hook 方法,修改应用逻辑** 249 | ✅ **如何拦截 & 伪造 API 响应,绕过区域限制** 250 | 251 | 🚀 **下一步(Day 38)**:**游戏破解基础!** 🎯 -------------------------------------------------------------------------------- /AndroidReverse101/第二阶段_APK逆向基础/Day_39_反反调试.md: -------------------------------------------------------------------------------- 1 | # **📜 Day 39: 反反调试** 2 | 3 | ## **📌 学习目标** 4 | ✅ **掌握 Android 应用的常见反调试(Anti-Debugging)机制,理解其工作原理**。 5 | ✅ **学习如何绕过 `ptrace()`、`TracerPid` 检测,避免调试被中断**。 6 | ✅ **掌握 Frida、Xposed、GDB 等工具,绕过动态调试检测**。 7 | ✅ **学习如何修改 `libnative.so` 逆向 ELF 反调试代码**。 8 | ✅ **实战:绕过 `ptrace()`、`syscall` 监控,成功调试目标应用!** 9 | 10 | --- 11 | 12 | # **1️⃣ 什么是反调试?** 13 | Android 应用通常会使用 **反调试技术(Anti-Debugging)**,防止调试器(如 GDB、Frida)分析应用逻辑。 14 | 15 | 📌 **常见反调试检测方式** 16 | | **方法** | **原理** | **绕过方法** | 17 | |---------|--------|------------| 18 | | **`ptrace()`** | 防止进程被调试 | Hook `ptrace()`,返回 `0` | 19 | | **`TracerPid` 监测** | 读取 `/proc/self/status` 判断是否被调试 | Hook `read()` 修改返回值 | 20 | | **`getppid()` 监测** | 检测父进程是否为调试器 | Hook `getppid()`,返回 `0` | 21 | | **`isDebuggerConnected()`** | 调用 `Debug.isDebuggerConnected()` 检测调试状态 | Hook 方法,返回 `false` | 22 | | **`syscall` 监控** | 监视系统调用 | Hook `syscall`,修改 `ptrace` 调用 | 23 | | **`anti-Frida` 检测** | 扫描 Frida 进程 & 端口 | 隐藏 Frida 进程,Hook `open()` | 24 | 25 | --- 26 | 27 | # **2️⃣ 反编译 & 分析反调试代码** 28 | ## **✅ 1. 反编译 APK** 29 | 📌 **使用 `jadx` 反编译** 30 | ```bash 31 | jadx -d output/ app.apk 32 | ``` 33 | 📌 **查找反调试代码** 34 | ```bash 35 | grep -r "Debug" output/ 36 | grep -r "ptrace" output/ 37 | grep -r "TracerPid" output/ 38 | ``` 39 | 📌 **示例 Java 代码** 40 | ```java 41 | public boolean isDebuggerConnected() { 42 | return android.os.Debug.isDebuggerConnected(); 43 | } 44 | ``` 45 | 📌 **示例 `ptrace()` 调用** 46 | ```java 47 | System.loadLibrary("native-lib"); 48 | public native void antiDebug(); 49 | ``` 50 | 📌 **Native 层 `ptrace` 代码** 51 | ```c 52 | #include 53 | void antiDebug() { 54 | if (ptrace(PTRACE_TRACEME, 0, 0, 0) == -1) { 55 | exit(1); 56 | } 57 | } 58 | ``` 59 | 60 | --- 61 | 62 | # **3️⃣ 使用 Frida 绕过反调试** 63 | ## **✅ 1. Hook `ptrace()`** 64 | 📌 **Frida Hook** 65 | ```js 66 | Interceptor.attach(Module.findExportByName(null, "ptrace"), { 67 | onEnter: function(args) { 68 | console.log("[*] Bypassing ptrace"); 69 | args[0] = 0; 70 | }, 71 | onLeave: function(retval) { 72 | retval.replace(0); 73 | } 74 | }); 75 | ``` 76 | 📌 **运行 Frida** 77 | ```bash 78 | frida -U -n com.example.app -e "..." 79 | ``` 80 | 81 | --- 82 | 83 | ## **✅ 2. Hook `isDebuggerConnected()`** 84 | 📌 **Frida Hook** 85 | ```js 86 | Java.perform(function() { 87 | var Debug = Java.use("android.os.Debug"); 88 | Debug.isDebuggerConnected.implementation = function() { 89 | console.log("[*] Bypassing isDebuggerConnected()"); 90 | return false; 91 | }; 92 | }); 93 | ``` 94 | 95 | --- 96 | 97 | ## **✅ 3. Hook `TracerPid` 读取** 98 | 📌 **Frida Hook** 99 | ```js 100 | Interceptor.attach(Module.findExportByName(null, "read"), { 101 | onEnter: function(args) { 102 | var fd = args[0].toInt32(); 103 | var buf = args[1]; 104 | if (fd == "/proc/self/status") { 105 | console.log("[*] Bypassing TracerPid"); 106 | Memory.writeUtf8String(buf, "TracerPid:\t0\n"); 107 | } 108 | } 109 | }); 110 | ``` 111 | 112 | --- 113 | 114 | # **4️⃣ 使用 Xposed 绕过反调试** 115 | 📌 **Hook `isDebuggerConnected()`** 116 | ```java 117 | XposedHelpers.findAndHookMethod("android.os.Debug", lpparam.classLoader, "isDebuggerConnected", 118 | new XC_MethodReplacement() { 119 | @Override 120 | protected Object replaceHookedMethod(MethodHookParam param) { 121 | return false; 122 | } 123 | }); 124 | ``` 125 | 126 | 📌 **Hook `getppid()`** 127 | ```java 128 | XposedHelpers.findAndHookMethod("android.os.Process", lpparam.classLoader, "getParentPid", 129 | new XC_MethodReplacement() { 130 | @Override 131 | protected Object replaceHookedMethod(MethodHookParam param) { 132 | return 0; 133 | } 134 | }); 135 | ``` 136 | 137 | --- 138 | 139 | # **5️⃣ 逆向 `libnative.so` 进行修改** 140 | ## **✅ 1. 提取 `libnative.so`** 141 | 📌 **查找 so 文件** 142 | ```bash 143 | adb shell ls /data/app/com.example.app/lib/arm64/ 144 | ``` 145 | 📌 **提取 so** 146 | ```bash 147 | adb pull /data/app/com.example.app/lib/arm64/libnative.so . 148 | ``` 149 | 150 | ## **✅ 2. 反编译 `libnative.so`** 151 | 📌 **使用 IDA Pro** 152 | 1. **加载 `libnative.so`** 153 | 2. **搜索 `ptrace` 调用** 154 | 3. **修改 `CMP R0, -1` 为 `CMP R0, 0`** 155 | 156 | 📌 **使用 Ghidra** 157 | 1. **加载 `libnative.so`** 158 | 2. **搜索 `antiDebug()`** 159 | 3. **修改 `ptrace` 逻辑** 160 | 161 | --- 162 | 163 | # **6️⃣ 绕过 Frida 反检测** 164 | 部分应用会检测 Frida 进程: 165 | 📌 **检测 Frida 进程** 166 | ```bash 167 | ps -A | grep frida 168 | ``` 169 | 📌 **Hook `open()` 隐藏 Frida** 170 | ```js 171 | Interceptor.attach(Module.findExportByName(null, "open"), { 172 | onEnter: function(args) { 173 | var path = Memory.readUtf8String(args[0]); 174 | if (path.includes("frida")) { 175 | console.log("[*] Bypassing Frida detection"); 176 | args[0] = Memory.allocUtf8String("/dev/null"); 177 | } 178 | } 179 | }); 180 | ``` 181 | 182 | --- 183 | 184 | # **🛠 实战任务** 185 | ### **✅ 1. 反编译 & 分析 APK** 186 | ```bash 187 | jadx -d output/ app.apk 188 | grep -r "ptrace" output/ 189 | grep -r "TracerPid" output/ 190 | ``` 191 | ### **✅ 2. Hook `ptrace()`** 192 | ```js 193 | Interceptor.attach(Module.findExportByName(null, "ptrace"), { 194 | onEnter: function(args) { 195 | args[0] = 0; 196 | }, 197 | onLeave: function(retval) { 198 | retval.replace(0); 199 | } 200 | }); 201 | ``` 202 | ### **✅ 3. Hook `isDebuggerConnected()`** 203 | ```js 204 | Java.perform(function() { 205 | var Debug = Java.use("android.os.Debug"); 206 | Debug.isDebuggerConnected.implementation = function() { 207 | return false; 208 | }; 209 | }); 210 | ``` 211 | ### **✅ 4. Hook `TracerPid`** 212 | ```js 213 | Interceptor.attach(Module.findExportByName(null, "read"), { 214 | onEnter: function(args) { 215 | var fd = args[0].toInt32(); 216 | var buf = args[1]; 217 | if (fd == "/proc/self/status") { 218 | Memory.writeUtf8String(buf, "TracerPid:\t0\n"); 219 | } 220 | } 221 | }); 222 | ``` 223 | ### **✅ 5. 逆向 `libnative.so`** 224 | ```bash 225 | adb pull /data/app/com.example.app/lib/arm64/libnative.so . 226 | ``` 227 | 1. **使用 IDA Pro 或 Ghidra 反编译** 228 | 2. **修改 `ptrace(PTRACE_TRACEME, 0, 0, 0)` 返回值** 229 | 3. **重新打包 & 运行 APK** 230 | 231 | --- 232 | 233 | # **📚 参考资料** 234 | 📌 **反调试绕过** 235 | - `Frida`:[https://frida.re](https://frida.re) 236 | - `Xposed`:[http://repo.xposed.info/](http://repo.xposed.info/) 237 | 238 | 📌 **逆向分析** 239 | - `IDA Pro`:[https://hex-rays.com/](https://hex-rays.com/) 240 | - `Ghidra`:[https://ghidra-sre.org/](https://ghidra-sre.org/) 241 | 242 | --- 243 | 244 | 🔥 **任务完成后,你将掌握:** 245 | ✅ **如何绕过 `ptrace()` 反调试** 246 | ✅ **如何 Hook `TracerPid`,隐藏调试器** 247 | ✅ **如何修改 `libnative.so`,逆向 ELF 反调试代码** 248 | ✅ **如何绕过 Frida 检测,隐藏 Hook 进程** 249 | 250 | 🚀 **下一步(Day 40)**:**Android 加固原理!** 🎯 -------------------------------------------------------------------------------- /AndroidReverse101/第二阶段_APK逆向基础/Day_33_绕过_SSL_Pinning.md: -------------------------------------------------------------------------------- 1 | # **📜 Day 33: 绕过 SSL Pinning** 2 | 3 | ## **📌 学习目标** 4 | ✅ **掌握 SSL Pinning 的原理,理解为什么应用会校验证书**。 5 | ✅ **学习如何使用 `Frida`、`Xposed`、`Burp Suite` 绕过 SSL Pinning**,拦截 HTTPS 请求。 6 | ✅ **掌握 `Java.use` Hook Java 方法,动态修改 SSL 校验逻辑**。 7 | ✅ **学习如何分析 `OkHttp`、`HttpURLConnection`、`SSLSocketFactory` 相关代码,找到 SSL Pinning 实现方式**。 8 | ✅ **实战:使用 Frida 绕过 SSL Pinning,成功拦截 HTTPS 请求,抓取 API 数据!** 9 | 10 | --- 11 | 12 | # **1️⃣ 什么是 SSL Pinning?** 13 | SSL Pinning 是一种 **防止中间人攻击(MITM)的安全机制**,Android 应用通过 SSL Pinning 绑定特定证书,使得 **仅受信任的证书才能建立 HTTPS 连接**,防止流量被劫持。 14 | 15 | 📌 **为什么要绕过 SSL Pinning?** 16 | - **抓取 API 请求** 17 | - **分析应用加密通信** 18 | - **模拟 HTTP 请求,绕过认证** 19 | - **拦截敏感数据,如 Token、密码、加密数据** 20 | 21 | 📌 **常见 SSL Pinning 实现方式** 22 | | **方式** | **描述** | **绕过方式** | 23 | |---------|--------|------------| 24 | | **`OkHttp` 证书校验** | 使用 `CertificatePinner` 绑定证书 | Hook `check()` 方法 | 25 | | **`HttpsURLConnection`** | 校验 `X509TrustManager` | Hook `checkServerTrusted()` | 26 | | **`SSLSocketFactory`** | 直接校验证书 | Hook `createSocket()` | 27 | | **JNI 层校验** | 通过 `libcrypto.so` 进行证书校验 | Hook `SSL_get_verify_result()` | 28 | 29 | --- 30 | 31 | # **2️⃣ 分析应用的 SSL Pinning 代码** 32 | ## **✅ 1. 反编译 APK** 33 | 📌 **使用 `jadx` 反编译 APK** 34 | ```bash 35 | jadx -d output/ app.apk 36 | ``` 37 | 📌 **查找 `CertificatePinner` 关键字** 38 | ```bash 39 | grep -r "CertificatePinner" output/ 40 | ``` 41 | 📌 **示例 Java 代码** 42 | ```java 43 | OkHttpClient client = new OkHttpClient.Builder() 44 | .certificatePinner(new CertificatePinner.Builder() 45 | .add("api.example.com", "sha256/abcdef123456") 46 | .build()) 47 | .build(); 48 | ``` 49 | 📌 **查找 `checkServerTrusted()`** 50 | ```bash 51 | grep -r "checkServerTrusted" output/ 52 | ``` 53 | 📌 **示例 Java 代码** 54 | ```java 55 | public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException { 56 | if (!chain[0].equals(VALID_CERT)) { 57 | throw new CertificateException("SSL Pinning Failed!"); 58 | } 59 | } 60 | ``` 61 | 62 | --- 63 | 64 | # **3️⃣ 使用 Frida 绕过 SSL Pinning** 65 | ## **✅ 1. Hook `OkHttp` 证书校验** 66 | 📌 **Frida Hook** 67 | ```js 68 | Java.perform(function() { 69 | var CertificatePinner = Java.use("okhttp3.CertificatePinner"); 70 | CertificatePinner.check.overload("java.lang.String", "java.util.List").implementation = function(hostname, peerCertificates) { 71 | console.log("[*] Bypassing SSL Pinning for: " + hostname); 72 | return; 73 | }; 74 | }); 75 | ``` 76 | 📌 **运行 Frida** 77 | ```bash 78 | frida -U -n com.example.app -e "..." 79 | ``` 80 | 81 | --- 82 | 83 | ## **✅ 2. Hook `checkServerTrusted()`** 84 | 📌 **Frida Hook** 85 | ```js 86 | Java.perform(function() { 87 | var TrustManager = Java.use("javax.net.ssl.X509TrustManager"); 88 | TrustManager.checkServerTrusted.implementation = function(chain, authType) { 89 | console.log("[*] Bypassing checkServerTrusted()"); 90 | return; 91 | }; 92 | }); 93 | ``` 94 | 95 | --- 96 | 97 | ## **✅ 3. Hook `SSLSocketFactory`** 98 | 📌 **Frida Hook** 99 | ```js 100 | Java.perform(function() { 101 | var SSLSocketFactory = Java.use("javax.net.ssl.SSLSocketFactory"); 102 | SSLSocketFactory.createSocket.overload("java.net.Socket", "java.io.InputStream", "boolean").implementation = function(s, i, b) { 103 | console.log("[*] Bypassing SSL Pinning"); 104 | return this.createSocket(s, i, b); 105 | }; 106 | }); 107 | ``` 108 | 109 | --- 110 | 111 | # **4️⃣ 使用 Xposed 绕过 SSL Pinning** 112 | 📌 **Xposed Hook** 113 | ```java 114 | XposedHelpers.findAndHookMethod("javax.net.ssl.X509TrustManager", lpparam.classLoader, "checkServerTrusted", 115 | X509Certificate[].class, String.class, new XC_MethodReplacement() { 116 | @Override 117 | protected Object replaceHookedMethod(MethodHookParam param) { 118 | return; 119 | } 120 | }); 121 | ``` 122 | 123 | --- 124 | 125 | # **5️⃣ 使用 Burp Suite 拦截流量** 126 | 📌 **步骤** 127 | 1. **在 Burp Suite 设置代理** 128 | - 监听端口 `8080` 129 | - 设置 `Intercept Off` 130 | 2. **在 Android 设备上安装 Burp 证书** 131 | ```bash 132 | adb push burp_cert.der /sdcard/ 133 | ``` 134 | 3. **配置 WiFi 代理** 135 | - 进入 `WiFi 设置` 136 | - 代理地址填写 PC IP,端口 `8080` 137 | 4. **尝试抓包** 138 | - **未绕过 SSL Pinning** → 证书错误 139 | - **成功绕过** → 可看到 API 请求数据 140 | 141 | --- 142 | 143 | # **6️⃣ 绕过 Native 层 SSL Pinning** 144 | 某些应用会在 Native 层(C/C++)进行证书校验,如 `libcrypto.so`。 145 | 📌 **Frida Hook `SSL_get_verify_result()`** 146 | ```js 147 | Interceptor.attach(Module.findExportByName("libcrypto.so", "SSL_get_verify_result"), { 148 | onLeave: function(retval) { 149 | console.log("[*] Bypassing Native SSL Pinning"); 150 | retval.replace(0); 151 | } 152 | }); 153 | ``` 154 | 155 | --- 156 | 157 | # **🛠 实战任务** 158 | ### **✅ 1. 查找 SSL Pinning 代码** 159 | ```bash 160 | jadx -d output/ app.apk 161 | grep -r "CertificatePinner" output/ 162 | grep -r "checkServerTrusted" output/ 163 | ``` 164 | ### **✅ 2. Hook `OkHttp`** 165 | ```js 166 | Java.perform(function() { 167 | var CertificatePinner = Java.use("okhttp3.CertificatePinner"); 168 | CertificatePinner.check.overload("java.lang.String", "java.util.List").implementation = function(hostname, peerCertificates) { 169 | return; 170 | }; 171 | }); 172 | ``` 173 | ### **✅ 3. Hook `checkServerTrusted()`** 174 | ```js 175 | Java.perform(function() { 176 | var TrustManager = Java.use("javax.net.ssl.X509TrustManager"); 177 | TrustManager.checkServerTrusted.implementation = function(chain, authType) { 178 | return; 179 | }; 180 | }); 181 | ``` 182 | ### **✅ 4. Hook `SSLSocketFactory`** 183 | ```js 184 | Java.perform(function() { 185 | var SSLSocketFactory = Java.use("javax.net.ssl.SSLSocketFactory"); 186 | SSLSocketFactory.createSocket.overload("java.net.Socket", "java.io.InputStream", "boolean").implementation = function(s, i, b) { 187 | return this.createSocket(s, i, b); 188 | }; 189 | }); 190 | ``` 191 | ### **✅ 5. Hook Native SSL Pinning** 192 | ```js 193 | Interceptor.attach(Module.findExportByName("libcrypto.so", "SSL_get_verify_result"), { 194 | onLeave: function(retval) { 195 | retval.replace(0); 196 | } 197 | }); 198 | ``` 199 | ### **✅ 6. 运行 Frida** 200 | ```bash 201 | frida -U -n com.example.app -e "..." 202 | ``` 203 | 204 | --- 205 | 206 | # **📚 参考资料** 207 | 📌 **Frida Hook** 208 | - `Frida`:[https://frida.re](https://frida.re) 209 | 210 | 📌 **Xposed Hook** 211 | - `Xposed`:[http://repo.xposed.info/](http://repo.xposed.info/) 212 | 213 | 📌 **Burp Suite** 214 | - `Burp Suite`:[https://portswigger.net/burp](https://portswigger.net/burp) 215 | 216 | 📌 **Native SSL Pinning** 217 | - `libcrypto.so Hook`:[https://frida.re/docs/android/](https://frida.re/docs/android/) 218 | 219 | --- 220 | 221 | 🔥 **任务完成后,你将掌握:** 222 | ✅ **如何分析 & 绕过 SSL Pinning,成功抓取 HTTPS 数据** 223 | ✅ **如何使用 Frida Hook SSL Pinning 代码** 224 | ✅ **如何使用 Xposed 绕过 `checkServerTrusted()`** 225 | ✅ **如何 Hook Native 层 `libcrypto.so` 绕过证书校验** 226 | 227 | 🚀 **下一步(Day 34)**:**Android 代码混淆与解混淆!** 🎯 --------------------------------------------------------------------------------