Skip to content

Instantly share code, notes, and snippets.

@ezdiy
Created May 11, 2018 23:21
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ezdiy/1fc2782f34b6f7233fe9895ad938ca11 to your computer and use it in GitHub Desktop.
Save ezdiy/1fc2782f34b6f7233fe9895ad938ca11 to your computer and use it in GitHub Desktop.
#include <Windows.h>
__declspec(dllexport)
DWORD WINAPI GetIpAddrTable(void *p, long *n, BOOL o) {
return 1;
}
void *(*mono_runtime_invoke)(void *, void *, void **, void **);
void *(*mono_method_desc_new)(const char *name, BOOL include_namespace);
void *(*mono_method_desc_search_in_image)(void *, void*);
void *(*mono_array_new)(void *, void *, uintptr_t);
void *(*mono_get_string_class)();
void *(*mono_get_root_domain)();
void *(*mono_assembly_get_image)(void *);
void *(*mono_assembly_open_full)(const char *name, int *stat, BOOL refonly);
void (*mono_register_bundled_assemblies)(void **);
void (*mono_jit_exec)(void *dom, void *ass, int, const char**);
void (*mono_profiler_install)(void *, void *);
void (*mono_profiler_set_events)(int mask);
void (*mono_profiler_install_module)(void *, void *, void *, void *);
void (*mono_profiler_install_assembly)(void *, void *, void *, void *);
// gets called for every dll module loaded, memory or not.
// we need to skip one call for mscorlib to get a chance, but no further so we can hijack implicit System.*
static int count = 0;
static void hook(void *prof, void *ldrimg) {
count++;
if (count != 2)
return;
MessageBoxA(NULL, "Intro", "Fatal", MB_OK);
mono_profiler_set_events(0);
void *ass = mono_assembly_open_full("patch.exe", NULL, FALSE);
if (!ass) {
MessageBoxA(NULL, "Failed to load embedded assembly. The game will run without patch.", "Fatal", MB_OK);
return;
}
void *domain = mono_get_root_domain();
void *image = mono_assembly_get_image(ass);
void *desc = mono_method_desc_new("*:Main", FALSE);
void *meth = mono_method_desc_search_in_image(desc, image);
void *args = mono_array_new(domain, mono_get_string_class(), 0);
mono_runtime_invoke(meth, NULL, args, NULL);
}
BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved)
{
if (ul_reason_for_call != DLL_PROCESS_ATTACH)
return TRUE;
// load mono
wchar_t name[MAX_PATH + 1];
int len = GetModuleFileName(NULL, name, MAX_PATH);
lstrcpy(name + len - 4, L"_Data\\Mono\\mono.dll");
HMODULE mono = LoadLibrary(name);
if (!mono) {
lstrcpy(name + len - 4 + 5, L"\\EmbedRuntime\\mono.dll");
mono = LoadLibrary(name);
if (!mono) {
MessageBoxA(NULL, "Can't find mono.dll. Is this the right game folder?", "Fatal", MB_OK | MB_ICONASTERISK);
return FALSE;
}
}
#define LOAD(n) \
n = (void*)GetProcAddress(mono, #n); \
if (!n) { \
MessageBoxA(NULL, #n, "Method missing", MB_OK | MB_ICONASTERISK); \
ExitProcess(1); \
}
LOAD(mono_jit_exec);
LOAD(mono_register_bundled_assemblies);
LOAD(mono_assembly_open_full);
LOAD(mono_assembly_get_image);
LOAD(mono_profiler_install);
LOAD(mono_profiler_set_events);
LOAD(mono_profiler_install_module);
LOAD(mono_profiler_install_assembly);
LOAD(mono_runtime_invoke);
LOAD(mono_method_desc_new);
LOAD(mono_method_desc_search_in_image);
LOAD(mono_array_new);
LOAD(mono_get_string_class);
LOAD(mono_get_root_domain);
// load assembly
HRSRC hres = FindResource(hModule, MAKEINTRESOURCE(12123), MAKEINTRESOURCE(RT_RCDATA));
if (!hres) {
MessageBoxA(NULL, "Failed to load embedded resource. The game will run without patch.", "Fatal", MB_OK);
return TRUE;
}
HGLOBAL hglob = LoadResource(hModule, hres);
void *res_data = (char*)LockResource(hglob);
int stat = 0;
static struct {
const char *name;
unsigned char *data;
unsigned int len;
} info, *infol[2] = { &info, NULL };
info.name = "patch.exe";
info.data = LockResource(hglob);
info.len = SizeofResource(hModule, hres);
// register the assembly
mono_register_bundled_assemblies(&infol[0]);
// register assembly load hook
mono_profiler_install(NULL, NULL);
mono_profiler_set_events(1 << 2); // module load events
mono_profiler_install_module(&hook, NULL, NULL, NULL);
//mono_profiler_install_assembly(&hook, NULL, NULL, NULL); TBD
return TRUE;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment