问题
I'm not great at C++, more of a C# and PHP guy. I've been assigned a project that requires me to use GetTickCount
and hooking into an application. I need some help as for some reason it's not working as planned... Here is the code for hooking, I know it works because i've used it in projects before. The only thing i'm not so sure about is the GetTickCount
part of it. I tried GetTickCount64
thinking that was a fix to my problem (It didn't crash what i was injecting it into) but found out that instead it just wasn't working at all so it didn't crash it.
bool APIENTRY DllMain(HINSTANCE hDll, DWORD dwReason, LPVOID lpReserved)
{
switch(dwReason)
{
case DLL_PROCESS_ATTACH:
DisableThreadLibraryCalls(hDll);
CreateThread(0,0, (LPTHREAD_START_ROUTINE)KeyHooks, 0, 0, 0);
GetTickCount_orig = (DWORD (__stdcall *)(void))DetourFunction((PBYTE)GetProcAddress(GetModuleHandle("kernel32.dll"), "GetTickCount"), (PBYTE)GetTickCount_hooked);
case DLL_PROCESS_DETACH:
DetourRemove((PBYTE)GetProcAddress(GetModuleHandle("kernel32.dll"), "GetTickCount"), (PBYTE)GetTickCount_hooked);
break;
}
return true;
}
Here is the rest of the code that is used for GetTickCount
DWORD oldtick=0;
DWORD (WINAPI *GetTickCount_orig)(void);
DWORD WINAPI GetTickCount_hooked(void)
{
if(oldtick==0)
{
oldtick=(*GetTickCount_orig)();
return oldtick;
}
DWORD factor;
DWORD ret;
ret = (*GetTickCount_orig)();
factor = 3.0;
DWORD newret;
newret = ret+((oldtick-ret)*(factor-1));
oldtick=ret;
return newret;
}
Can you see something that is incorrect or that should be changed? Any help is appreciated. Thank you!
回答1:
What's the "KeyHooks" thread? If it's expecting to be calling detoured APIs, you ought to detour before creating the thread.
Is GetTickCount_orig getting set at all?
GetTickCount is likely a very, very short API causing problems for Detours (just not enough bytes to do the hooking in).
Your DetourRemove is removing for GetTickCount64, not GetTickCount.
Separately, if Detours isn't working out, there's the mhook library which has far simpler licensing.
回答2:
Don't modify oldtick
!
You have to save it just once, and then
// accelerating time by factor of "factor"
return oldtick + (realtick - oldtick) * factor;
EDIT:
Another possible problem is that GetTickCount
(at least on my computer, XP 32bit) does not have the standard "hookable" preamle:
8B FF mov edi, edi
55 push ebp
8B EC mov ebp, esp
Without it it can be hooked only from IAT, and this have to be done for each module that calls it. I suspect that DetourFunction
works per process, so it hooks APIs using preamble.
To solve this you can either try hooking the IAT of each module, or patch it manually, but then you won't be able to call the original version while it's hooked.
EDIT2: Using jump is the most common way, but this means that we have to overwrite 5 bytes at the beginning of the function. It's main problem isn't the size of function, but the code at its start. Sure, anything can be overwritten, but if you want to be able to call the old function while the hook is on (as in this question), then you have to know what are you overwritting.
You don't want to overwrite half of the opcode, and you have to execute the overwitten part. This means that in generic case you'll need a full disassembler for that.
To simplify that, most functions starts with an additional 2-byte NOP: mov edi, edi
, so that their preamble have 5 bytes that are standard and easy to relocate.
来源:https://stackoverflow.com/questions/4823887/hooking-gettickcount-with-c