BOOL AddDetour(DWORD address, PBYTE pfDetour, PBYTE pfTrampoline, DWORD Count, PCHAR Name) { CAutoLock Lock(&gDetourCS); CHAR szName[MAX_STRING] = { 0 }; if (Name && Name[0] != '\0') { strcpy_s(szName, Name); } else { strcpy_s(szName, "Unknown"); } BOOL Ret = TRUE; DebugSpew("AddDetour(%s, 0x%X,0x%X,0x%X,0x%X)", szName, address, pfDetour, pfTrampoline, Count); if (FindDetour(address)) { DebugSpew("Address for %s (0x%x) already detoured.", szName, address); return FALSE; } OurDetours *detour = new OurDetours; strcpy_s(detour->Name, szName); detour->addr = address; detour->count = Count; memcpy(detour->array, (char *)address, Count); detour->pNext = ourdetours; if (ourdetours) ourdetours->pLast = detour; detour->pLast = 0; if (pfTrampoline) { // its an indirect jump, likely due to incremental linking. The actual // function body is at the other end of the jump. We need to follow it. if (pfTrampoline[0] == 0xe9) { pfTrampoline = pfTrampoline + *(DWORD*)&pfTrampoline[1] + 5; } if (pfTrampoline[0] && pfTrampoline[1]) { DWORD oldperm = 0, tmp; VirtualProtectEx(GetCurrentProcess(), (LPVOID)pfTrampoline, 2, PAGE_EXECUTE_READWRITE, &oldperm); pfTrampoline[0] = 0x90; pfTrampoline[1] = 0x90; VirtualProtectEx(GetCurrentProcess(), (LPVOID)pfTrampoline, 2, oldperm, &tmp); } } if (pfDetour && !DetourFunctionWithEmptyTrampoline(pfTrampoline, (PBYTE)address, pfDetour)) { detour->pfDetour = 0; detour->pfTrampoline = 0; Ret = FALSE; DebugSpew("Detour of %s failed.", szName); } else { detour->pfDetour = pfDetour; detour->pfTrampoline = pfTrampoline; DebugSpew("Detour of %s was successful.", szName); } ourdetours = detour; return Ret; }
BOOL AddDetour(DWORD address, PBYTE pfDetour, PBYTE pfTrampoline, DWORD Count) { CAutoLock Lock(&gDetourCS); BOOL Ret=TRUE; DebugSpew("AddDetour(0x%X,0x%X,0x%X,0x%X)",address,pfDetour,pfTrampoline,Count); if (FindDetour(address)) { DebugSpew("Address 0x%x already detoured.",address); return FALSE; } OurDetours *detour = new OurDetours; detour->addr=address; detour->count=Count; memcpy(detour->array,(char *)address, Count); detour->pNext=ourdetours; if (ourdetours) ourdetours->pLast=detour; detour->pLast=0; if (pfDetour && !DetourFunctionWithEmptyTrampoline(pfTrampoline, (PBYTE)address, pfDetour)) { detour->pfDetour=0; detour->pfTrampoline=0; Ret=FALSE; DebugSpew("Detour failed."); } else { detour->pfDetour=pfDetour; detour->pfTrampoline=pfTrampoline; DebugSpew("Detour success."); } ourdetours=detour; return Ret; }