注入C++ DLL

Bal*_*i C 22 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;
}
Run Code Online (Sandbox Code Playgroud)

和我试图注入的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;
}
Run Code Online (Sandbox Code Playgroud)

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

Rom*_* R. 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;
}
Run Code Online (Sandbox Code Playgroud)

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

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

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


Buk*_*kes 6

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

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


rko*_*egi 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;
}
Run Code Online (Sandbox Code Playgroud)