All Projects → Zeex → Subhook

Zeex / Subhook

Licence: bsd-2-clause
Simple hooking library for C/C++ (x86 only, 32/64-bit, no dependencies)

Programming Languages

c
50402 projects - #5 most used programming language
cplusplus
227 projects

Projects that are alternatives of or similar to Subhook

Khook
Linux Kernel hooking engine (x86)
Stars: ✭ 144 (-69.36%)
Mutual labels:  hooking, x86
Distormx
The ultimate hooking library
Stars: ✭ 146 (-68.94%)
Mutual labels:  hooking, x86
Urmem
[x86] Simple C++11 header-only cross-platform memhack library (hooks, patches, pointers, sig scan)
Stars: ✭ 76 (-83.83%)
Mutual labels:  hooking, x86
Corehook
A library that simplifies intercepting application function calls using managed code and the .NET Core runtime
Stars: ✭ 191 (-59.36%)
Mutual labels:  hooking, x86
DbgChild
Debug Child Process Tool (auto attach)
Stars: ✭ 221 (-52.98%)
Mutual labels:  x86, hooking
Boomerang
Boomerang Decompiler - Fighting the code-rot :)
Stars: ✭ 265 (-43.62%)
Mutual labels:  cmake, x86
Dbgchild
Debug Child Process Tool (auto attach)
Stars: ✭ 145 (-69.15%)
Mutual labels:  hooking, x86
Anticuckoo
A tool to detect and crash Cuckoo Sandbox
Stars: ✭ 233 (-50.43%)
Mutual labels:  hooking, x86
Xray 16
Improved version of the X-Ray Engine, the game engine used in the world-famous S.T.A.L.K.E.R. game series by GSC Game World. Join OpenXRay! ;)
Stars: ✭ 1,806 (+284.26%)
Mutual labels:  cmake, x86
RenHook
An open-source x86 / x86-64 hooking library for Windows.
Stars: ✭ 80 (-82.98%)
Mutual labels:  x86, hooking
Teamviewer permissions hook v1
A proof of concept injectable C++ dll, that uses naked inline hooking and direct memory modification to change your TeamViewer permissions.
Stars: ✭ 297 (-36.81%)
Mutual labels:  hooking, x86
Cmake Raytracer
Ray tracer written in pure CMake
Stars: ✭ 444 (-5.53%)
Mutual labels:  cmake
Dosbox Staging
DOS/x86 emulator focusing on ease of use
Stars: ✭ 412 (-12.34%)
Mutual labels:  x86
Innoextract
A tool to unpack installers created by Inno Setup
Stars: ✭ 407 (-13.4%)
Mutual labels:  cmake
Ros 21 tutorials
《古月 · ROS入门21讲》课件&源码
Stars: ✭ 405 (-13.83%)
Mutual labels:  cmake
Invaders
Invaders game in 512 bytes (boot sector)
Stars: ✭ 461 (-1.91%)
Mutual labels:  x86
Cpp Reflection
C++ Reflection Parser / Runtime Skeleton
Stars: ✭ 440 (-6.38%)
Mutual labels:  cmake
Y86
A Y86 pipeline CPU simulator in JavaScript.
Stars: ✭ 404 (-14.04%)
Mutual labels:  x86
Opencv Mingw Build
👀 MinGW 32bit and 64bit version of OpenCV compiled on Windows. Including OpenCV 3.3.1, 3.4.1, 3.4.1-x64, 3.4.5, 3.4.6, 3.4.7, 3.4.8-x64, 3.4.9, 4.0.0-alpha-x64, 4.0.0-rc-x64, 4.0.1-x64, 4.1.0, 4.1.0-x64, 4.1.1-x64, 4.5.0-with-contrib
Stars: ✭ 401 (-14.68%)
Mutual labels:  cmake
Cnl
A Compositional Numeric Library for C++
Stars: ✭ 397 (-15.53%)
Mutual labels:  cmake

Build Status Build Status - Windows

SubHook is a super-simple hooking library for C and C++ that works on Windows, Linux and macOS. It supports x86 only (32-bit and 64-bit).

Installation

Easy method:

  1. Copy the source and header files to your project and include subhook.c in your build.
  2. On Windows only: Define SUBHOOK_STATIC before including subhook.h.

With CMake:

  1. Copy the subhook repo to your project tree.

  2. Call add_subdirectory(path/to/subhook) in your CMakeLists.txt.

  3. Optional: configure how the library is built by setting these varaible prior to add_subdirectory(...):

    • SUBHOOK_STATIC - Build as static library (OFF by default)
    • SUBHOOK_INSTALL - Enable installation and packaging of targets/files with CPack (OFF by default)
    • SUBHOOK_TESTS - Enable tests (ON by default)
    • SUBHOOK_FORCE_32BIT - Configure for compiling 32-bit binaries on 64-bit systems (default is OFF)

Use of CMake is not mandatory, the library can be built without it (no extra build configuration is required).

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, 0);

  /* 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 the 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. You can delegate instruction decoding to a custom disassembler of your choice via subhook_set_disasm_handler().

C++

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

subhook::Hook foo_hook;
subhook::Hook foo_hook_tr;

typedef void (*foo_func)(int x);

void my_foo(int x) {
  // ScopedHookRemove removes the specified hook and automatically re-installs
  // it when the object goes out of scope (thanks to C++ destructors).
  subhook::ScopedHookRemove 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);
}

Known issues

  • subhook_get_trampoline() may return NULL because only a small subset of x86 instructions is supported by the disassembler in this library (just common prologue instructions). As a workaround you can plug in a more advanced instruction length decoder using subhook_set_disasm_handler().

  • If a target function (the function you are hooking) is less than N bytes in length, for example if it's a short 2-byte jump to a nearby location (sometimes compilers generate code like this), then you will not be able to hook it.

    N is 5 by default: 1 byte for jmp opcode + 4 bytes for offset. But if you enable the use of 64-bit offsets in 64-bit mode N becomes 14 (see the definition of subhook_jmp64).

  • Some systems protect executable code form being modified at runtime, which will not allow you to install hooks, or don't allow to mark heap-allocated memory as executable, which prevents the use of trampolines.

    For example, on Fedora you can have such problems because of SELinux (though you can disable it or exclude your files). On macOS Catalina the mprotect() call inside subhook_new will fail with "Permission denied" (see https://github.com/Zeex/subhook/issues/45).

License

Licensed under the 2-clause BSD license.

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].