Skip to content

Commit 7ac81b6

Browse files

File tree

7 files changed

+201
-64
lines changed

7 files changed

+201
-64
lines changed

src/MinHook.c

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -206,7 +206,6 @@ static MH_STATUS EnableHook(ULONG_PTR hookIdent, LPVOID pTarget, BOOL enable)
206206
if (pos != INVALID_HOOK_POS)
207207
{
208208
DETOUR_TRANSACTION_OPTIONS options = {
209-
sizeof(options),
210209
g_threadFreezeMethod != MH_FREEZE_METHOD_NONE_UNSAFE
211210
};
212211
hr = SlimDetoursTransactionBeginEx(&options);
@@ -286,7 +285,6 @@ static MH_STATUS EnableHook(ULONG_PTR hookIdent, LPVOID pTarget, BOOL enable)
286285
if (pHook->isEnabled != enable)
287286
{
288287
DETOUR_TRANSACTION_OPTIONS options = {
289-
sizeof(options),
290288
g_threadFreezeMethod != MH_FREEZE_METHOD_NONE_UNSAFE
291289
};
292290
hr = SlimDetoursTransactionBeginEx(&options);
@@ -389,7 +387,6 @@ static MH_STATUS ApplyQueued(ULONG_PTR hookIdent)
389387
if (pos != INVALID_HOOK_POS)
390388
{
391389
DETOUR_TRANSACTION_OPTIONS options = {
392-
sizeof(options),
393390
g_threadFreezeMethod != MH_FREEZE_METHOD_NONE_UNSAFE
394391
};
395392
hr = SlimDetoursTransactionBeginEx(&options);

src/SlimDetours/Memory.c

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -141,14 +141,16 @@ detour_memory_free(
141141
return RtlFreeHeap(_detour_memory_heap, 0, BaseAddress);
142142
}
143143

144-
VOID
144+
BOOL
145145
detour_memory_uninitialize(VOID)
146146
{
147-
if (_detour_memory_heap != NULL)
147+
if (_detour_memory_heap != NULL && _detour_memory_heap != NtGetProcessHeap())
148148
{
149-
RtlDestroyHeap(_detour_memory_heap);
150-
_detour_memory_heap = NULL;
149+
_detour_memory_heap = RtlDestroyHeap(_detour_memory_heap);
150+
return _detour_memory_heap == NULL;
151151
}
152+
153+
return TRUE;
152154
}
153155

154156
BOOL

src/SlimDetours/SlimDetours.h

Lines changed: 34 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -27,13 +27,8 @@ extern "C" {
2727
#define DETOUR_INSTRUCTION_TARGET_NONE ((PVOID)0)
2828
#define DETOUR_INSTRUCTION_TARGET_DYNAMIC ((PVOID)(LONG_PTR)-1)
2929

30-
HRESULT
31-
NTAPI
32-
SlimDetoursTransactionBegin(VOID);
33-
3430
typedef struct _DETOUR_TRANSACTION_OPTIONS
3531
{
36-
ULONG cbSize;
3732
BOOL fSuspendThreads;
3833
} DETOUR_TRANSACTION_OPTIONS, *PDETOUR_TRANSACTION_OPTIONS;
3934

@@ -44,6 +39,15 @@ NTAPI
4439
SlimDetoursTransactionBeginEx(
4540
_In_ PCDETOUR_TRANSACTION_OPTIONS pOptions);
4641

42+
FORCEINLINE
43+
HRESULT
44+
SlimDetoursTransactionBegin(VOID)
45+
{
46+
DETOUR_TRANSACTION_OPTIONS Options;
47+
Options.fSuspendThreads = TRUE;
48+
return SlimDetoursTransactionBeginEx(&Options);
49+
}
50+
4751
HRESULT
4852
NTAPI
4953
SlimDetoursTransactionAbort(VOID);
@@ -58,11 +62,35 @@ SlimDetoursAttach(
5862
_Inout_ PVOID* ppPointer,
5963
_In_ PVOID pDetour);
6064

65+
typedef struct _DETOUR_DETACH_OPTIONS
66+
{
67+
PVOID *ppTrampolineToFreeManually;
68+
} DETOUR_DETACH_OPTIONS, *PDETOUR_DETACH_OPTIONS;
69+
70+
typedef const DETOUR_DETACH_OPTIONS* PCDETOUR_DETACH_OPTIONS;
71+
6172
HRESULT
6273
NTAPI
74+
SlimDetoursDetachEx(
75+
_Inout_ PVOID* ppPointer,
76+
_In_ PVOID pDetour,
77+
_In_ PCDETOUR_DETACH_OPTIONS pOptions);
78+
79+
FORCEINLINE
80+
HRESULT
6381
SlimDetoursDetach(
6482
_Inout_ PVOID* ppPointer,
65-
_In_ PVOID pDetour);
83+
_In_ PVOID pDetour)
84+
{
85+
DETOUR_DETACH_OPTIONS Options;
86+
Options.ppTrampolineToFreeManually = NULL;
87+
return SlimDetoursDetachEx(ppPointer, pDetour, &Options);
88+
}
89+
90+
HRESULT
91+
NTAPI
92+
SlimDetoursFreeTrampoline(
93+
_In_ PVOID pTrampoline);
6694

6795
PVOID
6896
NTAPI

src/SlimDetours/SlimDetours.inl

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -100,17 +100,24 @@ _STATIC_ASSERT(sizeof(DETOUR_TRAMPOLINE) == 96);
100100
_STATIC_ASSERT(sizeof(DETOUR_TRAMPOLINE) == 184);
101101
#endif
102102

103+
enum
104+
{
105+
DETOUR_OPERATION_NONE = 0,
106+
DETOUR_OPERATION_ADD,
107+
DETOUR_OPERATION_REMOVE,
108+
};
109+
103110
typedef struct _DETOUR_OPERATION DETOUR_OPERATION, *PDETOUR_OPERATION;
104111

105112
struct _DETOUR_OPERATION
106113
{
107114
PDETOUR_OPERATION pNext;
108-
BOOL fIsAdd : 1;
109-
BOOL fIsRemove : 1;
115+
DWORD dwOperation;
110116
PBYTE* ppbPointer;
111117
PBYTE pbTarget;
112118
PDETOUR_TRAMPOLINE pTrampoline;
113119
ULONG dwPerm;
120+
PVOID* ppTrampolineToFreeManually;
114121
};
115122

116123
/* Memory management */
@@ -134,7 +141,7 @@ BOOL
134141
detour_memory_free(
135142
_Frees_ptr_ PVOID BaseAddress);
136143

137-
VOID
144+
BOOL
138145
detour_memory_uninitialize(VOID);
139146

140147
BOOL
@@ -269,6 +276,10 @@ detour_free_trampoline(
269276

270277
VOID detour_free_unused_trampoline_regions(VOID);
271278

279+
VOID
280+
detour_free_trampoline_region_if_unused(
281+
_In_ PDETOUR_TRAMPOLINE pTrampoline);
282+
272283
BYTE
273284
detour_align_from_trampoline(
274285
_In_ PDETOUR_TRAMPOLINE pTrampoline,

src/SlimDetours/Thread.c

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ detour_thread_suspend(
2323
HANDLE CurrentTID = (HANDLE)(ULONG_PTR)NtCurrentThreadId();
2424
BOOL ClosePrevThread = FALSE;
2525
HANDLE ThreadHandle = NULL;
26+
2627
while (TRUE)
2728
{
2829
HANDLE NextThreadHandle;
@@ -44,21 +45,18 @@ detour_thread_suspend(
4445
ThreadHandle = NextThreadHandle;
4546
ClosePrevThread = TRUE;
4647

48+
/* Skip the current thread */
4749
if (!CurrentThreadSkipped)
4850
{
4951
THREAD_BASIC_INFORMATION BasicInformation;
50-
if (!NT_SUCCESS(NtQueryInformationThread(
51-
ThreadHandle,
52-
ThreadBasicInformation,
53-
&BasicInformation,
54-
sizeof(BasicInformation),
55-
NULL
56-
)))
52+
if (!NT_SUCCESS(NtQueryInformationThread(ThreadHandle,
53+
ThreadBasicInformation,
54+
&BasicInformation,
55+
sizeof(BasicInformation),
56+
NULL)))
5757
{
5858
continue;
5959
}
60-
61-
/* Skip the current thread */
6260
if (BasicInformation.ClientId.UniqueThread == CurrentTID)
6361
{
6462
CurrentThreadSkipped = TRUE;
@@ -82,6 +80,10 @@ detour_thread_suspend(
8280
if (Buffer == s_Handles)
8381
{
8482
p = (PHANDLE)detour_memory_alloc(BufferCapacity * sizeof(HANDLE));
83+
if (p)
84+
{
85+
RtlCopyMemory(p, Buffer, SuspendedCount * sizeof(HANDLE));
86+
}
8587
} else
8688
{
8789
p = (PHANDLE)detour_memory_realloc(Buffer, BufferCapacity * sizeof(HANDLE));
@@ -186,7 +188,7 @@ detour_thread_update(
186188
bUpdateContext = FALSE;
187189
for (o = PendingOperations; o != NULL && !bUpdateContext; o = o->pNext)
188190
{
189-
if (o->fIsRemove)
191+
if (o->dwOperation == DETOUR_OPERATION_REMOVE)
190192
{
191193
if (cxt.CONTEXT_PC >= (ULONG_PTR)o->pTrampoline->rbCode &&
192194
cxt.CONTEXT_PC < ((ULONG_PTR)o->pTrampoline->rbCode + RTL_FIELD_SIZE(DETOUR_TRAMPOLINE, rbCode)))
@@ -202,7 +204,7 @@ detour_thread_update(
202204
bUpdateContext = TRUE;
203205
}
204206
#endif
205-
} else if (o->fIsAdd)
207+
} else if (o->dwOperation == DETOUR_OPERATION_ADD)
206208
{
207209
if (cxt.CONTEXT_PC >= (ULONG_PTR)o->pbTarget &&
208210
cxt.CONTEXT_PC < ((ULONG_PTR)o->pbTarget + o->pTrampoline->cbRestore))

src/SlimDetours/Trampoline.c

Lines changed: 39 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -400,24 +400,29 @@ detour_is_region_empty(
400400
return TRUE;
401401
}
402402

403+
static
403404
VOID
404-
detour_free_unused_trampoline_regions(VOID)
405+
detour_free_region(
406+
_In_ PDETOUR_REGION* ppRegionBase,
407+
_In_ PDETOUR_REGION pRegion)
405408
{
406-
PVOID pMem;
407-
SIZE_T sMem;
409+
*ppRegionBase = pRegion->pNext;
410+
PVOID pMem = pRegion;
411+
SIZE_T sMem = 0;
412+
NtFreeVirtualMemory(NtCurrentProcess(), &pMem, &sMem, MEM_RELEASE);
413+
}
408414

415+
VOID
416+
detour_free_unused_trampoline_regions(VOID)
417+
{
409418
PDETOUR_REGION* ppRegionBase = &s_pRegions;
410419
PDETOUR_REGION pRegion = s_pRegions;
411420

412421
while (pRegion != NULL)
413422
{
414423
if (detour_is_region_empty(pRegion))
415424
{
416-
*ppRegionBase = pRegion->pNext;
417-
418-
pMem = pRegion;
419-
sMem = 0;
420-
NtFreeVirtualMemory(NtCurrentProcess(), &pMem, &sMem, MEM_RELEASE);
425+
detour_free_region(ppRegionBase, pRegion);
421426
s_pRegion = NULL;
422427
} else
423428
{
@@ -427,6 +432,32 @@ detour_free_unused_trampoline_regions(VOID)
427432
}
428433
}
429434

435+
VOID
436+
detour_free_trampoline_region_if_unused(
437+
_In_ PDETOUR_TRAMPOLINE pTrampoline)
438+
{
439+
PDETOUR_REGION pTargetRegion = (PDETOUR_REGION)((ULONG_PTR)pTrampoline & ~(ULONG_PTR)0xffff);
440+
441+
PDETOUR_REGION* ppRegionBase = &s_pRegions;
442+
PDETOUR_REGION pRegion = s_pRegions;
443+
444+
while (pRegion != NULL)
445+
{
446+
if (pRegion == pTargetRegion)
447+
{
448+
if (detour_is_region_empty(pRegion))
449+
{
450+
detour_free_region(ppRegionBase, pRegion);
451+
s_pRegion = NULL;
452+
}
453+
break;
454+
}
455+
456+
ppRegionBase = &pRegion->pNext;
457+
pRegion = *ppRegionBase;
458+
}
459+
}
460+
430461
BYTE
431462
detour_align_from_trampoline(
432463
_In_ PDETOUR_TRAMPOLINE pTrampoline,

0 commit comments

Comments
 (0)