AntiHook

AntiFishHook

antiFishHook 是我今年早些时候学习庆总的书,写的一个反fishhook的一个工具
根据mach-o的符号动态链接原理,让non-lazy/lazy symbol 指针重新指向对应的symbol stub代码位置,起到在runtime的反hook

那么如何找到符号指针对应的stub代码,其实可以先用MachOView静态的观察数据段的lazy symbol pointers指向的指令的特点。如下图,

每个指针的值减去0x100000000可以得到一个文件偏移的值,0x7E74,0x7E38 … 而文件偏移值指向的是代码段 stub helper的位置, 并且每个函数的指令格式都一样, 如下

ldr w16 #xxxx0
b xxxx1
xxxx0

xxxx0表示ldr w16 #xxxx0指令位置 + 8字节内存地址的数据
xxxx1表示symbol stub代码的位置

每个不同的符号,xxxx0是不同的,但是xxxx1的位置是一样的
因此可以知道符号的信息在xxxx0中,那么xxxx0代表什么呢?

首先先来看看xxxx0的值都是些什么吧,xxxx0占用4个字节,某个符号的xxxx0数据如下

0x20,0x01,0x00,0x00, 机器读取的数据为0x0120, 那么这代表什么数据呢?

如果对mach-o比较熟悉的可能知道mach-o有一个Dynamic Loader Info段, 这里一共有四个区,分别是

Rebase Info: pointer rebase的信息
Binding Info: non-lazy symbol pointer绑定需要的信息
Lazy Binding Info: lazy symbol pointer绑定需要的信息
Export Info: 暴露给外部的符号的信息

在拜读庆总的《iOS应用逆向与安全》过程中, 书中有说到0x0120是Binding Info或者Lazy Binding Info区起始开始到符号信息的偏移,而符号信息如下图


可以看到偏移+6 bytes是该符号名,根据这个信息,就可以筛选出stub helper模板指令对应的符号了,从而将non/lazy symbol pointer从新指向对应的stub helper区代码地址,起到anti-fishhook的功能

AntiMSHook

antiMSHook 是我最近学习MSHookFunction原理的时候想到一个anti-msHook方案,实现效果和anti-fishhook一样,让msHook在runtime失效。

anti-msHook包括两个hook check和anti-hook

hook check 比较简单,主要是检测函数入口的前面4个指令是否是MSHook的模板指令

anti-hook 则利用了MSHook将被hook的指令分配到新的内存区域(mmap),通过遍历进程的虚拟内存区域,查看可读可执行的区域开头几个指令是否存在下面指令,如果存在,则找到了被msHook的指令。直接jump到该内存区域,执行原来的函数逻辑

ldr x16 #8
br x16
bytes  // bytes(pointer) => orig_func_address + 16

(最近写的,目前在我的越狱iOS 8.1.3 5s上实验了一个demo是OK的)

单指令Hook检测

在学习iOS inlinehook绕过反调试时产生的想法。
目前还只是想法, 也不知道可行性怎么样

还是反调试那个例子

  1. 检查目的函数起始地址到10个(视情况定)指令内是否存在mov x16, #26(0xd2800350); svc #128(0xd4001001) 二进制 (检测svc 没被patch)
  2. 参考金丝雀的思路,在写代码时,在目的函数执行前初始化1个变量如int a=0; 在svc指令后面对a++, 目的函数执行完判断a == 1 (防止svc #128之前被patch ret)

(当然完整性校验或许更为简单)

刚学逆向没多久,初级UI仔说的不对地方或者可行性有问题的,还请大佬们多多指教:grinning:

8 个赞

整活整挺好

正准备做stub的inlinehook…:sweat_smile:

看了源码,32位机器是不是需要做一下适配修改呢?我的5c好像没生效

没有32位的机子,验证不了所以就没适配了

如果你说的是antiFishHook,我新开了个分支arm32, 你可以测试下。有没有生效麻烦和我分享一下,谢谢:grinning:

如果你说的是antiMSHook, 没有越狱32位机子目前不打算适配,不好意思

嗯嗯,我昨天就在试着改一下,看看生不生效,我是没有64位的:rofl:

32bit的机器都deprecate了适配有意义吗

1 个赞

不是适配,就是手头上只有32位的,今天已经搞了台64的,再仔细康康

emmmm 不错

AntiFishHook “可以看到偏移+6 bytes是该符号名” 这句话描述是不是不太准确?我在测试过程中发现的有的是偏移+5 bytes是符号名,有的是偏移+4bytes是符号名。庆哥书上的例子好像是偏移+5bytes。

是的,不应该写死偏移,而是根据 BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM 这个标志位来判断。目前开源的已经不用这套了,而是自己实现了dlsym函数来做的。不开源的通过定制化llvm实现的,不同于上面和dlsym方式

LLVM大佬太强了

太强了,太强了,大佬给咸鱼们留口饭吃啊 :pleading_face: