• 用 Xcode 开发 Cydia Substrate 插件(一)


    关于这方面的中文资料太少了,以至于可能很多对插件开发感兴趣的孩子们都不知从何下手,于是呢我就写了这篇文章,希望对你能有所帮助。如果你觉得文章内容有什么错误呢也请提出来。

    准备开发环境

    1. 从 App Store 安装 Xcode,再安装 Command Line Tools。这个可以在 Xcode 的偏好设置里找到。

    image

    2. 安装 dpkg,用于 Debian 打包。先到 http://www.macports.org/install.php 下载安装对应操作系统版本的 MacPorts。然后在终端中通过 MacPorts 安装 dpkg,这里还是挺耗时间的,看网速了。

    sudo port install dpkg

    3. 同意 Xcode 的用户协议。在终端分别运行下面的两个命令,协议出来之后一直翻页到最后,输入 agree 后回车。

    xcode-license
    sudo xcode-license

    4. 安装 iOSOpenDev。这是一个用于 Xcode 的各类 iOS 插件和工具开发的工程模板包。到 http://iosopendev.com/download/ 下载最新版本安装即可。

    一个例子

    iOSOpenDev 提供了各种各样的工程模板,涵盖命令行程序和各类插件,这里以一个 Substrate 插件为例,其它请同学们自行探索吧。

    1. 新建一个工程,使用 CaptainHook Tweak 模板。记得要关闭 ARC。

    image

    image

    2. 模板里面的注释很多,我觉得我已经没什么可说的了。于是偷懒一下啦,复制过来。重要的地方我加了中文注释。

    //
    //  Hello.mm
    //  Hello
    //
    
    // CaptainHook by Ryan Petrich
    // see https://github.com/rpetrich/CaptainHook/
    
    #import <Foundation/Foundation.h>
    #import "CaptainHook/CaptainHook.h"
    #include  // not required; for examples only
    
    // Objective-C runtime hooking using CaptainHook:
    //   1. declare class using CHDeclareClass()
    //   2. load class using CHLoadClass() or CHLoadLateClass() in CHConstructor
    //   3. hook method using CHOptimizedMethod()
    //   4. register hook using CHHook() in CHConstructor
    //   5. (optionally) call old method using CHSuper()
    
    
    @interface Hello : NSObject
    
    @end
    
    @implementation Hello
    
    -(id)init
    {
    	if ((self = [super init]))
    	{
    	}
    
        return self;
    }
    
    @end
    
    
    @class ClassToHook; // 这里以及下面所有的 ClassToHook 都换成你要 Hook 的类的名字
    
    CHDeclareClass(ClassToHook); // declare class
    
    CHOptimizedMethod(0, self, void, ClassToHook, messageName) // hook method (with no arguments and no return value) // Hook 一个没有参数和返回值的方法,同学们按这个格式依葫芦画瓢地来就可以了,下面也一样。
    {
    	// write code here ...
    	
    	CHSuper(0, ClassToHook, messageName); // call old (original) method
    }
    
    CHOptimizedMethod(2, self, BOOL, ClassToHook, arg1, NSString*, value1, arg2, BOOL, value2) // hook method (with 2 arguments and a return value) // Hook 一个有 2 个参数,有返回值的方法
    {
    	// write code here ...
    
    	return CHSuper(2, ClassToHook, arg1, value1, arg2, value2); // call old (original) method and return its return value
    }
    
    static void WillEnterForeground(CFNotificationCenterRef center, void *observer, CFStringRef name, const void *object, CFDictionaryRef userInfo)
    {
    	// not required; for example only
    }
    
    static void ExternallyPostedNotification(CFNotificationCenterRef center, void *observer, CFStringRef name, const void *object, CFDictionaryRef userInfo)
    {
    	// not required; for example only
    }
    
    CHConstructor // code block that runs immediately upon load
    {
    	NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
    	
    	// listen for local notification (not required; for example only)
    	CFNotificationCenterRef center = CFNotificationCenterGetLocalCenter();
    	CFNotificationCenterAddObserver(center, NULL, WillEnterForeground, CFSTR("UIApplicationWillEnterForegroundNotification"), NULL, CFNotificationSuspensionBehaviorCoalesce);
    	
    	// listen for system-side notification (not required; for example only)
    	// this would be posted using: notify_post("Qusic.Tweaks.Hello.eventname");
    	CFNotificationCenterRef darwin = CFNotificationCenterGetDarwinNotifyCenter();
    	CFNotificationCenterAddObserver(darwin, NULL, ExternallyPostedNotification, CFSTR("Qusic.Tweaks.Hello.eventname"), NULL, CFNotificationSuspensionBehaviorCoalesce);
    	
    	// CHLoadClass(ClassToHook); // load class (that is "available now")
    	// CHLoadLateClass(ClassToHook);  // load class (that will be "available later")
    	
    	CHHook(0, ClassToHook, messageName); // register hook
    	CHHook(2, ClassToHook, arg1, arg2); // register hook
    	
    	[pool drain];
    }
    

    LZ你是不是忘了什么重要的东西?

    讲到这里新同学们估计就会有类似下面的各种问题了:

    • Hook 是什么东西?
    • 我怎么知道我要 Hook 的类叫什么名字?
    • 我怎么知道我要 Hook 的方法的名字、参数、返回类型?
    • ……

    你应该注意到文章的标题里的“一”了吧… 好吧,我将在下一篇教程里回答上面的问题。

  • 相关阅读:
    自动生成build.xml文件
    【luogu 3371】【模板】单源最短路径
    【noip 2005】 采药
    【poj 3253】Fence Repair
    【poj 3069】Saruman's Army
    【poj 3617】Best Cow Line
    【poj 2386】Lake Counting
    【noip 2010】 关押罪犯
    【rqnoj 343】mty的考验
    【codevs 1073】家族
  • 原文地址:https://www.cnblogs.com/lkislam/p/4781011.html
Copyright © 2020-2023  润新知