我不擅长C ++,更像是C#和PHP人。我被分配了一个项目,要求我使用GetTickCount
并挂钩到应用程序。我需要一些帮助,因为它没有按计划工作......这是挂钩的代码,我知道它有效,因为我以前在项目中使用它。我唯一不确定的是GetTickCount
部分。我试过GetTickCount64
认为这是我的问题的解决方法(它没有崩溃我注入它的内容)但发现它只是根本没有工作所以它没有崩溃它。 / p>
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;
}
以下是用于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;
}
你能看到不正确或应该改变的东西吗?任何帮助表示赞赏。谢谢!
答案 0 :(得分:3)
什么是“KeyHooks”主题?如果它希望调用绕道的API,你应该在创建线程之前绕道而行。
GetTickCount_orig是否已完全设置?
GetTickCount可能是一个非常非常短的API,导致Detours出现问题(只是没有足够的字节来挂钩)。
您的DetourRemove正在移除GetTickCount64,而不是GetTickCount。
另外,如果Detours没有运行,那么mhook库的许可证就会简单得多。
答案 1 :(得分:1)
请勿修改oldtick
!
您只需保存一次,然后
// accelerating time by factor of "factor"
return oldtick + (realtick - oldtick) * factor;
编辑:
另一个可能的问题是GetTickCount
(至少在我的电脑上,XP 32bit)没有标准的“可挂钩”的前导码:
8B FF mov edi, edi
55 push ebp
8B EC mov ebp, esp
没有它,它只能从IAT挂钩,必须为每个调用它的模块完成。我怀疑DetourFunction
每个进程都有效,所以它使用前导码挂钩API。
要解决此问题,您可以尝试连接每个模块的IAT,也可以手动修补它,但是当它被连接时,您将无法调用原始版本。
EDIT2 :使用跳转是最常用的方法,但这意味着我们必须在函数开头覆盖5个字节。它的主要问题不是函数的大小,而是代码的开头。当然,任何东西都可以被覆盖,但如果你想在钩子打开时能够调用旧函数(如本问题所示),那么你必须知道你在覆盖什么。
您不想覆盖一半的操作码,并且您必须执行被覆盖的部分。这意味着在通用情况下,您需要一个完整的反汇编程序。
为了简化这一点,大多数函数都以一个额外的2字节NOP开始:mov edi, edi
,因此它们的前导码有5个字节,是标准的,易于重定位。