我有这个代码可以使用clr运行时主机从非托管c ++程序执行c#assembly 它适用于c#,但是使用vb.net它不起作用,尽管两种语言都被编译为il代码并运行.net框架
这是代码:
#include <stdio.h>
#include <tchar.h>
#include <metahost.h>
#pragma comment(lib, "MSCorEE.lib")
#import "C:\Windows\Microsoft.NET\Framework\v2.0.50727\mscorlib.tlb"
raw_interfaces_only \
high_property_prefixes("_get","_put","_putref") \
rename("ReportEvent", "InteropServices_ReportEvent")
using namespace mscorlib;
unsigned char rawData[] = {
// .net exe bytes
};
#define RAW_ASSEMBLY_LENGTH sizeof(rawData);
int _tmain(int argc, _TCHAR* argv[])
{
ICLRMetaHost* pMetaHost = NULL;
HRESULT hr;
/* Get ICLRMetaHost instance */
hr = CLRCreateInstance(CLSID_CLRMetaHost, IID_ICLRMetaHost,
(VOID**)&pMetaHost);
if(FAILED(hr))
{
printf("[!] CLRCreateInstance(...) failed\n");
getchar();
return -1;
}
printf("[+] CLRCreateInstance(...) succeeded\n");
ICLRRuntimeInfo* pRuntimeInfo = NULL;
/* Get ICLRRuntimeInfo instance */
hr = pMetaHost->GetRuntime(L"v2.0.50727", IID_ICLRRuntimeInfo,
(VOID**)&pRuntimeInfo);
if(FAILED(hr))
{
printf("[!] pMetaHost->GetRuntime(...) failed\n");
getchar();
return -1;
}
printf("[+] pMetaHost->GetRuntime(...) succeeded\n");
BOOL bLoadable;
/* Check if the specified runtime can be loaded */
hr = pRuntimeInfo->IsLoadable(&bLoadable);
if(FAILED(hr) || !bLoadable)
{
printf("[!] pRuntimeInfo->IsLoadable(...) failed\n");
getchar();
return -1;
}
printf("[+] pRuntimeInfo->IsLoadable(...) succeeded\n");
ICorRuntimeHost* pRuntimeHost = NULL;
/* Get ICorRuntimeHost instance */
hr = pRuntimeInfo->GetInterface(CLSID_CorRuntimeHost, IID_ICorRuntimeHost,
(VOID**)&pRuntimeHost);
if(FAILED(hr))
{
printf("[!] pRuntimeInfo->GetInterface(...) failed\n");
getchar();
return -1;
}
printf("[+] pRuntimeInfo->GetInterface(...) succeeded\n");
/* Start the CLR */
hr = pRuntimeHost->Start();
if(FAILED(hr))
{
printf("[!] pRuntimeHost->Start() failed\n");
getchar();
return -1;
}
printf("[+] pRuntimeHost->Start() succeeded\n");
IUnknownPtr pAppDomainThunk = NULL;
hr = pRuntimeHost->GetDefaultDomain(&pAppDomainThunk);
if(FAILED(hr))
{
printf("[!] pRuntimeHost->GetDefaultDomain(...) failed\n");
getchar();
return -1;
}
printf("[+] pRuntimeHost->GetDefaultDomain(...) succeeded\n");
_AppDomainPtr pDefaultAppDomain = NULL;
/* Equivalent of System.AppDomain.CurrentDomain in C# */
hr = pAppDomainThunk->QueryInterface(__uuidof(_AppDomain), (VOID**)
&pDefaultAppDomain);
if(FAILED(hr))
{
printf("[!] pAppDomainThunk->QueryInterface(...) failed\n");
getchar();
return -1;
}
printf("[+] pAppDomainThunk->QueryInterface(...) succeeded\n");
_AssemblyPtr pAssembly = NULL;
SAFEARRAYBOUND rgsabound[1];
rgsabound[0].cElements = RAW_ASSEMBLY_LENGTH;
rgsabound[0].lLbound = 0;
SAFEARRAY* pSafeArray = SafeArrayCreate(VT_UI1, 1, rgsabound);
void* pvData = NULL;
hr = SafeArrayAccessData(pSafeArray, &pvData);
if(FAILED(hr))
{
printf("[!] SafeArrayAccessData(...) failed\n");
getchar();
return -1;
}
printf("[+] SafeArrayAccessData(...) succeeded\n");
memcpy(pvData, rawData, RAW_ASSEMBLY_LENGTH);
hr = SafeArrayUnaccessData(pSafeArray);
if(FAILED(hr))
{
printf("[!] SafeArrayUnaccessData(...) failed\n");
getchar();
return -1;
}
printf("[+] SafeArrayUnaccessData(...) succeeded\n");
/* Equivalent of System.AppDomain.CurrentDomain.Load(byte[] rawAssembly) */
hr = pDefaultAppDomain->Load_3(pSafeArray, &pAssembly);
if(FAILED(hr))
{
printf("[!] pDefaultAppDomain->Load_3(...) failed\n");
getchar();
return -1;
}
printf("[+] pDefaultAppDomain->Load_3(...) succeeded\n");
_MethodInfoPtr pMethodInfo = NULL;
/* Assembly.EntryPoint Property */
hr = pAssembly->get_EntryPoint(&pMethodInfo);
if(FAILED(hr))
{
printf("[!] pAssembly->get_EntryPoint(...) failed\n");
getchar();
return -1;
}
printf("[+] pAssembly->get_EntryPoint(...) succeeded\n");
VARIANT retVal;
ZeroMemory(&retVal, sizeof(VARIANT));
VARIANT obj;
ZeroMemory(&obj, sizeof(VARIANT));
obj.vt = VT_NULL;
//TODO! Change cElement to the number of Main arguments
SAFEARRAY *psaStaticMethodArgs = SafeArrayCreateVector(VT_VARIANT, 0, 1);
/* EntryPoint.Invoke(null, new object[0]) */
hr = pMethodInfo->Invoke_3(obj, psaStaticMethodArgs, &retVal); // fails here
if(FAILED(hr))
{
printf("[!] pMethodInfo->Invoke_3(...) failed, hr = %X\n", hr);
getchar();
return -1;
}
printf("[+] pMethodInfo->Invoke_3(...) succeeded\n");
getchar();
return 0;
}
当我使用vb bytes时,我得到了这个:
[!] pMethodInfo-&gt; Invoke_3(...)失败,hr = 80131604
我尝试过使用.net框架版本v4和v2并更改了参数数量但没有效果