首页
社区
课程
招聘
[原创]APP加固dex解密流程分析
发表于: 2024-2-22 04:44 46699

[原创]APP加固dex解密流程分析

2024-2-22 04:44
46699
收藏
免费 67
支持
分享
打赏 + 10.00雪花
打赏次数 1 雪花 + 10.00
 
赞赏  万里星河   +10.00 2024/02/27 如沐春风 收益匪浅 敬仰之情 涛涛不绝
最新回复 (84)
雪    币: 478
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
51
万里星河 太强了我的佬
最后于 2024-4-3 12:30 被mb_eiaothcj编辑 ,原因:
2024-4-3 12:29
0
雪    币: 478
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
52
oacia 这里program header table的大小应该是0x38*0x6的,不过我当时好奇后面是不是还有数据所以就dump的稍微多了些[em_85][em_85][em_85]
这个看010editor就能看出来大小为0x150,我看的时候还比较好奇,你dump出来的多了0x20是怎么修复回去的,不会多么
2024-4-5 15:45
0
雪    币: 401
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
53
太强了
2024-4-17 05:03
0
雪    币: 116
活跃值: (1012)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
54
话说三次指针佬你是怎么发现的
2024-4-25 15:21
0
雪    币: 0
活跃值: (532)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
55
楼主分析问题真的举重若轻啊,思路非常清晰!
2024-4-29 10:01
0
雪    币: 718
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
56
过于牛逼,无法阅读
2024-6-10 15:06
1
雪    币: 2
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
57
太牛了,感谢分享
2024-6-10 18:08
0
雪    币: 950
活跃值: (1405)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
tmi
58
硬核
2024-6-11 10:12
0
雪    币: 72
活跃值: (422)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
59
楼主太厉害了,基本分析干净了~
持续关注native oncteate~
2024-6-11 10:38
0
雪    币: 116
活跃值: (1012)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
60
oacia 因为section段的信息被修改了,而ida静态分析首先依据的就是section段的相关内容,其实对于壳ELF来说,我们可以直接将section段的内容全部都置为0这样IDA会自己通过动态表找到对应的 ...

重温经典 实际复现后 我感觉dlopen的交叉引用也许真的只有一个 理由如下:

1.so_fixer是基于动态段对节区进行重构
2.so_fixer的github官网作者也说对重定位的计算有些问题 而dlopen作为导入函数与重定位直接挂钩
3.实践后发现经so_fixer修复后的so dlopen处并没有被重定位到真正的dlopen 而是存在着一个符号的错位
4.正如大佬所说 经过so_fixer修复后再将重构的节区置0 ida就会根据动态段直接进行解析 同样的数据源 ida大概率没有so_fixer已有的bug 结果更加可信
5.经测试 ida直接解析的dlopen的引用位置也没有问题 在其他函数中对其它导入符号的解析看起来也比so_fixer正常很多
综上 so_fixer有些问题 dlopen的交叉引用大概真的只有一个

最后于 2024-6-12 17:42 被万里星河编辑 ,原因:
2024-6-12 17:37
0
雪    币: 3443
活跃值: (14163)
能力值: ( LV9,RANK:230 )
在线值:
发帖
回帖
粉丝
61
目前是我看到分析最全的一篇文章,???? 。

但是我一点不太理解,就是这种自定义linker这种,直接dump内存在修复不行么?
2024-8-7 17:13
0
雪    币: 3507
活跃值: (4838)
能力值: ( LV9,RANK:140 )
在线值:
发帖
回帖
粉丝
62
珍惜Any 目前是我看到分析最全的一篇文章,???? 。 但是我一点不太理解,就是这种自定义linker这种,直接dump内存在修复不行么?
这里使用的思路也是dump内存再修复,只是这个由自定义linker加载的so在dump下来之后因为program header table被加密的缘故,而解密后的pht又和被加载so所映射的内存是分离的,sofixer这种so修复工具没有办法正常解析so,所以得找到解密后的pht,我使用的办法是直接追函数执行流找到pht的解密函数,然后静态解密出来再patch回去,其实应该有更加通用的方法就是找到soinfo然后去读soinfo->phdr,重构program header table,我看到seeflower大佬的一篇blog https://blog.seeflower.dev/archives/299/ 中,是通过hook soinfo->call_constructors获取到soinfo指针的。我觉得或许只要拿到soinfo,通过对这个结构体的各个成员进行逆向解析,依次获取soinfo中记录的ELF文件各个字段所映射的地址,并读取相对应的内存,就能够重构出一个标准的so来?。
2024-8-8 06:41
0
雪    币: 3443
活跃值: (14163)
能力值: ( LV9,RANK:230 )
在线值:
发帖
回帖
粉丝
63
oacia 这里使用的思路也是dump内存再修复,只是这个由自定义linker加载的so在dump下来之后因为program header table被加密的缘故,而解密后的pht又和被加载so所映射的内存是分离 ...
我也遇到过这个问题,program header table 他其实不是被加密,是抹掉了,我在sofixer里面跳过了 program header table的检测 ,就好了 。

不过你说的这个也是个办法。感谢分享
2024-8-8 14:55
0
雪    币: 15003
活跃值: (6213)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
64
楼主研究一下360vip加固?
2024-8-9 16:05
0
雪    币: 0
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
65
function hook_5E6C(){
    var module = Process.findModuleByName("libjiagu_64.so");
    Interceptor.attach(module.base.add(0x5E6C), {
        // fd, buff, len
        onEnter: function (args) {
            console.log(hexdump(args[0], {
              offset: 0,// 相对偏移
              length: 0x38*0x6+0x20,//dump 的大小
              header: true,
              ansi: true
            }));
            console.log(args[1])
            console.log(args[2])
            console.log(`base = ${module.base}`)
        },
        onLeave: function (ret) {
        }
    });
}这里的0x20是什么
2024-9-7 09:03
0
雪    币: 3507
活跃值: (4838)
能力值: ( LV9,RANK:140 )
在线值:
发帖
回帖
粉丝
66
mb_ytiyqklv function hook_5E6C(){ var module = Process.findModuleByName("libjiagu_64.so"); I ...
当时想看看后面还有没有其他的数据所以就dump的稍微多了一些
2024-9-7 13:37
1
雪    币: 3507
活跃值: (4838)
能力值: ( LV9,RANK:140 )
在线值:
发帖
回帖
粉丝
67
tDasm 楼主研究一下360vip加固?
之后如果有遇到的话会去分析一下滴
2024-9-7 13:39
0
雪    币: 15003
活跃值: (6213)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
68
oacia 之后如果有遇到的话会去分析一下滴[em_27]
北京时间app
2024-9-7 14:39
0
雪    币: 0
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
69
function hook_libjiagu() {
    var module_name = "libjiagu_64.so";

    Interceptor.attach(Module.findExportByName(null, "android_dlopen_ext"), {
        onEnter: function (args) {
            this.path = args[0].readCString();
        },
        onLeave: function (retval) {
            // 检查模块是否是我们关心的模块
            if (this.path.indexOf(module_name) !== -1) {
                console.log(module_name + " loaded at: " + Module.findBaseAddress(module_name));
                
                // 模块加载后进行 Hook
                var module = Process.findModuleByName(module_name);
                if (module) {
                    Interceptor.attach(module.base.add(0x1770C), {
                        onEnter: function (args) {
                            try {
                                var s = this.context.x6.readCString();
                                if (s.indexOf('frida') !== -1 ||
                                    s.indexOf('gum-js-loop') !== -1 ||
                                    s.indexOf('gmain') !== -1 ||
                                    s.indexOf('linjector') !== -1 ||
                                    s.indexOf('/proc/') !== -1) {

                                    console.log(s);
                                    Memory.protect(this.context.x0, Process.pointerSize, 'rwx');
                                    var replace_str = "00";
                                    /*
                                    for (var i = 0; i < s.length; i++) {
                                        replace_str += "0";
                                    }
                                        */
                                    this.context.x0.writeUtf8String(replace_str);
                                }
                            } catch (e) {
                                //console.error("Error: ", e);
                            }
                        },
                        onLeave: function (ret) {}
                    });
                } else {
                    console.error("Module not found: " + module_name);
                }
            }
        }
    });
}

// 调用函数启动 Hook
hook_libjiagu();
过调试部分需要模块加载以后hook
2024-9-8 00:10
0
雪    币: 202
活跃值: (1250)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
70
大神,能不能讲下i国网这个app怎么开启webview调试
2024-9-8 16:29
0
雪    币: 409
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
71
太强啦我的佬
2024-9-23 13:14
0
雪    币: 11
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
72
太卷了我的佬,头发还好嘛
2024-10-4 03:16
0
雪    币: 2299
活跃值: (3012)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
73
感谢分享
2024-10-4 10:40
0
雪    币: 10
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
74
万里星河 oacia 因为section段的信息被修改了,而ida静态分析首先依据的就是section段的相关内容,其实对于壳ELF来说,我们可以直 ...
确实,我也发现sofixer修复的有一些导入函数解析错了
2024-10-7 20:01
0
雪    币: 116
活跃值: (1012)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
75
night star 确实,我也发现sofixer修复的有一些导入函数解析错了

不容易啊 快半年了 终于有人遇到和我一样的问题了 感动

最后于 2024-10-8 03:12 被万里星河编辑 ,原因:
2024-10-8 03:11
1
游客
登录 | 注册 方可回帖
返回
//