hook getter修改property的时候出现SIGABRT


#1

起因:
作为菜鸡我想试试庆总的MonkeyDev,然后在pp助手下载了一个越狱版本的UC浏览器。运行起来之后首页提示网络错误,但是直接访问网页是可以打开的。因为没设置代理什么的,所以应该不是证书校验的问题。然后我就猜测可能是校验自身信息是否正确,所以我hook了NSBundle的infoDictionary,发现每次报错之前都有调用这个。于是我就想要把bundle id改回初始值。看庆总的wiki,写的使用原来的bundleid直接填aaa就行了,但是我填aaa的时候Xcode就提示不能用aaa,让我改成其他的。然后我就尝试hook NSBundle的infoDictionary,结果在return的时候就报了SIGABRT的错。(按理说NSDictionary的内存应该是在堆里面分配的吧,我return的时候内存也不会被回收吧。)

需求:
我想要修改NSBundle的infoDictionary,然后把其中的CFBundleIdentifier替换会原来的值。

tweak代码:

%hook NSBundle

- (NSDictionary<NSString *, id> *) infoDictionary {
    NSLog(@"call infoDictionary");
    NSDictionary<NSString *, id> *origdic = %orig();
    NSMutableDictionary *tmpdic = [NSMutableDictionary dictionaryWithDictionary:origdic];
    [tmpdic setObject:@"com.ucweb.iphone" forKey:@"CFBundleIdentifier"];
    NSDictionary<NSString *, id> *newdic = [NSDictionary dictionaryWithDictionary:tmpdic];
    NSString *bundleid = [newdic objectForKey:@"CFBundleIdentifier"];
    NSLog(@"bundle id %@", bundleid);
    NSLog(@"%@", newdic);
    return newdic;
}

%end

报错的时候只有signal SIGABRT,没有其他日志。报错时的backtrace:

* thread #1, queue = 'com.apple.main-thread', stop reason = signal SIGABRT
  * frame #0: 0x0000000184b5d2ec libsystem_kernel.dylib`__pthread_kill + 8
    frame #1: 0x0000000184d026a8 libsystem_pthread.dylib`pthread_kill$VARIANT$armv81 + 360
    frame #2: 0x0000000184acbd0c libsystem_c.dylib`abort + 140
    frame #3: 0x0000000186f7ec7c GraphicsServices`_GSRegisterPurpleNamedPortInPrivateNamespace + 404
    frame #4: 0x000000018ef7e1dc UIKit`UIStartMIGServer + 176
    frame #5: 0x000000018ec6bccc UIKit`-[UIApplication _run] + 320
    frame #6: 0x000000018ef7d78c UIKit`UIApplicationMain + 236
    frame #7: 0x0000000104fb8744 UCWEB`___lldb_unnamed_symbol1634$$UCWEB + 132
    frame #8: 0x0000000184a2dfc0 libdyld.dylib`start + 4

环境:
macOS High Sierra 10.13.4 (17E202)
Xcode 9.4 (9F1027a)
MonkeyDev 目前最新版
UC版本 11.9.8.1071


#2

是系统库丢的异常吧。