This is a post is about my C++ hooking library for Windows (GitHub).

hook

What is a hooking library?

A hooking library allows to change a target programs control flow. This can be useful to debug own applications but also to change or extend functionality of other programs. This functionality can be achieved using different methods. I implemented the following methods:

  • Byte patching .text section
  • Import Address Table (IAT)
  • Virtual Function Table (VFT)
  • Vectored Expcetion Handler (VEH)

Why write another Windows hooking library?

My motivation to write this library was twofold. First of all I wanted to really understand how hooking works and get an understanding of some of the low levels details, like relocating ASM instructions. Secondly I wasn’t really happy with the publicly available hooking libraries. Nearly all of the big names do not offer midfunction hooking (hooking withing a function instead of its prolog). An exception is Frida but the concept to inject an entire javascript engine into the target process to then communicate using a python binding seems like such a strange idea when dealing with this inherintly low level topic.

Relocation

When byte patching the .text section to hook a program, the overwritten bytes have to be saved and executed to preserve the target processes functionality (and not crash it). The issue with this is that many assembler instructions are position dependend - meaning that copying them somewhere else and then execute them will change their semantic. Therefore such instructions have to be detected and modified to preserve their original meaning. To do so a disassembler is required. I chose Zydis since it offers all the low level details about the disassembled instructions required to relocate instructions, has no third party dependencies, can be built using CMAKE and is blazing fast - all at the same time!

Using the library

The easiest way to use hookFTW is by cloning it recursivly and building the library using CMAKE. Hooking at a target address then becomes as easy as:

// use a midfunction hook. In this example we pass the proxy function as a lambda.
hookftw::MidfunctionHook prologHook;
prologHook.Hook(
	targetAddress,
	[](hookftw::context* ctx) {
		printf("inside hooked function\n"); 
		ctx->PrintRegister();
	}
);

Roadmap

There are some limitations on locations where hooks can be placed. Hooking a location where the target binary jumps to results in undefined behavior and most likely a crash. While I don’t know any feasable method to detect if a binary jumps to the code location, this rarely becomes a problem since hookFTW offers direct register access which usually allows to just hook a couple of bytes before/after and then get/set the desired value from the registers. There are some other handy features that I hope to implement in the near future.


This is it for now. In my next blogpost I will demonstrate how I put hookFTW to good use. Stay tuned!