【逆向】Android程序Hook native方法
提供的 CrackmeTest.apk 功能为:对输入密码进行验证,程序含有反调试机制(不影响hook),通过Frida实现Hook native库的验证方法,始终返回true实现绕过。
也可以通过动态调试+patch方法实现:Android逆向去壳
目录
环境
Frida
安装
反编译
代码
利用
环境
环境:Windows,java环境。
工具:Frida,jadx-gui , 雷神模拟器,adb工具。
Frida
Frida Client (客户端):主机上运行的工具(如 frida、frida-trace、frida-ps 等)。
Frida Server (服务器):在目标设备(Android)上运行的程序。
安装Client:
pip3 install frida-tools
frida --version
安装Server:Releases · frida/frida
下载frida-server-*-android-x86_64.xz,解压,重命名,注意版本要与Windows上安装的frida-client一致,推荐17.4.1。
安装
安装Frida,上传apk:
(若不能su,在雷神模拟器设置中找到高级设置,开启Root权限,重启模拟器。)
#检查adb设备是否识别:
adb devices# 推送frida-server到模拟器
adb push frida-server /data/local/tmp/
adb push crackme.apk /data/local/tmp/#安装APK应用
adb install crackme.apk# 进入模拟器shell
adb shell# 提权并运行
su
cd /data/local/tmp
chmod 755 frida-server
./frida-server &
另开一个shell运行Client:
# 查看所有进程
frida-ps -U# 查看安装的应用
frida-ps -Uai# 附加到正在运行的进程
frida -U -l script.js 进程名# 启动并附加到新进程
frida -U -f 包名 -l script.js
反编译
下载jadx:jadx
使用 jadx 反编译 APK,可以得到包com.mytest0.crackme,包含类MainActivity、ResultActivity、资源映射R,以及APK签名。

代码
package com.mytest0.crackme;import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;public class MainActivity extends Activity {public Button btn_submit;public EditText inputCode;public native boolean securityCheck(String str);/* access modifiers changed from: protected */public void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);getWindow().setBackgroundDrawableResource(R.drawable.bg);this.inputCode = (EditText) findViewById(R.id.inputcode);this.btn_submit = (Button) findViewById(R.id.submit);this.btn_submit.setOnClickListener(new View.OnClickListener() {/* class com.mytest0.crackme.MainActivity.AnonymousClass1 */public void onClick(View v) {if (MainActivity.this.securityCheck(MainActivity.this.inputCode.getText().toString())) {MainActivity.this.startActivity(new Intent(MainActivity.this, ResultActivity.class));return;}Toast.makeText(MainActivity.this.getApplicationContext(), "验证码校验失败", 0).show();}});}static {System.loadLibrary("crackme");}
}
package com.mytest0.crackme;import android.app.Activity;
import android.os.Bundle;
import android.widget.TextView;public class ResultActivity extends Activity {public void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);TextView tv = new TextView(this);tv.setText("密码正确!");setContentView(tv);}
}
代码逻辑即调用native库的securityCheck方法验证输入密码是否正确,若正确则调用ResultActivity,使用Frida Hook securityCheck方法返回恒为true即可。
利用
Java.perform(function() {console.log("[+] CrackMe Application Hook");console.log("====================================");var MainActivity = Java.use("com.mytest0.crackme.MainActivity");// Hook securityCheck 方法MainActivity.securityCheck.implementation = function(inputCode) {console.log("\n[+] === securityCheck Called ===");console.log(" Input Code: " + inputCode);console.log(" Input Length: " + inputCode.length);console.log(" Input Type: " + typeof inputCode);// 打印调用栈console.log("\n[+] Call Stack:");console.log(Java.use("android.util.Log").getStackTraceString(Java.use("java.lang.Throwable").$new()));// 调用原始方法var originalResult = this.securityCheck(inputCode);console.log("\n[+] Original Result: " + originalResult);if (originalResult) {console.log("[+] Original validation PASSED");} else {console.log("[+] Original validation FAILED");}// 强制返回 true 绕过验证console.log("[!] FORCING RETURN: true (Bypass activated)");return true;};// Hook 按钮点击事件(可选)var OnClickListener = Java.use("android.view.View$OnClickListener");OnClickListener.onClick.implementation = function(view) {console.log("\n[+] Button clicked!");return this.onClick(view);};console.log("[+] All hooks installed successfully");console.log("[+] Waiting for user input...");
});
启动:
adb shell am start -n com.mytest0.crackme/.MainActivity
运行 Hook 脚本:
frida -U -l hook_crackme.js -f com.mytest0.crackme
然后直接点击即可通过验证:

