当前位置: 首页 > news >正文

某梆企业壳frida检测绕过

遇到个汽车app 是个企业壳 有frida检测,导致无法注入,本文记录下绕过的过程

一、尝试hook pthread_create 定位线程 通过杀线程方法干掉他

function hook_pthread_create(){var pthread_create_addr = Module.findExportByName("libc.so", "pthread_create");console.log("pthread_create_addr: ", pthread_create_addr);Interceptor.attach(pthread_create_addr,{onEnter:function(args){console.log(args[2], Process.findModuleByAddress(args[2]).name);},onLeave:function(retval){}});}hook_pthread_create();

发现没有起到什么用,应该是检测到 pthread_create被hook了,它既然检测 pthread_create 函数得hook ,那clone函数应该没有把 通过hook clone函数 得到线程相关信息然后去nop 干掉线程 是不是就可以实现绕过。

二、在app中的系统目录下找到libc.so文件,导出一份用ida打开,看pthread_create 如何去调用clone函数创建线程的

// Hook clone 系统调用Interceptor.attach(Module.findExportByName(null, 'clone'), {onEnter: function (args) {// 获取线程函数的地址(即第一个参数)var thread_func = args[0];// 打印线程函数地址console.log('Thread function address: ' + thread_func);// 获取线程函数所在模块(.so 文件)var module = Process.findModuleByAddress(thread_func);if (module) {console.log('Thread function is located in module: ' + module.name);} else {console.log('Thread function is not in a loaded module or location could not be determined.');}},onLeave: function (retval) {// 可以在这里修改 clone 的返回值(如需要)}});输出Thread function address: 0x749b4140dcThread function is located in module: libc.soThread function address: 0x749b4140dcThread function is located in module: libc.soThread function address: 0x749b4140dcThread function is located in module: libc.so

从上面 clone hook处 ,打印下堆栈 ,看下哪里调用了 代码和hook 结果如下

Interceptor.attach(Module.findExportByName(null, 'clone'), {onEnter: function (args) {// 获取线程函数地址var thread_func = args[0];// 尝试获取线程函数所在模块var module = Process.findModuleByAddress(thread_func);if (module) {console.log('Thread function is located in module: ' + module.name);} else {}// 打印调用栈console.log('Backtrace:');console.log(Thread.backtrace(this.context, Backtracer.ACCURATE).map(DebugSymbol.fromAddress).join('\n'));},onLeave: function (retval) {// 返回值处理(如果需要)}});结果Thread function is located in module: libc.soBacktrace:0x749b413e40 libc.so!pthread_create+0x27c

然后 IDA跳转到pthread_create+0x27c 此处 调用了函数E6850 于是进去瞧一瞧 发现是DCQ数据

继续使用frida hook 读取下 结果是clone 也就说这里调用了clone函数

Interceptor.attach(Module.findExportByName(null, 'clone'), {onEnter: function (args) {// 获取线程函数地址var thread_func = args[0];// 尝试获取线程函数所在模块var module = Process.findModuleByAddress(thread_func);if (module) {console.log('Thread function is located in module: ' + module.name);const address = module.base.add(0xF06E8);const value = Memory.readU64(address);const symbol = DebugSymbol.fromAddress(ptr(value));console.log("name",symbol.name)} else {}// 打印调用栈},onLeave: function (retval) {// 返回值处理(如果需要)}});结果 clone

观察 pthread_create 函数的传参走向 也就是 a3,我们将a3改名为kanwoquanli。

红色箭头所指的 E6850是clone 而 通过 pthread_create 函数创建线程传递的 线程函数 就是 v50 而clone函数的第四个参数 v27 + 96 是所需要的线程函数 这样 就可以去试试 写一下hook clone代码了

var clone = Module.findExportByName('libc.so', 'clone');Interceptor.attach(clone, {onEnter: function(args) {// args[3] 子线程的栈地址。如果这个值为 0,可能意味着没有指定栈地址if(args[3] != 0){var addr = args[3].add(96).readPointer()var so_name = Process.findModuleByAddress(addr).name;var so_base = Module.getBaseAddress(so_name);var offset = (addr - so_base);console.log("===============>", so_name, addr,offset, offset.toString(16));}},onLeave: function(retval) {}});

后运行后发现, 打印出来了我们所需要的参数 

最后 我们 去给他nop掉 即可

function hook_dlopen(so_name) {Interceptor.attach(Module.findExportByName(null, "android_dlopen_ext"), {onEnter: function (args) {var pathptr = args[0];if (pathptr !== undefined && pathptr != null) {var path = ptr(pathptr).readCString();// console.log(path)if (path.indexOf(so_name) !== -1) {this.match = true}}},onLeave: function (retval) {if (this.match) {console.log(so_name, "加载成功");var base = Module.findBaseAddress("libDexHelper.so")patch_func_nop(base.add(322008));patch_func_nop(base.add(308756));}}});}function patch_func_nop(addr) {Memory.patchCode(addr, 8, function (code) {code.writeByteArray([0xE0, 0x03, 0x00, 0xAA]);code.writeByteArray([0xC0, 0x03, 0x5F, 0xD6]);console.log("patch code at " + addr)});}hook_dlopen("libDexHelper.so")

http://www.dtcms.com/a/319135.html

相关文章:

  • 网页前端CSS实现表格3行平均分配高度,或者用div Flexbox布局
  • Springboot2+vue2+uniapp 实现搜索联想自动补全功能
  • vue2.如何给一个页面设置动态的name。不同路由使用一样的组件。页面不刷新怎么办?
  • 小米前端笔试和面试
  • Redis 分布式Session
  • 内存杀手机器:TensorFlow Lite + Spring Boot移动端模型服务深度优化方案
  • 前端三大核心要素以及前后端通讯
  • 机器学习之随机森林(Random Forest)实战案例
  • 数据结构第8问:什么是树?
  • 深入理解String类:揭秘Java字符串常量池的优化机制
  • word生成问题总结
  • 【智能协同云图库】第六期:基于 百度API 和 Jsoup 爬虫实现以图搜图
  • 北京-4年功能测试2年空窗-报培训班学测开-第七十天-面试第一天
  • 国内主流数据集成厂商有哪些?有那些免费的数据集成平台?
  • 容器 vs 虚拟机
  • 机器学习核心算法与实践要素(全篇)
  • 汽车流通行业4S门店生存性指标:零服吸收率
  • 0基础法考 单选50条错题总结
  • 安卓系统属性之androidboot.xxx转换成ro.boot.xxx
  • 分布式面经
  • 虚幻GAS底层原理解剖七 (ASC)
  • Day 6: CNN卷积神经网络 - 计算机视觉的核心引擎
  • 多场景两阶段分布式鲁棒优化模型、数据驱动的综合能源系统
  • PostgreSQL面试题及详细答案120道(61-80)
  • 59.螺旋矩阵II
  • 恒虚警检测(CFAR)仿真:杂波边缘与多目标场景分析
  • 目标检测数据集 - 疟疾检测数据集下载「包含VOC、COCO、YOLO三种格式」
  • 微算法科技(NASDAQ:MLGO)利用集成学习方法,实现更低成本、更稳健的区块链虚拟货币交易价格预测
  • RocketMQ概览
  • Kotlin中String的==相等比较符