Coder Social home page Coder Social logo

8dcc / libdetour Goto Github PK

View Code? Open in Web Editor NEW
11.0 1.0 0.0 109 KB

Simple C/C++ library for detour hooking in Linux and Windows

Home Page: https://8dcc.github.io/programming/detour-hooking.html

License: GNU General Public License v3.0

Makefile 6.67% C 93.33%
c c-library detour detour-hook hacking hooking hooking-library cpp cpp-library linux

libdetour's Introduction

Detour library

Simple C/C++ library for detour hooking in linux and windows.

Description

This library is for detour hooking. For more information on how it works, check out my blog entry. It supports x64 and x86 architectures.

Currently, this library supports both windows and unix-like systems, since the only OS-specific function is protect_addr().

This library was originally made for 8dcc/hl-cheat, but I ended up using it in multiple projects (like 8dcc/devildaggers-re). It was inspired by this OOP abomination (mirror).

Performance

Because of its simplicity, this library is really fast. Other hooking methods like VMT hooking have basically zero performance impact by design, but their use case is way more specific.

First, a note about compiler optimizations. This library works fine in projects compiled with -O2 and -O3, but because all the functions in this example are inside main.c, the compiler optimizes the calls so the hooking never occurs. This can be proven by moving the foo() and hook() functions to a separate source, so the compiler can’t optimize the calls when compiling main.c.

The library only needs to enable write permissions for the memory region of the function, write 7 or 12 bytes (x86/x64) and remove the write permission. All this is explained in more detail in the article I linked above.

Building the example

If you want to use this library, simply copy the detour source and headers to your project, include the header in your source files and compile the detour source with the rest of your code. Please see src/main.c and the Usage section for an example on how to use it.

If you want to try the example, simply run:

$ git clone https://github.com/8dcc/libdetour
$ cd libdetour
$ make
$ ./libdetour-test.out
main: hooked, calling foo...
hook: got values 5.0 and 2.0
hook: calling original with custom values...
foo: 9.5 + 1.5 = 11.0
hook: calling with original values...
foo: 5.0 + 2.0 = 7.0
hook: original returned 7.0
hook: returning custom value...
main: hooked foo returned 420.0

main: unhooked, calling again...
foo: 11.0 + 3.0 = 14.0
main: unhooked foo returned 14.0

Usage

First, you will need to specify the type and arguments of the original function with the LIBDETOUR_DECL_TYPE macro. You will also need to declare a libdetour_ctx_t context struct:

/* int orig(double a, double b); */
LIBDETOUR_DECL_TYPE(int, orig, double, double);

libdetour_ctx_t detour_ctx;

This macro will typedef a type needed internally by the library, so make sure you call it globally. The context struct should be accesible when calling the original function (e.g. from your hook), so keep that in mind as well.

Then, initialize the context struct by calling libdetour_init with a pointer to the original function and a pointer to your hook function:

void* orig_ptr = &orig; /* orig(...) */
void* hook_ptr = &hook; /* hook(...) */

/* Initialize the libdetour context */
libdetour_init(&detour_ctx, orig_ptr, hook_ptr);

/* Hook the original function */
libdetour_add(&detour_ctx);

If you want to call the original function from your hook, you can use one of the following macros:

  • LIBDETOUR_ORIG_CALL: Calls the original function, ignores the returned value.
  • LIBDETOUR_ORIG_GET: Takes an extra parameter used for storing the return value.
double hook(double a, double b) {
    /* Call original ignoring return */
    LIBDETOUR_ORIG_CALL(&detour_ctx, orig, a, b);

    /* Store return value in variable */
    double result;
    LIBDETOUR_ORIG_GET(&detour_ctx, result, orig, a, b);

    /* Our hook can overwrite the return value */
    return 123.0;
}

Once we are done, we can call libdetour_del to remove the hook:

/* Remove hook */
libdetour_del(&detour_ctx);

If we call orig() again, our hook function will not be called.

For a full working example, see src/main.c. You can also run make all or make all-32bit, and try executing libdetour-test.out.

libdetour's People

Contributors

8dcc avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 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.