Crackme反调试思路
启动后会出现两个进程 别hook错了
PS C:\\Users\\HiMaq> adb shell "ps -A | grep igio90"
u0_a78 10757 678 2232368 43924 SyS_epoll_wait 7a996441d4 S com.igio90.crackme2:main
u0_a78 10780 678 2228224 41632 futex_wait_queue_me 7a995f8630 S com.igio90.crackme2:launcher
此处launcher 直接来个nativeInit 事情不简单 
IDA 查看导出函数
修复下变量名 基本可以得知是一个反射函数
盲猜是MainActivity的 init 函数 刚好也是一个静态函数 
这个init其实就是重启它自己,这样做的好处是什么呢?
signal 6 (SIGABRT), code -6 (SI_TKILL), fault addr ——–
Abort message: 'java_vm_ext.cc:504] JNI DETECTED ERROR IN APPLICATION: java_class == null'
PS C:\\Users\\HiMaq> adb shell am force-stop com.igio90.crackme2
PS C:\\Users\\HiMaq> adb shell am start -D -n com.igio90.crackme2/.Launcher
Starting: Intent { cmp=com.igio90.crackme2/.Launcher }
PS C:\\Users\\HiMaq> adb jdwp
4144
4720
4177
2155
4766
919
5224
4119
5250
2543
4260
4625
4471
2145
4418
5945
10757
10780
PS C:\\Users\\HiMaq> adb shell "ps -A | grep igio90"
u0_a78 10757 678 2232368 43924 SyS_epoll_wait 7a996441d4 S com.igio90.crackme2:main
u0_a78 10780 678 2228224 41632 futex_wait_queue_me 7a995f8630 S com.igio90.crackme2:launcher
PS C:\\Users\\HiMaq> adb forward tcp:31280 jdwp:10780
PS C:\\Users\\HiMaq> jdb -connect com.sun.jdi.SocketAttach:hostname=127.0.0.1,port=31280
设置未捕获的java.lang.Throwable
设置延迟的未捕获的java.lang.Throwable
正在初始化jdb…
> resume
已恢复所有线程。
>
这里jdb 启动app后 ,立即使用frida hook,最后再connect 31280 和resume 顺序不要错
PS C:\\Users\\HiMaq> adb root
restarting adbd as root
PS C:\\Users\\HiMaq> adb shell setenforce 0
PS C:\\Users\\HiMaq> adb shell
angler:/ # su
angler:/ # ./data/lo
local/ lost+found/
angler:/ # ./data/local/tmp/frida-server-17.9.8-android-arm64 &
firda 端口转发
PS C:\\Users\\HiMaq> adb forward tcp:27042 tcp:27042
27042
hook_jni.js
Java.perform(function () {
console.log("[*] 正在挂钩目标类: com.igio90.crackme2.MainActivity");
// Hook MainActivity 中的 init 方法
var MainActivity = Java.use("com.igio90.crackme2.MainActivity");
MainActivity.init.implementation = function () {
console.log("[+] 成功拦截到 init() 方法!");
console.log("[+] 正在屏蔽自毁逻辑 (System.exit(0))…");
try {
// 这里我们只执行跳转逻辑,但不执行 postDelayed 里的退出
var application = this.getApplicationUsingReflection();
var Intent = Java.use("android.content.Intent");
var intent = Intent.$new(application, Java.use("com.igio90.crackme2.MainActivity").class);
intent.addFlags(268435456);
application.startActivity(intent);
console.log("[+] 页面已成功启动,已跳过自毁计时器。");
} catch (e) {
console.log("[-] 错误: " + e);
}
};
});
(frida_env) PS D:\\FridaWorkSpace> uv run frida -U -p 10780 -l hook_jni.js
____
/ _ | Frida 17.9.8 – A world-class dynamic instrumentation toolkit
| (_| |
> _ | Commands:
/_/ |_| help -> Displays the help system
. . . . object? -> Display information about 'object'
. . . . exit/quit -> Exit
. . . .
. . . . More info at https://frida.re/docs/home/
. . . .
. . . . Connected to AOSP on angler (id=8XV7N16125004864)
[AOSP on angler::PID::10780 ]-> [*] 正在挂钩目标类: com.igio90.crackme2.MainActivity
[+] 成功拦截到 init() 方法!
[+] 正在屏蔽自毁逻辑 (System.exit(0))…
[+] 页面已成功启动,已跳过自毁计时器。
当我们点击按钮就不会重启自己了!!! 
接下来我们干啥呢? 当然还是IDA动态调试了
5|angler:/ # ./data/local/tmp/as64
IDA Android 64-bit remote debug server(ST) v9.2.31. Hex-Rays (c) 2004-2025
2026-06-05 11:51:43 Listening on :::23946...
2026-06-05 11:52:13 [1] Accepting connection from ::ffff:127.0.0.1...
PS C:\\Users\\HiMaq> adb forward tcp:23946 tcp:23946
23946
我们开始附加pid,注意是下面这个10780 
再使用frida hook MainActivity
adb shell am start com.igio90.crackme2/.MainActivity
adb shell am start -D -n com.igio90.crackme2/.MainActivity
拦截main进程 unlock 函数
private native void unlock(int arg1) { }
function doHook() {
Java.perform(function () {
var MainActivity = Java.use("com.igio90.crackme2.MainActivity");
MainActivity.unlock.implementation = function (pin) {
console.log("[+] 捕获到 unlock 调用,PIN: " + pin);
// 【关键点】:完全注释掉 return this.unlock(pin);
// 如果程序不依赖 unlock 的返回值(即该方法只是为了校验),
// 那么不调用原逻辑可能直接绕过崩溃!
console.log("[+] 已拦截执行流,尝试跳过 Native 校验…");
};
});
}
setImmediate(doHook);
执行
(frida_env) PS D:\\FridaWorkSpace> uv run frida -U -p 8429 -l hook_jni2.js
____
/ _ | Frida 17.9.8 – A world-class dynamic instrumentation toolkit
| (_| |
> _ | Commands:
/_/ |_| help –> Displays the help system
. . . . object? –> Display information about 'object'
. . . . exit/quit –> Exit
. . . .
. . . . More info at https://frida.re/docs/home/
. . . .
. . . . Connected to AOSP on angler (id=8XV7N16125004864)
[AOSP on angler::PID::8429 ]–> [+] 捕获到 unlock 调用,PIN: 1234
[+] 已拦截执行流,尝试跳过 Native 校验...
[+] 捕获到 unlock 调用,PIN: 1234
[+] 已拦截执行流,尝试跳过 Native 校验...
[+] 捕获到 unlock 调用,PIN: 1234
[+] 已拦截执行流,尝试跳过 Native 校验...
[+] 捕获到 unlock 调用,PIN: 1234
[+] 已拦截执行流,尝试跳过 Native 校验...
[+] 捕获到 unlock 调用,PIN: 1234
[+] 已拦截执行流,尝试跳过 Native 校验...
好的 我们注释掉hook代码 接下来使用 ida 来动态调试一波 attach 就直接崩了~
回到静态分析 hook_jni2.js 以下是CC给我出的答案
Java.perform(function () {
var moduleName = "libigio.so";
var mod = Process.findModuleByName(moduleName);
if (!mod) {
console.log("[-] 模块未找到,等待中…");
setTimeout(doHook, 1000);
return;
}
console.log("[+] 基址: " + mod.base);
// 在校验比较处打印v81的实际内容
Interceptor.attach(mod.base.add(0xC30), {
onEnter: function (args) {
this.pass = args[2].toInt32();
}
});
// 暴力枚举
for (var i = 1000; i <= 9999; i++) {
var s = i.toString();
var v49 = 0x43 ^ s.charCodeAt(0);
var v46 = s.charCodeAt(1);
var v47 = s.charCodeAt(2);
var v48 = s.charCodeAt(3);
if (v49 == 0x71
&& (v46 ^ v49) == 0x45
&& (v47 ^ v46 ^ v49) == 0x74
&& (v48 ^ v47 ^ v46 ^ v49) == 0x44) {
console.log("[!!!] 找到答案: " + i);
}
}
});
(frida_env) PS D:\\FridaWorkSpace> uv run frida -U -p 4866 -l hook_jni2.js
____
/ _ | Frida 17.9.8 – A world-class dynamic instrumentation toolkit
| (_| |
> _ | Commands:
/_/ |_| help –> Displays the help system
. . . . object? –> Display information about 'object'
. . . . exit/quit –> Exit
. . . .
. . . . More info at https://frida.re/docs/home/
. . . .
. . . . Connected to AOSP on angler (id=8XV7N16125004864)
Attaching...
[*] PID: 4866
[+] 基址: 0x793b8e1000
[!!!] 找到答案: 2410
输入密码 如愿以尝~ 成功夺旗! 
我们来回顾下 这段静态分析的代码 白帽子之逆向Crackme2.apk – 反调试(二)