I wrote a plug-in, based on BepInEx, this plug-in is responsible for loading a c++ dll,dll through the location
GcEnable(),GcDisable(), and then use the c# plugin to call the c++ interface for control
// dllmain.cpp :
#include "pch.h"
// unity-2018.1.7\mono\metadata\gc.c -> mono_gc_init
// gc
DWORD* gc_disabled = nullptr;
typedef void(WINAPI* gcEnableCloseCallType)();
gcEnableCloseCallType pfnGcDisable = nullptr;
gcEnableCloseCallType pfnGcEnable = nullptr;
BOOL gcEnable = true;
/*
base:0x7FF9B6CD0000
.text:00007FF9B6E28E8C
.text:00007FF9B6E28E8C
.text:00007FF9B6E28E8C ; void gc_enableX()
.text:00007FF9B6E28E8C gc_enableX proc near ; CODE XREF: j_gc_enableX↑j
.text:00007FF9B6E28E8C ; DATA XREF: .pdata:00007FF9B6F9E6E8↓o
.text:00007FF9B6E28E8C 48 83 EC 28 sub rsp, 28h
.text:00007FF9B6E28E90 48 8D 0D 49 8E 16 00 lea rcx, stru_7FF9B6F91CE0 ; lpCriticalSection
.text:00007FF9B6E28E97 FF 15 23 74 03 00 call cs:EnterCriticalSection
.text:00007FF9B6E28E9D FF 0D 59 0D 11 00 dec cs:GC_dont_gc
.text:00007FF9B6E28EA3 48 8D 0D 36 8E 16 00 lea rcx, stru_7FF9B6F91CE0
.text:00007FF9B6E28EAA 48 83 C4 28 add rsp, 28h
.text:00007FF9B6E28EAE 48 FF 25 03 74 03 00 jmp cs:LeaveCriticalSection
.text:00007FF9B6E28EAE gc_enableX endp
.text:00007FF9B6E28EAE
.text:00007FF9B6E28EAE ; ---------------------------------------------------------------------------
.text:00007FF9B6E28EB5 algn_7FF9B6E28EB5: ; DATA XREF: .pdata:00007FF9B6F9E6E8↓o
.text:00007FF9B6E28EB5 CC CC CC align 8
.text:00007FF9B6E28EB8
.text:00007FF9B6E28EB8 ; =============== S U B R O U T I N E =======================================
.text:00007FF9B6E28EB8
.text:00007FF9B6E28EB8
.text:00007FF9B6E28EB8 ; void gc_disabledX()
.text:00007FF9B6E28EB8 gc_disabledX proc near ; CODE XREF: j_gc_disabledX↑j
.text:00007FF9B6E28EB8 ; DATA XREF: .pdata:00007FF9B6F9E6F4↓o
.text:00007FF9B6E28EB8 48 83 EC 28 sub rsp, 28h
.text:00007FF9B6E28EBC 48 8D 0D 1D 8E 16 00 lea rcx, stru_7FF9B6F91CE0 ; lpCriticalSection
.text:00007FF9B6E28EC3 FF 15 F7 73 03 00 call cs:EnterCriticalSection
.text:00007FF9B6E28EC9 FF 05 2D 0D 11 00 inc cs:GC_dont_gc
.text:00007FF9B6E28ECF 48 8D 0D 0A 8E 16 00 lea rcx, stru_7FF9B6F91CE0
.text:00007FF9B6E28ED6 48 83 C4 28 add rsp, 28h
.text:00007FF9B6E28EDA 48 FF 25 D7 73 03 00 jmp cs:LeaveCriticalSection
.text:00007FF9B6E28EDA gc_disabledX endp
.text:00007FF9B6E28EDA
.text:00007FF9B6D0897C 75 22 jnz short loc_7FF9B6D089A0
.text:00007FF9B6D0897E
.text:00007FF9B6D0897E loc_7FF9B6D0897E: ; CODE XREF: sub_7FF9B6D088A4+C9↑j
.text:00007FF9B6D0897E ; sub_7FF9B6D088A4+D3↑j
.text:00007FF9B6D0897E 4C 8D 0D 13 E2 15 00 lea r9, aMonoMetadataGc ; "..\\mono\\metadata\\gc.c"
.text:00007FF9B6D08985 4C 8D 05 0C EB 20 00 lea r8, aAssertionShoul ; "* Assertion: should not be reached at %"...
.text:00007FF9B6D0898C BA 04 00 00 00 mov edx, 4
.text:00007FF9B6D08991 33 C9 xor ecx, ecx
.text:00007FF9B6D08993 C7 44 24 20 4A 04 00 00 mov [rsp+38h+var_18], 44Ah
.text:00007FF9B6D0899B E8 C4 87 FC FF call sub_7FF9B6CD1164
.text:00007FF9B6D089A0
.text:00007FF9B6D089A0 loc_7FF9B6D089A0: ; CODE XREF: sub_7FF9B6D088A4+D8↑j
.text:00007FF9B6D089A0 45 33 C9 xor r9d, r9d ; lpName
.text:00007FF9B6D089A3 33 D2 xor edx, edx ; lInitialCount
.text:00007FF9B6D089A5 41 B8 FF FF FF 7F mov r8d, 7FFFFFFFh ; lMaximumCount
.text:00007FF9B6D089AB 33 C9 xor ecx, ecx ; lpSemaphoreAttributes
.text:00007FF9B6D089AD FF 15 55 7A 15 00 call cs:CreateSemaphoreW
.text:00007FF9B6D089B3 48 89 05 0E FD 22 00 mov cs:qword_7FF9B6F386C8, rax
.text:00007FF9B6D089BA E8 B9 AA FF FF call mono_domain_get
.text:00007FF9B6D089BF 48 8D 15 EA FD FF FF lea rdx, sub_7FF9B6D087B0
.text:00007FF9B6D089C6 45 33 C9 xor r9d, r9d
.text:00007FF9B6D089C9 45 33 C0 xor r8d, r8d
.text:00007FF9B6D089CC 48 8B C8 mov rcx, rax
.text:00007FF9B6D089CF E8 60 B7 06 00 call sub_7FF9B6D74134
.text:00007FF9B6D089D4 48 89 05 BD FC 22 00 mov cs:qword_7FF9B6F38698, rax
.text:00007FF9B6D089DB EB 0A jmp short loc_7FF9B6D089E7
.text:00007FF9B6D089DD ; ---------------------------------------------------------------------------
.text:00007FF9B6D089DD
.text:00007FF9B6D089DD loc_7FF9B6D089DD: ; CODE XREF: sub_7FF9B6D088A4+5D↑j
.text:00007FF9B6D089DD ; sub_7FF9B6D088A4+72↑j
.text:00007FF9B6D089DD C7 05 E9 FC 22 00 01 00 00 00 mov cs:gc_disabled, 1 /////////////////////////////////////////////////
.text:00007FF9B6D089E7
.text:00007FF9B6D089E7 loc_7FF9B6D089E7: ; CODE XREF: sub_7FF9B6D088A4+137↑j
.text:00007FF9B6D089E7 48 83 C4 38 add rsp, 38h
.text:00007FF9B6D089EB C3 retn
.text:00007FF9B6D089EB sub_7FF9B6D088A4 endp
.data:00007FF9B6F386A0 ?? ?? ?? ?? ?? ?? ?? ?? ; sub_7FF9B6D077BC+43↑o ...
.data:00007FF9B6F386C8 ?? ?? ?? ?? ?? ?? ?? ?? qword_7FF9B6F386C8 dq ? ; DATA XREF: sub_7FF9B6D081AC↑o
.data:00007FF9B6F386C8 ; sub_7FF9B6D087B0:loc_7FF9B6D08800↑o ...
.data:00007FF9B6F386D0 ?? ?? ?? ?? gc_disabled dd ? ; DATA XREF: sub_7FF9B6D081C4+4↑r
.data:00007FF9B6F386D0 ; sub_7FF9B6D088A4:loc_7FF9B6D089DD↑w ...
.data:00007FF9B6F386D4 ?? ?? ?? ?? dword_7FF9B6F386D4 dd ? ; DATA XREF: sub_7FF9B6D08368+B8↑r
.data:00007FF9B6F386D4 ; mono_domain_finalize+86↑r ...
.data:00007FF9B6F386D8 ?? ?? ?? ?? ?? ?? ?? ?? qword_7FF9B6F386D8 dq ? ; DATA XREF: sub_7FF9B6D087B0+63↑r
.data:00007FF9B6F386D8 ; sub_7FF9B6D087B0+7A↑r ...
*/
EXTERN_C __declspec(dllexport) BOOL monoPatchInit()
{
auto monoDll = (BYTE*)GetModuleHandle(L"mono.dll");
if (monoDll == nullptr)
return false;
pfnGcEnable = (gcEnableCloseCallType)(monoDll + 0x158E8C);
pfnGcDisable = (gcEnableCloseCallType)(monoDll + 0x158EB8);
if (*(BYTE*)pfnGcEnable != 0x48 && *(BYTE*)((BYTE*)pfnGcEnable + 4) != 0x48)
return false;
gc_disabled = (DWORD*)(monoDll + 0x2686D0);
gcEnable = true;
return true;
}
EXTERN_C __declspec(dllexport) BOOL monoSetGCStatus(BOOL bEnable)
{
if (gc_disabled && pfnGcDisable && pfnGcEnable)
{
if (bEnable)
{
if (!gcEnable)
{
pfnGcEnable();
//*gc_disabled = 0;
gcEnable = true;
}
}
else
{
if (gcEnable)
{
//*gc_disabled = 1;
pfnGcDisable();
gcEnable = false;
}
}
return true;
}
return false;
}
BOOL APIENTRY DllMain( HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}