A simple hooking library for C/C++
Go to file
2016-07-24 05:18:51 +06:00
test Convert tabs to spaces 2016-07-24 05:18:51 +06:00
.editorconfig Convert tabs to spaces 2016-07-24 05:18:51 +06:00
.gitattributes Add .gitattributes 2015-01-09 14:48:58 +06:00
.travis.yml Add Travis CI config 2015-01-16 18:19:26 +05:00
appveyor.yml Add AppVeyor config 2015-02-16 22:04:57 +06:00
CMakeLists.txt Convert tabs to spaces 2016-07-24 05:18:51 +06:00
README.md Mention license in README 2015-03-22 15:49:31 +05:00
subhook_linux.c Convert tabs to spaces 2016-07-24 05:18:51 +06:00
subhook_private.h Convert tabs to spaces 2016-07-24 05:18:51 +06:00
subhook_windows.c Convert tabs to spaces 2016-07-24 05:18:51 +06:00
subhook_x86.c Convert tabs to spaces 2016-07-24 05:18:51 +06:00
subhook.c Convert tabs to spaces 2016-07-24 05:18:51 +06:00
subhook.h Convert tabs to spaces 2016-07-24 05:18:51 +06:00

Version Build Status Build Status - Windows

SubHook is a super-simple hooking library for C/C++ that works on Linux and Windows. It currently supports x86 and x86-64.

Examples

In the following examples foo is some function or a function pointer that takes a single argument of type int and uses the same calling convention as my_foo (depends on compiler).

Basic usage

#include <stdio.h>
#include <subhook.h>

subhook_t foo_hook;

void my_foo(int x) {
  /* Remove the hook so that you can call the original function. */
  subhook_remove(foo_hook);

  printf("foo(%d) called\n", x);
  foo(x);

  /* Install the hook back to intercept further calls. */
  subhook_install(foo_hook);
}

int main() {
  /* Create a hook that will redirect all foo() calls to to my_foo(). */
  foo_hook = subhook_new((void *)foo, (void *)my_foo);

  /* Install it. */
  subhook_install(foo_hook);

  foo(123);

  /* Remove the hook and free memory when you're done. */
  subhook_remove(foo_hook);
  subhook_free(foo_hook);
}

Trampolines

Using trampolines allows you to jump to the original code without removing and re-installing hooks every time your function gets called.

typedef void (*foo_func)(int x);

void my_foo(int x) {
  printf("foo(%d) called\n", x);

  /* Call foo() via trampoline. */
  ((foo_func)subhook_get_trampoline(foo_hook))(x);
}

int main() {
   /* Same code as in previous example. */
}

Please note that subhook has a very simple length disassmebler engine (LDE) that works only with most common prologue instructions like push, mov, call, etc. When it encounters an unknown instruction subhook_get_trampoline() will return NULL.

C++

#include <iostream>
#include <subhook.h>

SubHook foo_hook;
SubHook foo_hook_tr;

typedef void (*foo_func)(int x);

void my_foo(int x) {
  // ScopedRemove removes the specified hook and automatically re-installs it
  // when the objectt goes out of scope (thanks to C++ destructors).
  SubHook::ScopedRemove remove(&foo_hook);

  std::cout << "foo(" << x < ") called" << std::endl;
  foo(x + 1);
}

void my_foo_tr(int x) {
  std::cout << "foo(" << x < ") called" << std::endl;

  // Call the original function via trampoline.
  ((foo_func)foo_hook_tr.GetTrampoline())(x + 1);
}

int main() {
  foo_hook.Install((void *)foo, (void *)my_foo);
  foo_hook_tr.Install((void *)foo, (void *)my_foo_tr);
}

License

Licensed under the 2-clause BSD license.