我对C++不是很在行,我更喜欢C#和PHP。我被分配了一个项目,该项目要求我使用GetTickCount并连接到应用程序中。我需要一些帮助,因为出于某种原因,它没有按计划工作...这是钩子的代码,我知道它是有效的,因为我以前在项目中用过它。我唯一不确定的是它的GetTickCount部分。我试着尝试GetTickCount64,以为这是我的问题的修复方法(它没有使我注入的东西崩溃),但发现它根本不起作用,所以它没有崩溃。
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;
}你能看到一些不正确的地方或者应该改变的地方吗?任何帮助都是非常感谢的。谢谢!
发布于 2011-02-01 07:12:46
什么是"KeyHooks“线程?如果它希望调用绕道的API,你应该在创建线程之前绕道而行。
GetTickCount_orig已经准备好了吗?
GetTickCount很可能是一个非常、非常短的API,给绕道带来了问题(只是没有足够的字节来完成挂接)。
您的DetourRemove正在为GetTickCount64删除,而不是为GetTickCount删除。
另外,如果Detour不能正常工作,还有一个mhook库,它的许可要简单得多。
发布于 2011-01-28 09:31:07
不要修改oldtick!
你只需要保存一次,然后
// accelerating time by factor of "factor"
return oldtick + (realtick - oldtick) * factor;编辑:
另一个可能的问题是GetTickCount (至少在我的电脑上,XP 32位)没有标准的“可挂接”前言:
8B FF mov edi, edi
55 push ebp
8B EC mov ebp, esp如果没有它,它只能从IAT挂接,并且必须为调用它的每个模块执行此操作。我怀疑DetourFunction是按进程工作的,所以它使用前同步码挂接API。
要解决此问题,您可以尝试挂钩每个模块的IAT,或者手动对其进行修补,但这样就无法在挂钩时调用原始版本。
EDIT2:使用jump是最常见的方式,但这意味着我们必须在函数的开头覆盖5个字节。它的主要问题不是函数的大小,而是它开始时的代码。当然,任何东西都可以被重写,但是如果你想在钩子打开的时候调用旧的函数(就像这个问题一样),那么你必须知道你在重写什么。
你不想重写一半的操作码,你必须执行重写部分。这意味着在一般情况下,你需要一个完整的反汇编程序。
为了简化这一点,大多数函数都从一个额外的2字节NOP:mov edi, edi开始,这样它们的前同步码就有5个字节,这是标准的,很容易重新定位。
https://stackoverflow.com/questions/4823887
复制相似问题