我正在尝试为iOS创建动态库并在运行时加载它。看了this question和this answer之后,我一直在使用iOSOpenDev并在我的iPhone上部署所有内容。 dylib的xCode项目名为KDylibTwo,我修改的文件是:
KDylibTwo.h
#import <Foundation/Foundation.h>
@interface KDylibTwo : NSObject
-(void)run;
@end
KDylibTwo.m
#import "KDylibTwo.h"
@implementation KDylibTwo
-(id)init
{
if ((self = [super init]))
{
}
return self;
}
-(void)run{
NSLog(@"KDylibTwo loadded.");
}
@end
为了测试我的库是否有效,在构建它以进行性能分析后(iOSOpenDev在iPhone上部署它的方式),我可以在/usr/lib/libKDylibTwo.dylib
找到它存储在我的设备上并构建一个调整(再次使用iOSOpenDev) ,按如下方式挂接SpringBoard:
#include <dlfcn.h>
%hook SBApplicationIcon
-(void)launch{
NSLog(@"\n\n\n\n\n\n\nSBHook For libKDylibTwo.dylib");
void* dylibLink = dlopen("/usr/lib/libKDylibTwo.dylib", RTLD_NOW);
if(dylibLink == NULL) {
NSLog(@"Loading failed.");
} else {
NSLog(@"Dylib loaded.");
void (*function)(void);
*(void **)(&function) = dlsym(dylibLink, "run");
if (function) {
NSLog(@"Function found.");
(*function)();
} else {
NSLog(@"Function NOT found");
}
}
NSLog(@"End of code");
%log;
%orig;
}
%end
在设备上安装调整并点击图标(可以触发挂钩代码)之后,控制台输出如下所示:
Aug 28 13:03:35 Pudge SpringBoard[18254] <Warning>: SBHook For libKDylibTwo.dylib
Aug 28 13:03:35 Pudge SpringBoard[18254] <Warning>: Dylib loaded.
Aug 28 13:03:35 Pudge SpringBoard[18254] <Warning>: Function NOT found
Aug 28 13:03:35 Pudge SpringBoard[18254] <Warning>: End of code
Aug 28 13:03:35 Pudge SpringBoard[18254] <Warning>: -[<SBApplicationIcon: 0x1d5008c0> launch]
我的问题是我做错了什么,并且没有调用或执行库的功能!我想我应该澄清一下,我只是在谈论越狱设备,而不是App Store开发,所以请不要继续发布它无法完成!
提前谢谢你,
帕纳约蒂斯。
答案 0 :(得分:6)
正如Victor Ronin指出的那样,“dlsym”代表C符号。要从运行时链接的dylib获取objective-C类,可以使用objc运行时函数。在你的情况下:
void* dylibLink = dlopen("/usr/lib/libKDylibTwo.dylib", RTLD_NOW);
id KDylibTwo = [[objc_getClass("KDylibTwo") alloc] init];
[KDylibTwo run];
第一行是在运行时链接您的库。这是在其中使用代码所必需的。
第二行创建类KDylibTwo
的实例。 objc_getClass
函数返回类对象,您可以稍后使用它来创建此类的实例,就像使用任何objective-C类一样 - 使用alloc
和init
方法。一旦你用objc_getClass
获得了类对象,你可以像他一样无事可做。此时您可能会忘记在运行时动态链接库。
第三行是调用run
方法。如您所见,这是正常的Objective-C语法。没有更改,因为您在运行时链接了库。你可以调用你想要的任何方法。
答案 1 :(得分:2)
我从未使用过dlsym来获取指向Objective c方法的指针(我相信不可能通过dlsym调用Objective c方法,但我可能错了)。
然而,最重要的信息是dlsym的第二个参数应该是符号名称。
符号名称“run”仅适用于C函数。类似的东西:
EXPORT void run()
{
NSLog(@"Run");
}
对象C方法有更复杂的符号名称,正如我所说,我不确定它们是否可以传递给dlsym。