/
/
导入常用的UI框架和Foundation框架
/
/
导入MonkeyDev提供的头文件,这头文件,后边我们创建framework插件时也可使用
/
*
定义你需要Hook的类及需要Hook的方法。
*
/
@interface
DetailViewController : NSObject
/
/
需要Hook的实例方法
-
(void)loginButtonDidClick:(UIButton
*
)sender;
/
/
以下两个方法并不存在,在这只是为了演示如何hook多个参数的方法和hook类方法
-
(NSString
*
)loginWithPhone:(NSString
*
)phone password:(NSString
*
)pwd;
+
(
id
)factory:(
id
)arg1;
@end
CHDeclareClass(DetailViewController);
/
/
步骤
1
、申明需要Hook的类
/
*
步骤
3
、你的勾子函数,Hook函数被调用时,会执行到这
CHOptimizedMethod的参数说明
第一个参数:固定写死
self
即可
第二个参数:返回值类型,无返回值写void。c语言的类型,直接写对应的类型即可(
int
,
float
,double...)。其他类型,直接写
id
即可,如果你知道具体的类型,也可写具体的类型
第三个参数:类名
第四个参数:方法名
/
/
方法名有一个参数时
第五个参数:第一个入参的类型,和第二个参数写法类型
第六个参数:第一个入参的形参名
/
/
方法名有两个参数时
第七个参数:第二个入参的类型,和第二个参数写法类型
第八个参数:第二个入参的形参名
...
*
/
CHOptimizedMethod1(
self
, void, DetailViewController, loginButtonDidClick, UIButton
*
, sender) {
CHSuper1(DetailViewController, loginButtonDidClick, sender);
/
/
调用原方法
NSLog(@
"witchan =该方法的入参为:%@"
, sender);
}
/
/
Hook两个入参的实例方法
CHOptimizedMethod2(
self
,
id
, DetailViewController, loginWithPhone, NSString
*
, p, password, NSString
*
, pwd) {
id
result
=
CHSuper2(DetailViewController, loginWithPhone, p, password, pwd);
/
/
调用原方法
NSLog(@
"witchan =该方法的第一个入参为:%@"
, p);
NSLog(@
"witchan =该方法的第二个入参为:%@"
, pwd);
NSLog(@
"witchan =该方法的返回值为:%@"
, result);
return
result;
}
/
/
Hook一个入参的类方法,相对于实例方法,只是在Method前多了个Class单词。其他操作完全一样
CHOptimizedClassMethod1(
self
,
id
, DetailViewController, factory,
id
, arg1) {
id
result
=
CHSuper1(DetailViewController, factory, arg1);
/
/
调用原方法
NSLog(@
"witchan =该方法的入参为:%@"
, arg1);
NSLog(@
"witchan =该方法的返回值为:%@"
, result);
/
*
由于deb格式、dylib格式还是framework格式,都支持使用c、c
+
+
和OC语言进行开发。
以下代码为oc语法的简单示例。
注意:整个插件的写法,和ios开发完全一致,你可以创建新类,也可以调用oc提供的类及相关方法
如果你不熟悉oc语法,请看我公众号的另一篇文章,iOS快速入门:https:
/
/
mp.weixin.qq.com
/
s
/
g89Sdyqc4ONlyAWtXTCwRA
*
/
NSMutableDictionary
*
params
=
[NSMutableDictionary dictionary];
params[@
"微信公众号"
]
=
@
"移动端Android和iOS开发技术分享"
;
params[@
"QQ群"
]
=
@
"812546729"
;
NSData
*
body
=
[NSJSONSerialization dataWithJSONObject:params options:NSJSONWritingPrettyPrinted error:nil];
/
/
调用登录接口
NSURL
*
loginURL
=
[NSURL URLWithString:@
"258K9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1j5I4x3U0N6Q4x3X3f1H3i4K6u0W2x3q4)9J5k6e0q4Q4x3@1p5&6x3o6R3H3i4K6u0r3L8r3!0Y4K9h3^5`."
];
/
/
接口
NSMutableURLRequest
*
request
=
[NSMutableURLRequest requestWithURL:loginURL];
/
/
请求对象
request.HTTPMethod
=
@
"POST"
;
/
/
请求方式
[request setValue:@
"d83kd9d323"
forHTTPHeaderField:@
"x-sign"
];
/
/
设置header
request.HTTPBody
=
body;
/
/
注意,HTTPBody是一个
16
进制数据,一般直接
16
进制输出,再转换成文本查看
NSURLSession
*
session
=
[NSURLSession sharedSession];
/
/
获取网络对象
NSURLSessionTask
*
task
=
[session dataTaskWithRequest:request
completionHandler:^(NSData
*
_Nullable data, NSURLResponse
*
_Nullable response, NSError
*
_Nullable error) {
/
/
请求结果会调到这
if
(error !
=
nil) {
NSLog(@
"witchan =网络请求出错了"
);
}
else
{
NSLog(@
"witchan =网络请求成功"
);
}
}];
/
/
创建请求任务
[task resume];
/
/
发起网络请求
return
result;
}
/
/
入口函数
CHConstructor
{
@autoreleasepool
{
NSLog(@
"witchan =FirsFramework hook success!="
);
/
/
一般在入口函数输出一条日志,确定你的插件是否加载成功
CHLoadLateClass(DetailViewController);
/
/
步骤
2
、加载需要Hook的类
CHHook1(DetailViewController, loginButtonDidClick);
/
/
步骤
4
、注册你需要hook的实例方法
CHHook2(DetailViewController, loginWithPhone, password);
CHClassHook1(DetailViewController, factory);
/
/
注册需要hook的类方法
}
}