23

我知道有各种各样的问题和书籍,但我似乎无法将我的 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(进程也以管理员身份运行),但它没有被注入。当我运行它时,什么也没有发生,有什么想法吗?

4

5 回答 5

26

不要MessageBoxDllMain. 为什么?看:

您的消息框在出现之前可能只是死锁。为确保您到达感兴趣的代码行,请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。Win32DLL 到Win32进程,或x64DLL 到x64进程。

更新。我是从评论中提出的:这是执行此操作的 Visual Studio 2010 项目的源代码:SVNTrac

  • 您将进程标识符放入源代码
  • 可执行文件创建远程线程并加载库
  • 该库从 DllMain 开始并生成调试输出
  • DebugView显示输出
  • ProcessExplorer向您显示创建的线程,并且您还打印了它的标识符
于 2012-06-11T14:07:35.473 回答
6

您可能遇到的问题是您的应用程序中 LoadLibraryA() 的地址可能与目标进程中的地址不同,因为ASLR是一种专门用于阻止您尝试的活动的技术。现代版本的 Windows (Vista+) 默认为系统 DLL 启用此功能

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

于 2012-06-11T14:15:09.843 回答
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;
}
于 2012-06-07T12:46:45.440 回答
3

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

这是关于Hooking 和 DLL的。

还有一个。和谷歌搜索你。

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

将 UI-Access 设置为 true,并将可执行文件放在 C:/Program Files/ 中,并对 dll 进行数字签名,有助于访问 Windows 中的一些安全窗口。这是一篇讨论其中一些事情的文章。

希望有帮助。

于 2012-06-13T05:17:01.233 回答
0

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

于 2012-06-17T01:54:57.153 回答