//========================================================================= // Internal function: // // Will try to allocate the trampoline structure within 2 gigabytes of // the target function. //========================================================================= static MHOOKS_TRAMPOLINE* TrampolineAlloc(PBYTE pSystemFunction, S64 nLimitUp, S64 nLimitDown) { MHOOKS_TRAMPOLINE* pTrampoline = NULL; // determine lower and upper bounds for the allocation locations. // in the basic scenario this is +/- 2GB but IP-relative instructions // found in the original code may require a smaller window. PBYTE pLower = pSystemFunction + nLimitUp; pLower = pLower < (PBYTE)(DWORD_PTR)0x0000000080000000 ? (PBYTE)(0x1) : (PBYTE)(pLower - (PBYTE)0x7fff0000); PBYTE pUpper = pSystemFunction + nLimitDown; pUpper = pUpper < (PBYTE)(DWORD_PTR)0xffffffff80000000 ? (PBYTE)(pUpper + (DWORD_PTR)0x7ff80000) : (PBYTE)(DWORD_PTR)0xfffffffffff80000; ODPRINTF((L"mhooks: TrampolineAlloc: Allocating for %p between %p and %p", pSystemFunction, pLower, pUpper)); // try to find a trampoline in the specified range pTrampoline = FindTrampolineInRange(pLower, pUpper); if (!pTrampoline) { // if it we can't find it, then we need to allocate a new block and // try again. Just fail if that doesn't work g_pFreeList = BlockAlloc(pSystemFunction, pLower, pUpper); pTrampoline = FindTrampolineInRange(pLower, pUpper); } // found and allocated a trampoline? if (pTrampoline) { ListPrepend(&g_pHooks, pTrampoline); } return pTrampoline; }
bool TestListInsertAfter(List *list) { ListDeleteAll(list); // Already tested if (!ListEmpty(list)) { sprintf(error, "This test requires list to be empty"); return false; } int i; int k = 5; for (i = length-k; i < length; i++) ListAppend(list, numbers[i]); // Already tested for (i = k - 1; i >= 0; i--) ListPrepend(list, numbers[i]); // Already tested ListItor itor = ListHead(list); for (i = 0; i < k-1; i++) itor = ListItorNext(itor); for (i = length - k - 1; i >= k; i--) if (!ListInsertAfter(itor, numbers[i])) { sprintf(error, "ListInsertAfter failed"); return false; } if (!VerifyListConsistency(list)) { sprintf(error, "List is not consistent with numbers after ListInsertAfter"); return false; } return true; }
//========================================================================= // Internal function: // // Free a trampoline structure. //========================================================================= static VOID TrampolineFree(MHOOKS_TRAMPOLINE* pTrampoline, BOOL bNeverUsed) { ListRemove(&g_pHooks, pTrampoline); // If a thread could feasinbly have some of our trampoline code // on its stack and we yank the region from underneath it then it will // surely crash upon returning. So instead of freeing the // memory we just let it leak. Ugly, but safe. if (bNeverUsed) { ListPrepend(&g_pFreeList, pTrampoline); } g_nHooksInUse--; }
bool TestListPrepend(List *list) { int i; for (i = length-1; i >= 0; i--) { if (!ListPrepend(list, numbers[i])) { sprintf(error, "Prepend failed!!"); return false; } } if (!VerifyListConsistency(list)) { strcat(error, " - after ListPrepend"); return false; } return true; }