├── 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 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/.idea/modules.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/.idea/misc.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
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 代码混淆与解混淆!** 🎯
--------------------------------------------------------------------------------