首页
社区
课程
招聘
[原创]ART下Hook系统函数修改内存中指定方法的运行指令逻辑案例分享
发表于: 2020-4-2 00:12 8952

[原创]ART下Hook系统函数修改内存中指定方法的运行指令逻辑案例分享

2020-4-2 00:12
8952

可以在 jadx 中看到当check函数返回True时候则就成功了,因为 onCreate 被壳native 了,看不到逻辑,大概猜测就是在输入框输入flag点击按钮触发onClick中调用check返回True即可。

分析一下check函数,check函数首先是调用copyAssetAndWrite 复制了Assets中的 a.bin 到 CacheDir,然后调用testDexClassLoader,返回testDexClassLoader的返回值,为True就能得到flag了。

那就先分析a.bin这个dex文件吧,可以看到,当传进来的字符串做md5后等于zipCode时候,返回True,这尼玛这个逻辑明显永远不可能返回True。



把所有函数和人都怀疑了一遍,之后想起我在使用FART时候并未触发onClick函数(包括FART主动调用),这也就是说这8个dex没有一个是a.bin的内存dump,挨个确认了确实如此。重新回到FART的dump目录中,发现现在是9个dex文件,也就是新增的一个是a.bin的内存dump。拉下来看看,发现和a.bin的不一样。zipCode变成了一串hash了。这个hash也就是kanxue的MD5。




关掉程序重新打开,输入 kanxue ,点击按钮,打印了Congratulations!,也就是我们获取到了flag为 kanxue,接着输入第二次kanxue但提示sorry,这也就是为什么要关掉程序重新打开,原理未深究。猜测是因为第二次onClick执行testDexClassLoader加载插件类时候,因插件类已被加载到了内存而不能二次加载导致抛出异常返回了False(未验证的想法)。下面将进行由zipCode变为md5("kanxue")的原理分析,这也是本篇文章的重点。

首先MainActivity中的native函数ccccccc首先调用了ddddd()函数


ddddd()函数首先使用j_dlopen_compat函数,接着就是hook了libc中的execve函数, registerInlineHook参数为1、原始函数地址,2、hook的新函数地址,3、原始函数的二级指针。

    

当Android7.0或以上时候进入j_fake_dlsym() fake_dlopen(),这也是为什么我使用基于安卓8.0的FART的原因。


整个函数ddddd()函数最终目的是hook execve使得dex2oat失败,从而使得加载的插件类dex不会被优化,变为oat文件之后我们动态修改的dex中的smali指令流就无效,所有hook execve禁用dex2oat是关键步骤。


进入下一个逻辑eeeee(), eeeeee()函数跟ddddd()函数类似,在/proc/self/maps中找到libart.so的内存进而hook art::ClassLinker::LoadMethod函数(上面一大串字符是其导出函数) ,registerInlineHook参数为1、原始函数地址,2、hook的新函数地址,3、原始函数的二级指针。



在Hook了LoadMethod之后,在加载插件类中的testcontent方法时候做了手脚。 下面图片可以看到 ART的LoadMethod的函数的参数,其中dst参数是类方法的指针,通过其就能拿到类函数的CodeItem的Offset。



但在本案例,在myloadmethod中,使用了a2也就是dex_file参数


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

最后于 2020-4-2 10:46 被mb_atbohrok编辑 ,原因: 添加附件
上传的附件:
收藏
免费 3
支持
分享
最新回复 (3)
雪    币: 4883
活跃值: (18890)
能力值: ( LV13,RANK:317 )
在线值:
发帖
回帖
粉丝
2
感谢分享
2020-4-2 15:43
0
雪    币:
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
3
感谢分享
2020-4-14 20:47
0
雪    币: 3372
活跃值: (762)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
4
感谢分享
2020-7-15 21:19
0
游客
登录 | 注册 方可回帖
返回
//