Можно во много раз проще, без проблем с патчингом под изменение кода в клиенте. Достаточно убить глобальные мьютексы во всем клиенте, ибо они используются только для контроля запуска вторичных инстансов. Это можно сделать, например, так:
Код:
DWORD WINAPI SetupKernel(PVOID) {
PVOID lib;
while((lib = GetModuleHandleW(L"kernel32.dll")) == nullptr) {
Sleep(10);
}
pHookCreateMutex = new Hook(wstring(L"kernel32.dll"), string("CreateMutexA"), &hCreateMutex);
pHookCreateMutex->SetFlushCache(true);
adrCreateMutex = reinterpret_cast<DWORD>(pHookCreateMutex->GetFunctionAddress());
pHookCreateMutex->Apply();
return 0;
}
Код:
HANDLE WINAPI hCreateMutex(LPSECURITY_ATTRIBUTES lpMutexAttributes, BOOL bInitialOwner, LPCSTR lpName) {
const char* filter = "Global";
if(strncmp(lpName, filter, strlen(filter)) != 0) {
//try call original kernel function from virtual dll stub (minwin kernel)
typedef HANDLE (*TCreateMutexA)(LPSECURITY_ATTRIBUTES, BOOL, LPCSTR);
TCreateMutexA oCreateMutex = (TCreateMutexA)GetProcAddress(GetModuleHandleA("api-ms-win-core-synch-l1-1-0.dll"), "CreateMutexA");
return oCreateMutex;
}
return nullptr;
}