#include <Windows.h>
typedef void* (*mono_thread_attach)(PVOID domain);
typedef void* (*mono_get_root_domain)();
typedef void* (*mono_assembly_open)(PCHAR file, PVOID stat);
typedef void* (*mono_assembly_get_image)(PVOID assembly);
typedef void* (*mono_class_from_name)(PVOID image, PCHAR namespacee, PCHAR name);
typedef void* (*mono_class_get_method_from_name)(PVOID classs, PCHAR name, DWORD param_count);
typedef void* (*mono_runtime_invoke)(PVOID method, PVOID instance, PVOID *params, PVOID exc);
mono_get_root_domain do_mono_get_root_domain;
mono_assembly_open do_mono_assembly_open;
mono_assembly_get_image do_mono_assembly_get_image;
mono_class_from_name do_mono_class_from_name;
mono_class_get_method_from_name do_mono_class_get_method_from_name;
mono_runtime_invoke do_mono_runtime_invoke;
mono_thread_attach do_mono_thread_attach;
HMODULE MonoDll;
byte bmono_domain_assembly_open[64];
byte bmono_assembly_open_full[14];
byte bmono_assembly_load_from_full[14];
byte bmono_class_from_name[14];
byte bmono_assembly_names_equal[22];
byte bmono_runtime_invoke[14];
LPCSTR FuncName[6] = {
"mono_domain_assembly_open",
"mono_assembly_open_full",
"mono_assembly_load_from_full",
"mono_class_from_name",
"mono_assembly_names_equal",
"mono_runtime_invoke" };
FARPROC GPAF;
int i;
typedef void* (*VP)(LPVOID lpAddress, SIZE_T dwSize, DWORD flNewProtect, PDWORD lpflOldProtect);
VP do_VP;
HINSTANCE Kernel;
VOID LoadLib()//Load second KernelBase.dll
{
Kernel = LoadLibrary("C:/KernelBase2.dll");
do_VP = (VP)GetProcAddress(Kernel, "VirtualProtect");
}
void WriteToMemory(void *adr, void *ptr, int size)
{
DWORD OldProtection;
do_VP(adr, size, PAGE_EXECUTE_READWRITE, &OldProtection);
memcpy(adr, ptr, size);//куда, что, сколько
do_VP(adr, size, OldProtection, &OldProtection);
}
void CopyTo(void *adr, void *ptr, int size)
{
memcpy(adr, ptr, size);
}
VOID RestoreFunc()
{
for (i = 0; i < 5; i++)
{
GPAF = GetProcAddress(MonoDll, FuncName[i]);
switch (i)
{
case 0:
WriteToMemory((void*)GPAF, (void*)bmono_domain_assembly_open, 64);//mono_domain_assembly_open
break;
case 1:
WriteToMemory((void*)GPAF, (void*)bmono_assembly_open_full, 14);//mono_assembly_open_full
break;
case 2:
WriteToMemory((void*)GPAF, (void*)bmono_assembly_load_from_full, 14);//mono_assembly_load_from_full
break;
case 3:
WriteToMemory((void*)GPAF, (void*)bmono_class_from_name, 14);//mono_class_from_name
break;
case 4:
WriteToMemory((void*)GPAF, (void*)bmono_assembly_names_equal, 22);//mono_assembly_names_equal
break;
case 5:
WriteToMemory((void*)GPAF, (void*)bmono_assembly_names_equal, 14);//mono_assembly_names_equal
break;
}
}
RunProcess(GetCurrentProcessId());
}
VOID Inject() {
// Prepare code //
do_mono_thread_attach = (mono_thread_attach)GetProcAddress(MonoDll, "mono_thread_attach");
do_mono_get_root_domain = (mono_get_root_domain)GetProcAddress(MonoDll, "mono_get_root_domain");
do_mono_assembly_open = (mono_assembly_open)GetProcAddress(MonoDll, "mono_assembly_open");
do_mono_assembly_get_image = (mono_assembly_get_image) GetProcAddress(MonoDll, "mono_assembly_get_image");
do_mono_class_from_name = (mono_class_from_name) GetProcAddress(MonoDll, "mono_class_from_name");
do_mono_class_get_method_from_name = (mono_class_get_method_from_name) GetProcAddress(MonoDll, "mono_class_get_method_from_name");
do_mono_runtime_invoke = (mono_runtime_invoke)GetProcAddress(MonoDll, "mono_runtime_invoke");
// Init code //
do_mono_thread_attach(do_mono_get_root_domain());
PVOID assembly = do_mono_assembly_open("C:/SharpLibrary.dll", NULL);
PVOID Image = do_mono_assembly_get_image(assembly);
PVOID MonoClass = do_mono_class_from_name(Image, "PluginUnload", "Russia");
PVOID MonoClassMethod = do_mono_class_get_method_from_name(MonoClass, "SiberiaCod", 0);
do_mono_runtime_invoke(MonoClassMethod, NULL, NULL, NULL);
RestoreFunc();//come back
}
VOID ModFunc()//copy orig bytes and patch
{
MessageBox(0,"Run","",1);
while ((MonoDll = GetModuleHandleA("mono.dll")) == NULL) Sleep(10);
LoadLib();
for (i = 0; i < 5; i++)
{
GPAF = GetProcAddress(MonoDll, FuncName[i]);
switch (i)
{
case 0:
CopyTo((void*)bmono_domain_assembly_open, (void*)GPAF, 64);//mono_domain_assembly_open
WriteToMemory((void*)GPAF, (void*)"\x48\x89\x5C\x24\x08\x48\x89\x6C\x24\x10\x48\x89\x74\x24\x18\x57\x48\x83\xEC\x20\x48\x8B\xF9\x48\x81\xC1\xB8\x01\x00\x00\x48\x8B\xEA\xFF\x15\x89\x9E\x15\x00\x4C\x8B\x9F\xC0\x00\x00\x00\xEB\x2A\x49\x8B\x33\x48\x8B\xC5\x48\x8B\x56\x10\x48\x2B\xD5\x0F\xB6\x08", 64);
break;//original bytes function from RustClient.exe(Without EAC)
case 1:
CopyTo((void*)bmono_assembly_open_full, (void*)GPAF, 14);//mono_assembly_open_full
WriteToMemory((void*)GPAF, (void*)"\x48\x89\x5C\x24\x10\x55\x56\x57\x41\x54\x41\x55\x48\x83", 14);
break;
case 2:
CopyTo((void*)bmono_assembly_load_from_full, (void*)GPAF, 14);//mono_assembly_load_from_full
WriteToMemory((void*)GPAF, (void*)"\x48\x89\x5C\x24\x08\x48\x89\x6C\x24\x10\x48\x89\x74\x24", 14);
break;
case 3:
CopyTo((void*)bmono_class_from_name, (void*)GPAF, 14);//mono_class_from_name
WriteToMemory((void*)GPAF, (void*)"\x48\x89\x5C\x24\x20\x55\x56\x57\x48\x8D\xAC\x24\x80\xFC", 14);
break;
case 4:
CopyTo((void*)bmono_assembly_names_equal, (void*)GPAF, 22);//mono_assembly_names_equal
WriteToMemory((void*)GPAF, (void*)"\x45\x33\xC0\xE9\xC0\xDC\xFF\xFF\x48\x89\x5C\x24\x10\x55\x56\x57\x41\x54\x41\x55\x48\x83", 22);
break;
case 5:
CopyTo((void*)bmono_runtime_invoke, (void*)GPAF, 14);//mono_assembly_names_equal
WriteToMemory((void*)GPAF, (void*)"\x48\x89\x5C\x24\x08\x48\x89\x6C\x24\x10\x48\x89\x74\x24", 14);
break;
}
}
Inject();
}
bool DllMain(HMODULE iModule, DWORD dwReason, LPVOID lpReserved)
{
if (dwReason == DLL_PROCESS_ATTACH)
CreateThread(NULL,NULL,(LPTHREAD_START_ROUTINE)ModFunc, NULL,NULL,NULL);
return TRUE;
}