MicroBlock 发表于 2024-7-30 20:42

【C++23】手搓一个新的 hook 框架:blook

本帖最后由 MicroBlock 于 2024-7-30 20:47 编辑



blookhttps://github.com/MicroCBer/blook
# 介绍

这段时间主要是在搓这个 blook (https://github.com/MicroCBer/blook),一个自己的 hook/hack 框架

为什么已经有这么多好的 Hook 框架了(比如 MinHook, Dobby, frida, subhook, detours.....)还要自己造轮子呢?其实还是对它们的 API 都不满意;
个个都声称有 C++ 兼容,但是个个的 API 都长得像 hook(void* target, void* hook) 这种东西;
用的时候东 cast 一下、西 cast 一下,南边还写一堆全局变量,也不支持 lambda 作为 hook 函数等...
同时,它们对逆向工程利用的周边建筑(infrastructure?)都不完善甚至没有,比如 xref, aob scan, CRT injection 等;
对某些特殊需求(如需要在函数中间 hook)支持也无法令人满意;
这些以前都是我手搓的,组合起来很别扭,一点都不优雅
于是出于解决这些种种问题的目的,我又造了个这个轮子。
现在,B* 已经完全切换至该框架运行,足见其完备性。将来 chronocat-native/crychiccat 也会切换至该框架~
不过目前还是项目初期,可能会有一些 bug 之类的,也还只支持 Windows x64,大伙看看就好~
Fun Facts
在重构至 blook 后:
> 20 changed files with 385 additions and 2,177 deletions.
> 初始化时间加速了约 80%
> 非常方便地实现了 Failing gracefully
# 示例代码Inline hook a function? Easy!

```cpp
auto process = blook::Process::self();
auto hook = process->module("user32.dll").value()
                   ->exports("MessageBoxA")
                   ->inline_hook();
    hook->install([=](int64_t a, char *text, char *title, int64_t b) -> int64_t {
      return hook->trampoline_t<int64_t(int64_t, char *, char *, int64_t)>()(
      a, "oh yes", text, b);
    });

MessageBoxA(nullptr, "hi", "hi", 0);
```

...hook more? Sure!

```cpp
auto process = blook::Process::self();
auto mod = process->module("user32.dll").value();
for (auto& func: mod.obtain_exports()) {
    auto hook = mod
                ->exports(func)
                ->inline_hook();
    hook->install([=](int64_t a) -> int64_t {
      // Yes, capture anything you want!
      std::cout << "Someone called: " << std::hex << func << "\n";
      return hook->trampoline_t<int64_t(int64_t)>()(a);
    });
}
```

How about hooking a method that's not exported?

```cpp
auto process = blook::Process::self();
auto mod = process->module().value();
// Let's find the specific function in .text (Code Segment) with blook's AOB shortcut!.
auto text_segment = mod->section(".text").value();
using ANYp = blook::memory_scanner::ANYPattern;
auto hook = text_segment.find_one({
    0x55, 0x56, 0x57, 0x48, 0x83, 0xec, 0x70, 0x48, 0x8d, 0x6c, 0x24, 0x70,
    0x48, 0xc7, 0x45, 0xf8, 0xfe, 0xff, 0xff, 0xff, 0x48, 0x89, 0xce, 0x48,
    0x8d, 0x7d, 0xd0, 0x48, 0x89, 0xfa, 0xe8, 0x44, ANYp, ANYp, ANYp
})->sub(-0x28).as_function().inline_hook();

// And now it's easy to hook it.
hook->install([=](int64_t a) -> int64_t {
    std::cout << "Someone called some internal function!\n";
    return hook->trampoline_t<int64_t(int64_t)>()(a);
});
```

# 技术细节
我使用的反编译库是 https://github.com/zyantific/zydis,同时支持 assemble(有近似于asmjit的API,比较好使)和 disassemble,在易用性,二进制体积方面都挺不错的;另外,它还是无 allocation 的,意味着在 kernel module 之类的地方用变简单了一点

其他没什么好说的,就是一个比较方便的 inline_hook & trampoline;还对内存访问,xref等做了一些抽象

justwz 发表于 2024-7-30 21:51

厉害了   跟着学学

liuhaiqi 发表于 2024-7-30 22:18

支持int 3HOOK嘛?不支持希望支持下!

fhsuh7 发表于 2024-7-30 22:20

可以讲得再详细吗?拜托

MicroBlock 发表于 2024-7-30 22:33

liuhaiqi 发表于 2024-7-30 22:18
支持int 3HOOK嘛?不支持希望支持下!

现在还没,后面做做

xixicoco 发表于 2024-7-30 22:41

看起来很厉害

fhlfxtd 发表于 2024-7-30 23:28

厉害了,学习

vbuser 发表于 2024-7-31 08:02

能不能出个视频教程,详细说一下原理吗

linix 发表于 2024-7-31 09:10

不明觉厉,膜拜大佬!

dik88chen 发表于 2024-7-31 09:32

大佬,谢谢分享
页: [1] 2 3
查看完整版本: 【C++23】手搓一个新的 hook 框架:blook