如何调用 app 中已有的方法?

需求:

简单来说是希望在 app 中启一个 socket 连接自己的服务器,然后搞点事情。然后分析代码后发现该 app 原本使用了 facebook 开源的 SRWebSocket, 所以我就打算简单粗暴点就用这个 SRWebSocket 来连自己的服务器。

目前的做法也是简单粗暴的,先随便找了个 viewDidAppear 方法 hook 住,然后下载了 SRWebSocket.h 头文件放进项目。锵锵!链接失败……

总之我是这么想的:首先项目中既然已经有了 SRWebSocket,而且已经上架 app store 了,肯定用的是静态库,那么肯定是 lazy symbol,那么肯定是有符号的……我导入头文件后让编译通过,剩下的事情就交给无敌的白银……呃 LLVM 就行了。但是 LLVM 说:我拒绝……

我想我现在把完整的 SRWebSocket 搬进来应该是没问题的,但是我总感觉这样比较蠢,所以想问一下各位大佬,如何调用 app 中已有的方法?

日志:


Undefined symbols for architecture x86_64:

"_OBJC_CLASS_$_SRWebSocket", referenced from:

objc-class-ref in WeChatWork.o

ld: symbol(s) not found for architecture x86_64

clang: error: linker command failed with exit code 1 (use -v to see invocation)


Showing Recent Messages

:-1: symbol(s) not found for architecture x86_64

objc_getClass / -Xlinker,-undefined,dynamic_lookup

我试了一下,我把整个 SRWebSocket 搬进来确实是没问题了。还原成最开始的状态后在 Xcode 的 OTHER_LDFLAGS 下添加 -Xlinker -undefined dynamic_lookup 后报错说找不到 -Xlinker 选项

ld: unknown option: -Xlinker

改为 -Wl,-undefined,dynamic_lookup 后报错:

packing...
dyld: Symbol not found: _OBJC_CLASS_$_SRWebSocket

objc_getClass 这个还没有尝试

那就是没导出,老老实实get_Class

最终我选择了导入整个 SRWebSocket 工程……

总之学到了,毕竟用 objc_getClass 要写很多代码,而用 LLVM 就可以偷很多懒了……

这特么跟LLVM有什么关系

success = objc_msgSendT<BOOL>(cache, @selector(addContainerMetadata:forUser:url:transient:updateSandbox:error:), meta, uid, newurl, NO, YES, &error);

我现在都偷懒了, 写个模块直接 objc_msgSendT

1 个赞

我想让 LLVM 帮我找到这个函数啊,如果有符号有头文件的话。。。总之我是这么想的……

哇,这个好啊!!!跪求 objc_msgSendT<T> :laughing:

template<typename RET_TYPE = id, typename ...ARGS>
inline __attribute__((always_inline)) RET_TYPE objc_msgSendT(id obj, SEL cmd, ARGS... args)
{
    return ((RET_TYPE(*)(id, SEL, ARGS...))objc_msgSend)(obj, cmd, args...);
}

template<typename RET_TYPE = id, typename ...ARGS>
inline __attribute__((always_inline)) RET_TYPE objc_msgSendT(const char* className, SEL cmd, ARGS... args)
{
    return ((RET_TYPE(*)(id, SEL, ARGS...))objc_msgSend)(objc_getClass(className), cmd, args...);
}
1 个赞

万分感激!!!

球球里学点编译原理

他是把LD Clang LLVM dyld都弄混了

#import "SocketRocket.h"

SRWebSocket *socket = [[NSClassFromString(@"SRWebSocket") alloc] initWithURLRequest:request];
socket.delegate = self;
[socket open];
1 个赞

真是非常的尴尬……

我,根本不会,编译原理orz

那有没有办法继承这个类呢?我想给它加两个属性……

请问有办法给这个 SRWebSocket 加属性或者方法吗?

球球里学点 OC 基础