【问题标题】:DLL Injection on two processes两个进程的DLL注入
【发布时间】: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


【解决方案1】:

好吧,正如我在上一条评论中所说的那样

尝试使用 SetWindowsHook,行为相同。想出了一个窗口重命名+名称比较。完美运行!感谢您的帮助

我使用了重命名 + 名称比较。其他问题出现了,所以我不得不重新考虑实现它的方法。这是最终版本:

bool isSameProcess(HWND window, DWORD pid)
{
    DWORD activePId;
    DWORD activeThreadId = GetWindowThreadProcessId(window, &activePId);
    return activePId == pid;
}

说明: window 是活动窗口,pid 我们自己的进程id。 我们将检查我们的 pid 是否等于活动窗口的进程 ID。如果是,则返回 true,否则返回 false。

这样,你可以这样使用它:

if ((GetAsyncKeyState(VK_F9) & 0x8000))
{
    window = GetForegroundWindow();
    if(isSameProcess(window, pid))
    {/* Whatever you want to do */}
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2023-03-06
    • 2012-01-01
    • 2011-07-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-06-10
    • 1970-01-01
    相关资源
    最近更新 更多