使用frida进行hook(二)

继续对frida进行学习,依旧是参考前一篇看雪前辈的帖子学习(https://bbs.pediy.com/thread-229597.htm)
使用frida进行hook(二)_第1张图片

找到判断字符串是否正确的逻辑是解题关键。此apk采用了美团的Robust热修复方案。
在mainactivity的oncreate的方法中发现有runRobust()方法,顾名思义猜测是来实现热修复的方法,并在执行完热修复后才执行的关键的onclick方法,猜测onclick方法被热修复了:
使用frida进行hook(二)_第2张图片
跟进runRobust()方法:根据网上的一些开发教程,找到了PatchManpulateImpl类用来实现自己的加载补丁策略。
使用frida进行hook(二)_第3张图片
跟进此类,按照网上教程实现加载补丁策略最终是通过PatchManpulateImpl类的fetchPatchList方法来实现:
下图教程参考:https://blog.csdn.net/liujinjiaer/article/details/72785004
使用frida进行hook(二)_第4张图片
按照开发教程,首先会实例化patch对象,之后利用实例化后对象实现加载补丁目的。
因此跟进PatchManpulateImpl类的fetchPatchList方法:发现了初始化Patch实例
使用frida进行hook(二)_第5张图片
之后应该就是实现加载补丁策略的实现,由代码可以看到,初始化后首先加载了一个BMP的文件,并写入到了GeekTan.jar中:
使用frida进行hook(二)_第6张图片
之后参考上面教程会调用patch对象的setPatchesInfoImplClassFullName方法,果不其然,发现了相关代码:
使用frida进行hook(二)_第7张图片
而对于补丁而言有三个文件比较重要:
1.PatchesInfoImpl 类 用于记录修改的类,及其对应的 ChangeQuickRedirect 接口的实现,也就是哪些类要被修复。
2.xxxPatchControl 类 它是 ChangeQuickRedirect 接口的具体实现,是一个代理,具体的替换方法是在 xxxPatch 类中。该方法最终会调用 accessDispatch 方法,该方法会根据传递过来的方法签名,然后调用xxxPatch的修改过的方法。:
3.xxxPatch 类 里面包含具体的替换方法

之后得调用PatchExecutor来进行补丁加载:
使用frida进行hook(二)_第8张图片
在PatchExecutor类中,首先获取补丁列表:
使用frida进行hook(二)_第9张图片
之后调用applyPatchList应用补丁,applyPathlist方法里最终会调用path方法加载补丁类。
使用frida进行hook(二)_第10张图片
上述教程参考:https://blog.csdn.net/qq_22393017/article/details/82224656

那么首先看下BMP文件,因为apk在调用patch对象的setPatchesInfoImplClassFullName方法之前首先对这个文件进行了某些操作。
将该BMP文件拖入010中进行查看,文件头缀位PK,意味着这是个压缩文件,并且发现后面有dex.035字样,说明该文件压缩的很可能是个dex文件,那么改BMP后缀位tar进行解压缩:
在这里插入图片描述

得到dex文件,拖入jadx-gui中进行分析:
在这里插入图片描述
首先看到的就是上面说的三个重要类的第一个:PatchesInfoImpl 类 ,里面记录了要被修复的类:MainActivity和MainActivity$1两个类
在这里插入图片描述
首先看MainActivity类,accessDispatch中可以看到要被修复的方法,也就是oncreate和Joseph()被修复,真正的执行逻辑被放到 mainActivityPatch中:
使用frida进行hook(二)_第11张图片
但是这里我们想找的是onclick的热修复方法,因此不对这两个方法进行深入,查看另一个要被修复的类MainActivity$1,accessDispatch中可以看到要被修复的方法:
使用frida进行hook(二)_第12张图片
果然找到了onclick方法,去MainActivity$1Patch中找到其真正执行的逻辑:
使用frida进行hook(二)_第13张图片
猜测一下,onclick实现的逻辑肯定是获取输入的字符串然后与经过某些运算得到的答案进行比较,然后Toast出flag或者跳转到另一个activity中然后settext(flag)。那么我们就按照这个逻辑来分析这个修复的onclick方法:
果不其然,onclick方法的最后会toast出恭喜的字样,从最后的输出也可以理解为函数的返回值往上追溯:
在这里插入图片描述
也看到了equal方法:
在这里插入图片描述
那么我们要找到反射获取输入字符串的代码以及获得答案的代码:
很明显,onclick方法开始处就是获取输入字符串的函数:最终结果放到了r04中,看上图equal后也出现了r04,猜想应该正确。
在这里插入图片描述
那么equal中既然r04是获取的字符串,那么正确答案就应该是str5:
在这里插入图片描述
由下至上进行溯源str5的形成过程:
使用frida进行hook(二)_第14张图片
就是一路append的操作,首先是DDCTF{,然后append了Joseph的返回值,这个Joseph我们刚刚在MainActivity中提到过只不过没有分析。然后又append了一次Joseph的返回值然后再加上}结束。

通过上面的分析,可以发现hook有2个思路:
1.hook EnhancedRobustUtils类下的invokeReflectMethod方法获取方法执行的返回值。
2.hook 动态加载的类MainActivityPatch的Joseph方法,直接调用它获取返回值。

1.invokeReflectMethod方法在java层,第一个参数为类名:使用frida进行hook(二)_第15张图片
写出脚本如下:
使用frida进行hook(二)_第16张图片
hook结果如下:可见Joseph的两次调用返回值就是flag{}中的内容。
使用frida进行hook(二)_第17张图片
2.看雪前辈的教程是使用了frida的spawn方法,刚开始时提示Failed to spawn: the connection is closed(后来发现电脑中有两个版本的frida,pip uninstall了两次后重装了最新的版本,但是模拟器可以用,真机不能用…),所以这里先使用xpsoed来直接hook:
使用frida进行hook(二)_第18张图片
hook结果如下图所示:
在这里插入图片描述
与第一种frida hook方法的结果是一样的。将两次调用结果拼接起来即可。

你可能感兴趣的:(逆向)