Injecting C++ DLL

Injecting C++ DLL

本文关键字:DLL C++ Injecting      更新时间:2023-10-16

我知道有各种各样的问题和书籍,但我似乎无法将我的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 DLLn", "Process Attach", MB_ICONINFORMATION);
        break;
      case DLL_PROCESS_DETACH:
           MessageBox (0, "From DLLn", "Process Detach", MB_ICONINFORMATION);
        break;
      case DLL_THREAD_ATTACH:
           MessageBox (0, "From DLLn", "Thread Attach", MB_ICONINFORMATION);
        break;
      case DLL_THREAD_DETACH:
           MessageBox (0, "From DLLn", "Thread Detach", MB_ICONINFORMATION);
        break;
    }
    return TRUE;
}

我不知道C++不知道这是哪里出了问题。我已经在我尝试注入的进程上运行了进程资源管理器(进程也以管理员身份运行),但它没有被注入。当我运行它时,什么也没发生,有什么想法吗?

不要从DllMainMessageBox。为什么?看:

  • DLL_PROCESS_ATTACH无法在 Windows 7 C++ 上执行
  • 不要在你的DllMain做任何可怕的事情的一些原因
  • 不要在静态初始值设定项/DllMain 中使用标准库/CRT 函数!

您的消息框可能只是在显示在那里之前死锁。若要确保到达感兴趣的代码行,请改用OutputDebugString。正如您所指出的,您熟悉进程资源管理器,您可能会注意到那里创建了线程(您可以通过在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 %drn"), 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项目的源代码:SVN或Trac。

  • 将进程标识符放入源代码中
  • 可执行文件创建远程线程并加载库
  • 该库从 DllMain 开始并生成调试输出
  • DebugView显示输出
  • ProcessExplorer显示创建的线程,并且还打印了其标识符

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

为了执行所需的操作,需要在加载 DLL 的应用程序中实现适当的 ThreadProc,在目标进程中分配一些可执行内存 (PAGE_EXECUTE) 内存,将其复制到该位置,并使用此地址作为线程起点。

管理员帐户不需要隐式拥有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;
}

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

这是一个关于挂钩和DLL的。

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

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

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

希望有帮助。

SetWindowsHookEx 还可以将 DLL 注入到另一个进程中。