iphone-越狱机Hook APP
价值
实现一下:如果微信群里发几个大的红包时,你永远是第一个抢到的。如果APP有运营活动,你能绕过限制拿到第一大奖。如果在APP里面你无需充值就是VIP用户.......当然所有这些其实最重要的是帮助我们增强我们APP的安全性能,不知攻焉知防~
思路
现在有一个城堡,如果派兵去攻打,需要什么?大的来说应该就2步:第一步:找出这个城堡最脆弱的地方,然后呢,当然就是打的问题了:排兵布阵集中优势火力攻打这个最脆弱的地方。
对于要说的IOS来说,我们首先会讲解如何去攻打,然后再后续讲解如何找到城堡中最薄弱的地方。
原理:
Object-C中方法Method的数据结构:
typedef struct method_t *Method;
struct method_t {
SEL name;
const char *types;
IMP imp;
struct SortBySELAddress :
public std::binary_function
{
bool operator() (const method_t& lhs,
const method_t& rhs)
{ return lhs.name < rhs.name; }
};
};
name 表示的是方法的名称,用于唯一标识某个方法,比如 @selector(viewWillAppear:) ;
types 表示的是方法的返回值和参数类型(详细信息可以查阅苹果官方文档中的 Type Encodings);
imp 是一个函数指针,指向方法的实现;
SortBySELAddress 顾名思义,是一个根据 name 的地址对方法进行排序的函数。
Method Swizzling原理
Method Swizzling 的实质是在运行时,访问对象的方法结构体,并改变它的底层实现。
项目中应用
给项目中所有图片名称加前缀,所有按钮点击事件都加一个统计......
#import <objc/runtime.h>
@implementation UIViewController (Tracking)
+ (void)load {
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
Class class = [self class];
SEL originalSelector = @selector(viewWillAppear:);
SEL swizzledSelector = @selector(my_viewWillAppear:);
[self swizzleMethods:class originalSelector:originalSelector swizzledSelector:swizzledSelector];
});
}
- (void)my_viewWillAppear:(BOOL)animated {
[self my_viewWillAppear:animated];
NSString *strPageName = NSStringFromClass([self class]);
NSLog(@"%@已被Hook掉", strPageName);
}
+ (void)swizzleMethods:(Class)class originalSelector:(SEL)originalSelector swizzledSelector:(SEL)swizzledSelector {
Method origMethod = class_getInstanceMethod(class, originalSelector);
Method swizMethod = class_getInstanceMethod(class, swizzledSelector);
if (!origMethod || !swizMethod) {
return;
}
IMP originalIMP = method_getImplementation(origMethod);
IMP swizzledIMP = method_getImplementation(swizMethod);
const char *originalType = method_getTypeEncoding(origMethod);
const char *swizzledType = method_getTypeEncoding(swizMethod);
// 这儿的先后顺序是有讲究的,如果先执行后一句,那么在执行完瞬间方法被调用容易引发死循环
class_replaceMethod(class,swizzledSelector,originalIMP,originalType);
class_replaceMethod(class,originalSelector,swizzledIMP,swizzledType);
}
实现
工具的安装
一、Theos越狱开发工具的配置和安装:
- 下载框架到本地,一般直接在这个目录即可。
git clone https://github.com/DHowett/theos /opt/theos
- 打包工具安装,theos开发的插件将会以deb的格式进行发布
sudo port install dkpg
- 在Theos开发插件中,iOS文件的签名是使用ldid工具来完成的,也就是说ldid取代了Xcode自带的Codesign。下方就是ldid的安装过程
sudo port install ldid
然后sudo chmod 777 /opt/theos/bin/ldid
- 配置CydiaSubstrate
用iFun等iPhone上的工具,将iOS上
/Library/Frameworks/CydiaSubstrate.framework/CydiaSubstrate拷贝到电脑上,然后改名为libsubstrate.dylib , 然后拷贝到/opt/theos/lib 中.
Hook开发
- 打开Terminal
- 设置环境变量
export THEOS=/opt/theos
- 进入你打算放置项目的文件夹
- 创建工程:
$THEOS/bin/nic.pl
会出现如下图,进行如下操作即可,主要输入的是MobileSubstrate Bundle filter和APP的bundleIdentifier对应,目前操作系统的面板,则输入如下即可。
xianggedeMacBook-Pro:ReverseProjects root# $THEOS/bin/nic.pl
NIC 2.0 - New Instance Creator
[1.] iphone/activator_event
[2.] iphone/application_modern
[3.] iphone/cydget
[4.] iphone/flipswitch_switch
[5.] iphone/framework
[6.] iphone/ios7_notification_center_widget
[7.] iphone/library
[8.] iphone/notification_center_widget
[9.] iphone/preference_bundle_modern
[10.] iphone/tool
[11.] iphone/tweak
[12.] iphone/xpc_service
Choose a Template (required): 11
Project Name (required): hookspringboardtest1
Package Name [com.yourcompany.hookspringboardtest1]:
Author/Maintainer Name [System Administrator]: xiang
[iphone/tweak] MobileSubstrate Bundle filter [com.apple.springboard]: com.apple.springboard
[iphone/tweak] List of applications to terminate upon installation (space-separated, '-' for none) [SpringBoard]:
Instantiating iphone/tweak in hookspringboardtest1/...
Done.
5.Makefile文件开头输入你需要安装手机的ip地址
THEOS_DEVICE_IP = 172.22.11.11
6.Tweak.xm输入你需要hook的程序
#import <SpringBoard/SpringBoard.h>
%hook SpringBoard
- (void)applicationDidFinishLaunching:(id)application {
%orig;
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"标题" message:@"更改系统行为成功" delegate:self cancelButtonTitle:@"OK" otherButtonTitles:nil];
[alert show];
}
%end
- %hook 指定需要hook的类名,以%end结尾
- %log 用来打印log的,将信息输入到syslog中,如%log((NSString *)@"xiang")
- %orig 执行被hook函数的原始代码,类似于super.method功能
编译安装
- 编译:
执行命令make:
> Making all for tweak hookspringboardtest1…
==> Preprocessing Tweak.xm…
==> Compiling Tweak.xm (armv7)…
==> Linking tweak hookspringboardtest1 (armv7)…
clang: warning: libstdc++ is deprecated; move to libc++ with a minimum deployment target of iOS 7 [-Wdeprecated]
==> Generating debug symbols for hookspringboardtest1 (armv7)…
==> Preprocessing Tweak.xm…
==> Compiling Tweak.xm (arm64)…
==> Linking tweak hookspringboardtest1 (arm64)…
clang: warning: libstdc++ is deprecated; move to libc++ with a minimum deployment target of iOS 7 [-Wdeprecated]
==> Generating debug symbols for hookspringboardtest1 (arm64)…
==> Merging tweak hookspringboardtest1…
==> Signing hookspringboardtest1…
- 打包:
执行命令:make package
> Making all for tweak hookspringboardtest1…
make[2]: Nothing to be done for `internal-library-compile'.
> Making stage for tweak hookspringboardtest1…
dm.pl: building package `com.yourcompany.hookspringboardtest1:iphoneos-arm' in `./packages/com.yourcompany.hookspringboardtest1_0.0.1-1+debug_iphoneos-arm.deb'
- 安装:
执行命令:make install
过程会让你输入两次iphoen密码 , 默认是alpine
hook-APP实现
过程基本一样,只是输入[iphone/tweak] MobileSubstrate Bundle filter 时,输入APP的bundile identifier。
Tweak.xm代码如下:
#import <UIKit/UIKit.h>
%hook ViewController
- (void)clickBt{
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"标题" message:@"真的安全嘛,呵呵,幼稚" delegate:self cancelButtonTitle:@"懂了吧" otherButtonTitles:nil];
[alert show];
}
%end