安卓逆向2025 Frida学习之native层hook案例

admin 2025年2月10日11:43:44评论38 views字数 2201阅读7分20秒阅读模式
一、当我们随便填写注册码后,点击好吧,程序会自动退出
安卓逆向2025  Frida学习之native层hook案例
二、将apk载入jadx,搜索关键字“已保存”
安卓逆向2025  Frida学习之native层hook案例
三、双击进入该节点
安卓逆向2025  Frida学习之native层hook案例
四、分析上面代码,点击“好吧”之后,会结束进程,上面还有个加密函数saveSN,我们点击saveSN进去
安卓逆向2025  Frida学习之native层hook案例
五、这个是native原生函数,在myjni so文件里面,我们hook这里的saveSN函数,可以获取我们输入的值
letMyApp = Java.use("com.gdufs.xman.MyApp");MyApp["saveSN"].implementation = function (str) {console.log(`MyApp.saveSN is called: str=${str}`);this["saveSN"](str);        };
安卓逆向2025  Frida学习之native层hook案例
六、再hook 结束进程的函数killProcess,这里hook到后,不让该函数运行,点击“好吧”就不会退出了。
let prc = Java.use("android.os.Process");        prc["killProcess"].implementation = function (str) {console.log(`MyApp.saveSN is called: str=${str}`);//this["saveSN"](str);  hook不执行        };
七、so文件在lib文件夹里,通过ida载入该so文件
安卓逆向2025  Frida学习之native层hook案例
八、载入后在导出函数找不到saveSN函数,所以我们查看JNI_onload函数,双击进入,并按F5让汇编代码转为伪C代码
安卓逆向2025  Frida学习之native层hook案例
九、找到GetEnv函数,我们把光标移动到第一个箭头&g_env哪里,按快捷键Y,修改数据类型为JNIEnv*
安卓逆向2025  Frida学习之native层hook案例
安卓逆向2025  Frida学习之native层hook案例
十、此时会看到RegisterNatives函数,这是动态注册函数,双击他第三个参数,这是个数组,动态加载的函数都会在这个数组里面
安卓逆向2025  Frida学习之native层hook案例
十一、这时就看到了saveSN函数,下面的n2+1就是该函数地址,我们双击进去
安卓逆向2025  Frida学习之native层hook案例
十二、这就saveSN函数的汇编代码,我们hook一下这个函数
安卓逆向2025  Frida学习之native层hook案例
十三、通过findExportByName这个函数找到saveSN函数的地址,第一个参数so的名字,n2可以理解为saveSN的一个别名
let n2=Module.findExportByName("libmyjni.so","n2");console.log("n2地址:",n2)
十三、运行结果是这个,上面n2的函数地址为00011F8,加上so文件的基地址是0xcb9301f8,还是相差1
安卓逆向2025  Frida学习之native层hook案例
十四、选择General,将opecode这里改为4,点击ok
安卓逆向2025  Frida学习之native层hook案例
安卓逆向2025  Frida学习之native层hook案例
十五、有的四个字节,有的事两个字节,这是用到了两种编码方式arm和thumb,所以这时应该在看到的地址上+1才是他的真实地址。
安卓逆向2025  Frida学习之native层hook案例
十六、F5获取伪C代码,将第一个参数的数据类型修改为JNIENv*,a3是我们传进去的参数
安卓逆向2025  Frida学习之native层hook案例
十七、根据上面的伪C代码,逆向出还原算法如下:
function decrypt(encryptedStr) {    // 密钥表 v21    const v21 = Array.from("W3_arE_whO_we_ARE").map(c => c.charCodeAt(0));    // 初始化 v13    let v13 = 2016;    // 将加密字符串转换为字符数组    const encryptedArr = Array.from(encryptedStr);    // 遍历每个字符    for (let v15 = 0; v15 < encryptedArr.length; v15++) {        let v19;        // 根据 v15 % 3 的值更新 v13 并获取 v19        if (v15 % 3 === 1) {            v13 = (v13 + 5) % 16;            v19 = v21[v13 + 1];        } else if (v15 % 3 === 2) {            v13 = (v13 + 7) % 15;            v19 = v21[v13 + 2];        } else {            v13 = (v13 + 3) % 13;            v19 = v21[v13 + 3];        }        // 异或操作解密        encryptedArr[v15] = String.fromCharCode(encryptedArr[v15].charCodeAt(0) ^ v19);    }    // 返回解密后的字符串    return encryptedArr.join("");}
十八、再分析一下initSN这个函数,转为伪C代码,这段代码意思,就是判断我们输入的字符串经过saveSN函数加密后,再和这里面的字符串EoPAoY62@ElRD进行比较,如果相同就是正确的flag。
安卓逆向2025  Frida学习之native层hook案例
安卓逆向2025  Frida学习之native层hook案例
十九、运行JS代码,并把加密内容放进去
const encryptedStr = "EoPAoY62@ElRD";const decryptedStr = decrypt(encryptedStr);console.log("解密后的字符串:", decryptedStr);
运行结果:
 201608Am!2333

欢 迎 关 注

更多精彩内容关注下方公众号:逆向有你

个人微信:ivu123ivu

每日自动更新各类学习教程及工具下载合集

https://pan.quark.cn/s/8c91ccb5a474

安卓逆向2025  Frida学习之native层hook案例

原文始发于微信公众号(逆向有你):安卓逆向2025 -- Frida学习之native层hook案例

免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉。
  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2025年2月10日11:43:44
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   安卓逆向2025 Frida学习之native层hook案例https://cn-sec.com/archives/3720206.html
                  免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉.

发表评论

匿名网友 填写信息