Skip to content

Commit

Permalink
Code improvements
Browse files Browse the repository at this point in the history
  • Loading branch information
RatinCN committed Jul 21, 2024
1 parent a3daab8 commit c11c16d
Show file tree
Hide file tree
Showing 11 changed files with 916 additions and 251 deletions.
522 changes: 449 additions & 73 deletions Source/SlimDetours/Disasm.c → Source/SlimDetours/Disassembler.c

Large diffs are not rendered by default.

95 changes: 76 additions & 19 deletions Source/SlimDetours/Instruction.c
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,11 @@

#include "SlimDetours.inl"

static BOOL detour_is_imported(_In_ PVOID pbCode, _In_ PVOID pbAddress)
static
BOOL
detour_is_imported(
_In_ PVOID pbCode,
_In_ PVOID pbAddress)
{
NTSTATUS Status;
MEMORY_BASIC_INFORMATION mbi;
Expand Down Expand Up @@ -106,7 +110,10 @@ static BOOL detour_is_imported(_In_ PVOID pbCode, _In_ PVOID pbAddress)
#if defined(_M_IX86) || defined(_M_X64)

_Ret_notnull_
PBYTE detour_gen_jmp_immediate(_In_ PBYTE pbCode, _In_ PBYTE pbJmpVal)
PBYTE
detour_gen_jmp_immediate(
_In_ PBYTE pbCode,
_In_ PBYTE pbJmpVal)
{
PBYTE pbJmpSrc = pbCode + 5;
*pbCode++ = 0xe9; // jmp +imm32
Expand All @@ -115,7 +122,10 @@ PBYTE detour_gen_jmp_immediate(_In_ PBYTE pbCode, _In_ PBYTE pbJmpVal)
}

_Ret_notnull_
PBYTE detour_gen_jmp_indirect(_In_ PBYTE pbCode, _In_ PBYTE* ppbJmpVal)
PBYTE
detour_gen_jmp_indirect(
_In_ PBYTE pbCode,
_In_ PBYTE* ppbJmpVal)
{
#if defined(_M_X64)
PBYTE pbJmpSrc = pbCode + 6;
Expand All @@ -131,7 +141,10 @@ PBYTE detour_gen_jmp_indirect(_In_ PBYTE pbCode, _In_ PBYTE* ppbJmpVal)
}

_Ret_notnull_
PBYTE detour_gen_brk(_In_ PBYTE pbCode, _In_ PBYTE pbLimit)
PBYTE
detour_gen_brk(
_In_ PBYTE pbCode,
_In_ PBYTE pbLimit)
{
while (pbCode < pbLimit)
{
Expand All @@ -141,7 +154,9 @@ PBYTE detour_gen_brk(_In_ PBYTE pbCode, _In_ PBYTE pbLimit)
}

_Ret_notnull_
PBYTE detour_skip_jmp(_In_ PBYTE pbCode)
PBYTE
detour_skip_jmp(
_In_ PBYTE pbCode)
{
// First, skip over the import vector if there is one.
if (pbCode[0] == 0xff && pbCode[1] == 0x25)
Expand Down Expand Up @@ -201,7 +216,11 @@ PBYTE detour_skip_jmp(_In_ PBYTE pbCode)
return pbCode;
}

VOID detour_find_jmp_bounds(_In_ PBYTE pbCode, _Outptr_ PVOID* ppLower, _Outptr_ PVOID* ppUpper)
VOID
detour_find_jmp_bounds(
_In_ PBYTE pbCode,
_Outptr_ PVOID* ppLower,
_Outptr_ PVOID* ppUpper)
{
// We have to place trampolines within +/- 2GB of code.
PVOID lo = detour_memory_2gb_below(pbCode);
Expand Down Expand Up @@ -245,7 +264,9 @@ VOID detour_find_jmp_bounds(_In_ PBYTE pbCode, _Outptr_ PVOID* ppLower, _Outptr_
*ppUpper = hi;
}

BOOL detour_does_code_end_function(_In_ PBYTE pbCode)
BOOL
detour_does_code_end_function(
_In_ PBYTE pbCode)
{
if (pbCode[0] == 0xeb || // jmp +imm8
pbCode[0] == 0xe9 || // jmp +imm32
Expand Down Expand Up @@ -278,7 +299,9 @@ BOOL detour_does_code_end_function(_In_ PBYTE pbCode)
return FALSE;
}

ULONG detour_is_code_filler(_In_ PBYTE pbCode)
ULONG
detour_is_code_filler(
_In_ PBYTE pbCode)
{
// 1-byte through 11-byte NOPs.
if (pbCode[0] == 0x90)
Expand Down Expand Up @@ -344,12 +367,19 @@ ULONG detour_is_code_filler(_In_ PBYTE pbCode)
#endif // defined(_M_IX86) || defined(_M_X64)

#if defined(_M_ARM64)
inline ULONG fetch_opcode(PBYTE pbCode)
inline
ULONG
fetch_opcode(
PBYTE pbCode)
{
return *(ULONG*)pbCode;
}

inline PBYTE write_opcode(PBYTE pbCode, ULONG Opcode)
inline
PBYTE
write_opcode(
PBYTE pbCode,
ULONG Opcode)
{
*(ULONG*)pbCode = Opcode;
return pbCode + 4;
Expand Down Expand Up @@ -394,7 +424,10 @@ union ARM64_INDIRECT_IMM
};

_Ret_notnull_
PBYTE detour_gen_jmp_indirect(_In_ PBYTE pbCode, _In_ PULONG64 pbJmpVal)
PBYTE
detour_gen_jmp_indirect(
_In_ PBYTE pbCode,
_In_ PULONG64 pbJmpVal)
{
// adrp x17, [jmpval]
// ldr x17, [x17, jmpval]
Expand Down Expand Up @@ -430,7 +463,11 @@ PBYTE detour_gen_jmp_indirect(_In_ PBYTE pbCode, _In_ PULONG64 pbJmpVal)
}

_Ret_notnull_
PBYTE detour_gen_jmp_immediate(_In_ PBYTE pbCode, _In_opt_ PBYTE* ppPool, _In_ PBYTE pbJmpVal)
PBYTE
detour_gen_jmp_immediate(
_In_ PBYTE pbCode,
_In_opt_ PBYTE* ppPool,
_In_ PBYTE pbJmpVal)
{
PBYTE pbLiteral;
if (ppPool != NULL)
Expand All @@ -456,7 +493,10 @@ PBYTE detour_gen_jmp_immediate(_In_ PBYTE pbCode, _In_opt_ PBYTE* ppPool, _In_ P
}

_Ret_notnull_
PBYTE detour_gen_brk(_In_ PBYTE pbCode, _In_ PBYTE pbLimit)
PBYTE
detour_gen_brk(
_In_ PBYTE pbCode,
_In_ PBYTE pbLimit)
{
while (pbCode < pbLimit)
{
Expand All @@ -465,7 +505,11 @@ PBYTE detour_gen_brk(_In_ PBYTE pbCode, _In_ PBYTE pbLimit)
return pbCode;
}

inline INT64 detour_sign_extend(UINT64 value, UINT bits)
inline
INT64
detour_sign_extend(
UINT64 value,
UINT bits)
{
const UINT left = 64 - bits;
const INT64 m1 = -1;
Expand All @@ -475,7 +519,9 @@ inline INT64 detour_sign_extend(UINT64 value, UINT bits)
}

_Ret_notnull_
PBYTE detour_skip_jmp(_In_ PBYTE pbCode)
PBYTE
detour_skip_jmp(
_In_ PBYTE pbCode)
{
// Skip over the import jump if there is one.
pbCode = (PBYTE)pbCode;
Expand Down Expand Up @@ -564,7 +610,11 @@ then unsigned size-unscaled (8) 12-bit offset, then opcode bits 0xF94.
return pbCode;
}

VOID detour_find_jmp_bounds(_In_ PBYTE pbCode, _Outptr_ PVOID* ppLower, _Outptr_ PVOID* ppUpper)
VOID
detour_find_jmp_bounds(
_In_ PBYTE pbCode,
_Outptr_ PVOID* ppLower,
_Outptr_ PVOID* ppUpper)
{
// The encoding used by detour_gen_jmp_indirect actually enables a
// displacement of +/- 4GiB. In the future, this could be changed to
Expand All @@ -578,7 +628,9 @@ VOID detour_find_jmp_bounds(_In_ PBYTE pbCode, _Outptr_ PVOID* ppLower, _Outptr_
*ppUpper = hi;
}

BOOL detour_does_code_end_function(_In_ PBYTE pbCode)
BOOL
detour_does_code_end_function(
_In_ PBYTE pbCode)
{
ULONG Opcode = fetch_opcode(pbCode);
if ((Opcode & 0xfffffc1f) == 0xd65f0000 || // br <reg>
Expand All @@ -590,7 +642,9 @@ BOOL detour_does_code_end_function(_In_ PBYTE pbCode)
return FALSE;
}

ULONG detour_is_code_filler(_In_ PBYTE pbCode)
ULONG
detour_is_code_filler(
_In_ PBYTE pbCode)
{
if (*(ULONG*)pbCode == 0xd503201f)
{
Expand All @@ -607,7 +661,10 @@ ULONG detour_is_code_filler(_In_ PBYTE pbCode)

#endif // defined(_M_ARM64)

PVOID NTAPI SlimDetoursCodeFromPointer(_In_ PVOID pPointer)
PVOID
NTAPI
SlimDetoursCodeFromPointer(
_In_ PVOID pPointer)
{
return detour_skip_jmp((PBYTE)pPointer);
}
98 changes: 63 additions & 35 deletions Source/SlimDetours/Memory.c
Original file line number Diff line number Diff line change
Expand Up @@ -6,26 +6,6 @@

#include "SlimDetours.inl"

/*
* System memory information with defaults
*
* Result from NtQuerySystemInformation(SystemBasicInformation, ...) is better,
* and those default values are enough to work properly.
*/

static SYSTEM_BASIC_INFORMATION g_sbi = {
.PageSize = PAGE_SIZE,
.AllocationGranularity = MM_ALLOCATION_GRANULARITY,
.MinimumUserModeAddress = (ULONG_PTR)MM_LOWEST_USER_ADDRESS,
#if defined(_WIN64)
.MaximumUserModeAddress = 0x00007FFFFFFEFFFF,
#else
.MaximumUserModeAddress = 0x7FFEFFFF,
#endif
};

static HANDLE g_hHeap = NULL;

/*
* Region reserved for system DLLs
*
Expand Down Expand Up @@ -60,10 +40,39 @@ static ULONG_PTR s_ulSystemRegionLowUpperBound = SYSTEM_RESERVED_REGION_HIGHEST;
static ULONG_PTR s_ulSystemRegionLowLowerBound = SYSTEM_RESERVED_REGION_LOWEST;
#endif

VOID detour_memory_init()
/*
* System memory information with defaults
*
* Result from NtQuerySystemInformation(SystemBasicInformation, ...) is better,
* and those default values are enough to work properly.
*/

static SYSTEM_BASIC_INFORMATION g_sbi = {
.PageSize = PAGE_SIZE,
.AllocationGranularity = MM_ALLOCATION_GRANULARITY,
.MinimumUserModeAddress = (ULONG_PTR)MM_LOWEST_USER_ADDRESS,
#if defined(_WIN64)
.MaximumUserModeAddress = 0x00007FFFFFFEFFFF,
#else
.MaximumUserModeAddress = 0x7FFEFFFF,
#endif
};

static HANDLE _detour_memory_heap = NULL;
static RTL_RUN_ONCE g_stInitMemory = RTL_RUN_ONCE_INIT;

static
_Function_class_(RTL_RUN_ONCE_INIT_FN)
_IRQL_requires_same_
LOGICAL
NTAPI
detour_memory_init(
_Inout_ PRTL_RUN_ONCE RunOnce,
_Inout_opt_ PVOID Parameter,
_Inout_opt_ PVOID *Context)
{
/* Initialize memory management information */
NtQuerySystemInformation(SystemBasicInformation, &g_sbi, sizeof(g_sbi), NULL);

#if defined(_WIN64)
PLDR_DATA_TABLE_ENTRY NtdllLdrEntry;

Expand All @@ -79,30 +88,45 @@ VOID detour_memory_init()
}
#endif

if (g_hHeap == NULL)
/* Initialize private heap */
_detour_memory_heap = RtlCreateHeap(HEAP_NO_SERIALIZE | HEAP_GROWABLE, NULL, 0, 0, NULL, NULL);
if (_detour_memory_heap == NULL)
{
g_hHeap = RtlCreateHeap(HEAP_NO_SERIALIZE | HEAP_GROWABLE, NULL, 0, 0, NULL, NULL);
DETOUR_TRACE("RtlCreateHeap failed, fallback to process default heap\n");
_detour_memory_heap = NtGetProcessHeap();
}

return TRUE;
}

_Must_inspect_result_
_Ret_maybenull_
_Post_writable_byte_size_(Size)
PVOID detour_memory_alloc(_In_ SIZE_T Size)
PVOID
detour_memory_alloc(
_In_ SIZE_T Size)
{
if (g_hHeap == NULL)
{
g_hHeap = NtGetProcessHeap();
}
return RtlAllocateHeap(g_hHeap, 0, Size);
/*
* detour_memory_alloc is called BEFORE any other detour_memory_* functions,
* otherwise should find another way to initialize.
*/
/* Don't need try/except */
#pragma warning(disable: __WARNING_PROBE_NO_TRY)
RtlRunOnceExecuteOnce(&g_stInitMemory, detour_memory_init, NULL, NULL);
#pragma warning(default: __WARNING_PROBE_NO_TRY)
return RtlAllocateHeap(_detour_memory_heap, 0, Size);
}

BOOL detour_memory_free(_Frees_ptr_ PVOID BaseAddress)
BOOL
detour_memory_free(
_Frees_ptr_ PVOID BaseAddress)
{
return RtlFreeHeap(g_hHeap, 0, BaseAddress);
return RtlFreeHeap(_detour_memory_heap, 0, BaseAddress);
}

BOOL detour_memory_is_system_reserved(_In_ PVOID Address)
BOOL
detour_memory_is_system_reserved(
_In_ PVOID Address)
{
return
((ULONG_PTR)Address >= s_ulSystemRegionLowLowerBound && (ULONG_PTR)Address <= s_ulSystemRegionLowUpperBound)
Expand All @@ -114,15 +138,19 @@ BOOL detour_memory_is_system_reserved(_In_ PVOID Address)
}

_Ret_notnull_
PVOID detour_memory_2gb_below(_In_ PVOID Address)
PVOID
detour_memory_2gb_below(
_In_ PVOID Address)
{
return (ULONG_PTR)Address > g_sbi.MinimumUserModeAddress + _2GB ?
(PBYTE)Address - (_2GB - _512KB) :
(PVOID)(g_sbi.MinimumUserModeAddress + _512KB);
}

_Ret_notnull_
PVOID detour_memory_2gb_above(_In_ PVOID Address)
PVOID
detour_memory_2gb_above(
_In_ PVOID Address)
{
return (
#if !defined(_WIN64)
Expand Down
15 changes: 0 additions & 15 deletions Source/SlimDetours/SlimDetours.cpp

This file was deleted.

Loading

0 comments on commit c11c16d

Please sign in to comment.