iOS 6.1动态库构建和链接

时间:2013-08-28 10:10:12

标签: ios jailbreak dylib iphone-privateapi

我正在尝试为iOS创建动态库并在运行时加载它。看了this questionthis 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开发,所以请不要继续发布它无法完成!

提前谢谢你,
帕纳约蒂斯。

2 个答案:

答案 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类一样 - 使用allocinit方法。一旦你用objc_getClass获得了类对象,你可以像他一样无事可做。此时您可能会忘记在运行时动态链接库。

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

答案 1 :(得分:2)

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

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

符号名称“run”仅适用于C函数。类似的东西:

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

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