使用 C++ 挂钩 GetTickCount

E3p*_*3pO 5 c++ hook winapi detours gettickcount

我不太擅长 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;
}
Run Code Online (Sandbox Code Playgroud)

这是用于的其余代码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; 
}
Run Code Online (Sandbox Code Playgroud)

您能看到一些不正确或应该更改的内容吗?任何帮助表示赞赏。谢谢你!

rus*_*lik 1

请勿修改oldtick

您只需保存一次,然后

// accelerating time by factor of "factor"
return oldtick + (realtick - oldtick) * factor;
Run Code Online (Sandbox Code Playgroud)

编辑:

另一个可能的问题是GetTickCount(至少在我的电脑上,XP 32位)没有标准的“hookable”序言:

8B FF     mov     edi, edi
55        push    ebp
8B EC     mov     ebp, esp
Run Code Online (Sandbox Code Playgroud)

如果没有它,它只能从 IAT 挂钩,并且必须为调用它的每个模块完成此操作。我怀疑DetourFunction每个进程都有效,因此它使用前导码挂钩 API。

要解决这个问题,您可以尝试挂接每个模块的 IAT,或者手动修补它,但这样您将无法在挂接时调用原始版本。

EDIT2:使用跳转是最常见的方法,但这意味着我们必须覆盖函数开头的 5 个字节。主要问题不在于函数的大小,而在于其开头的代码。当然,任何内容都可以被覆盖,但是如果您希望能够在挂钩打开时调用旧函数(如本问题所示),那么您必须知道您要覆盖什么。
您不想覆盖一半的操作码,并且必须执行被覆盖的部分。这意味着在一般情况下,您将需要一个完整的反汇编程序。

为了简化这一点,大多数函数都以额外的 2 字节 NOP: 开头mov edi, edi,因此它们的前导码具有标准且易于重新定位的 5 个字节。