Giter Site home page Giter Site logo

samplling / subhook Goto Github PK

View Code? Open in Web Editor NEW

This project forked from zeex/subhook

0.0 0.0 0.0 132 KB

Simple hooking library for C/C++ (x86 only, 32/64-bit, no dependencies)

License: BSD 2-Clause "Simplified" License

CMake 13.93% C 61.03% C++ 20.95% Assembly 4.09%

subhook's Introduction

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

Simply copy the files to your project and include subhook.c in your build. The other source files wil be #included by the main C file automatically depending on the OS and achitecture.

Use of CMake is not mandatory, the library can be built wihtout it (no extra build configuration 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).

License

Licensed under the 2-clause BSD license.

subhook's People

Contributors

zeex avatar gocha avatar omgtehlion avatar y-less avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.