乐趣区

关于ios:iOS-逆向hook的几种方法

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);
    }
    
}
退出移动版