我正在尝试构建一个dll(以便注入到进程中),并且遇到一些问题。
让我解释一下:
当我将dll注入目标时,一切正常。当我在第一个目标仍在运行时添加了另一个目标(相同的可执行文件)后,就会出现一些冲突。
公平地说,我认为只有“一次”冲突。这是代码。
DWORD WINAPI MainThread(LPVOID param)
{
// Same behaviour with GetKeyState
while (!GetAsyncKeyState(VK_F9)) // While F9 is not pressed, do nothing
Sleep(5);
fprintf(stdout, "Clicked !"); // Print Clicked when F9 is pressed
while(true); // Just to stop.
return false;
}
BOOL APIENTRY DllMain(HMODULE hModule,DWORD ul_reason_for_call,LPVOID lpReserved)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH: // Gets ran when injected
AllocConsole(); // Enable the console
freopen_s((FILE**)stdout, "CONOUT$", "w", stdout);
freopen_s((FILE**)stdin, "CONIN$", "r", stdin);
CreateThread(0, 0, MainThread, hModule, 0, 0); // Creates our thread
break;
}
return TRUE;
}
此示例将执行以下操作:我启动Target.exe,将Inject.dll注入其中,然后按F9,出现“单击”。预期。现在,我启动Target.exe,注入Indect.dll,我不按F9。取而代之的是,我启动另一个Target.exe,将Inject.dll注入其中,现在,如果我按F9,则会在两个控制台上打印Clicked。出乎意料。
为什么?
我在https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-getasynckeystate上阅读了以下内容
尽管返回值的最低有效位指示自上一次查询以来是否已按下键,但由于Windows的抢先式多任务处理特性,另一个应用程序可以调用GetAsyncKeyState并接收“最近按下”位,而不是应用。为了与16位My Windows应用程序(非抢占式)兼容,严格保留返回值的最低有效位的行为,因此不应依赖。
Target.exe和Inject.dll都是32位,所以我想我不必为该报价而烦恼,所以我对造成它的原因一无所知。
请注意,我也使用getchar进行了测试,但是由于它与控制台相关,因此即使它不能在第二个控制台上打印,也无法使用它。
嗯,正如我在最后一条评论中所述
与SetWindowsHook尝试过,行为相同。出现一个窗口重命名+名称比较。完美的作品!感谢您的帮助
我使用重命名+名称比较。其他问题出现了,所以我不得不重新考虑实现它的方式。这是最终版本:
bool isSameProcess(HWND window, DWORD pid)
{
DWORD activePId;
DWORD activeThreadId = GetWindowThreadProcessId(window, &activePId);
return activePId == pid;
}
说明:window是活动窗口,请输入我们自己的进程ID。我们将检查我们的pid是否等于活动窗口的进程ID。如果是,则返回true,否则返回false。
因此,您可以这样使用它:
if ((GetAsyncKeyState(VK_F9) & 0x8000))
{
window = GetForegroundWindow();
if(isSameProcess(window, pid))
{/* Whatever you want to do */}
}