iOS逆向之添加新按钮(新功能)
由于我第一次写的文章第一次写Tweak,走进iOS逆向的世界,文中只展示了怎么将按钮显示出来,并没有真正的添加新功能,@StephenMark这位朋友想试一下,然后又闪退,所以我这里专门写一篇添加按钮的方法,其实也很简单,只是之前没提到这些而已。下面开始直接操作吧,我就直接使用这位朋友发给我的Demo来写这篇文章。
这位朋友发给我的Demo效果如下:Demo地址
就是一个页面上有个黄色按钮,点击后模态推出出一个新页面.他想要的效果是在模态推出的新页面里添加一个按钮,点击按钮就关闭模态页面回到第一个页面,由于我第一次的文章没提到怎么添加,所以导致这位朋友按我之前显示按钮的思路做出来会崩溃!接下来我写一下添加按钮的方法。
首先这次思路是明确的,添加按钮,处理方法,没有多余的步骤,这位朋友已经将他的Tweak发给我了,我就直接用他的来表述
#import "WLNextViewController.h"
%hook WLNextViewController
- (void)viewDidLoad {
%orig;
CGFloat x = 50.0f;
CGFloat y = 100.0f;
UIButton * btn = [[UIButton alloc] initWithFrame:CGRectMake(x, y, self.view.frame.size.width-x*2, 50)];
[self.view addSubview:btn];
[btn setTitle:@"back" forState:UIControlStateNormal];
btn.backgroundColor = [UIColor blueColor];
[btn setTitleColor:[UIColor yellowColor] forState:UIControlStateNormal];
[btn addTarget:self action:@selector(btnDidClicked) forControlEvents:UIControlEventTouchUpInside];
}
- (void)btnDidClicked {
[self dismissViewControllerAnimated:YES completion:nil];
}
%end
这位朋友应该也是搞正向开发的,所以他是自己写的测试Demo,这里就没有了去分析App的思路的,直接就能知道是哪个控制器,该怎么hook,按这位朋友的写法,如果按我之前那篇的思路,其实就是正确的,将这份tweak进行make package打包出来的deb装到手机上,点击黄色按钮后推出来的页面确实多了个蓝色的按钮,但是,点击蓝色按钮,就崩溃了,因为这个Demo有源代码,我直接用Xcode运行,查看崩溃信息
reason: '-[WLNextViewController btnDidClicked]: unrecognized selector sent to instance 0x10023d540'
做过正向开发的都知道这种问题,就是因为WLNextViewController
里找不到btnDidClicked
这个方法,所以导致崩溃,按照我们正向开发是思路就是,.m
文件里肯定写了这个方法,找不到的话应该是在.h
里没有声明,但是我们写Tweak的时候,就只有一个.h
文件,所以这位朋友按照正向思路在.h文件中构造了这个方法,如下
// Generated by class-dump 3.5 (64 bit).
//
// class-dump is Copyright (C) 1997-1998, 2000-2001, 2004-2013 by Steve Nygard.
//
#import <UIKit/UIKit.h>
@interface WLNextViewController : UIViewController
- (void)viewDidLoad;
- (void)btnDidClicked;
@end
当然,这样肯定也是会报错的,因为写Tweak的时候的这个.h文件,其实只是为了保证我们Tweak在编译的时候不报错,并不会替换掉App包里的相同文件,所以这样写肯定也找不到这个按钮的点击方法。解决方法就是使用Logos语法。如下
#import "WLNextViewController.h"
%hook WLNextViewController
- (void)viewDidLoad {
%orig;
CGFloat x = 50.0f;
CGFloat y = 100.0f;
UIButton * btn = [[UIButton alloc] initWithFrame:CGRectMake(x, y, self.view.frame.size.width-x*2, 50)];
[self.view addSubview:btn];
[btn setTitle:@"back" forState:UIControlStateNormal];
btn.backgroundColor = [UIColor blueColor];
[btn setTitleColor:[UIColor yellowColor] forState:UIControlStateNormal];
[btn addTarget:self action:@selector(btnDidClicked) forControlEvents:UIControlEventTouchUpInside];
}
%new
- (void)btnDidClicked {
[self dismissViewControllerAnimated:YES completion:nil];
}
%end
仔细看,在- (void)btnDidClicked
上面有个%new,这样写后打包出来的deb安装后点击蓝色按钮,就能成功的dismiss了,效果如下
我下面会介绍一些Logos语法。Wiki上有详细的介绍,不知道需不需要梯子,这是链接,如果可以看到的朋友请点击Logos
Logos
是Theos开发套件中的语法,可以使用其中的语法轻松的来hook
- %hook
指定需要hook的class,必须以%end结尾
// hook WLNextViewController类里面的viewDidLoad函数
%hook WLNextViewController
- (void)viewDidLoad{
}
%end
- %orig
(该指令在%hook内部使用,执行被hook的函数的原始代码;也可以用%orig更改原始函数的参数)
第一种用法
%hook SpringBorad
- (void)setCustomSubtitleText:(id)arg1 withColor:(id)arg2
{
%orig(@"change arg2",arg2);// 将arg2的参数修 改为"change arg2"
}
%end
第二种用法
%hook WLNextViewController
- (void)viewDidLoad{
%orig;//执行viewDidLoad的原始代码
}
%end
- %new
在%hook内部使用,给一个现有class添加新函数,功能与class_addMethod相同. 使用%new添加,而不需要向.h文件中添加函数声明
%new
- (void)btnDidClicked {//将此方法动态添加到class
[self dismissViewControllerAnimated:YES completion:nil];
}
以上三个是我经常用到的,还有一些例如%ctor
、%init
、%group
等我没怎么用过,所以也就不敢随意介绍使用方法,不然怕误导一些朋友,需要的朋友可要到Wiki上去看介绍,或者搜索一些其他人发布的文章来学习!
此篇文章到此结束!文章中有错误的地方还希望大家及时指出共同进步!