Bugku Reverse 与 Android 题解总集:APK / native / PE / IPA

平台:ctf.bugku.com|范围:逆向分类(Android、native、托管、IPA) 主张:逆向题的胜负手是定位校验函数,不是把反汇编读完。

0. 分类与首步动作

目标 首步 关键工具
APK(Java 层) jadx 打开,先看 AndroidManifest 与入口 Activity jadx / apktool
APK(native 层) 判断是否 native-activity(jadx 里只有 BuildConfig/R)→ 解包取 .so r2 / objdump / Ghidra
PE(C/C++) checksec 与入口,找 scanf/strcmp IDA / x64dbg
PE(.NET) 先判 CLR 头,再选 dnSpy dnSpy / dnlib
JAR 解压看 META-INF 与类名,JD-GUI/jadx jadx
IPA Mach-O 头、.app 目录、Swift mangling otool / Hopper / r2

图 1:Android / native / 托管 / IPA 的分层与工具(Archify architecture)

1. Android:java 层与 native 层要分开

1.1 java 层常规路线

  1. jadx -d out app.apk;
  2. 搜 flag、check、verify、decrypt,或从 MainActivity.onCreate 往下跟;
  3. 常见校验:字符串比较、MessageDigest 摘要、Base64/异或。

1.2 native 层(132 LittleRotatorGame 的完整路径)

  1. 先判断「Java 层是不是空的」 :jadx 里只有 BuildConfig/R → 说明是 NDK native-activity ,逻辑全在 .so;
  2. 解包取 .so:
bash 复制代码
unzip app.apk 'lib/*' -d libs
file libs/arm64-v8a/libnative.so
  1. 先搜格式串 :.rodata 里搜 flag{/%s,本例找到 "The flag is:njctf{%s}";
  2. 从其 xref 反查生成函数:flg(int,char*)@0x2f98,函数体恰好 12 个 strb(12 个字符一次写入);
  3. 翻译表达式 :取 7 个十进制位 d[i]=(N/10^i)%10,12 个字符表达式含 20*d3-d4 的 2³² 抵消、d2*d2*d1*d0-4;
  4. 反解 :由校验式反推 arg1 = 1635274(0 ms),flg_py(1635274)=='PvrNa7iv3Al1',枚举 0..2e6 2.6 s 唯一命中。

踩坑清单:

坑 表现 处理
误读 helper 把除法/取模识别错 查 __aeabi_idiv、__aeabi_idivmod 调用约定
寄存器归属错 r3 实际是 d2,按 d3 算卡 20 min 逐指令标注 def-use,别凭印象
unicorn 模拟失败 helper 未打桩 直接静态翻译,或用 QEMU 跑整段
2.6 MB dex 误导 以为是 Java 逻辑 看 dex 里只有 support 框架 → 回 native

1.3 动态辅助

  • frida:Interceptor.attach(Module.findExportByName(null,'strcmp'), ...) 看比较参数;
  • 或 hook 目标函数打印入参/返回值,比盲猜校验式快得多;
  • 注意反调试(ptrace、/proc/self/status 检查),必要时改 smali 或 patch so。

2. 托管层(.NET):先确认是 IL 还是 native

  1. 看 PE 可选头 Data Directory 第 14 项(CLR)非 0 → 托管;
  2. dnSpy/dnlib 打开,字符串常被混淆 → 找 strings 解混淆函数,或直接动态调用;
  3. IL 阅读要点:ldstr(字符串)、call(调用)、switch(状态机)、stloc/ldloc(局部变量);
  4. 若被 ConfuserEx 等加壳:先 de4dot 脱壳,再按上面流程。

3. PE 原生

  1. checksec:看 ASLR/NX/Canary(同时决定是否有 pwn 空间);
  2. 入口 → main → 找输入函数(scanf/ReadFile/getchar)与比较函数(strcmp/memcmp);
  3. 常数与 S 盒:看到 256 字节表 → AES/S 盒;看到 4 个 32 位常数(67452301/efcdab89...)→ MD5/SHA;
  4. 注意 反调试 (IsDebuggerPresent、ptrace、时间差检测)与 SMC(自修改代码,需在运行时 dump 解密后段)。

4. IPA / Mach-O 要点

  • file 判断是否 FAT(多架构),lipo -thin arm64 拆;
  • Swift 程序符号被 mangle,用 swift demangle 还原可读名;
  • Info.plist 看 Bundle ID 与 URL Scheme,Mach-O 看 LC_LOAD_DYLIB 判断依赖;
  • 逻辑常在 __TEXT.__text 的自定义类里,按字符串 xref 定位更快。

5. 逆向通用方法论

  1. 先找「输出点」:格式串、打印、文件写入 ------ 顺藤摸瓜找到校验;
  2. 先找「输入点」 :scanf/getline、EditText、argv;
  3. 两点之间才是要翻的范围,其余函数一律跳过;
  4. 能反解就不爆破:由校验式反推输入(132 是反解 + 枚举验证,不是暴力试);
  5. 动态优先于静态:frida/x64dbg 看一眼入参,胜过读 100 行反汇编;
  6. 写脚本固化:把定位→翻译→反解→验证串成脚本,下次同型题 1 分钟跑完。

6. 一页检查表

复制代码
[ ] 先 file / unzip 判格式,别拿 APK 当普通 zip
[ ] jadx 里只有 BuildConfig/R?→ 去 native
[ ] 搜格式串(flag{ / %s)再 xref
[ ] 判断 helper 调用约定(除法/取模/字符串)
[ ] .NET 先查 CLR 目录项,再决定 dnSpy
[ ] PE 看反调试/SMC,动态配合
[ ] 能反解就反解,别写爆破

7. 图形附件(Archify)

图 文件 说明
逆向题型分层与工具链 reverse-arch.html(交互图,本地交付包) APK / native / 托管 / 动态
逆向作战流程 reverse-timeline.html(交互图,本地交付包) 定位→翻译→反解→动态复核→归档

流程视图

从判型到归档的主线流程:每步都要求留下原始输出,结论必须能被独立脚本重跑。

两图 archify check 均 issues: [];archify finalize 均 ok:true + browser-check:pass;正文内嵌同源 PNG 截图。

相关推荐
大尚来也1 小时前
PHP 内存溢出常见原因与优化排查步骤
android
美狐美颜SDK开放平台2 小时前
开发直播APP、电商短视频与视频社交平台时,能否共用一套美颜SDK?
android·图像处理·人工智能·音视频·直播美颜sdk
事圆则缓2 小时前
Android 中的 MQTT 协议:从设备状态推送到可靠消息处理
android
三雷科技2 小时前
Android 开发环境搭建指南
android
赵庆明老师3 小时前
Android Studio Google源代理配置
android·ide·android studio
虎鲸不是鱼4 小时前
AI 自动化逆向(三十六)先找不加密的部分
人工智能·自动化·大模型·逆向·ai逆向
事圆则缓4 小时前
Android 核心名词手册跟读版
android
snysy4 小时前
WordPress伪静态404故障排查笔记
android·笔记·wordpress
zhangphil4 小时前
海量小文件造成Android存储碎片化与I/O变慢
android