你如何添加“物”到现有的应用程序?
例如, EasyRefresh为Chrome的调整,使得iOS版Chrome浏览器应用内执行新的按钮,像许多其他的调整。
请问有什么可以添加一个简单UIButton
,例如,在Twitter的应用程序?
有没有GitHub的项目,可能会帮助我理解它是如何做?
图片来源: ModMyI
谢谢。
你如何添加“物”到现有的应用程序?
例如, EasyRefresh为Chrome的调整,使得iOS版Chrome浏览器应用内执行新的按钮,像许多其他的调整。
请问有什么可以添加一个简单UIButton
,例如,在Twitter的应用程序?
有没有GitHub的项目,可能会帮助我理解它是如何做?
图片来源: ModMyI
谢谢。
诀窍涉及到一些(很基本的)逆向工程和由几个步骤: 我会尝试尽可能清楚地解释它们。
第零步:如果应用从AppStore的下载,它的加密。 你必须解密使用通常用于破解应用脚本/应用中的一个它; 一个命令行脚本是poedCrack.sh(谷歌,你会很快找到它的粘贴网站之一),一个GUI应用程序是Crakculous(它可以在Cydia)。 需要注意的是需要方便(自动)解密其中的一个 - 手动解密方法是太参与放在一个StackOverflow的答案,这就是为什么我建议这些工具)。但是,我不以任何方式鼓励。您破解应用程序! (基本上我是让你不使用这些工具为他们的初衷:)如果你想看看手动解密过程, 这里头。
步骤一:你需要做什么类的应用程序使用/创建。 对于这一点,你需要的类突降或类转储-Z工具。 此命令行应用程序颠倒了应用程序的二进制可执行文件和应用程序使用并具有内部的所有Objective-C类生成接口声明。 你可以找到类转储-Z,更先进的和优选的变体在这里。
第二步:你有一流的声明之后,你将不得不猜测哪些类做什么和什么时候(是的,有点混乱)。 例如,在由类突降-Z从上面的应用程序,谷歌Chrome,生成的文件之一,您可能会发现类似的东西:
@interface ChromeUrlToolbar: UIToolbar {
UISearchBar *urlBar;
}
- (id)initWithFrame:(CGRect)frame;
- (void)loadURL:(NSURL *)url;
@end
嗯,这听起来不错,不是吗? 你可以看到,它的实施有一个initWithFrame:方法方法(因为所有的UIView子类) - 为什么不尝试对其进行修改?
第三步:这一修改,你需要MobileSubstrate有 。 MobileSubstrate有是Saurik公司,苹果蠹的创造者,为了使代码注入到Google Apps容易建立开发库。 你可以在网上找到一些很好的教程,包括这一项 。 所以,你有一个类,你想“钩子”呢 - 所以你写一些像这样的代码:
static IMP __original_init; // A
id __modified_init(id __self, SEL __cmd, CGRect frame) // B
{
__self = __original_init(__self, __cmd, frame); // C
// D
UIButton *newButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
[newButton setTitle:@"Chrome Pwned"];
newButton.frame = CGRectMake(0, 0, 100, 40);
[__self addSubview:newButton];
return __self;
}
// E
__attribute__((constructor))
void init()
{
Class clazz = objc_getClass("ChromeUrlToolbar"); // F
MSHookMessageEx(clazz, @selector(initWithFrame:), __modified_init, &__original_init); // G
}
说明:让我们从末端开始。 在init
函数(E)宣布__attribute__((constructor))
这意味着,当我们将创建出这个代码库将被加载到浏览器它自动调用。 这正是我们想要的beause我们要改变我们的应用程序的行为已经开始它之前。
在标线// F
,我们捕获类对象本身我们要修改。 目标C是一个高度动态的语言; 这意味着我们可以获取和修改有关在运行时类和对象的信息。 在标线// G
,我们使用MobileSubstrate有API的最重要的功能:MSHookMessageEx。 要了解它是如何工作(而不是它做什么),你必须了解以下信息:Objective-C的本身是作为一个普通的C库中实现 - 语言本身,抽油烟机下,只是简单C.所以每次消息Obejctive发送实际上-C是C函数调用。 这些C函数有两种特殊参数: self
和cmd
-前者是指向对象被传递消息,后者则是选择器(一个特殊的,唯一的指针以该消息的名称被发送)。 那么,什么MSHookMessageEx确实是需要一个类和选择,求解函数对应它们的执行情况,并在其第三个参数本身(所提供的功能发挥作用的交流__modified_init
在这种情况下)。 为了不丢失数据,它也返回功能在其第四个参数(在这里它__original_init
)。
所以,现在的浏览器工具栏URL的初始化被重定向到我们的功能,下一步该做什么? 好了,没有什么特别的:第一,我们只需要调用原来的初始化函数(注意前两个特殊的参数,__self和__cmd!)它创建工具栏,就好像正常(这行代码是由表示// C
)。 然后,我们做实际的改变:在部分// D
,我们创建了一个的UIButton,设置其标题和地点,并添加作为一个子视图到我们的新创建的工具栏。 然后,知道这是一个initalization功能,我们与注入到它,我们的按钮的代码一起返回回原来的实例。
嗯,这是基本上你需要知道这是什么; 如果你有兴趣,你可以如何Objective-C的工作以及如何创建很酷的iOS调整更深层次的细节,我建议你阅读苹果的话题官方文档 ,你可以通过浏览我的一些开源Cydia的调整的。 为好。
我希望这能帮到您!
你需要在为了做到这一点,了解的Objective-C运行时是如何工作的。 特别是消息传送系统(即,调用一个方法)。 特别是要调用的方法在运行时确定的,VS等语言它是在编译时。 这允许特定的方法改变全球又名方法交叉混合 。
使用移动底库 ,你将被允许用自己更换任何方法实现,甚至调用原始的实现。 你需要,当然,要知道方法的名称和它需要的参数,以及它所属的类。
因此,要修改实例的跳板,你必须知道哪个类包含和方法。 你将不得不使用class-dump
或class-dump-z
工具,它会替你( class-dump-z
是近期多地用于iOS的开发, class-dump
更灵活,与旧的二进制文件兼容以及64位)。
因此类转储跳板,你需要在Terminal.app进入
class-dump -H /Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS5.0.sdk/System/Library/CoreServices/SpringBoard.app/SpringBoard -o ~/Desktop/SpringBoard
对于类转储-Z,则-p
选项将产生@property
,而不是getter / setter方法,这是比较明显的,所以你可能会键入
class-dump-z -p -H /Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS5.0.sdk/System/Library/CoreServices/SpringBoard.app/SpringBoard -o ~/Desktop/SpringBoard
该行将在桌面上创建一个文件夹跳板所有类定义。 当然,你可能需要更改路径,一个适合你的系统(有关,对于最新版本的Xcode,开发文件夹是在 Xcode,所以你需要像
/Applications/Xcode/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS5.1.sdk/System/Library/CoreServices/SpringBoard.app/SpringBoard
您也可以在网上找到的人谁这样做,你的大部分现有的框架, 这是如果你确定他们是在正确的版本为你的系统非常方便 。
现在,对于AppStore的应用程序,您需要先解密他们,因为他们的保护。 你可能会需要找到的名称和链接自己,因为这很可能是对堆栈溢出的ToS,虽然使用gdb
可以达到这一目的。
为了方便工作,一些工具,如标志 (你可能还需要看看西奥斯 )已创建减少所需的样板代码。 还有一个(很旧) 的MobileSubstrate有Xcode的模板和教程 ,提供很好的帮助。
标志很容易上钩的方法method
从类classname
:
%hook classname //declares the class from your application you're going to override
-(void)method {
dosomethingnew(); //put all your new code for the method here
return %orig; //this calls the original definition of the method
}
%end //end hooking classname
对于系统中的,他们是有用的,以什么样的框架的列表,请参阅这里
最后一件事:被opensourced流行的调整名单(链接到GitHub上如果可能):
一些小的调整
最后,看看在WeekTweak ,他们发布的开源每周调整,所以你可以通过看别人的源尝试和做自己的东西学习。 而#theos瓒在IRC(irc.saurik.com)也将提供帮助,如果你问它亲切。