Skip to content

Commit dc310e3

Browse files
committed
Free unused trampoline regions on abort and attach error
Similar to the implementation in SlimDetoursTransactionCommit.
1 parent f117cbb commit dc310e3

File tree

3 files changed

+50
-8
lines changed

3 files changed

+50
-8
lines changed

Source/SlimDetours/SlimDetours.inl

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -266,6 +266,10 @@ detour_free_trampoline(
266266

267267
VOID detour_free_unused_trampoline_regions(VOID);
268268

269+
VOID
270+
detour_free_trampoline_region_if_unused(
271+
_In_ PDETOUR_TRAMPOLINE pTrampoline);
272+
269273
BYTE
270274
detour_align_from_trampoline(
271275
_In_ PDETOUR_TRAMPOLINE pTrampoline,

Source/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,

Source/SlimDetours/Transaction.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,7 @@ SlimDetoursTransactionAbort(VOID)
9898
PVOID pMem;
9999
SIZE_T sMem;
100100
DWORD dwOld;
101+
BOOL freed = FALSE;
101102

102103
if (s_nPendingThreadId != NtCurrentThreadId())
103104
{
@@ -115,13 +116,18 @@ SlimDetoursTransactionAbort(VOID)
115116
{
116117
detour_free_trampoline(o->pTrampoline);
117118
o->pTrampoline = NULL;
119+
freed = TRUE;
118120
}
119121

120122
PDETOUR_OPERATION n = o->pNext;
121123
detour_memory_free(o);
122124
o = n;
123125
}
124126
s_pPendingOperations = NULL;
127+
if (freed)
128+
{
129+
detour_free_unused_trampoline_regions();
130+
}
125131

126132
// Make sure the trampoline pages are no longer writable.
127133
detour_runnable_trampoline_regions();
@@ -324,6 +330,7 @@ SlimDetoursAttach(
324330
if (pTrampoline != NULL)
325331
{
326332
detour_free_trampoline(pTrampoline);
333+
detour_free_trampoline_region_if_unused(pTrampoline);
327334
pTrampoline = NULL;
328335
}
329336
if (o != NULL)

0 commit comments

Comments
 (0)