如何Hook住IOS上的Compress函数

尝试MSHookFunction手机上的压缩函数

根据IDA自动分析的数据类型编写Tweak代码,如下:

运行,成功加载tweak插件,但是程序一调用compress则闪退

不服,则查看崩溃日志:
Date/Time: 2019-07-31 23:24:43.43 +0800
Launch Time: 2019-07-31 23:24:37.37 +0800
OS Version: iOS 9.3.2 (13F69)
Report Version: 105
Exception Type: EXC_BAD_INSTRUCTION (SIGILL)
Exception Codes: 0x0000000000000001, 0x00000000087a7e54
Triggered by Thread: 0
Filtered syslog:
None found
Thread 0 name: Dispatch queue: com.apple.main-thread
Thread 0 Crashed:
0 libz.1.dylib 0x0000000180cc56d8 0x180cc4000 + 5848

嗯?zlib库报错,肯定是参数类型没传对,继续修改如下

无果,继续闪退,相同崩溃日志

不服,LLDB看数据类型,只有(unsigned long)和(unsigned int),
(阔能书看到眼睛里去了没看到脑里去)

继续改,进程依旧崩溃。。。。。

Two thousand years later…:expressionless:

问:参数类型是否正确?如何把IDA伪代码的参数类型修改成我们需要的参数类型?
环境:SE IOS9.3.2 LLDB Frida + 一只菜鸡

大概是compress指令太少了,lldb看一下汇编hook更底层的函数

简单看了下由于_compress和_compressBound两个函数在libz.dylib中是相邻的且_compress函数比较短,可能是hook的时候把_compressBound的函数前几个字节改动了。从而导致指令非法。
这里建议hook _compress内部的_compress2函数。
另外对于这种三方库导入的函数,用fishhook那种GOT表的hook方式也行。

我又确认了一下,这是libz.dylib中_compress函数的反汇编代码

int __cdecl compress(Bytef *dest, uLongf *destLen, const Bytef *source, uLong sourceLen)
                EXPORT _compress
_compress
                MOV             W4, #0xFFFFFFFF ; level
                B               _compress2
; End of function _compress
; =============== S U B R O U T I N E =======================================
; uLong __cdecl compressBound(uLong sourceLen)
                EXPORT _compressBound
_compressBound
                ADD             X8, X0, X0,LSR#12
                ADD             X8, X8, X0,LSR#14
                ADD             X8, X8, X0,LSR#25
                ADD             X0, X8, #0xD
                RET

这里可以看出_compress的实现只有4个字节小于8字节,所以libsubstrate.dylib中用MSHookFunction去hook的时候会hook异常,会覆盖_compressBound函数头部的4字节指令。你可以用lldb调试,可以发现这个指令非法的异常出现在_compressBound这个函数调用的时候。

这里和函数的参数倒不是很大关系
另外这里的_compress2 的函数签名如下:
int _compress2(void * dest, void * destLen, void * source, int sourceLen, int level)

符号查找如下

MSImageRef  image =  MSGetImageByName("/usr/lib/libz.1.dylib");
void * compress2_symbol = (void*)MSFindSymbol(image,"_compress2");
1 个赞