【发布时间】:2020-04-27 23:06:17
【问题描述】:
我正在尝试构建一个 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,出现“Clicked”。预期。
现在,我启动 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测试过,但是因为它是控制台相关的,所以我不能使用它,即使它没有在第二个控制台上打印。
【问题讨论】:
-
您需要检查 & 0x8000。另外一些键不起作用,但我已经测试了 ctrl 和 backspace 来解决这个问题。
-
忘了提到我已经尝试过
while (!(GetAsyncKeyState(VK_F9) & 0x8000))。另外,刚刚发现即使在单个进程中,如果我不在该窗口上时按 F9(或任何键),它仍会打印“已单击”。所以我想我只需要检查我的窗口是否是活动的? -
是的,或者挂上窗户——我听说必须有tools 来做这件事。因为
GetAsyncKeyState会检查全局状态。 -
尝试使用 SetWindowsHook,行为相同。想出了一个窗口重命名+名称比较。完美运行!感谢您的帮助
标签: c++ dll code-injection