Frida:
1.攔截器 frida-trace oc方法hook:
frida-trace -U -m "類方法+/實例方法-[類名 方法名:]" 應用名 -m hook某方法 -M 排除某方法
執行后找到相應的js文件函數塊添加相應代碼打印內容
var objcData = new ObjC.Object(args[2]) //轉oc對象然后打印
.readUtf8String()
.UTF8String()
2.hook c函數:
Interceptor.attach(Module.findExportByName(null, "方法"), {
onEnter: function(args) {
console.log("方法");
},
onLeave: function(retval) {
console.log("after之后操作");
},
})
3.hook oc方法//采用API查找器和攔截器組合使用
var resolver = new ApiResolver('objc');
//objc為要過濾的類
resolver.enumerateMatches('*[objc *]', {
onMatch: function(match) {
var method = match['name'];
var implementation = match['address'];
// 過濾需要攔截的方法objc_method
if ((method.indexOf("objc_method") != -1)) {
console.log(match['name'] + ":" + match['address']);
try {
Interceptor.attach(implementation, {
onEnter: function(args) {
//參數打印
var className = ObjC.Object(args[0]);
var methodName = args[1];
var arg_info = ObjC.Object(args[2]);
console.log("className: " + className.toString());
console.log("methodName: " + methodName.readUtf8String());
console.log("arg_info: " + arg_info.toString());
},
onLeave: function(retval) {
}
});
} catch (err) {
console.log("[!] Exception: " + err.message);
}
}
},
onComplete: function() {
}
});
4.hook oc 方法2:implementation
//hook +[NSURL URLWithString:]
var method = ObjC.classes.NSURL['+ URLWithString:'];
var origImp = method.implementation;
method.implementation = ObjC.implement(method, function (self, sel, url){
console.log("+ [NSURL URLWithString:]");
var urlString = ObjC.Object(url);
console.log("url: " + urlString.toString());
return origImp(self, sel, url); //調用原方法,如果不調用則原方法得不到執行
//替換參數,將 URL 替換成 http://www.ioshacker.net
//var newUrl = ObjC.classes.NSString.stringWithString_("http://www.ioshacker.net");
//return origImp(self, sel, newUrl);
});
5.frida rpc使用:傳送
6. frida hook block
var handler = new ObjC.Block({ retType: 'void', argTypes: ['object','object'], implementation: function (age,age2) { console.log('test') console.log(age) console.log(age2) } }); let lClassName= "DCDevice" let _methodName = "- generateTokenWithCompletionHandler:" let dcclass = ObjC.classes[lClassName]['+ currentDevice']() console.log(dcclass['- isSupported']()) dcclass[_methodName](handler)
// 普通參數 function hook01(){ let class_name = 'JDYUserContextManager' let method = '+ sharedInstance' let sharedInstance = ObjC.classes[class_name][method] let oldImpl = sharedInstance.implementation sharedInstance.implementation = ObjC.implement(sharedInstance,function(handle,selector,arg1,arg2){ // 如果有參數的話,就是第三個參數為該方法的第一個參數:args[n-2] // 查看值 console.log("arg1",new ObjC.Object(arg1)) let result = oldImpl(handle,selector,arg1,arg2) return result }) } // 參數類型為NSStackBlock let method = '+ autoLogin:session:callBack:' let impl = ObjC.classes.ALBBSessionRpcService[method] const oldImpl = impl.implementation; impl.implementation = ObjC.implement(impl, function(handle,selector,arg1,arg2,arg3) { try{ console.log("arg1",new ObjC.Object(arg1)) console.log("arg2",arg2,JSON.stringify(new ObjC.Object(arg2))) console.log("arg3",arg3,new ObjC.Object(arg3)) //此參數為NSStackBlock var block = new ObjC.Block(arg3); const appCallback = block.implementation; block.implementation = function (resp) { console.log(resp) // ALBBResponse const result = appCallback(resp); return result; }; var ret = oldImpl(handle,selector,arg1,arg2,arg3); // console.log(ret) }catch(err){ console.log(err) } return ret });
MonkeyDev:

1.CaptainHook:使用CaptainHook提供的頭文件進行OC 函數的Hook以及屬性的獲取。
類方法+ :
例如: +[objC objc_method:參數別名]
CHDeclareClass(objC); CHClassMethod參數個數(id, objC, objc_method, id, arg1, 參數別名, id, arg2){ NSLog(@"參數1:%@",arg1); NSLog(@"參數2:%@",arg2); id result = CHSuper參數個數(objC, objc_method, arg1, 參數別名, arg2); NSLog(@"jieguo:%@",result); return result; } CHConstructor{ CHLoadLateClass(objC); CHClassHook參數個數(objC, objc_method, 參數別名); }
對象方法- : 例如:- (void)方法:; void的為返回類型第二個參數 CHDeclareClass(objC); CHOptimizedMethod0(self,void返回值類型, objC, objc_method){ id result = CHSuper0(objC, objc_method); NSLog(@"result:%@",result); return result; } CHConstructor{ CHLoadLateClass(objC); CHClassHook0(objC, objc_method); }
多參數
CHDeclareClass(類);
CHOptimizedMethod2(self,id, 類, 方法,id,arg1,參數別名,id,arg2){
id result = CHSuper2(類, 方法,arg1,別名,arg2);
return CHSuper2(類, 方法,arg1,別名,arg2);
}
CHConstructor{
CHLoadLateClass(類);
CHClassHook2(類, 方法,別名);
}
區別:
類方法CHClassMethod0:第一個參數為id
對象方法CHOptimizedMethod0:第一個參數為self 第二個返回值類型
CaptainHook 中block hook
//一個類型聲明
typedef id (^FinishBlockType)(參數類型 block參數);
CHClassMethod1(id, 類, 方法,FinishBlockType,arg1){
//構造新的block 打印傳入參數和結果,將原結果返回
FinishBlockType finished = ^返回類型(參數類型 block參數) {
return arg1(block參數);
};
id result = CHSuper1(類, 方法,finished);
NSLog(@"-jieguo:%@",result);
return result;
}
主動調用
SEL sel = @selector(objc_method:參數2別名:); return ((id (*)(Class _Nullable, SEL _Nonnull, id, id))(void *)objc_msgSend)(NSClassFromString(@"ClassName"), sel, arg1, arg2);
SEL sel = @selector(方法:參數別名1:參數別名2:); return ((id (*)(Class _Nullable, SEL _Nonnull, 參數1類型, 參數2類型,.....))(void *)objc_msgSend)(類名, sel, 傳入參數1, 傳入參數2);
2.Logos hook:官網文檔
%hook SBApplicationController -(void)uninstallApplication:(SBApplication *)application { NSLog(@"Hey, we're hooking uninstallApplication:!"); %orig; // Call the original implementation of this method return; } %end
有無參數對象方法
%hook CIPThreadSafeMutableDictionary
- (NSMutableDictionary *)dictionary{
%log;
NSLog(@"CIPThreadSafeMutableDictionary dictionary: %@", %orig);
return %orig;
}
- (void)setObject:(id)arg1 forKey:(id)arg2{
%log;
if([arg2 isEqualToString:@"146"]){
NSMutableDictionary *dicTemp = [NSMutableDictionary dictionary];
[dicTemp setObject:@"1" forKey:@"value"];
[dicTemp setObject:@"1" forKey:@"code"];
arg1 = dicTemp;
}
else if([arg2 isEqualToString:@"237"]){
NSMutableDictionary *dicTemp = [NSMutableDictionary dictionary];
[dicTemp setObject:@"xxx" forKey:@"value"];
[dicTemp setObject:@"1" forKey:@"code"];
arg1 = dicTemp;
}
NSLog(@"CIPThreadSafeMutableDictionary setObject: %@ forKey: %@", arg1, arg2);
%orig(arg1, arg2); //傳參調用原方法 void不用return 需要改參數就加()傳入改動參數,不需要改就直接 %orig
}
%end
類方法
%hook xxxxclass
+ (id)xxxxmethod{
// NSLog(@"xxxxmethod--->%@", %orig);
if ([%orig isKindOfClass: [NSString class]])
{
return @"abc";
}
return %orig;
}
+ (id)xxxxmethod1{
// NSLog(@"xxxxmethod1--->%@", %orig);
if ([%orig isKindOfClass: [NSString class]])
{
return @"abc";
}
return %orig;
}
%end
%hook SAKxxxx
+ (id)encrypt:(id)arg1 withKey:(id)arg2 byAlgorithm:(id)arg3{
%log;
NSLog(@"xxxxx encrypt ret--->%@", %orig);
return %orig;
}
%end
3.Method Swizzing hook
#import "UIDevice Swizzing.h"
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
#import <objc-runtime.h>
@implementation UIDevice (swizzling)
+ (void)load{
static dispatch_once_t onceToken;
dispatch_once(&onceToken,^{
Class class = [self class];
SEL originalSelector = @selector(systemVersion);
SEL swizzledSelector = @selector(NewsystemVersion);
Method originalMethod = class_getInstanceMethod(class, originalSelector);
Method swizzledMethod = class_getInstanceMethod(class, swizzledSelector);
method_exchangeImplementations(originalMethod, swizzledMethod);
});
}
-(NSString*) NewsystemVersion {
NSLog(@"systemVersion method swizzing..........");
NSString *strVer = @"0.0.1";
// NssTring *strVer = [self NewsystemVersion];
return strVer;
}
@end
4.finshhook
+ (void)load{
struct rebinding ptracebd;
// 要hook的方法名
ptracebd.name = "ptrace";
// 保存原來方法的地址
ptracebd.replaced = (void *)&ptrace_p;
// 新方法
ptracebd.replacement = myPtrace;
struct rebinding bds[] = {ptracebd};
rebind_symbols(bds, 1);
}
// 函數指針
int (*ptrace_p)(int _request, pid_t _pid, caddr_t _addr, int _data);
// 新函數
int myPtrace(int _request, pid_t _pid, caddr_t _addr, int _data){
if(_request == PT_DENY_ATTACH){
return 0;
}
return ptrace_p(_request, _pid, _addr, _data);
}
Dobby 框架(https://github.com/jmpews/Dobby)是一個全平台的 inline Hook框架
相關文檔
