注入C ++ DLL

时间:2012-06-07 10:52:56

标签: c++ dll

我知道有关于此的各种问题和书籍,但我似乎无法将我的C ++ DLL注入任何进程。

注入DLL的代码:

#include <iostream>
#include "windows.h"

bool Inject(DWORD pId, char *dllName);

using namespace std;

int main()
{
    Inject(600, "C:\\d.dll");
    return 0;
}

bool Inject(DWORD pId, char *dllName)
{
    HANDLE h = OpenProcess(PROCESS_ALL_ACCESS, false, pId);
    if(h)
    {
        LPVOID LoadLibAddr = (LPVOID)GetProcAddress(GetModuleHandleA("kernel32.dll"), "LoadLibraryA");
        LPVOID dereercomp = VirtualAllocEx(h, NULL, strlen(dllName), MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
        WriteProcessMemory(h, dereercomp, dllName, strlen(dllName), NULL);
        HANDLE asdc = CreateRemoteThread(h, NULL, NULL, (LPTHREAD_START_ROUTINE)LoadLibAddr, dereercomp, 0, NULL);
        WaitForSingleObject(asdc, INFINITE);
        VirtualFreeEx(h, dereercomp, strlen(dllName), MEM_RELEASE);
        CloseHandle(asdc);
        CloseHandle(h);
        return true;
    }
    return false;
}

和我试图注入的DLL:

#include <windows.h>
#include <stdio.h>

BOOL APIENTRY DllMain (HINSTANCE hInst     /* Library instance handle. */ ,
                       DWORD reason        /* Reason this function is being called. */ ,
                       LPVOID reserved     /* Not used. */ )
{
switch (reason)
    {
      case DLL_PROCESS_ATTACH:
           MessageBox (0, "From DLL\n", "Process Attach", MB_ICONINFORMATION);
        break;

      case DLL_PROCESS_DETACH:
           MessageBox (0, "From DLL\n", "Process Detach", MB_ICONINFORMATION);
        break;

      case DLL_THREAD_ATTACH:
           MessageBox (0, "From DLL\n", "Thread Attach", MB_ICONINFORMATION);
        break;

      case DLL_THREAD_DETACH:
           MessageBox (0, "From DLL\n", "Thread Detach", MB_ICONINFORMATION);
        break;
    }

    return TRUE;
}

我不知道足够的C ++知道这出错的地方。我已经在我尝试注入的进程上运行Process Explorer(进程以admin身份运行),但它没有被注入。当我运行它时,没有任何反应,任何想法?

5 个答案:

答案 0 :(得分:26)

不要从MessageBox执行DllMain。为什么?参见:

您的消息框可能会在出现之前陷入僵局。为确保您能够访问感兴趣的代码行,请改用OutputDebugString。正如您所说,您熟悉Process Explorer,您可能会注意到那里创建的线程(您可以通过在CreateRemoteThread中提供最后一个参数来获取其在启动器中的标识符)以及在内核库中执行时的锁定状态。

这是您需要放置OutputDebugString

的地方
BOOL APIENTRY DllMain(HMODULE hModule, DWORD nReason, VOID* pvReserved)
{
    pvReserved;
    TCHAR pszMessage[1024] = { 0 };
    _stprintf_s(pszMessage, _T("GetCurrentProcessId() %d, hModule 0x%p, nReason %d\r\n"), GetCurrentProcessId(), hModule, nReason);
    OutputDebugString(pszMessage);
    /*switch(nReason)
    {
    case DLL_PROCESS_ATTACH:
    case DLL_THREAD_ATTACH:
    case DLL_THREAD_DETACH:
    case DLL_PROCESS_DETACH:
        break;
    }*/
    return TRUE;
}

要确保的另一件事是你正在加载正确位数的DLL。 Win32 DLL进入Win32进程,或x64 DLL进入x64进程。

更新。我从评论中提出这个问题:这是Visual Studio 2010项目的源代码:SVNTrac

  • 您将流程标识符放入源代码
  • 可执行文件创建远程线程并加载库
  • 库从DllMain启动并生成调试输出
  • DebugView显示输出
  • ProcessExplorer显示创建的主题,并且还打印了标识符

答案 1 :(得分:6)

您可能遇到的问题是,由于ASLR - 专门设计用于阻止您的活动的技术{{3}},您的应用程序中LoadLibraryA()的地址可能与目标进程中的地址不同。重新尝试。现代版本的Windows(Vista +)默认为系统DLL启用

为了做你想做的事,你需要在你的应用程序中实现一个正确的ThreadProc来加载你的DLL,在你的目标进程中分配一些可执行内存(PAGE_EXECUTE)内存,在那里复制它,并使用这个地址作为你的线程起点。

答案 2 :(得分:5)

管理员帐户无需隐式拥有SE_DEBUG权限。 如果您在Vista / Win7下运行,请确保已禁用UAC。 在尝试打开进程内存之前,请使用此代码启用它:

BOOL EnableDebugPrivilege()
{
    HANDLE hToken;
    LUID luid;
    TOKEN_PRIVILEGES tkp;

    if(!OpenProcessToken( GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken ))
    {
        return FALSE;
    }

    if(!LookupPrivilegeValue( NULL, SE_DEBUG_NAME, &luid ))
    {
        return FALSE;
    }

    tkp.PrivilegeCount = 1;
    tkp.Privileges[0].Luid = luid;
    tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;

    if(!AdjustTokenPrivileges( hToken, false, &tkp, sizeof( tkp ), NULL, NULL ))
    {
        return FALSE;
    }

    if(!CloseHandle( hToken ))
    {
        return FALSE;
    }

    return TRUE;
}

答案 3 :(得分:3)

我会从其他人的工作示例开始,然后从那里开始。 CodeProject上的示例项目,教程和解释非常可靠。

这是Hooking and DLLs上的一个。

another。并为您google search

对于某些类型的挂钩,您必须克服权限限制,或者您必须接受不能挂钩每个进程的事实。

将UI-Access设置为true,并将您的可执行文件设置为C:/ Program Files /,并对您的dll进行数字签名有助于访问Windows中的某些安全窗口。这是article,讨论了其中的一些内容。

希望有所帮助。

答案 4 :(得分:0)

SetWindowsHookEx还可以将您的DLL注入另一个进程。