【问题标题】:DLL Code injection to third party process using QueueUserAPC使用 QueueUserAPC 向第三方进程注入 DLL 代码
【发布时间】:2018-03-29 09:45:27
【问题描述】:

我想将我的 dll 注入 64 位应用程序,我已经尝试使用 QueueUserAPC 在给定的link 中解释的逻辑。我收到每个 API 的成功消息,但是当我在 ProcessExplorer 中看到时,我无法在进程中看到我的 dll。 以下是我的代码:

bool FindProcess(PCWSTR exeName, DWORD& pid, vector<DWORD>& tids) {
auto hSnapshot = ::CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS | TH32CS_SNAPTHREAD, 0);
if (hSnapshot == INVALID_HANDLE_VALUE)
    return false;
pid = 0;
PROCESSENTRY32 pe = { sizeof(pe) };
if (::Process32First(hSnapshot, &pe)) {
    do {
        if (_wcsicmp(pe.szExeFile, exeName) == 0) {
            pid = pe.th32ProcessID;
            THREADENTRY32 te = { sizeof(te) };
            if (::Thread32First(hSnapshot, &te)) {
                do {
                    if (te.th32OwnerProcessID == pid) {
                        tids.push_back(te.th32ThreadID);
                    }
                } while (::Thread32Next(hSnapshot, &te));
            }
            break;
        }
    } while (::Process32Next(hSnapshot, &pe));
}
::CloseHandle(hSnapshot);
return pid > 0 && !tids.empty();}



void main(){
DWORD pid;
vector<DWORD> tids;
if (FindProcess(L"DataGrid.exe", pid, tids))
{
    printf("OpenProcess\n");
    HANDLE hProcess = ::OpenProcess(PROCESS_VM_WRITE | PROCESS_VM_OPERATION, FALSE, pid);
    printf("VirtualAllocEx\n");
    auto p = ::VirtualAllocEx(hProcess, nullptr, 1 << 12, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
    wchar_t buffer[] = L"C:\\Users\\sbhuma\\Documents\\Visual Studio 2015\\Projects\\GalaxyHook\\Debug\\GalaxyHook.dll";
    printf("WriteProcessMemory\n");
    ::WriteProcessMemory(hProcess, p, buffer, sizeof(buffer), nullptr);
    for (const auto& tid : tids)
    {
        printf("OpenThread\n");
        HANDLE hThread = ::OpenThread(THREAD_SET_CONTEXT, FALSE, tid);
        if (hThread)
        {
            printf("GetProcAddress\n");
            DWORD word = ::QueueUserAPC((PAPCFUNC)::GetProcAddress(GetModuleHandle(L"kernel32"), "LoadLibraryW"), hThread, (ULONG_PTR)p);
            if (word)
            {
                printf("insdie if\n");
            }
            printf("End of IF\n");
        }
    }
    printf("VirtualFreeEx\n");
    ::VirtualFreeEx(hProcess, p, 0, MEM_RELEASE | MEM_DECOMMIT);
}}

任何与将 dll 注入 64 位应用程序相关的帮助都会有所帮助,因为我是该主题的新手。

问候,

Sowmya。

【问题讨论】:

  • 这个字符串中的空格是故意的吗?:wchar_t buffer[] = L" C:\\...
  • 我已经删除了空间并尝试了,仍然没有运气

标签: dll-injection


【解决方案1】:

首先,确保您将注入器应用程序构建为 64 位。

一个可能的原因是您过早释放缓冲区。 QueueUserAPC 不等待;它将调用加入队列并立即返回。可能是您的注入器进程结束运行 for 循环,调用 VirtualFreeEx,然后您的目标进程接收 APC,尝试加载您的 DLL 但名称缓冲区已经被释放,因此 LoadLibrary 失败。要验证,请注释掉对 VirtualFreeEx 的调用。如果您的 DLL 可以正常加载,解决内存泄漏的一种方法是在 DllMain(DLL_PROCESS_ATTACH) 中调用 QueueUserAPC()、OpenEventSetEventCloseHandle 之前,在注入器应用程序中使用命名事件 CreateEvent对于您要注入的 DLL,WaitForSingleObject 在注入器应用程序中 VirtualFreeEx 之前,我建议使用超时等待,最后是 CloseHandle。作为副作用,您的注入器应用程序将能够找出并在某处报告注入是否成功。

另一个可能的原因是您的目标应用永远不会进入警报状态。并非所有应用程序都使用 APC,有多种替代方法可以在 Windows 中实现异步内容。因此,并非所有应用程序都调用过这些 SleepEx / WaitForMultipleObjectsEx 函数。这样的应用程序永远不会收到该 APC。如果是这种情况,您应该使用另一种 DLL 注入方法。 DataGrid.exe 名称暗示您的目标应用程序可能是一个 GUI 应用程序。您可以EnumWindowsFindWindow 找到它的顶级窗口,GetWindowThreadProcessId 获得拥有该窗口的线程ID,SetWindowsHookEx 将您的DLL 注入目标进程。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-08-29
    • 2017-04-20
    • 1970-01-01
    • 2013-11-25
    • 1970-01-01
    • 2013-04-28
    相关资源
    最近更新 更多