远程的DLL注入进程的实现

进程注入的原理就是让目标进程执行一段自己的代码,而这个实现的前提是

1.让目标进程可以访问我们自己写的代码
2.让目标进程跳到我们的代码入口执行
3.执行完成后可以正常退出,不引发进程的crash。

这里采用的是DLL远程注入方式.
大概原理是基本上所有的进程都会依赖kernel32.dll,而这个DLL中有2个导出函数LoadLibraryA和LoadLibraryW,其实这2个函数没啥 区别,一个是多字节的接口,一个是宽字节的接口,而多字节的会在内部对多字节进行转换成宽字节,再调用宽字节继续执行。

而windows为了节省内存,所有的动态库都会加载到同一物理内存地址,同时为了便于内存管理,这些物量内存也会引映射到不同进程的内一虚执地址空间。所以A进程中的某个API函数和另一个进程的地址的样同。

而为了让这个目标进程能正常调用我们的代码,可以采用开线程的方式来实现,这样不影响进程原有的运行。

这样我们可以采用API函数CreateRemoteThread来产生远程线程,而线程的入口函数使用LoadLibraryA(W),参数为DLL的路径。

所以为了实现以上功能,需要解决2个问题,CreateRemoteThread的入口地址LoadLibraryA(W)和LoadLibraryA(W)的存储路径,且这个路径地址必须为目标进程的地址。

第一个问题可按上面说的,用协注入进程来获取LoadLibraryA(W)的地址。

第二个问题可以采用打开目标进程,使用API函数VirtualAllocEx来申请一段目标进程内存地址,然后将LoadLibraryA(W)的存储路径复制进去,然后将这个地址传给CreateRemoteThread远程线程函数即可。

BOOL InjectProcessByPID(DWORD dwPId, TCHAR *szDllName)
{
    HANDLE hProcess = NULL;
    LPVOID pRemoteBuf = NULL;
    FARPROC pThreadProc = NULL;
    DWORD dwBufSize = (DWORD)(_tcslen(szDllName) + 1) * sizeof(TCHAR);

    if (!(hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwPId)))
    {
        printf("[ERROR] OpenProcess(%d) failed!!! [%d]", dwPId, GetLastError());
        return FALSE;
    }

    TCHAR path[MAX_PATH] = {0};
    GetModuleFileNameEx(hProcess, NULL, path, MAX_PATH + 1);
    for (unsigned int i = 0; i < m_WhiteList.size(); i++)
    {
        if (_tcsstr(path, m_WhiteList[i].c_str()))
        {
            _tprintf(TEXT("white list :%s"), m_WhiteList[i].c_str());
            return FALSE;
        }
    }

    pRemoteBuf = VirtualAllocEx(hProcess, NULL, dwBufSize, MEM_COMMIT, PAGE_READWRITE);

    WriteProcessMemory(hProcess, pRemoteBuf, (LPVOID)szDllName, dwBufSize, NULL);

#ifdef UNICODE
    pThreadProc = GetProcAddress(GetModuleHandle(TEXT("kernel32.dll")), "LoadLibraryW");
#else
    pThreadProc = GetProcAddress(GetModuleHandle(TEXT("kernel32.dll")), "LoadLibraryA");
#endif

    if (!ExecuteRemoteThread(hProcess, (LPTHREAD_START_ROUTINE)pThreadProc, pRemoteBuf))
    {
        printf("[ERROR] ExecuteRemoteThread() failed!!!");
    }

    VirtualFreeEx(hProcess, pRemoteBuf, 0, MEM_RELEASE);

    CloseHandle(hProcess);

    return TRUE;
}
BOOL ExecuteRemoteThread(HANDLE hProcess, LPTHREAD_START_ROUTINE pThreadProc, LPVOID pRemoteBuf)
{
    HANDLE      hThread = NULL;
    FARPROC     pFunc = NULL;

    if (IsVistaOrLater())    // Vista, 7, Server2008
    {
        #define THREAD_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED | SYNCHRONIZE | 0xFFFF)
        pFunc = GetProcAddress(GetModuleHandle(TEXT("ntdll.dll")), "NtCreateThreadEx");
        if (pFunc == NULL)
        {
            printf(" MyCreateRemoteThread() : GetProcAddress("NtCreateThreadEx") failed!!!  [%d]
", GetLastError());
            return FALSE;
        }

        INT_PTR rtn = ((_NtCreateThreadEx)pFunc)(&hThread, THREAD_ALL_ACCESS, NULL, hProcess, pThreadProc, pRemoteBuf, FALSE, NULL, NULL, NULL, NULL);

        if (hThread == NULL)
        {
            printf("win7 MyCreateRemoteThread() : NtCreateThreadEx() failed!!! [%d]", GetLastError());
            return FALSE;
        }
    }
    else
    {
        hThread = CreateRemoteThread(hProcess, NULL, 0, pThreadProc, pRemoteBuf, 0, NULL);
        if (hThread == NULL)
        {
            printf("xp MyCreateRemoteThread() : CreateRemoteThread() failed!!! [%d]", GetLastError());
            return FALSE;
        }
    }

    if (WAIT_FAILED == WaitForSingleObject(hThread, INFINITE))
    {
        printf("MyCreateRemoteThread() : WaitForSingleObject() failed!!! [%d]", GetLastError());
        return FALSE;
    }

    return TRUE;
}
取消
感谢您的支持,我会继续努力的!
扫码支持
扫码打赏,你说多少就多少

打开支付宝扫一扫,即可进行扫码打赏哦

Powered by bytekits.com,汇天下文字,成非凡梦想!!!