美文网首页
fishhook代码注入

fishhook代码注入

作者: HelloBinary | 来源:发表于2020-08-31 11:31 被阅读0次

github代码地址https://github.com/xuebzufo/FishhookDemo.git

fishhook是什么

fishhook是facebook开源的第三方框架,顾名思义就是"钩子"的意思。在计算机里就是勾住某一个程序或者一个函数。从而扩展程序功能或者改变程序运行流程。
总所周知,c语言是静态语言,而静态语言编译后变量,函数以及参数已经确定,不能修改。但fishhook能够在程序运行时动态修改c函数(动态链接库函数).自定义的c函数是不行的。

应用场景

hook除了用于逆向攻击,如:ptrace的反调试攻破,也有很多都正向开发,如拦截用户手势进行用户行为分析,OA中拦截网络,截屏,剪贴板功能防止数据泄露。

原理

fishhook为何不能hook自定义函数呢?

通过xcode汇编可以知道自定义函数是直接通过call 来调用的,代码放在Mach-O中的代码段 image.png
自定义函数在代码段,代码段具有只读可执行权限,却不能修改。

而如NSLog函数这些外部动态库的函数是在那个段呢?


image.png

可以看到NSLog函数符号位于数据段,是可读可写的。

函数符号为何在数据段?

image.png

真正的函数符号NSLog位于外部动态链接库Foundation.framework,属于外部符号,由于每次程序加载到内存,要进行ASLR动态地址重新计算一个随机值,所以地址需要重新绑定,来找到真正的NSLog。这个就是也懒加载符号了

那么如何找到对应的真正函数呢

image.png

可以看到通过 他的值进行各种跳转后,最后到达了dyld_stub_binder,就是so-called桩绑定了。dyld符号重绑定。

fishhook就是通过dyld来实现方法交换

image.png
dyld动态加载器提供了获取镜像数据的接口,从而获取Mach-O中的函数符号信息

大概了解了流程我们来hook下ptrace 来破解防调试。

首先我们去github上下载fishhook源码导入工程。
fishhook的代码很简单直接上代码

//
//  InjectCode.m
//  FishhookDemo
//
//  Created by Sem on 2020/8/31.
//  Copyright © 2020 SEM. All rights reserved.
//

#import "InjectCode.h"
#import "fishhook.h"
#import <dlfcn.h>
#define PT_DENY_ATTACH 31
@implementation InjectCode
// 定义函数指针. 保存原来函数地址
int(*ptrace_ptr_t)(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 myPtrace(_request, _pid, _addr, _data);
    }
    // 如果拒绝加载, 破坏此防护
    return 0;
}
static void (*orig_NSLog)(NSString *format, ...);
void(new_NSLog)(NSString *format, ...) {
    va_list args;
    if(format) {
        va_start(args, format);
        NSString *message = [[NSString alloc] initWithFormat:format arguments:args];
        orig_NSLog(@"%@🚌😁😄❤️!!!!", message);
        va_end(args);
    }
}
+(void)load{
    struct rebinding ptrace1; //
    ptrace1.name = "ptrace";  // 函数符号
    ptrace1.replacement = myPtrace; // 新函数地址
    ptrace1.replaced = (void *)&ptrace_ptr_t; // 原始函数地址的指针
    
    struct rebinding ptrace2; //
    ptrace2.name = "NSLog";  // 函数符号
    ptrace2.replacement = new_NSLog; // 新函数地址
    ptrace2.replaced = (void *)&orig_NSLog; // 原始函数地址的指针
    
    // 创建数组
    struct rebinding rebinds[]={ptrace1,ptrace2};
    // 重绑定
    rebind_symbols(rebinds, 2);
    
}
@end

部分资料来自逻辑教育公开课

相关文章

网友评论

      本文标题:fishhook代码注入

      本文链接:https://www.haomeiwen.com/subject/lixusktx.html