将一个C#窗体应用程序注入另一个应用程序

本文关键字:应用程序 窗体 注入 另一个 一个 | 更新日期: 2023-09-27 18:26:56

关于如何将DLL注入另一个进程,有很多答案。我该如何使用C#窗体应用程序(exe)而不是DLL来做同样的事情。

基本上,我希望它在另一个进程的虚拟地址空间中运行。首先我分配内存,然后创建远程线程。现在,我如何让我现有的exe在那里运行?还有什么限制吗?(例如,我可以让它在explorer.exe中运行吗?)?

将一个C#窗体应用程序注入另一个应用程序

不久前,我为自己的非托管应用程序做了这件事(没有任何注入,这无关紧要)。一旦您将非托管DLL注入所需应用程序的地址空间,您就应该创建一个专用线程,初始化上面的COM(使用CoInitializeExOleInitialize),然后执行以下操作(为简洁起见,跳过错误检查):

HMODULE hmodMscoree = LoadLibrary(_T("mscoree.dll"))
HRESULT (STDAPICALLTYPE *pCorBindToRuntimeEx)(LPCWSTR pwszVersion, LPCWSTR pwszBuildFlavor, DWORD startupFlags, REFCLSID rclsid, REFIID riid, LPVOID FAR *ppv);
GET_PROC_ADDRESS(hmodMscoree, CorBindToRuntimeEx);
CComQIPtr<ICorRuntimeHost> m_host;
pCorBindToRuntimeEx(NULL, NULL, 0, CLSID_CorRuntimeHost, IID_ICorRuntimeHost, (void**)&m_host);
m_host->Start();
CComQIPtr<IUnknown> unk;
m_host->CreateDomainSetup(&unk);
CComQIPtr<mscorlib::IAppDomainSetup> domainSetup;
unk->QueryInterface(&domainSetup);
domainSetup->put_ApplicationBase(curDir);
CComBSTR appName;
ParseParam(m_commandLine, CMDLINEOPT_APPNAME, &appName);
domainSetup->put_ApplicationName(appName);
CComBSTR config;
ParseParam(m_commandLine, CMDLINEOPT_CONFIGFILE, &config);
domainSetup->put_ConfigurationFile(config);
unk.Release();
m_host->CreateDomainEx(m_managedApp, domainSetup, NULL, &unk);
CComQIPtr<mscorlib::_AppDomain> appDomain;
unk->QueryInterface(&appDomain);
appDomain->ExecuteAssembly_2(m_managedApp, &m_exitCode);

确保所有依赖程序集(如果有的话)都在基本文件夹中可用(在我的代码中为curDir)。

已编辑:这是为.NET 2.0完成的。我不知道从那以后有没有什么变化。您可以在此处找到有关CLR托管的更多信息。

编辑GET_PROC_ADDRESS正是这样做的:

#ifdef _UNICODE
    #define FUNC_T(func) func##W
    #define GET_PROC_ADDRESS_T(mod, func) '
        ((FARPROC&)p##func = ::GetProcAddress(mod, #func "W"))
#else
    #define FUNC_T(func) func##A
    #define GET_PROC_ADDRESS_T(mod, func) '
        ((FARPROC&)p##func = ::GetProcAddress(mod, #func "A"))
#endif

您还需要#include fusion.hmscoree.h(可以在Windows SDK中找到)和#import mscorlib.tlb(对于.NET 2.0,它是C:'WINDOWS'Microsoft.NET'Framework'v2.0.50727'mscorlib.tlb)。