C++/CLI 注入是可能的吗?

C++/CLI injection is possible?

所以我的 C++/CLI 应用程序将自身注入到目标进程中。 但是虽然注入似乎成功了,但入口点并没有被调用。这是我的注射器:

#include "stdafx.h"
#include <Windows.h>
#include <TlHelp32.h>
#include <string>
#include <stdlib.h>
#include <comdef.h>
#include "Hooking.h"
#include "HCommonEnsureCleanup.h"

VOID Hooking::HookProcess()
{
    DWORD firefox = Hooking::FindProcessId("firefox.exe");
    Inject(firefox);
}
BOOL Hooking::Inject(DWORD pID)
{
    const wchar_t* DLL_NAME = (const wchar_t*)(void*)System::Runtime::InteropServices::Marshal::StringToHGlobalAnsi(System::Windows::Forms::Application::ExecutablePath);
    HANDLE Proc;
    HMODULE hLib;
    char buf[50] = { 0 };
    LPVOID RemoteString, LoadLibAddy;
    if (!pID)
        return false;
    Proc = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pID);
    if (!Proc)
    {
        return false;
    }
    LoadLibAddy = (LPVOID)GetProcAddress(GetModuleHandle(L"kernel32.dll"), "LoadLibraryA");
    RemoteString = (LPVOID)VirtualAllocEx(Proc, NULL, (wcslen(DLL_NAME) + 1) * sizeof(wchar_t), MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
    WriteProcessMemory(Proc, (LPVOID)RemoteString, DLL_NAME, (wcslen(DLL_NAME) + 1) * sizeof(wchar_t), NULL);
    CreateRemoteThread(Proc, NULL, NULL, (LPTHREAD_START_ROUTINE)LoadLibAddy, (LPVOID)RemoteString, NULL, NULL);
    CloseHandle(Proc);
    return true;
}
DWORD Hooking::FindProcessId(const char *processname)
{
    HANDLE hProcessSnap;
    PROCESSENTRY32 pe32;
    DWORD result = NULL;
    hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
    if (INVALID_HANDLE_VALUE == hProcessSnap) return(FALSE);
    pe32.dwSize = sizeof(PROCESSENTRY32);
    if (!Process32First(hProcessSnap, &pe32))
    {
        CloseHandle(hProcessSnap);
        return(NULL);
    }
    do
    {
        if (0 == strcmp(processname, _bstr_t(pe32.szExeFile)))
        {
            result = pe32.th32ProcessID;
            break;
        }
    } while (Process32Next(hProcessSnap, &pe32));
    CloseHandle(hProcessSnap);
    return result;
}

然后(因为我的程序是可执行的)我创建了一个 dll 入口点:

int APIENTRY wWinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ LPWSTR lpCmdLine, _In_ int nCmdShow)
{
    Hooking::HookProcess();
    return 0;
}
BOOL WINAPI DllMain(
    HINSTANCE hinstDLL,
    DWORD fdwReason,
    LPVOID lpvReserved
)
{
    MessageBoxA(NULL, "Injection OK", "Injection OK", NULL);
}

但是,无论是 Dll 还是 exe,我的入口点都没有被调用。所以我在想这可能是因为这个 exe 包含 .Net 代码但在更改它之前我想在这里问一下。

感谢您的宝贵时间

首先将“(wcslen(DLL_NAME) + 1) * sizeof(wchar_t)”改为"wcslen(DLL_NAME)"即可。确保同时更新内存分配。

其次,您将一个 unicode 编码的缓冲区传递给 LoadLibraryA。这是行不通的,因为 LoadLibraryA 不接受 unicode 编码的缓冲区,它需要一个 Ascii 编码的缓冲区。请改用 LoadLibraryW。

第三,您没有进行任何错误检查。不能就假设这两个虚拟内存操作和创建远程线程的操作都会成功,需要检查每个操作的return状态,确保成功,否则就停止追寻注入的套路。这也将深入了解操作失败的原因。您需要将调试器附加到目标进程,以确保内存在分配和写入后也能正常运行。

最后但同样重要的是,确保您有足够的权限来定位目标进程。例如,如果您是 运行 标准权限,则不能将提升的进程作为目标,也不能将启用自我保护的传统安全解决方案作为目标。这里有很多不同的因素。