iOS hook

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框架

 相关文档

 

posted @ 2021-05-06 15:28  小君~  阅读(1310)  评论(0编辑  收藏  举报