钩子CreateProcess并在每个子进程中注入一个DLL

时间:2014-07-30 14:46:15

标签: c winapi dll-injection

我想做什么:将DLL注入进程以挂钩CreateProcess并监视受害者进程的调用。进行调用时,我检索子进程ID并将相同的DLL注入其中。等等。

我成功完成了第一部分:将我的DLL注入进程,挂钩CreateProcess,监视调用。

挂钩是非常基本的:用jmp将前5个字节覆盖到另一个看起来像这样的函数:

__declspec(naked)
InterceptCreateProc()
{
    LPBYTE pJmpAdr;

    LPCTSTR lpApplicationName;
    LPTSTR lpCommandLine;
    LPSECURITY_ATTRIBUTES lpProcessAttributes;
    LPSECURITY_ATTRIBUTES lpThreadAttributes;
    BOOL bInheritHandles;
    DWORD dwCreationFlags;
    LPVOID lpEnvironment;
    LPCTSTR lpCurrentDirectory;
    LPSTARTUPINFO lpStartupInfo;
    LPPROCESS_INFORMATION lpProcessInformation;
    DWORD retv;

    void *inject;

    inject = (void* )Inject; // address of the function that should inject the DLL

    __asm
    {
        pop retv // return address
        // parameters
        pop lpApplicationName
        pop lpCommandLine
        pop lpProcessAttributes
        pop lpThreadAttributes
        pop bInheritHandles
        pop dwCreationFlags
        pop lpEnvironment
        pop lpCurrentDirectory
        pop lpStartupInfo
        pop lpProcessInformation
    };

    dwCreationFlags = dwCreationFlags | CREATE_SUSPENDED; // change creation flags to create suspended
    returnAdr = retv; // save the return address
    retv = (DWORD)inject; // redirect CreateProcess to return to the injection function
    g_procInfo = lpProcessInformation; 

    // push back all parameters on the stack
    __asm
    {
        push lpProcessInformation
        push lpStartupInfo
        push lpCurrentDirectory
        push lpEnvironment
        push dwCreationFlags
        push bInheritHandles
        push lpThreadAttributes
        push lpProcessAttributes
        push lpCommandLine
        push lpApplicationName
        push retv
    };

    // the bytes I have over written with my hook
    __asm
    {
        push ebp
        mov ebp, esp
    };

    pJmpAdr = pOldFuncAdr + 5; // the point in CreateProcess where I should jump

    __asm
    {
        jmp pJmpAdr
    };
}

现在,执行注入的功能:

__declspec(naked)
void
Inject()
{
    DWORD rValue;

    LPVOID baseAdr;

    HMODULE kernel32;

    FARPROC loadLib;

    HANDLE hThread;
    HANDLE hProc;

    __asm
    {
        mov rValue, eax // save the return value from CreateProcess
    };

    hProc = NULL;
    hProc = OpenProcess(PROCESS_ALL_ACCESS,
        0,
        g_procInfo->dwProcessId);
    if(NULL == hProc)
    {
        LogErrors("OpenProcess failed ",
            GetLastError());
    }

    baseAdr = NULL;
    baseAdr = VirtualAllocEx(hProc,
        0,
        strlen(dllPath) + 1,
        MEM_COMMIT | MEM_RESERVE,
        PAGE_READWRITE);
    if(NULL == baseAdr)
    {
        LogErrors("VirtualAllocEx failed ",
            GetLastError());
    }

    if(!WriteProcessMemory(hProc,
        baseAdr,
        dllPath,
        strlen(dllPath) + 1,
        0))
    {
        LogErrors("WriteProcessMemory failed ",
            GetLastError());
    }

    kernel32 = NULL;
    kernel32 = LoadLibrary(TEXT("kernel32.dll"));
    if(NULL == kernel32)
    {
        LogErrors("LoadLibrary faild ",
            GetLastError());
    }

    loadLib = NULL;
    loadLib = GetProcAddress(kernel32,
        "LoadLibraryA");
    if(NULL == loadLib)
    {
        LogErrors("GetProcAddress failed ",
            GetLastError());
    }

    hThread = NULL;
    hThread = CreateRemoteThread(hProc,
        0,
        0,
        (LPTHREAD_START_ROUTINE)loadLib,
        baseAdr,
        0,
        0);

    if(NULL == hThread)
    {
        LogErrors("CreateRemoteThread failed ",
            GetLastError());
    }

    ResumeThread(g_procInfo->hThread);

    // I'm not sure if this is correct
    // it seems to be working -- CreateProcess returns a non zero value 
    __asm
    {
        mov eax, rValue // return value
        jmp returnAdr // return address
    }
}

每次调用CreateProcess时,都会调用Inject,但它唯一要做的就是恢复主线程。子进程没有发生注入。

我在这里犯的重大错误是什么?

编辑:事实证明上面的代码正在运行,问题是我的测试程序。 仍然,反馈表示赞赏。我在这里做了什么有什么好处?怎么了?

EDIT2:我发现了我的第一个问题。有时(经常是),我得到一个堆栈变量startupInformation已损坏。 startupInformation是一个STARTUPINFO结构,它是CreateProcess的out参数。这很奇怪,因为我根本不与startupInformation交互。我改变的唯一事情是创建标志。即使在我收到此错误的情况下,processInformation也具有正确的值。

0 个答案:

没有答案