InlineHook新秀Dobby框架

2021-01-20 10:21:55 浏览数 (1)

InlineHook新秀Dobby框架

此篇文章为 《利用纯地址进行HOOK》 的上篇

大家注意按照顺序阅读

由于最近研究InlineHook(内联钩子),发现了一个不错的框架,Dobby(原名:HOOKZz)。这家伙是一个全平台的inlineHook框架,它用起来就和fishhook一样,我们先看一下如何使用。

内联钩子:所谓InlineHook就是直接修改目标函数的头部代码。让它跳转到我们自定义的函数里面执行我们的代码,从而达到Hook的目的。这种Hook技术一般用在静态语言的HOOK上面

编译Dobby

首先我们将代码clone下来

代码语言:javascript复制
#depth用于指定克隆深度,为1即表示只克隆最近一次commit.
git clone https://github.com/jmpews/Dobby.git --depth=1 

注意由于这家伙是跨平台的,所以项目并不是一个Xcode工程,我们要使用cmake将这个工程编译成为Xcode工程。进入Dobby目录,创建一个文件夹,然后cmake编译工程

代码语言:javascript复制
cd Dobby && mkdir build_for_ios_arm64 && cd build_for_ios_arm64
cmake .. -G Xcode 
-DCMAKE_TOOLCHAIN_FILE=cmake/ios.toolchain.cmake 
-DPLATFORM=OS64 -DARCHS="arm64" -DCMAKE_SYSTEM_PROCESSOR=arm64 
-DENABLE_BITCODE=0 -DENABLE_ARC=0 -DENABLE_VISIBILITY=1 -DDEPLOYMENT_TARGET=9.3 
-DDynamicBinaryInstrument=ON -DNearBranch=ON -DPlugin.SymbolResolver=ON -DPlugin.Darwin.HideLibrary=ON -DPlugin.Darwin.ObjectiveC=ON

编译完成后,会生成一个Xcode工程

接下来编译Xcode工程。生成我们的Framework

导入Dobby.Framework

bitcode问题

我们新建一个工程开始使用Dobby。那么将Framework加入工程会有一个常见的问题,就是bitcode。

解决方案两种。1、解决Framework让他支持bitcode。2、工程关闭bitcode。

不了解的同学看下面的引用,其他的直接过。

bitcode 是苹果独有的一层中间代码。包含 bitcode 配置的程序将会在 App Store 上被编译和链接。bitcode允许苹果在后期重新优化我们程序的二进制文件,也就是苹果会将这个 bitcode 编译为可执行的64位或32位程序。

拷贝问题

Framework库首次拖入工程,Xcode不会自动帮你拷贝,运行时你会发现库没有打包进入App包。造成DYLD加载时找不到库的错误。

此刻需要手动添加拷贝

选择Framework

再次运行我们可以看到控制台的输出,说明引入成功了!

代码语言:javascript复制
[*] [DobbySymbolResolver] resolve image: /usr/lib/system/libdyld.dylib
[*] Initialize DobbyInstrument => 0x100538c40 => 0x100490b60
[*] ================ DynamicBinaryInstrumentRouting Start ================
[*] Initialize assembler code buffer at 0x2822420a0
[*] Initialize assembler code buffer at 0x282242080

使用Dobby

引入成功之后,我们就可以开始玩一下了。迫不及待!首先我们来看看最关键的函数。

代码语言:javascript复制
// replace function
/**
     arg1:需要HOOK的函数地址
     arg2:新函数地址
     arg3:保留原始函数的指针的地址
*/
int DobbyHook(void *function_address, void *replace_call, void **origin_call);

这个就是用来HOOK我们自定义函数的,那么我们来使用一下。你会发现这个函数的使用和fishhook非常像!

接下来,我们可以写一个Demo。比如我们有一个自定义的sum函数,明显的加法运算。

代码语言:javascript复制
int sum(int a,int b){
    return  a   b;
}

接下来,我们在ViewController的ViewDidLoad中输出

代码语言:javascript复制
- (void)viewDidLoad {
    [super viewDidLoad];
    NSLog(@"打印出:%d",sum(10, 20));
}

这个函数正常的执行结果应该是30。那么我们要在Load方法中去HOOK这个sum。

HOOK前的准备

首先我们要定义几个东西。

  • 函数指针,用于保存被替换函数的地址
代码语言:javascript复制
//函数指针用于保留原来的执行流程
static int(*sum_p)(int a,int b);
  • 新函数(用这个函数替换你需要HOOK的函数,那么该函数的返回值以及参数要保持一致)
代码语言:javascript复制
//新函数
int mySum(int a,int b){
    NSLog(@"原有的结果是:%d",sum_p(a,b));
    return a - b;
}

开始HOOK

使用DobbyHook来HOOK我们的函数。接下来,在Load方法中:

代码语言:javascript复制
 (void)load
{
    //Hook sum
    DobbyHook(sum, mySum, (void *)&sum_p);
}

参数解析

  • arg1(sum):需要HOOK的函数的地址,函数名称就是函数指针
  • arg2(mySum):新函数的地址
  • arg3(sum_p):将原来的sum函数的地址存放到sum_p这个函数指针中(因为要给指针赋值,所以取指针的地址,so:二级指针)

运行结果:

代码语言:javascript复制
原有的结果是:30
打印出:-10

顺利HOOK成功!

0 人点赞