Skip to content

Commit 464d4d7

Browse files
committed
1 parent 22e8dff commit 464d4d7

6 files changed

Lines changed: 396 additions & 158 deletions

File tree

SlimDetours/Instruction.c

Lines changed: 73 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -85,15 +85,14 @@ detour_is_imported(
8585
/* Step forward to IMAGE_OPTIONAL_HEADER and check magic */
8686
_STATIC_ASSERT(UFIELD_OFFSET(IMAGE_OPTIONAL_HEADER, Magic) == 0);
8787
wNtMagic = pNtHeader->OptionalHeader.Magic;
88-
if ((wNtMagic != IMAGE_NT_OPTIONAL_HDR64_MAGIC ||
89-
pNtHeader->FileHeader.SizeOfOptionalHeader != sizeof(IMAGE_OPTIONAL_HEADER64)) &&
90-
(wNtMagic != IMAGE_NT_OPTIONAL_HDR32_MAGIC ||
91-
pNtHeader->FileHeader.SizeOfOptionalHeader != sizeof(IMAGE_OPTIONAL_HEADER32)))
88+
if (wNtMagic != IMAGE_NT_OPTIONAL_HDR_MAGIC ||
89+
pNtHeader->FileHeader.SizeOfOptionalHeader != sizeof(IMAGE_OPTIONAL_HEADER))
9290
{
9391
return FALSE;
9492
}
9593

96-
if (pbAddress < Add2Ptr(mbi.AllocationBase,
94+
if (pNtHeader->OptionalHeader.NumberOfRvaAndSizes <= IMAGE_DIRECTORY_ENTRY_IAT ||
95+
pbAddress < Add2Ptr(mbi.AllocationBase,
9796
pNtHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IAT].VirtualAddress) ||
9897
pbAddress >= Add2Ptr(mbi.AllocationBase,
9998
pNtHeader->OptionalHeader
@@ -121,6 +120,20 @@ detour_gen_jmp_immediate(
121120
return pbCode + sizeof(INT32);
122121
}
123122

123+
BOOL
124+
detour_is_jmp_immediate_to(
125+
_In_ PBYTE pbCode,
126+
_In_ PBYTE pbJmpVal)
127+
{
128+
PBYTE pbJmpSrc = pbCode + 5;
129+
if (*pbCode++ != 0xe9) // jmp +imm32
130+
{
131+
return FALSE;
132+
}
133+
INT32 offset = *((INT32*)pbCode);
134+
return offset == (INT32)(pbJmpVal - pbJmpSrc);
135+
}
136+
124137
_Ret_notnull_
125138
PBYTE
126139
detour_gen_jmp_indirect(
@@ -140,6 +153,30 @@ detour_gen_jmp_indirect(
140153
return pbCode + sizeof(INT32);
141154
}
142155

156+
BOOL
157+
detour_is_jmp_indirect_to(
158+
_In_ PBYTE pbCode,
159+
_In_ PBYTE* ppbJmpVal)
160+
{
161+
#if defined(_AMD64_)
162+
PBYTE pbJmpSrc = pbCode + 6;
163+
#endif
164+
if (*pbCode++ != 0xff) // jmp [+imm32]
165+
{
166+
return FALSE;
167+
}
168+
if (*pbCode++ != 0x25)
169+
{
170+
return FALSE;
171+
}
172+
INT32 offset = *((INT32*)pbCode);
173+
#if defined(_AMD64_)
174+
return offset == (INT32)((PBYTE)ppbJmpVal - pbJmpSrc);
175+
#else
176+
return offset == (INT32)((PBYTE)ppbJmpVal);
177+
#endif
178+
}
179+
143180
_Ret_notnull_
144181
PBYTE
145182
detour_gen_brk(
@@ -489,6 +526,37 @@ detour_gen_jmp_indirect(
489526
return pbCode;
490527
}
491528

529+
BOOL
530+
detour_is_jmp_indirect_to(
531+
_In_ PBYTE pbCode,
532+
_In_ PULONG64 pbJmpVal)
533+
{
534+
const struct ARM64_INDIRECT_JMP* pIndJmp;
535+
union ARM64_INDIRECT_IMM jmpIndAddr;
536+
537+
jmpIndAddr.value = (((LONG64)pbJmpVal) & 0xFFFFFFFFFFFFF000) -
538+
(((LONG64)pbCode) & 0xFFFFFFFFFFFFF000);
539+
540+
pIndJmp = (const struct ARM64_INDIRECT_JMP*)pbCode;
541+
542+
return pIndJmp->ardp.Rd == 17 &&
543+
pIndJmp->ardp.immhi == (ULONG)jmpIndAddr.adrp_immhi &&
544+
pIndJmp->ardp.iop == 0x10 &&
545+
pIndJmp->ardp.immlo == (ULONG)jmpIndAddr.adrp_immlo &&
546+
pIndJmp->ardp.op == 1 &&
547+
548+
pIndJmp->ldr.Rt == 17 &&
549+
pIndJmp->ldr.Rn == 17 &&
550+
pIndJmp->ldr.imm == (((ULONG64)pbJmpVal) & 0xFFF) / 8 &&
551+
pIndJmp->ldr.opc == 1 &&
552+
pIndJmp->ldr.iop1 == 1 &&
553+
pIndJmp->ldr.V == 0 &&
554+
pIndJmp->ldr.iop2 == 7 &&
555+
pIndJmp->ldr.size == 3 &&
556+
557+
pIndJmp->br == 0xD61F0220;
558+
}
559+
492560
_Ret_notnull_
493561
PBYTE
494562
detour_gen_jmp_immediate(

SlimDetours/Memory.c

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,13 +123,34 @@ detour_memory_alloc(
123123
return RtlAllocateHeap(_detour_memory_heap, 0, Size);
124124
}
125125

126+
_Must_inspect_result_
127+
_Ret_maybenull_
128+
_Post_writable_byte_size_(Size)
129+
PVOID
130+
detour_memory_realloc(
131+
_Frees_ptr_opt_ PVOID BaseAddress,
132+
_In_ SIZE_T Size)
133+
{
134+
return RtlReAllocateHeap(_detour_memory_heap, 0, BaseAddress, Size);
135+
}
136+
126137
BOOL
127138
detour_memory_free(
128139
_Frees_ptr_ PVOID BaseAddress)
129140
{
130141
return RtlFreeHeap(_detour_memory_heap, 0, BaseAddress);
131142
}
132143

144+
VOID
145+
detour_memory_uninitialize(VOID)
146+
{
147+
if (_detour_memory_heap != NULL)
148+
{
149+
RtlDestroyHeap(_detour_memory_heap);
150+
_detour_memory_heap = NULL;
151+
}
152+
}
153+
133154
BOOL
134155
detour_memory_is_system_reserved(
135156
_In_ PVOID Address)

SlimDetours/SlimDetours.h

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,19 @@ HRESULT
3131
NTAPI
3232
SlimDetoursTransactionBegin(VOID);
3333

34+
typedef struct _DETOUR_TRANSACTION_OPTIONS
35+
{
36+
ULONG cbSize;
37+
BOOL fSuspendThreads;
38+
} DETOUR_TRANSACTION_OPTIONS, *PDETOUR_TRANSACTION_OPTIONS;
39+
40+
typedef const DETOUR_TRANSACTION_OPTIONS* PCDETOUR_TRANSACTION_OPTIONS;
41+
42+
HRESULT
43+
NTAPI
44+
SlimDetoursTransactionBeginEx(
45+
_In_ PCDETOUR_TRANSACTION_OPTIONS pOptions);
46+
3447
HRESULT
3548
NTAPI
3649
SlimDetoursTransactionAbort(VOID);
@@ -64,6 +77,10 @@ SlimDetoursCopyInstruction(
6477
_Out_opt_ PVOID* ppTarget,
6578
_Out_opt_ LONG* plExtra);
6679

80+
HRESULT
81+
NTAPI
82+
SlimDetoursUninitialize(VOID);
83+
6784
/* Inline Hook, base on Detours */
6885

6986
/// <summary>

SlimDetours/SlimDetours.inl

Lines changed: 30 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -87,13 +87,13 @@ typedef struct _DETOUR_TRAMPOLINE
8787
DETOUR_ALIGN rAlign[8]; // instruction alignment array.
8888
PBYTE pbRemain; // first instruction after moved code. [free list]
8989
PBYTE pbDetour; // first instruction of detour function.
90-
#if defined(_AMD64_)
90+
#if defined(_X86_) || defined(_AMD64_)
9191
BYTE rbCodeIn[8]; // jmp [pbDetour]
9292
#endif
9393
} DETOUR_TRAMPOLINE, *PDETOUR_TRAMPOLINE;
9494

9595
#if defined(_X86_)
96-
_STATIC_ASSERT(sizeof(DETOUR_TRAMPOLINE) == 72);
96+
_STATIC_ASSERT(sizeof(DETOUR_TRAMPOLINE) == 80);
9797
#elif defined(_AMD64_)
9898
_STATIC_ASSERT(sizeof(DETOUR_TRAMPOLINE) == 96);
9999
#elif defined(_ARM64_)
@@ -105,7 +105,8 @@ typedef struct _DETOUR_OPERATION DETOUR_OPERATION, *PDETOUR_OPERATION;
105105
struct _DETOUR_OPERATION
106106
{
107107
PDETOUR_OPERATION pNext;
108-
BOOL fIsRemove;
108+
BOOL fIsAdd : 1;
109+
BOOL fIsRemove : 1;
109110
PBYTE* ppbPointer;
110111
PBYTE pbTarget;
111112
PDETOUR_TRAMPOLINE pTrampoline;
@@ -121,10 +122,21 @@ PVOID
121122
detour_memory_alloc(
122123
_In_ SIZE_T Size);
123124

125+
_Must_inspect_result_
126+
_Ret_maybenull_
127+
_Post_writable_byte_size_(Size)
128+
PVOID
129+
detour_memory_realloc(
130+
_Frees_ptr_opt_ PVOID BaseAddress,
131+
_In_ SIZE_T Size);
132+
124133
BOOL
125134
detour_memory_free(
126135
_Frees_ptr_ PVOID BaseAddress);
127136

137+
VOID
138+
detour_memory_uninitialize(VOID);
139+
128140
BOOL
129141
detour_memory_is_system_reserved(
130142
_In_ PVOID Address);
@@ -158,12 +170,22 @@ detour_gen_jmp_immediate(
158170
_In_ PBYTE pbCode,
159171
_In_ PBYTE pbJmpVal);
160172

173+
BOOL
174+
detour_is_jmp_immediate_to(
175+
_In_ PBYTE pbCode,
176+
_In_ PBYTE pbJmpVal);
177+
161178
_Ret_notnull_
162179
PBYTE
163180
detour_gen_jmp_indirect(
164181
_In_ PBYTE pbCode,
165182
_In_ PBYTE* ppbJmpVal);
166183

184+
BOOL
185+
detour_is_jmp_indirect_to(
186+
_In_ PBYTE pbCode,
187+
_In_ PBYTE* ppbJmpVal);
188+
167189
#elif defined(_ARM64_)
168190

169191
_Ret_notnull_
@@ -179,6 +201,11 @@ detour_gen_jmp_indirect(
179201
_In_ PBYTE pbCode,
180202
_In_ PULONG64 pbJmpVal);
181203

204+
BOOL
205+
detour_is_jmp_indirect_to(
206+
_In_ PBYTE pbCode,
207+
_In_ PULONG64 pbJmpVal);
208+
182209
#endif
183210

184211
_Ret_notnull_

0 commit comments

Comments
 (0)