1.hook oc办法,应该是用runtime实现的吧
`#import <UIKit/UIKit.h>
#import <Foundation/Foundation.h>
%hook AppDelegate
- (BOOL)application:(UIApplication )application didFinishLaunchingWithOptions:(NSDictionary )launchOptions {
}
%end`
2.hook 零碎的c办法,零碎的c办法hook次要用fishhook神器.要晓得fishhook的原理就要晓得内部动态链接库的加载原理.
程序启动的时候,程序先通过dyld加载内部动态链接库(包含零碎库、dylib库),函数符号属于内部符号,因为ASLR偏移量动态链接库每次加载到内存的地址不定,就须要加载的时候将符号重绑定,以修改其地址内容.所用到的就是lazy_symbol_pointers(函数用到的时候再去绑定符号)和non-lazy_symbol_pointers(非懒加载,程序启动的时候就去符号绑定).
fishhook就是批改了lazy_symbol_pointers(处于_DATA数据段,可读可写)和non-lazy_symbol_pointers的绑定符号,从而达到hook 零碎c办法的目标.具体代码:
以uname函数为例int uname(struct utsname *);
第一步:申明一个函数和原函数一样的(参数和返回值类型要保持一致)int (* origuname)(struct utsname *);
第二步:实现一个和原函数一样的函数
int myuname(struct utsname *uts){ origuname(uts); char *mod = "_modified"; //机器名 strcat(uts->machine, mod);// Name of this network node strcat(uts->nodename, mod); strcat(uts->release, mod); strcat(uts->version, mod); strcat(uts->sysname, mod); NSLog(@"============ modify uname func"); return 0;}
第三步:用fishhook绑定
+ (void)toHookgettimeofday{ //定义rebinding构造体 struct rebinding nslogBind; //函数的名称 nslogBind.name = "uname"; //新的函数地址 nslogBind.replacement = myuname; //保留原始函数地址变量的指针 nslogBind.replaced = (void *)&origuname; // //定义数组 struct rebinding rebs[] = {nslogBind}; rebind_symbols(rebs, 1);}
3.hook app里的c函数,这个因为符号表不是动静链接的,符号存在mach_o的__Text,_text代码段,只读权限无奈批改,所以只能换substrate去hook.
第一步:通过ida剖析找到函数地址(先省了)
第二步:通过substrate去hook
static __attribute__((constructor(102))) void config(){ unsigned long slide = 0; unsigned long address = 0; //函数地址 address =0x1005DEFF8; if(address) { NSLog((@"start Hook")); slide = _dyld_get_image_vmaddr_slide(0)+address; MSHookFunction((void *)slide, (void *)myjmCallBackFunc, (void **)&originjmCallBackFunc);// MSHookFunction((void *)SecKeyRawVerify, (void *)new_SecKeyRawVerify, (void **)&original_SecKeyRawVerify); } }