Skip to content

Commit

Permalink
Feat/MidHook original RSP capture (#47)
Browse files Browse the repository at this point in the history
* MidHook: Capture the original RSP as well as the trampoline RSP

* Context: Additional documentation about rsp/esp
  • Loading branch information
cursey authored Dec 17, 2023
1 parent 6d87465 commit 56f7886
Show file tree
Hide file tree
Showing 4 changed files with 53 additions and 33 deletions.
8 changes: 6 additions & 2 deletions include/safetyhook/context.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,18 +19,22 @@ union Xmm {
/// @details This structure is used to pass the context of the hooked function to the destination allowing full access
/// to the 64-bit registers at the moment the hook is called.
/// @note rip will point to a trampoline containing the replaced instruction(s).
/// @note rsp is read-only. Modifying it will have no effect. Use trampoline_rsp to modify rsp if needed but make sure
/// the top of the stack is the rip you want to resume at.
struct Context64 {
Xmm xmm0, xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7, xmm8, xmm9, xmm10, xmm11, xmm12, xmm13, xmm14, xmm15;
uintptr_t rflags, r15, r14, r13, r12, r11, r10, r9, r8, rdi, rsi, rdx, rcx, rbx, rax, rbp, rsp, rip;
uintptr_t rflags, r15, r14, r13, r12, r11, r10, r9, r8, rdi, rsi, rdx, rcx, rbx, rax, rbp, rsp, trampoline_rsp, rip;
};

/// @brief Context structure for 32-bit MidHook.
/// @details This structure is used to pass the context of the hooked function to the destination allowing full access
/// to the 32-bit registers at the moment the hook is called.
/// @note eip will point to a trampoline containing the replaced instruction(s).
/// @note esp is read-only. Modifying it will have no effect. Use trampoline_esp to modify esp if needed but make sure
/// the top of the stack is the eip you want to resume at.
struct Context32 {
Xmm xmm0, xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7;
uintptr_t eflags, edi, esi, edx, ecx, ebx, eax, ebp, esp, eip;
uintptr_t eflags, edi, esi, edx, ecx, ebx, eax, ebp, esp, trampoline_esp, eip;
};

/// @brief Context structure for MidHook.
Expand Down
60 changes: 31 additions & 29 deletions src/mid_hook.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,36 +10,38 @@
namespace safetyhook {

#ifdef _M_X64
constexpr auto asm_data = std::to_array<uint8_t>({0xff, 0x35, 0x5c, 0x01, 0x00, 0x00, 0x54, 0x55, 0x50, 0x53, 0x51,
constexpr std::array<uint8_t, 388> asm_data = {0xFF, 0x35, 0x76, 0x01, 0x00, 0x00, 0x54, 0x54, 0x55, 0x50, 0x53, 0x51,
0x52, 0x56, 0x57, 0x41, 0x50, 0x41, 0x51, 0x41, 0x52, 0x41, 0x53, 0x41, 0x54, 0x41, 0x55, 0x41, 0x56, 0x41, 0x57,
0x9c, 0x48, 0x81, 0xec, 0x00, 0x01, 0x00, 0x00, 0xf3, 0x44, 0x0f, 0x7f, 0xbc, 0x24, 0x10, 0xff, 0xff, 0xff, 0xf3,
0x44, 0x0f, 0x7f, 0xb4, 0x24, 0x20, 0xff, 0xff, 0xff, 0xf3, 0x44, 0x0f, 0x7f, 0xac, 0x24, 0x30, 0xff, 0xff, 0xff,
0xf3, 0x44, 0x0f, 0x7f, 0xa4, 0x24, 0x40, 0xff, 0xff, 0xff, 0xf3, 0x44, 0x0f, 0x7f, 0x9c, 0x24, 0x50, 0xff, 0xff,
0xff, 0xf3, 0x44, 0x0f, 0x7f, 0x94, 0x24, 0x60, 0xff, 0xff, 0xff, 0xf3, 0x44, 0x0f, 0x7f, 0x8c, 0x24, 0x70, 0xff,
0xff, 0xff, 0xf3, 0x44, 0x0f, 0x7f, 0x44, 0x24, 0x80, 0xf3, 0x0f, 0x7f, 0x7c, 0x24, 0x90, 0xf3, 0x0f, 0x7f, 0x74,
0x24, 0xa0, 0xf3, 0x0f, 0x7f, 0x6c, 0x24, 0xb0, 0xf3, 0x0f, 0x7f, 0x64, 0x24, 0xc0, 0xf3, 0x0f, 0x7f, 0x5c, 0x24,
0xd0, 0xf3, 0x0f, 0x7f, 0x54, 0x24, 0xe0, 0xf3, 0x0f, 0x7f, 0x4c, 0x24, 0xf0, 0xf3, 0x0f, 0x7f, 0x04, 0x24, 0x48,
0x8d, 0x0c, 0x24, 0x48, 0x89, 0xe3, 0x48, 0x83, 0xec, 0x30, 0x48, 0x83, 0xe4, 0xf0, 0xff, 0x15, 0xa3, 0x00, 0x00,
0x00, 0x48, 0x89, 0xdc, 0xf3, 0x0f, 0x6f, 0x04, 0x24, 0xf3, 0x0f, 0x6f, 0x4c, 0x24, 0x10, 0xf3, 0x0f, 0x6f, 0x54,
0x24, 0x20, 0xf3, 0x0f, 0x6f, 0x5c, 0x24, 0x30, 0xf3, 0x0f, 0x6f, 0x64, 0x24, 0x40, 0xf3, 0x0f, 0x6f, 0x6c, 0x24,
0x50, 0xf3, 0x0f, 0x6f, 0x74, 0x24, 0x60, 0xf3, 0x0f, 0x6f, 0x7c, 0x24, 0x70, 0xf3, 0x44, 0x0f, 0x6f, 0x84, 0x24,
0x80, 0x00, 0x00, 0x00, 0xf3, 0x44, 0x0f, 0x6f, 0x8c, 0x24, 0x90, 0x00, 0x00, 0x00, 0xf3, 0x44, 0x0f, 0x6f, 0x94,
0x24, 0xa0, 0x00, 0x00, 0x00, 0xf3, 0x44, 0x0f, 0x6f, 0x9c, 0x24, 0xb0, 0x00, 0x00, 0x00, 0xf3, 0x44, 0x0f, 0x6f,
0xa4, 0x24, 0xc0, 0x00, 0x00, 0x00, 0xf3, 0x44, 0x0f, 0x6f, 0xac, 0x24, 0xd0, 0x00, 0x00, 0x00, 0xf3, 0x44, 0x0f,
0x6f, 0xb4, 0x24, 0xe0, 0x00, 0x00, 0x00, 0xf3, 0x44, 0x0f, 0x6f, 0xbc, 0x24, 0xf0, 0x00, 0x00, 0x00, 0x48, 0x81,
0xc4, 0x00, 0x01, 0x00, 0x00, 0x9d, 0x41, 0x5f, 0x41, 0x5e, 0x41, 0x5d, 0x41, 0x5c, 0x41, 0x5b, 0x41, 0x5a, 0x41,
0x59, 0x41, 0x58, 0x5f, 0x5e, 0x5a, 0x59, 0x5b, 0x58, 0x5d, 0x5c, 0xc3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00});
0x9C, 0x48, 0x81, 0xEC, 0x00, 0x01, 0x00, 0x00, 0xF3, 0x44, 0x0F, 0x7F, 0xBC, 0x24, 0x10, 0xFF, 0xFF, 0xFF, 0xF3,
0x44, 0x0F, 0x7F, 0xB4, 0x24, 0x20, 0xFF, 0xFF, 0xFF, 0xF3, 0x44, 0x0F, 0x7F, 0xAC, 0x24, 0x30, 0xFF, 0xFF, 0xFF,
0xF3, 0x44, 0x0F, 0x7F, 0xA4, 0x24, 0x40, 0xFF, 0xFF, 0xFF, 0xF3, 0x44, 0x0F, 0x7F, 0x9C, 0x24, 0x50, 0xFF, 0xFF,
0xFF, 0xF3, 0x44, 0x0F, 0x7F, 0x94, 0x24, 0x60, 0xFF, 0xFF, 0xFF, 0xF3, 0x44, 0x0F, 0x7F, 0x8C, 0x24, 0x70, 0xFF,
0xFF, 0xFF, 0xF3, 0x44, 0x0F, 0x7F, 0x44, 0x24, 0x80, 0xF3, 0x0F, 0x7F, 0x7C, 0x24, 0x90, 0xF3, 0x0F, 0x7F, 0x74,
0x24, 0xA0, 0xF3, 0x0F, 0x7F, 0x6C, 0x24, 0xB0, 0xF3, 0x0F, 0x7F, 0x64, 0x24, 0xC0, 0xF3, 0x0F, 0x7F, 0x5C, 0x24,
0xD0, 0xF3, 0x0F, 0x7F, 0x54, 0x24, 0xE0, 0xF3, 0x0F, 0x7F, 0x4C, 0x24, 0xF0, 0xF3, 0x0F, 0x7F, 0x04, 0x24, 0x48,
0x8B, 0x8C, 0x24, 0x80, 0x01, 0x00, 0x00, 0x48, 0x83, 0xC1, 0x10, 0x48, 0x89, 0x8C, 0x24, 0x80, 0x01, 0x00, 0x00,
0x48, 0x8D, 0x0C, 0x24, 0x48, 0x89, 0xE3, 0x48, 0x83, 0xEC, 0x30, 0x48, 0x83, 0xE4, 0xF0, 0xFF, 0x15, 0xA8, 0x00,
0x00, 0x00, 0x48, 0x89, 0xDC, 0xF3, 0x0F, 0x6F, 0x04, 0x24, 0xF3, 0x0F, 0x6F, 0x4C, 0x24, 0x10, 0xF3, 0x0F, 0x6F,
0x54, 0x24, 0x20, 0xF3, 0x0F, 0x6F, 0x5C, 0x24, 0x30, 0xF3, 0x0F, 0x6F, 0x64, 0x24, 0x40, 0xF3, 0x0F, 0x6F, 0x6C,
0x24, 0x50, 0xF3, 0x0F, 0x6F, 0x74, 0x24, 0x60, 0xF3, 0x0F, 0x6F, 0x7C, 0x24, 0x70, 0xF3, 0x44, 0x0F, 0x6F, 0x84,
0x24, 0x80, 0x00, 0x00, 0x00, 0xF3, 0x44, 0x0F, 0x6F, 0x8C, 0x24, 0x90, 0x00, 0x00, 0x00, 0xF3, 0x44, 0x0F, 0x6F,
0x94, 0x24, 0xA0, 0x00, 0x00, 0x00, 0xF3, 0x44, 0x0F, 0x6F, 0x9C, 0x24, 0xB0, 0x00, 0x00, 0x00, 0xF3, 0x44, 0x0F,
0x6F, 0xA4, 0x24, 0xC0, 0x00, 0x00, 0x00, 0xF3, 0x44, 0x0F, 0x6F, 0xAC, 0x24, 0xD0, 0x00, 0x00, 0x00, 0xF3, 0x44,
0x0F, 0x6F, 0xB4, 0x24, 0xE0, 0x00, 0x00, 0x00, 0xF3, 0x44, 0x0F, 0x6F, 0xBC, 0x24, 0xF0, 0x00, 0x00, 0x00, 0x48,
0x81, 0xC4, 0x00, 0x01, 0x00, 0x00, 0x9D, 0x41, 0x5F, 0x41, 0x5E, 0x41, 0x5D, 0x41, 0x5C, 0x41, 0x5B, 0x41, 0x5A,
0x41, 0x59, 0x41, 0x58, 0x5F, 0x5E, 0x5A, 0x59, 0x5B, 0x58, 0x5D, 0x48, 0x8D, 0x64, 0x24, 0x08, 0x5C, 0xC3, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
#else
constexpr auto asm_data = std::to_array<uint8_t>({0xff, 0x35, 0x91, 0x00, 0x00, 0x00, 0x54, 0x55, 0x50, 0x53, 0x51,
0x52, 0x56, 0x57, 0x9c, 0x81, 0xec, 0x80, 0x00, 0x00, 0x00, 0xf3, 0x0f, 0x7f, 0x7c, 0x24, 0x90, 0xf3, 0x0f, 0x7f,
0x74, 0x24, 0xa0, 0xf3, 0x0f, 0x7f, 0x6c, 0x24, 0xb0, 0xf3, 0x0f, 0x7f, 0x64, 0x24, 0xc0, 0xf3, 0x0f, 0x7f, 0x5c,
0x24, 0xd0, 0xf3, 0x0f, 0x7f, 0x54, 0x24, 0xe0, 0xf3, 0x0f, 0x7f, 0x4c, 0x24, 0xf0, 0xf3, 0x0f, 0x7f, 0x04, 0x24,
0x54, 0xff, 0x15, 0x8d, 0x00, 0x00, 0x00, 0x83, 0xc4, 0x04, 0xf3, 0x0f, 0x6f, 0x04, 0x24, 0xf3, 0x0f, 0x6f, 0x4c,
0x24, 0x10, 0xf3, 0x0f, 0x6f, 0x54, 0x24, 0x20, 0xf3, 0x0f, 0x6f, 0x5c, 0x24, 0x30, 0xf3, 0x0f, 0x6f, 0x64, 0x24,
0x40, 0xf3, 0x0f, 0x6f, 0x6c, 0x24, 0x50, 0xf3, 0x0f, 0x6f, 0x74, 0x24, 0x60, 0xf3, 0x0f, 0x6f, 0x7c, 0x24, 0x70,
0x81, 0xc4, 0x80, 0x00, 0x00, 0x00, 0x9d, 0x5f, 0x5e, 0x5a, 0x59, 0x5b, 0x58, 0x5d, 0x5c, 0xc3, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00});
constexpr std::array<uint8_t, 171> asm_data = {0xFF, 0x35, 0xA7, 0x00, 0x00, 0x00, 0x54, 0x54, 0x55, 0x50, 0x53, 0x51,
0x52, 0x56, 0x57, 0x9C, 0x81, 0xEC, 0x80, 0x00, 0x00, 0x00, 0xF3, 0x0F, 0x7F, 0x7C, 0x24, 0x90, 0xF3, 0x0F, 0x7F,
0x74, 0x24, 0xA0, 0xF3, 0x0F, 0x7F, 0x6C, 0x24, 0xB0, 0xF3, 0x0F, 0x7F, 0x64, 0x24, 0xC0, 0xF3, 0x0F, 0x7F, 0x5C,
0x24, 0xD0, 0xF3, 0x0F, 0x7F, 0x54, 0x24, 0xE0, 0xF3, 0x0F, 0x7F, 0x4C, 0x24, 0xF0, 0xF3, 0x0F, 0x7F, 0x04, 0x24,
0x8B, 0x8C, 0x24, 0xC0, 0x00, 0x00, 0x00, 0x83, 0xC1, 0x08, 0x89, 0x8C, 0x24, 0xC0, 0x00, 0x00, 0x00, 0x54, 0xFF,
0x15, 0xA3, 0x00, 0x00, 0x00, 0x83, 0xC4, 0x04, 0xF3, 0x0F, 0x6F, 0x04, 0x24, 0xF3, 0x0F, 0x6F, 0x4C, 0x24, 0x10,
0xF3, 0x0F, 0x6F, 0x54, 0x24, 0x20, 0xF3, 0x0F, 0x6F, 0x5C, 0x24, 0x30, 0xF3, 0x0F, 0x6F, 0x64, 0x24, 0x40, 0xF3,
0x0F, 0x6F, 0x6C, 0x24, 0x50, 0xF3, 0x0F, 0x6F, 0x74, 0x24, 0x60, 0xF3, 0x0F, 0x6F, 0x7C, 0x24, 0x70, 0x81, 0xC4,
0x80, 0x00, 0x00, 0x00, 0x9D, 0x5F, 0x5E, 0x5A, 0x59, 0x5B, 0x58, 0x5D, 0x8D, 0x64, 0x24, 0x04, 0x5C, 0xC3, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
#endif

std::expected<MidHook, MidHook::Error> MidHook::create(void* target, MidHookFn destination) {
Expand Down Expand Up @@ -102,7 +104,7 @@ std::expected<void, MidHook::Error> MidHook::setup(

// 32-bit has some relocations we need to fix up as well.
store(m_stub.data() + 0x02, m_stub.data() + m_stub.size() - 4);
store(m_stub.data() + 0x47, m_stub.data() + m_stub.size() - 8);
store(m_stub.data() + 0x59, m_stub.data() + m_stub.size() - 8);
#endif

auto hook_result = InlineHook::create(allocator, m_target, m_stub.data());
Expand Down
9 changes: 8 additions & 1 deletion src/mid_hook.x86.asm
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@ bits 32

; save context
push dword [trampoline]
push esp
push esp ; push trampoline esp
push esp ; push original esp (this gets fixed later)
push ebp
push eax
push ebx
Expand All @@ -21,6 +22,11 @@ movdqu [esp-32], xmm2
movdqu [esp-16], xmm1
movdqu [esp], xmm0

; fix stored esp.
mov ecx, [esp+192]
add ecx, 8
mov [esp+192], ecx

; call destination
push esp
call [destination]
Expand All @@ -44,6 +50,7 @@ pop ecx
pop ebx
pop eax
pop ebp
lea esp, [esp+4] ; skip original esp
pop esp
ret

Expand Down
9 changes: 8 additions & 1 deletion src/mid_hook.x86_64.asm
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@ bits 64

; save context
push qword [rel trampoline]
push rsp
push rsp ; push trampoline rsp
push rsp ; push original rsp (this gets fixed later)
push rbp
push rax
push rbx
Expand Down Expand Up @@ -37,6 +38,11 @@ movdqu [rsp-32], xmm2
movdqu [rsp-16], xmm1
movdqu [rsp], xmm0

; fix stored rsp.
mov rcx, [rsp+384]
add rcx, 16
mov [rsp+384], rcx

; set destination parameter
lea rcx, [rsp]

Expand Down Expand Up @@ -85,6 +91,7 @@ pop rcx
pop rbx
pop rax
pop rbp
lea rsp, [rsp+8] ; skip original rsp
pop rsp
ret

Expand Down

0 comments on commit 56f7886

Please sign in to comment.