注射器不注射dll

时间:2017-12-05 20:32:12

标签: c++ winapi dll inject

为“calculator.exe”进程编写了一个简单的Dll注入器,打印出一些行我确认注入器完成了它的工作,但是没有出现消息框。

上下文:

-void inject_dll(DWORD,char *)获取我想要注入的进程的ID以及它将注入的dll的名称。

-DWORD get_PId(const w_char_t *)是一个返回给定参数(processname)的processID的函数

我已经确认get_PId函数正常工作,因此错误应该在其他地方。

注射器代码:

#include "stdafx.h"
#include <windows.h>
#include <TlHelp32.h>
#include <iostream>
void inject_dll(DWORD PId, char* DllName)
{

HANDLE hProcess;
PVOID Alloc;
SIZE_T DllPathLen;
HMODULE Kernel32Base;
PVOID LoadLibAddress;

if (PId != 0 && DllName != NULL)
{
    DllPathLen = strlen(DllName);
    Kernel32Base = GetModuleHandleA("Kernel32.dll");
    if (Kernel32Base == NULL)
    {
        std::cout << "kernel32.dll not found" << std::endl;
        return;
    }

    LoadLibAddress = GetProcAddress(Kernel32Base, "LoadLibraryA");
    if (LoadLibAddress == NULL)
    {
        std::cout << "LoadLibraryA not found" << std::endl;
        return;
    }


    hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, PId);
    if (hProcess == NULL)
    {
        std::cout << "hProcess handle not opened" << std::endl;
        return;
    }


    Alloc = VirtualAllocEx(hProcess, NULL, DllPathLen + 1, MEM_COMMIT, PAGE_READWRITE);
    if (Alloc == NULL)
    {
        std::cout << "no memory allocated for DllPath" << std::endl;
        return;
    }

    if (!WriteProcessMemory(hProcess, Alloc, DllName, DllPathLen + 1, NULL))
    {
        std::cout << "didn't write dll to processmemory" << std::endl;
        return;
    }

    CreateRemoteThread(hProcess, NULL, 0, (LPTHREAD_START_ROUTINE)LoadLibAddress, Alloc, 0, NULL);
    std::cout << "end reached" << std::endl;
}

}


DWORD get_PId( const wchar_t* ProcessName) {

HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);

PROCESSENTRY32 pe32;
pe32.dwSize = sizeof(PROCESSENTRY32);

if (hSnapshot != NULL)
{
    if (Process32First(hSnapshot, &pe32)) {
        do
        {
            if (!wcscmp(pe32.szExeFile, ProcessName))
                return pe32.th32ProcessID;

        } while (Process32Next(hSnapshot, &pe32));
    }
}
return 0;
}

int main(int argc, char* argv[])
{
DWORD pid = get_PId(L"Calculator.exe");
std::cout << pid << std::endl;
if (pid) {
    char dllName[] = "CORRECT PATH (dont worry about this)";
    std::cout << dllName << std::endl;
    inject_dll(pid, dllName);

}

ExitPoint:
    system("Pause");
    return 0;
}

Dll代码,当它在注入进程的内存中时,它应该显示一个消息框:

#include <windows.h>

VOID ShowMessageBox() {
MessageBoxA(NULL, "injected", "injector", MB_OK);
}

BOOL APIENTRY DllMain( HMODULE hModule, DWORD  ul_reason_for_call, LPVOID lpReserved ){

switch (ul_reason_for_call)
{
    case DLL_PROCESS_ATTACH:
        ShowMessageBox();

    case DLL_THREAD_ATTACH:
    case DLL_THREAD_DETACH:
    case DLL_PROCESS_DETACH:
        break;
}
return TRUE;
}

2 个答案:

答案 0 :(得分:0)

我也不是100%确信这一点,但是我认为这是因为Windows Vista及更高版本中的会话分离。您可以详细了解here

  

自Vista以来,随着“会话分离”的引入,情况发生了变化。这是Vista中为保护系统而引入的众多防御措施之一。 “会话分离”确保了包括服务在内的核心系统进程始终在会话0中运行,而所有用户进程在不同的会话中运行。结果,在用户会话中运行的任何进程都无法将DLL注入系统进程,因为CreateRemoteThread无法跨会话边界工作...

在诸如notepad.exepaint.exe之类的进程上,注入应该可以正常工作。

答案 1 :(得分:-2)

我怀疑你遇到了DllMain的一个限制,你不应该从DllMain中调用user32.dll或gdi32.dll中的任何内容。