将GetTickCount与C+挂钩+; 我不擅长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与C+挂钩+; 我不擅长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; },c++,winapi,hook,detours,gettickcount,C++,Winapi,Hook,Detours,Gettickcount,下面是用于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)();

下面是用于
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; 
}

你能看到一些不正确或应该改变的地方吗?感谢您的帮助。谢谢大家!

不要修改
oldtick

你只需要保存一次,然后

// accelerating time by factor of "factor"
return oldtick + (realtick - oldtick) * factor;
编辑:

另一个可能的问题是
GetTickCount
(至少在我的计算机上,XP 32位)没有标准的“可挂接”前置MLE:

没有它,它只能从IAT连接,这必须为调用它的每个模块完成。我怀疑
DetourFunction
对每个进程都有效,所以它使用preamble钩住了API

要解决此问题,您可以尝试挂接每个模块的IAT,或手动对其进行修补,但挂接时将无法调用原始版本

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

为了简化这一点,大多数函数都从一个额外的2字节NOP:
mov edi,edi
,这样它们的前导码就有5个字节是标准的,并且很容易重新定位。

什么是“KeyHooks”线程?如果它希望调用绕道API,那么在创建线程之前应该绕道

GetTickCount_______________________________

GetTickCount很可能是一个非常非常短的API,它会导致绕道问题(只是没有足够的字节来进行连接)

您的DetourRemove正在删除GetTickCount64,而不是GetTickCount


另外,如果绕道不起作用,还有一个mhook库,它的许可证要简单得多。

这里的实际问题是什么?在尝试注入应用程序时,它会崩溃。我的QueryPerformanceCounter注入很好,没有问题。如何将
中断
案例DLL\u进程\u分离之前
?因为正如现在所写的,在初始化之后,你会立即移除你的钩子。我不认为迂回是如此愚蠢,以至于它不能处理任意的指令。他们不是提出了“蹦床”挂机想法的人吗?@wj32:那么为什么大多数Win32 API都以这个
mov edi,edi
开头?问题似乎在于
olddick=(*GetTickCount_orig)();返回oldtick
@E3pO:所以我是对的:)它被
jmp
无条件地修补,所以在钩子打开时无法调用原始函数。那你就得手工做了。@ruslik:那是为了更容易打补丁。这并不意味着在开始时没有填充就不可能进行修补@E3pO:我认为你需要使用蹦床的绕道功能。所有的钥匙钩所做的就是看看用户是否按下了shift键。void KeyHooks(void){while(true){makemetrue=false;while(GetAsyncKeyState(0x14)){makemetrue=true;}Sleep(50);}}。。我不确定GetTickCount__orig是否已设置好。当我没有GetTickCount64时,它会崩溃我尝试注入的任何内容。请退出调试器,查看是否设置了GetTickCount\u orig。另外,请参见上文valdo关于缺少break语句的观点(不敢相信我没有看到:)
8B FF     mov     edi, edi
55        push    ebp
8B EC     mov     ebp, esp