You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
*Simple C/C++ library for detour hooking in linux and windows.*
6
+
*Simple C/C++ library for detour hooking in Linux and Windows.*
8
7
9
8
#+TOC: headlines 2
10
9
11
10
* Description
12
11
13
12
This library is for detour hooking. For more information on how it works, check
14
-
out my [[https://8dcc.github.io/programming/detour-hooking.html][blog entry]]. It supports x64 and x86 architectures.
13
+
out my [[https://8dcc.github.io/programming/detour-hooking.html][blog entry]]. It supports x86 and x64 architectures.
15
14
16
15
Currently, this library supports both windows and unix-like systems, since the
17
16
only OS-specific function is =protect_addr()=.
@@ -29,102 +28,108 @@ case is way more specific.
29
28
First, a note about compiler optimizations. This library works fine in projects
30
29
compiled with =-O2= and =-O3=, but because all the functions in this example are
31
30
inside =main.c=, the compiler optimizes the calls so the hooking never occurs.
32
-
This can be proven by moving the =foo()= and =hook()= functions to a separate
33
-
source, so the compiler can't optimize the calls when compiling =main.c=.
31
+
This can be proven by moving the =foo= and =my_hook= functions to a separate source,
32
+
so the compiler can't optimize the calls when compiling =main.c=.
34
33
35
34
The library only needs to enable write permissions for the memory region of the
36
35
function, write 7 or 12 bytes (x86/x64) and remove the write permission. All
37
36
this is explained in more detail in the article I linked above.
38
37
39
38
* Building the example
40
39
41
-
If you want to use this library, simply copy the detour source and headers to
42
-
your project, include the header in your source files and compile the detour
43
-
source with the rest of your code. Please see [[https://github.com/8dcc/libdetour/blob/main/src/main.c][src/main.c]] and the /Usage/ section
44
-
for an example on how to use it.
40
+
If you want to use this library, simply copy the =libdetour.c= source and
41
+
=libdetour.h= headers to your project, include the header in your source files and
42
+
compile the libdetour source with the rest of your code. Please see [[https://github.com/8dcc/libdetour/blob/main/src/main.c][src/main.c]]
43
+
and the /Usage/ section for an example on how to use it.
Alternatively, you can compile the 32-bit test with ~make clean all-32bit~.
70
+
68
71
* Usage
69
72
70
-
First, you will need to specify the type and arguments of the original function
71
-
with the =LIBDETOUR_DECL_TYPE= macro. You will also need to declare a
72
-
=libdetour_ctx_t= context struct:
73
+
Since you will probably want to call the original function from your hook, you
74
+
will need to specify the type and arguments of the original function with the
75
+
=DETOUR_DECL_TYPE= macro. This macro will =typedef= an internal type used by the
76
+
=DETOUR_ORIG_CALL= and =DETOUR_ORIG_GET= macros, so you can skip this step if you
77
+
don't need to use them.
73
78
74
79
#+begin_src C
75
80
/* int orig(double a, double b); */
76
-
LIBDETOUR_DECL_TYPE(int, orig, double, double);
77
-
78
-
libdetour_ctx_t detour_ctx;
81
+
DETOUR_DECL_TYPE(int, orig, double, double);
79
82
#+end_src
80
83
81
-
This macro will =typedef= a type needed internally by the library, so make sure
82
-
you call it globally. The context struct should be accesible when calling the
83
-
original function (e.g. from your hook), so keep that in mind as well.
84
+
You will also need to declare a =detour_ctx_t= structure. Again, since you
85
+
probably want to use this structure from multiple places, it's a good idea to
86
+
declare it globally.
87
+
88
+
#+begin_src C
89
+
detour_ctx_t detour_ctx;
90
+
#+end_src
84
91
85
-
Then, initialize the context struct by calling =libdetour_init= with a pointer to
92
+
Then, initialize the context structure by calling =detour_init= with a pointer to
86
93
the original function and a pointer to your hook function:
87
94
88
95
#+begin_src C
89
-
void* orig_ptr = &orig; /* orig(...) */
90
-
void* hook_ptr = &hook; /* hook(...) */
96
+
void* orig_ptr = &orig; /* orig(...) */
97
+
void* hook_ptr = &my_hook; /* my_hook(...) */
91
98
92
-
/* Initialize the libdetour context */
93
-
libdetour_init(&detour_ctx, orig_ptr, hook_ptr);
99
+
/* Initialize the detour context. */
100
+
detour_init(&detour_ctx, orig_ptr, hook_ptr);
94
101
95
-
/* Hook the original function */
96
-
libdetour_add(&detour_ctx);
102
+
/* Hook to the original function. */
103
+
detour_enable(&detour_ctx);
97
104
#+end_src
98
105
99
-
If you want to call the original function from your hook, you can use one of the
106
+
If you want to call the original function from =my_hook=, you can use one of the
100
107
following macros:
101
108
102
-
- =LIBDETOUR_ORIG_CALL=: Calls the original function, ignores the returned value.
103
-
- =LIBDETOUR_ORIG_GET=: Takes an extra parameter used for storing the return
104
-
value.
109
+
- =DETOUR_ORIG_CALL=: Calls the original function, ignoring the returned value.
110
+
- =DETOUR_ORIG_GET=: Takes an extra parameter used for storing the return value.
105
111
106
112
#+begin_src C
107
-
double hook(double a, double b) {
108
-
/* Call original ignoring return */
109
-
LIBDETOUR_ORIG_CALL(&detour_ctx, orig, a, b);
113
+
double my_hook(double a, double b) {
114
+
/* Call original ignoring return. */
115
+
DETOUR_ORIG_CALL(&detour_ctx, orig, a, b);
110
116
111
-
/* Store return value in variable */
117
+
/* Store return value in the `result' variable. */
112
118
double result;
113
-
LIBDETOUR_ORIG_GET(&detour_ctx, result, orig, a, b);
119
+
DETOUR_ORIG_GET(&detour_ctx, result, orig, a, b);
114
120
115
-
/* Our hook can overwrite the return value */
121
+
/* Our hook can overwrite the value returned by `orig'. */
116
122
return 123.0;
117
123
}
118
124
#+end_src
119
125
120
-
Once we are done, we can call =libdetour_del= to remove the hook:
126
+
Once we are done, we can call =detour_del= to unhook the =orig= function.
121
127
122
128
#+begin_src C
123
-
/* Remove hook */
124
-
libdetour_del(&detour_ctx);
129
+
/* Disable the hook. */
130
+
detour_del(&detour_ctx);
125
131
#+end_src
126
132
127
-
If we call =orig()= again, our hook function will not be called.
133
+
If we call the =orig= function again, the =my_hook= function will /not/ be called.
128
134
129
-
For a full working example, see [[https://github.com/8dcc/libdetour/blob/main/src/main.c][src/main.c]]. You can also run =make all= or
130
-
=make all-32bit=, and try executing =libdetour-test.out=.
135
+
For a full working example, see [[https://github.com/8dcc/libdetour/blob/main/src/main.c][src/main.c]].
0 commit comments