3

我正在尝试为 iOS 创建一个动态库并在运行时加载它。在看了这个问题之后这个答案之后,我一直在使用 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 开发,所以请不要继续发布无法完成的帖子!

提前谢谢你,
Panagiotis。

4

2 回答 2

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];

第一行是在运行时链接你的库。这是在其中使用代码所必需的。

第二行创建 class 的实例KDylibTwoobjc_getClass函数返回类对象,您可以稍后使用它来创建此类的实例,就像使用任何 Objective-C 类一样 - 使用allocinit方法。一旦你获得了类对象,objc_getClass你就可以和他一起工作,就像什么都没发生一样。此时您可能会忘记在运行时动态链接库。

第三行是调用run方法。如您所见,这是正常的 Objective-C 语法。没有任何改变,因为您在运行时链接了您的库。你可以调用任何你想要的方法。

于 2013-08-28T20:45:36.657 回答
2

我从来没有使用过 dlsym 来获取指向目标 c 方法的指针(我相信不可能通过 dlsym 调用目标 c 方法,但我可能错了)。

然而,最重要的一点是 dlsym 的第二个参数应该是符号名称。

符号名称“run”仅适用于 C 函数。就像是:

EXPORT void run()
{
 NSLog(@"Run");
}

对象 C 方法具有更复杂的符号名称,正如我所说,我不确定它们是否可以传递给 dlsym。

于 2013-08-28T13:41:28.450 回答