From 384e15bb1cb905b9ef41dd712f1c90a0d86c0e74 Mon Sep 17 00:00:00 2001 From: Ducson Nguyen Date: Wed, 28 Apr 2021 09:02:59 -0400 Subject: [PATCH] Fix free list prev pointer when allocating new block When FindTrampolineInRange() can't locate a suitable trampoline in the existing free list, TrampolineAlloc() calls BlockAlloc() to create a new pool of trampolines. BlockAlloc() links the last node of the new free list to the beginning of the existing free list. But it did NOT link the head of the existing free list back to the tail of the new list via the pPrevTrampoline pointer. If that old head node was ever used for a trampoline, ListRemove() was unable to update its predecessor to properly remove it from the free list. That node would get pulled for use again if a hook needed another trampoline in its address range. Changing the hook address could misdirect the previous function(s) that used the same trampoline. --- mhook-lib/mhook.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/mhook-lib/mhook.cpp b/mhook-lib/mhook.cpp index 3380dce..7b88b2e 100644 --- a/mhook-lib/mhook.cpp +++ b/mhook-lib/mhook.cpp @@ -355,8 +355,12 @@ static MHOOKS_TRAMPOLINE* BlockAlloc(PBYTE pSystemFunction, PBYTE pbLower, PBYTE pRetVal[s].pNextTrampoline = &pRetVal[s + 1]; } - // last entry points to the current head of the free list + // last entry points to the current head of the free list and + // the current head points back to the last entry of the new block pRetVal[trampolineCount - 1].pNextTrampoline = g_pFreeList; + if (g_pFreeList) { + g_pFreeList->pPrevTrampoline = &pRetVal[trampolineCount - 1]; + } break; } }