360加固之libjiagu.so dump修复

本文详细介绍了如何修复360加固后的libjiagu.so dump文件,包括elf header的修复、so及其dump差异分析以及dump修复过程,特别是针对重定位数据的修复。修复后的dump文件能够被正常加载,并且导入函数和字符串能够被正确解析,对于加固SO的分析提供了便利。

一、elfheader修复

dump出来的内存如下图所示,elf header结构有缺失

下面是正常elf头的对比图

下面是010editor对正常elf header的解析

    由上图可知,dump出来的elf header除了e_phoff、e_phentsize、e_phum三个值,其它都为0。

   不过这里缺失的,除了e_shoff, e_shnum, e_shtrndx三个是变量,其它都是固定值。而实际上e_shoff, e_shnum, e_shtrndx这三个值在dlopen时并没有用到,全部填0,也可以正常使用。

   那么这里elf header把固定值填上,e_shoff, e_shnum, e_shtrndx三个值留空,elf header就修复好了。

   elf header修复完成后的dump就跟一个so经过dlopen后,dump出来的内存是一样的了。但是这样的dump是不能直接加载的,很多情况下用IDA分析也会缺失导入函数的解析。

 

二、so及其dump差异分析

    为了修复这个dump出来的so,我们写一个so来做个测试。

将测试so加载后,dump出来进行加载前后的对比


    后面一大块数据不一样。首先有个问题就是内存里的对齐跟文件是有差异的。

    看下elf Loadable Segment


    可以发现第二个Loadable Segmentp_offsetp_vadder是一样的,相差了0x1000,dump出来的内存在这个位置会比file0x1000

 

   Dynamic Segment同样存在这样的差异。

三、so dump修复

   由于dump的数据是跟内存加载后是一致的,把上面两个Segment里的p_offset都改成跟p_vaddr一样的值。

   完成这样的修改后,IDA就可以正常解析导入函数了,因为IDA对导入函数的解析依赖于Dynamic Segment里的数据。

   如果要能让dump能正常被dlopen起来,还需要继续对重定位数据进行修复

下面是DynamicSegmentrel对应的数据


可知rel对应的数据开始于0x6aa8,大小为0xf30


0x6aa8指向的elf32_rel结构体数组

typedef structelf32_rel {
       Elf32_Addr   r_offset;
       Elf32_Word  r_info;
} Elf32_Rel;

r_offset指向的地址会被重定位

下图是原始so的数据:


下图是dump内经过重定位的数据:


    可以发现dump里的数据被加上了so的加载基址,修复的时候,减去基址就可以恢复原始数据

    除了rel还有plt_rel需要修复,修复方法跟rel一样

    由于relplt_rel需要修复的数据量比较大,手动修复不太现实,需要编写个工具来完成这样的修复。可以把dlopen里的源码扣出来做一些修改完成这样的操作。

    下面是两张IDA分析的截图:




    修复后的so,跟普通so已经没什么区别了,导入函数和字符串暴露无遗。居然没有对字符串做加密,这样给分析者带来很大方便,对于加固核心so来说有点太依赖so加固了。

  (创建了一个Android逆向分析群,欢迎有兴趣的同学加入,群号码:376745720)

<think>嗯,用户想知道如何用Dobby Hook结合libart.so来脱壳并Dump Dex文件。首先,我需要回忆一下Dobby Hook的相关知识。Dobby是一个多平台的Hook库,支持Android的ARM和ARM64架构,对吧?用户提到的脱壳通常是指从加壳的Android应用中提取原始的Dex文件。而libart.so是Android运行时库,负责执行Dex字节码,所以脱壳的关键点可能在于Hook libart.so中的关键函数,比如加载Dex或执行方法时的函数。 根据引用中的资料,比如引用3提到Dobby的inline hook原理,以及引用4中提到的Hook so层的方法,应该需要找到libart.so中负责Dex加载的函数。可能的目标函数包括OpenMemory、DefineClass或者DexFile相关的函数。例如,Art::DexFile::OpenMemory这个函数,当应用加载Dex时会被调用,Hook它可能可以获取到内存中的Dex数据。 然后,用户需要编写Hook代码,使用Dobby的DobbyHook函数来替换目标函数。在回调函数中,获取Dex文件的起始地址和大小,然后将这段内存数据写入文件,完成Dump。需要注意的是,加壳技术可能会有反Hook措施,所以可能需要绕过这些保护,比如检查代码签名(如引用3中的情况),或者处理多进程注入的问题。 另外,脱壳的时机也很重要。有些壳会在运行时动态解密Dex,所以需要找到合适的时机进行Dump,比如在类被加载时或者方法被执行时。可能需要Hook多个函数,确保覆盖所有可能的解密阶段。 还需要考虑Android版本的问题,不同版本的libart.so可能有不同的函数符号,需要找到对应版本的偏移地址或者符号名。对于Android 8.0以上,可能需要使用dlopen和dlsym来动态获取函数地址,或者解析ELF头来定位。 用户可能需要参考现有的脱壳工具或方法,比如Frida的脚本或者Xposed模块,了解它们是如何Hook这些函数的,然后将其迁移到使用Dobby Hook来实现。同时,要注意权限问题,可能需要root权限或者绕过签名验证,尤其是在非越狱环境下(如引用3提到的代码签名检查)。 最后,测试和验证是关键。编写完Hook代码后,需要在目标应用上测试,确认能够成功Dump出Dex文件,并且文件没有损坏,可以使用反编译工具打开。如果遇到问题,可能需要调试Hook过程,检查参数是否正确,内存地址是否有效,以及是否有反调试机制在干扰。</think>### 如何结合Dobby Hook与libart.so进行Dex脱壳 #### 1. 核心思路 通过Hook `libart.so` 中与Dex加载相关的关键函数(如 `Art::DexFile::OpenMemory`),在内存中捕获解密后的Dex数据并导出。Dobby Hook用于实现函数拦截,绕过加壳保护[^3][^4]。 #### 2. 实现步骤 **(1) 定位关键函数** - 目标函数示例: - `Art::DexFile::OpenMemory`(Dex文件加载入口) - `ClassLinker::DefineClass`(类加载时触发) - `art::DexFile::WriteToMemory`(内存写入Dex) - 需根据Android版本适配符号名,例如Android 8.0后符号命名规则改变[^2]。 **(2) 编写Hook代码** ```cpp #include "dobby.h" // 定义原始函数指针 static void* (*orig_OpenMemory)(const uint8_t* base, size_t size, ...); // 自定义Hook函数 void* fake_OpenMemory(const uint8_t* dex_base, size_t dex_size, ...) { LOG("捕获到Dex内存地址: %p, 大小: %zu", dex_base, dex_size); // 将内存数据写入文件 FILE* fp = fopen("/data/local/tmp/dex_dump.dex", "wb"); fwrite(dex_base, 1, dex_size, fp); fclose(fp); return orig_OpenMemory(dex_base, dex_size, ...); } // 初始化Hook void init_hook() { void* target_addr = DobbySymbolResolver("libart.so", "_ZN3art7DexFile10OpenMemoryEPKhjRKNSt3__112basic_stringIcNS3_11char_traitsIcEENS3_9allocatorIcEEEEjPNS_6MemMapEPKNS_10OatDexFileEPS9_"); DobbyHook(target_addr, (void*)fake_OpenMemory, (void**)&orig_OpenMemory); } ``` **(3) 注入与触发** - 使用 `ptrace` 或 `LD_PRELOAD` 注入so到目标进程 - 调用 `init_hook()` 激活Hook - 触发目标应用加载Dex(如启动Activity) #### 3. 关键问题解决 **(1) 反调试绕过** - 通过Hook `ptrace`/`syscall` 阻止调试检测 - 修改进程状态标志(如 `TASK_PTRACE`) **(2) 多Dex处理** - 使用哈希表记录已导出的Dex地址,避免重复Dump - 监听多个生命周期阶段(安装时/运行时) #### 4. 验证结果 - 使用 `dex2jar` 或 `jadx` 验证导出的Dex文件可读性 - 对比加壳前后方法数量变化
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值