[求助]短短几行代码,试了好久请问为什么就是hook不住swift函数?

前提条件:

  1. ipa是从商店下载的

  2. 已经用frida成功砸壳了

  3. 项目是swift写的

  4. MonkeyDev的恢复符号表选项设置为YES, MONKEYDEV_RESTORE_SYMBOL = YES。

hook代码实现:

新建Tweak工程,代码如下:

%hook LoginViewController
static void (*origin_method)(void) = NULL;
void hook_method(void) {
        NSLog(@"hook success: hook_method");
}
%end

%ctor {
        %init(LoginViewController = objc_getClass("Order.LoginViewController"));
        unsigned long address = _dyld_get_image_vmaddr_slide(0) + 0x10006493c;
        MSHookFunction((void *)address, (void *)hook_method, (void **)&origin_method);
}

其中slide后面所加的偏移值0x10006493c是从MachOView查看得到的。
截图如下:
![截屏2025-05-20 01.47.21|689x130](upload://ptXLg1EC0jn2F30gyLMIzoN7aiX.png)

然后经过编译打包安装,点击测试,在log里面并没有观察到打印结果,恳求各位帮看一下我是不是哪里写错了,还是别的原因就是hook不到。期待回复。

首先类名有问题,可以通过 ida 或者 hopper 看下类名,然后再测试下

You can try deleting the first and sixth lines.

static void (*origin_method)(void) = NULL;
void hook_method(void) {
NSLog(@“hook success: hook_method”);
}

%ctor {
%init(LoginViewController = objc_getClass(“Order.LoginViewController”));
unsigned long address = _dyld_get_image_vmaddr_slide(0) + 0x10006493c;
MSHookFunction((void *)address, (void *)hook_method, (void **)&origin_method);
}

使用NSLog来判断是否hook住并不可靠,高版本系统下已经无法在console中打印log了,换os_系列的API输出log试试

There is no doubt that your point is valid; the oversight was entirely mine. :upside_down_face:

今天我用IDA看了下类名,类名的前面加的有下划线,对比了一下,这和我用nm命令看到的是一样的名字,我特意用IDA里面的类名又测试了几遍,还是一样hook不到。
IDA里面的类名,我写到Tweak里面是下面这样:

%hook _TtC9xxxxOrder19LoginViewController

Yes, I did, but it still doesn’t work.

我感觉我的iOS版本算是比较低了,它是12.5。另外,我同时还加上了对viewDidLoad函数的hook,结果可以hook成功,在控制台是可以看到打印的log,我感兴趣的signup()函数不能被hook。不知道为啥?这两个函数在源码中的区别是,一个是系统的viewDidLoad() {…}, 一个是@objc func signup() {…},难道是跟这有什么关系吗?另外还有一个现象是:在恢复符号表之前viewDidLoad就可以在符号表里看的到,而signup只有在恢复之后能查到在符号表。进而我又看到函数名前加@objc修饰的可以恢复,没有加这个关键词修饰的,在符号表里没看到有恢复。

系统的viewDidLoad,可以看到被hook。

override func viewDidLoad() {...}

源码里的signup,到现在为止依然没有hook成功。函数偏移量就是帖子一开始提到的0x10006493c,恢复符号表后可以看到函数名和偏移量

@objc func signup() {...}

另外,我在补充一句,我用LLDB调试,计算函数地址,用命令dis -s 是可以准确定位到函数的,说明偏移量应该是没问题的。LLDB调试结果如下:

**(lldb)** p/x 0x0000000000e18000+0x10006493c
(long) $0 = 0x0000000100e7c93c
**(lldb)** dis -s 0x0000000100e7c93c
xxxxOrder`-[_TtC9xxxxOrder19LoginViewController signup]:
        0x100e7c93c <+0>:  stp    x20, x19, [sp, #-0x20]!
        0x100e7c940 <+4>:  stp    x29, x30, [sp, #0x10]
        ......
        ......

看得出你是初学者,这种问题用一些对比法就能知道哪里问题

首先类名对不对,用frida检测下类名存在很容易就知道

其次偏移对不对,地址一般是base+slide+off计算,你这里只有个slide且偏移也明显不对。app自身模块直接base+off就可以了,取系统模块才需要slide,off取值不会超过二进制大小的,你这个off算下来都4G了;而且你也可以多打点日志把address地址打出来结合lldb去看地址是否正确;而且偏移这个东西真的可以用IDA去看而不是别的,不要给初学的自己增加难度

再次NSLog是否有效也很容易测出,直接在ctor里打印,如果无结果说明用不了NSLog可以改用os_log

3 个赞

是的,刚开始学,我再试试