Skip to content

Commit

Permalink
README: Greatly improve explanations and descriptions
Browse files Browse the repository at this point in the history
Don't explain internal details in the "Usage" section
  • Loading branch information
8dcc committed Dec 8, 2023
1 parent f171e7f commit 7049268
Show file tree
Hide file tree
Showing 2 changed files with 125 additions and 52 deletions.
91 changes: 48 additions & 43 deletions README.org
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,24 @@
#+export_file_name: ./doc/README.md
#+author: 8dcc

*Simple linux library for detour hooking in C.*
*Simple C library for detour hooking in linux.*

#+TOC: headlines 2

* Description
This is a linux library, and it supports x64 and x86.

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 it with the
rest of your code. Please see [[https://github.com/8dcc/detour-lib/blob/main/src/main.c][src/main.c]] for an example on how to use it.
This is a linux library, but it should be easy to port to windows. As far as I
know, you should only need to change the [[https://github.com/8dcc/detour-lib/blob/f171e7fcb0e10eeb04c942c6f004a2fea75c7b2c/src/detour.c#L18-L30][protect_addr]] function.

This library was originally made for [[https://github.com/8dcc/hl-cheat][8dcc/hl-cheat]], and was inspired by [[https://guidedhacking.com/threads/simple-linux-windows-detour-class.10580/][this OOP abomination]] ([[https://gist.github.com/8dcc/d0cbef32cd46ab9c73c6f830fa71d999][mirror]]).
It supports x64 and x86.

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 [[https://github.com/8dcc/detour-lib/blob/main/src/main.c][src/main.c]] and for an [[*Usage][Usage]]
example on how to use it.

This library was originally made for [[https://github.com/8dcc/hl-cheat][8dcc/hl-cheat]], and was inspired by
[[https://guidedhacking.com/threads/simple-linux-windows-detour-class.10580/][this OOP abomination]] ([[https://gist.github.com/8dcc/d0cbef32cd46ab9c73c6f830fa71d999][mirror]]).

* Building

Expand All @@ -28,64 +34,63 @@ $ make

* Usage

First of all, you will need to declare the type of the original function with
the =DECL_DETOUR_TYPE()= macro. You will also need to declare a =detour_data_t=
struct:
First, you will need to specify the type and arguments of the original function
with the =DETOUR_DECL_TYPE= macro. You will also need to declare a =detour_ctx_t=
context struct:

#+begin_src c
#+begin_src C
/* int orig(double a, double b); */
DECL_DETOUR_TYPE(int, orig, double, double);

detour_data_t detour_data;
detour_ctx_t detour_ctx;
#+end_src

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

#+begin_quote
*Note:* Make sure these 2 symbols (=orig_t= and =detour_data=) are accessible from your
hook function (i.e. make them global)
#+end_quote
Then, initialize the context struct by calling =detour_init= with a pointer to the
original function and a pointer to your hook function:

Once you have done that, initialize the =detour_data_t= struct by calling
=detour_init()= with the original and hook pointers, and enable the detour:
#+begin_src C
void* orig_ptr = &orig; /* orig(...) */
void* hook_ptr = &hook; /* hook(...) */

#+begin_src c
/* Initialize detour_data struct */
detour_init(&detour_data, orig_ptr, hook_ptr);
/* Initialize the detour context */
detour_init(&detour_ctx, orig_ptr, hook_ptr);

/* Detour hook the original function */
detour_add(&detour_data);
/* Hook the original function */
detour_add(&detour_ctx);
#+end_src

If you want to call the original from your hook, you can use the =CALL_ORIGINAL()=
or the =GET_ORIGINAL()= macros (depends on whether you care about the return
value):
If you want to call the original function from your hook, you can use one of the
following macros:

#+begin_src c
void hook(double p1, double p2) {
/* ... */
- =DETOUR_ORIG_CALL=: Calls the original function, ignores the returned value.
- =DETOUR_ORIG_GET=: Takes an extra parameter used for storing the return value.

/* We care about returned value */
#+begin_src C
double hook(double a, double b) {
/* Call original ignoring return */
CALL_ORIGINAL(&detour_ctx, orig, a, b);

/* Store return value in variable */
int result;
GET_ORIGINAL(detour_data, result, orig_type, p1, p2);
GET_ORIGINAL(&detour_ctx, result, orig, a, b);

/* We don't care about the returned value */
CALL_ORIGINAL(detour_data, orig_type, p1, p2);
/* Our hook can overwrite the return value */
return 123;
}
#+end_src

Once we are done hooking, and we want to restore the original function, we can
call =detour_del()=:
Once we are done, we can call =detour_del= to remove the hook:

#+begin_src c
detour_del(&detour_data);
#+begin_src C
/* Remove hook */
detour_del(&detour_ctx);
#+end_src

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

#+begin_quote
*Note:* The =CALL_ORIGINAL()= macros just remove the patched bytes, call the original
and then patch them again.
#+end_quote

For a full working example, see [[https://github.com/8dcc/detour-lib/blob/main/src/main.c][src/main.c]]. You can also run =make= or =make all-32bit=.
For a full working example, see [[https://github.com/8dcc/detour-lib/blob/main/src/main.c][src/main.c]]. You can also run =make all= or =make
all-32bit=, and try executing =detour-test.out=.
86 changes: 77 additions & 9 deletions doc/README.md
Original file line number Diff line number Diff line change
@@ -1,27 +1,95 @@
**Simple library for detour hooking in C for x86.**
**Simple C library for detour hooking in linux.**


# Table of Contents

1. [Description](#orgc7fd500)
2. [Building](#org0741475)
1. [Description](#orgc302a32)
2. [Building](#orgb606716)
3. [Usage](#org1418a31)


<a id="orgc7fd500"></a>
<a id="orgc302a32"></a>

# Description

To use in your project, simply add the detour source and headers and compile them with the rest of your code.
This is a linux library, but it should be easy to port to windows. As far as I
know, you should only need to change the [protect<sub>addr</sub>](https://github.com/8dcc/detour-lib/blob/f171e7fcb0e10eeb04c942c6f004a2fea75c7b2c/src/detour.c#L18-L30) function.

Made this for [8dcc/hl-cheat](https://github.com/8dcc/hl-cheat).
It supports x64 and x86.

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](https://github.com/8dcc/detour-lib/blob/main/src/main.c) and for an [Usage](#org1418a31)
example on how to use it.

<a id="org0741475"></a>
This library was originally made for [8dcc/hl-cheat](https://github.com/8dcc/hl-cheat), and was inspired by
[this OOP abomination](https://guidedhacking.com/threads/simple-linux-windows-detour-class.10580/) ([mirror](https://gist.github.com/8dcc/d0cbef32cd46ab9c73c6f830fa71d999)).


<a id="orgb606716"></a>

# Building

$ git clone https://github.com/8dcc/32bit-detour
$ cd 32bit-detour
$ git clone https://github.com/8dcc/detour-lib
$ cd detour-lib
$ make
...


<a id="org1418a31"></a>

# Usage

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

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

detour_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 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 `detour_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 detour context */
detour_init(&detour_ctx, orig_ptr, hook_ptr);

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

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

- `DETOUR_ORIG_CALL`: Calls the original function, ignores the returned value.
- `DETOUR_ORIG_GET`: Takes an extra parameter used for storing the return value.

double hook(double a, double b) {
/* Call original ignoring return */
CALL_ORIGINAL(&detour_ctx, orig, a, b);

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

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

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

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

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

For a full working example, see [src/main.c](https://github.com/8dcc/detour-lib/blob/main/src/main.c). You can also run `make all` or `make
all-32bit`, and try executing `detour-test.out`.

0 comments on commit 7049268

Please sign in to comment.