如何使用Frida脚本提取AES密钥及解决‘device not found’报错问题
解决Frida "device not found" 报错及提取AES密钥的实用方案
一、先搞定 "device not found" 报错
这个报错说白了就是Frida找不到你的USB设备,别慌,按下面的步骤逐一排查:
- 确认设备连接和调试状态
- 先把手机和电脑用靠谱的USB线连好,确保手机已经开启开发者模式,并且打开了USB调试(部分手机还需要开启“USB调试(安全设置)”以允许调试权限)。
- 打开命令行执行
adb devices,查看列表中是否有你的设备。如果没显示,要么更换USB口/数据线,要么检查手机驱动,或者重启调试开关重试。
- 确保Frida服务在设备上正常运行
- 先在电脑上查看Frida版本:
frida --version,然后下载对应版本的frida-server(需匹配手机架构,比如arm64架构选择android-arm64版本)。 - 将server推送到手机:
adb push frida-server-xxx-android-arm64 /data/local/tmp/ - 赋予执行权限:
adb shell chmod 755 /data/local/tmp/frida-server-xxx-android-arm64 - 后台启动服务:
adb shell /data/local/tmp/frida-server-xxx-android-arm64 &
- 先在电脑上查看Frida版本:
- 修正脚本中的设备调用逻辑
- 如果是多设备或模拟器环境,直接用
get_usb_device()可能会识别失败,可以添加超时时间或指定设备ID:# 给设备连接添加30秒超时,避免因识别过慢报错 device = frida.get_usb_device(timeout=30) # 或者通过adb devices获取的设备ID指定设备 # device = frida.get_device("你的设备ID") session = device.attach('com.example.a11x256.frida_test') - 务必确认包名正确!执行
adb shell pm list packages可以查看设备上所有应用包名,确保com.example.a11x256.frida_test确实存在。
- 如果是多设备或模拟器环境,直接用
二、用Frida提取AES密钥的有效方法
AES密钥通常会在加密API调用、密钥生成或存储环节暴露,我们可以通过Hook关键节点捕获密钥,分两种场景给出方案:
1. 针对Java/Kotlin编写的APP
这类APP大多依赖javax.crypto包,Hook密钥相关的构造方法即可直接获取:
// hook_java_aes.js Java.perform(function() { // Hook SecretKeySpec构造方法,密钥会在此处传入 var SecretKeySpec = Java.use('javax.crypto.spec.SecretKeySpec'); SecretKeySpec.$init.overload('[B', 'java.lang.String').implementation = function(keyBytes, algorithm) { console.log("[+] AES密钥(字节数组): " + Array.prototype.slice.call(keyBytes)); console.log("[+] AES密钥(十六进制): " + bytesToHex(keyBytes)); console.log("[+] 加密算法: " + algorithm); // 必须调用原方法,否则应用会崩溃 return this.$init(keyBytes, algorithm); }; // 辅助函数:将字节数组转换为十六进制格式,便于阅读 function bytesToHex(arr) { return arr.map(function(byte) { return ('0' + (byte & 0xFF).toString(16)).slice(-2); }).join(''); } });
运行脚本的命令:frida -U -f com.example.a11x256.frida_test -l hook_java_aes.js --no-pause
2. 针对使用Native层加密的APP
如果APP依赖OpenSSL或自定义Native AES逻辑,直接Hook对应的Native函数:
// hook_native_aes.js Interceptor.attach(Module.findExportByName('libcrypto.so', 'EVP_EncryptInit_ex'), { onEnter: function(args) { // 判断是否为AES算法 var cipherName = ptr(args[2]).readCString(); if (cipherName && cipherName.includes("AES")) { // args[3]为密钥指针,长度根据AES类型调整:16=AES-128,24=AES-192,32=AES-256 var keyLength = 32; var keyBytes = args[3].readByteArray(keyLength); console.log("[+] Native层AES密钥(十六进制): " + hexdump(keyBytes, { offset: 0, length: keyLength, header: false, ansi: false })); } } });
运行脚本的命令:frida -U com.example.a11x256.frida_test -l hook_native_aes.js
3. 内存扫描兜底方案
如果Hook不到密钥,还可以通过内存扫描查找(适合已知密钥部分特征的场景):
// scan_memory.js Java.perform(function() { var mainModule = Process.enumerateModules()[0]; var startAddr = mainModule.base; var endAddr = startAddr.add(mainModule.size); // 将此处十六进制替换为你猜测的密钥片段,比如已知的部分密钥内容 Memory.scan(startAddr, endAddr.sub(startAddr), 'a1b2c3d4e5f6a7b8', { onMatch: function(address, size) { console.log("[+] 找到疑似AES密钥的地址: " + address.toString()); console.log("[+] 密钥内容: " + hexdump(address, { offset: 0, length: 32, header: false, ansi: false })); }, onComplete: function() { console.log("[+] 内存扫描完成"); } }); });
内容的提问来源于stack exchange,提问作者umer siddique
相关产品推荐
相关产品推荐

