首页
社区
课程
招聘
[原创]通过DVM指令还原壳的抽空类
发表于: 2023-1-13 16:53 19713

[原创]通过DVM指令还原壳的抽空类

2023-1-13 16:53
19713

首先参考阅读这篇文章
ART 在 Android 安全攻防中的应用

code_item指令会执行到Execute函数

来自于EnterInterpreterFromInvoke的调用

对应于我的libart.so的地址分别是0x002D8F40 和 0x002D85C0

在0x002D8F40处下断点,第二个参数即为DexFile::CodeItem*的值
地址指针为esp+0x4处
根据CodeItem的定义可以得知

指令的长度为CodeItem+0xC的值*2+0x10

有了这两个参数就可以实时的导出所运行的指令

处于测试的目的我手动调用JAVA函数,并在每一条JAVA指令下打印LOG

最终结果如下

日志信息为

修复时首先在class_def_item 中找到指定的类

然后在encoded_method_list中找到需要修复的函数,就可以跳转到对应的code_item

原始的code_item的值如下

日志中的值为

直接二进制替换

我一共修复了3个函数,分别为getEncString、getEncCode和parseByte2HexStr
对比一下原始的反编译效果如下

以下是修复后的效果

 
267    static inline JValue Execute(
268        Thread* self,
269        const DexFile::CodeItem* code_item,
270        ShadowFrame& shadow_frame,
271        JValue result_register,
272        bool stay_in_interpreter = false) SHARED_REQUIRES(Locks::mutator_lock_)
267    static inline JValue Execute(
268        Thread* self,
269        const DexFile::CodeItem* code_item,
270        ShadowFrame& shadow_frame,
271        JValue result_register,
272        bool stay_in_interpreter = false) SHARED_REQUIRES(Locks::mutator_lock_)
391    void EnterInterpreterFromInvoke(Thread* self, ArtMethod* method, Object* receiver,
392        uint32_t* args, JValue* result,
393        bool stay_in_interpreter)
391    void EnterInterpreterFromInvoke(Thread* self, ArtMethod* method, Object* receiver,
392        uint32_t* args, JValue* result,
393        bool stay_in_interpreter)
280  // Raw code_item.
281  struct CodeItem {
282    uint16_t registers_size_;            // the number of registers used by this code
283                                         //   (locals + parameters)
284    uint16_t ins_size_;                  // the number of words of incoming arguments to the method
285                                         //   that this code is for
286    uint16_t outs_size_;                 // the number of words of outgoing argument space required
287                                         //   by this code for method invocation
288    uint16_t tries_size_;                // the number of try_items for this instance. If non-zero,
289                                         //   then these appear as the tries array just after the
290                                         //   insns in this instance.
291    uint32_t debug_info_off_;            // file offset to debug info stream
292    uint32_t insns_size_in_code_units_;  // size of the insns array, in 2 byte code units
293    uint16_t insns_[1];                  // actual array of bytecode.
294
295   private:
296    DISALLOW_COPY_AND_ASSIGN(CodeItem);
297  };
280  // Raw code_item.
281  struct CodeItem {
282    uint16_t registers_size_;            // the number of registers used by this code
283                                         //   (locals + parameters)
284    uint16_t ins_size_;                  // the number of words of incoming arguments to the method
285                                         //   that this code is for
286    uint16_t outs_size_;                 // the number of words of outgoing argument space required
287                                         //   by this code for method invocation
288    uint16_t tries_size_;                // the number of try_items for this instance. If non-zero,
289                                         //   then these appear as the tries array just after the
290                                         //   insns in this instance.
291    uint32_t debug_info_off_;            // file offset to debug info stream
292    uint32_t insns_size_in_code_units_;  // size of the insns array, in 2 byte code units
293    uint16_t insns_[1];                  // actual array of bytecode.
294
295   private:
296    DISALLOW_COPY_AND_ASSIGN(CodeItem);
297  };
 
function hook_art_module(){
    var art_module = Module.findBaseAddress("libart.so");
    var Execute = art_module.add(0x002D8F40);   
    Interceptor.attach(Execute, {
    onEnter: function(args)
        {
            var vm_addr = Memory.readPointer((this.context.esp).add(0x4));
            var vm_size = Memory.readUInt(vm_addr.add(0xC));
            var code_size = vm_size*2+0x10;               
            console.log(hexdump(vm_addr, {
                offset: 0,
                length: code_size,
                header: true,
                ansi: true
            }));
        },
        onLeave: function (retval) {
 
        }
    });
}
function hook_art_module(){
    var art_module = Module.findBaseAddress("libart.so");
    var Execute = art_module.add(0x002D8F40);   
    Interceptor.attach(Execute, {
    onEnter: function(args)
        {
            var vm_addr = Memory.readPointer((this.context.esp).add(0x4));
            var vm_size = Memory.readUInt(vm_addr.add(0xC));
            var code_size = vm_size*2+0x10;               
            console.log(hexdump(vm_addr, {
                offset: 0,
                length: code_size,
                header: true,
                ansi: true
            }));
        },
        onLeave: function (retval) {
 

[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)

最后于 2023-1-16 16:19 被易之生生编辑 ,原因: 标点符号
收藏
免费 3
支持
分享
最新回复 (5)
雪    币: 116
活跃值: (1012)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
支持一下 但以下这句话没懂
在0x002D8F40处下断点,第二个参数即为DexFile::CodeItem*的值 地址指针为esp+0x4处
1.第二个参数的地址不应该存在R1寄存器吗 怎么会是esp + 0x4
2.art::interpreter::Excute函数的第二个参数不是art::shadowFrame*吗 怎么变成了DexFile::CodeItem* ?
2023-1-14 18:29
0
雪    币: 36
活跃值: (320)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
万里星河 支持一下 但以下这句话没懂 在0x002D8F40处下断点,第二个参数即为DexFile::CodeItem*的值 地址指针为esp+0x4处 1.第二个参数的地址不应该存在R1寄存器吗 怎么会是 ...
1、因为是X86环境下实时调试的 堆栈传值是在esp+0x4处
2、是IDA识别时的问题 已更正
2023-1-16 16:22
0
雪    币: 116
活跃值: (1012)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
易之生生 1、因为是X86环境下实时调试的 堆栈传值是在esp+0x4处 2、是IDA识别时的问题 已更正
懂了 感谢大佬
2023-1-18 20:21
0
雪    币: 116
活跃值: (1012)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
易之生生 1、因为是X86环境下实时调试的 堆栈传值是在esp+0x4处 2、是IDA识别时的问题 已更正
等等 我还是有疑问 就算是x86环境 此时程序断在函数头 也就是刚执行了call指令 那么esp此时存的应该是返回地址 esp+4是第一个参数 那么第二个参数应该是存在esp+8才对呀
2023-1-20 17:37
0
雪    币: 922
活跃值: (1803)
能力值: ( LV4,RANK:40 )
在线值:
发帖
回帖
粉丝
6
学习了
2024-1-4 23:35
0
游客
登录 | 注册 方可回帖
返回
//