Skip to content

Commit

Permalink
add new TRAMPOLINE macro
Browse files Browse the repository at this point in the history
  • Loading branch information
FunkyFr3sh committed Jul 8, 2024
1 parent 1b3f11c commit c01896a
Show file tree
Hide file tree
Showing 4 changed files with 75 additions and 39 deletions.
22 changes: 22 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,28 @@ Example:
something();
}

You can also keep the original function intact by clearing only the first
instructions (just to make enough space for the 5 byte jump to fit) and afterwards
create a trampoline in sym.c to restore the instructions that were removed.

/* Clear first two instructions AND do a (far) jump from 0x410000 to label doMagic */`
DETOUR(0x410000, 0x410007, _doMagic);

EXTERN_C void doMagic(int arg1, int arg2, int arg3)
{
/* insert your own code here */
something();

/* call the orginal function that was replaced by the patch (optional) */
original(arg1, arg2, arg3);
}

/* sym.c - Create trampoline to restore the two instuctions removed by DETOUR */
TRAMPOLINE(0x410007, original, "sub esp, 8; mov eax, [esp+0x1C]");

/* Same as above, but for functions using the watcom register calling convention */
TRAMPOLINE(0x410007, original, "sub esp, 8; mov eax, [esp+0x1C]", 3);

Note: the `DETOUR` macro is NOT available for `NASM` and `GNU as` but the same can be done via `@HOOK` instead

### Hook
Expand Down
23 changes: 0 additions & 23 deletions res/inc/macros/patch.inc
Original file line number Diff line number Diff line change
Expand Up @@ -89,29 +89,6 @@
dest%1:
%endmacro

%macro @DETOUR 3
cglobal %1
%define @DETOUREND (%3 + 5)
@LJMP {(%3)}, %2
[section .text]
align 16, db 0xCC
%1:
%endmacro

%macro @DETOUR 4
cglobal %1
%define @DETOUREND %4
%if %4 - ((%3) + 5) < 0
%error "end must be at least 5 bytes (the size of a long jump) after start"
%endif

@CLEAR {(%3) + 5}, 0xCC, {(%4)}
@LJMP {(%3)}, %2
[section .text]
align 16, db 0xCC
%1:
%endmacro

%macro @CLEAR_NOP 2
@CLEAR %1, 0x90, %2
%endmacro
Expand Down
67 changes: 52 additions & 15 deletions res/inc/macros/setsym.h
Original file line number Diff line number Diff line change
@@ -1,17 +1,4 @@
#define SETCGLOB_2(addr, name) \
__asm ( \
".global _" #name ";" \
".equ _" #name ", " #addr ";" \
)

#define SETCGLOB_3(addr, name, arg_count) \
__asm ( \
".global _" #name ";" \
".global " #name ";" \
".equ " #name ", " #addr ";" \
".section .text;" \
".align 8, 0xCC;" \
"_" #name ":;" \
#define CDECL_TO_WATCALL(addr, arg_count) \
"push ebx;" \
"push ebp;" \
"mov ebp, esp;" \
Expand Down Expand Up @@ -66,7 +53,23 @@
"call " #addr ";" \
"pop ebp;" \
"pop ebx;" \
"ret;" \
"ret;"

#define SETCGLOB_2(addr, name) \
__asm ( \
".global _" #name ";" \
".equ _" #name ", " #addr ";" \
)

#define SETCGLOB_3(addr, name, arg_count) \
__asm ( \
".global _" #name ";" \
".global " #name ";" \
".equ " #name ", " #addr ";" \
".section .text;" \
".align 8, 0xCC;" \
"_" #name ":;" \
CDECL_TO_WATCALL(addr, arg_count) \
)

#define SETCGLOB_X(x,A,B,C,FUNC, ...) FUNC
Expand All @@ -77,3 +80,37 @@
SETCGLOB_1(__VA_ARGS__), \
SETCGLOB_0(__VA_ARGS__) \
)

#define TRAMPOLINE_3(addr, name, inst) \
__asm ( \
".global _" #name ";" \
".section .text;" \
".align 8, 0xCC;" \
"_" #name ":;" \
inst ";" \
"jmp " #addr ";" \
)

#define TRAMPOLINE_4(addr, name, inst, arg_count) \
__asm ( \
".global _" #name ";" \
".global " #name ";" \
".section .text;" \
".align 8, 0xCC;" \
#name ":;" \
inst ";" \
"jmp " #addr ";" \
".align 8, 0xCC;" \
"_" #name ":;" \
CDECL_TO_WATCALL(name, arg_count) \
)

#define TRAMPOLINE_X(x,A,B,C,D,FUNC, ...) FUNC
#define TRAMPOLINE(...) \
TRAMPOLINE_X(,##__VA_ARGS__, \
TRAMPOLINE_4(__VA_ARGS__), \
TRAMPOLINE_3(__VA_ARGS__), \
TRAMPOLINE_2(__VA_ARGS__), \
TRAMPOLINE_1(__VA_ARGS__), \
TRAMPOLINE_0(__VA_ARGS__) \
)
2 changes: 1 addition & 1 deletion res/inc/patch.h
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ static inline void patch_ljmp_int(char *start, char *end, char *dst)
patch_ljmp(start, dst);
}

static inline void patch_detour(char* start, char* end, char* dst)
static inline void patch_detour(char *start, char *end, char *dst)
{
patch_clear(start + 5, '\xCC', end);
patch_ljmp(start, dst);
Expand Down

0 comments on commit c01896a

Please sign in to comment.