一个破解游戏双开的问题

游戏名称:新热血英豪

将游戏丢进OD,然后分析后发现使用了CreateMutex创建互斥体来防止游戏躲开,遂按照这个思路走下去。

思路1:
编写注入程序A.exe和hook.dll,A中包含远程注入代码和创建游戏进程代码,hook.dll中使用了inlinehook将CreateMutex挂载到自己写的函数CreateMutexG去。

CreateMutex函数将随即生成一个字符串来代替原来CreateMutex参数中的lpName。以下是hook.dll代码:

#pragma comment(lib, "psapi.lib")
 
BYTE g_NewCode[7];
HMODULE g_hDllHandle = NULL;
HANDLE g_hProcess = NULL;
LPVOID g_CreateMutexA = NULL;
DWORD g_CreateMutexG = NULL;
char g_CurName[256];
 
void InlineHook();
void BackupDLL();
HANDLE WINAPI CreateMutexG(SECURITY_ATTRIBUTES*, BOOL, LPCTSTR);
 
BOOL APIENTRY DllMain( HANDLE hModule, 
DWORD ul_reason_for_call, 
LPVOID lpReserved
)
{
switch (ul_reason_for_call) 
{
case DLL_PROCESS_ATTACH:
{
BackupDLL();
InlineHook();
// ERROR_SUCCESS
 
break;
}
 
case DLL_THREAD_ATTACH:
{
break;
}
 
case DLL_PROCESS_DETACH:
{
break;
}
 
case DLL_THREAD_DETACH:
{
break;
}
}
 
return TRUE;
}
 
void InlineHook()
{
DWORD dwProtect = 0;
DWORD JmpAddr = (DWORD)CreateMutexG;
 
g_NewCode[0] = 0xB8;
memcpy(&g_NewCode[1], &JmpAddr, 4);
g_NewCode[5] = 0xFF;
g_NewCode[6] = 0xE0;
 
::VirtualProtect(g_CreateMutexA, 7, PAGE_EXECUTE_READWRITE, &dwProtect);
::WriteProcessMemory(g_hProcess, g_CreateMutexA, g_NewCode, sizeof(g_NewCode), NULL);
::VirtualProtect(g_CreateMutexA, 7, dwProtect, &dwProtect);
 
return;
}
 
void BackupDLL()
{
g_hProcess = ::GetCurrentProcess();
g_hDllHandle = ::LoadLibrary("kernel32.dll");
g_CreateMutexA = (LPVOID)::GetProcAddress(g_hDllHandle, "CreateMutexA");
 
MODULEINFO Mdl_Info;
LPVOID lpNewDLL = NULL;
 
::GetModuleInformation(g_hProcess, g_hDllHandle, &Mdl_Info, sizeof(Mdl_Info));
 
lpNewDLL = ::VirtualAllocEx(
g_hProcess,
NULL,
Mdl_Info.SizeOfImage,
MEM_COMMIT,
PAGE_EXECUTE_READWRITE
);
if (lpNewDLL == NULL)
return;
 
::WriteProcessMemory(g_hProcess, lpNewDLL, Mdl_Info.lpBaseOfDll, Mdl_Info.SizeOfImage, NULL);
g_CreateMutexG = (DWORD)g_CreateMutexA - (DWORD)Mdl_Info.lpBaseOfDll + (DWORD)lpNewDLL;
 
return;
}
 
HANDLE WINAPI CreateMutexG(SECURITY_ATTRIBUTES* sa, BOOL bOwner, LPCTSTR lpName)
{
typedef HANDLE WINAPI CREATEMUTEX(SECURITY_ATTRIBUTES* sa, BOOL bOwner, LPCTSTR lpMutexName);
 
CREATEMUTEX *pfnCreateMutex = (CREATEMUTEX*)g_CreateMutexG;
 
char lpNewName[256] = { 0x00 };
time_t t;
srand((unsigned)time(&t));
int n = rand() % 52266;
 
::wsprintf(lpNewName, "GETAMPED_NIJUUKIDOUBOUSHI_MUTEX_021002%dHackedByPapa", n);
// ::wsprintf(lpNewName, "%sHackedByPapa", lpName);
HANDLE hMutex = pfnCreateMutex(sa, bOwner, lpNewName);
int i = GetLastError();
char text[256];
strcpy(g_CurName, lpNewName);
::wsprintf(text, "%d - %s", i, lpNewName);
 
HANDLE hFile = CreateFile("1.txt",
GENERIC_WRITE,
FILE_SHARE_WRITE,
NULL,
CREATE_ALWAYS,
FILE_ATTRIBUTE_NORMAL,
0);
 
DWORD dw = 0;
WriteFile(hFile, text, strlen(text), &dw, NULL);
CloseHandle(hFile);
 
// 
 
return hMutex;
}

CreateFile函数是为了方便查看函数的返回信息。

运行注入程序,点击按钮进行创建和注入进程,第一次1.txt的信息返回值为0(ERROR_SUCCESS),第二次返回是183(ERROR_ALREADY_EXISTS),失败!

思路2:
直接修改汇编代码:

004221B0 /$ 81EC BC020000 sub esp,0x2BC
004221B6 |. A1 14104300 mov eax,dword ptr ds:[0x431014]
004221BB |. 33C4 xor eax,esp
004221BD |. 898424 B80200>mov dword ptr ss:[esp+0x2B8],eax
004221C4 |. 57 push edi
004221C5 |. 8BBC24 CC0200>mov edi,dword ptr ss:[esp+0x2CC]
004221CC |. 68 ADE74200 push amped.0042E7AD ; /MutexName = "ETAMPED_NIJUUKIDOUBOUSHI_MUTEX_021002"    ; lpName, 即Mutex名称
004221D1 |. 6A 00 push 0x0 ; |InitialOwner = FALSE
004221D3 |. 6A 00 push 0x0 ; |pSecurity = NULL
004221D5 |. FF15 1CE04200 call dword ptr ds:[<&KERNEL32.CreateMute>; \CreateMutexA
004221DB |. FF15 18E04200 call dword ptr ds:[<&KERNEL32.GetLastErr>; [GetLastError
004221E1 |. 3D B7000000 cmp eax,0xB7
	 |. 75 2A jnz Xamped.00422212              ;直接将jnz修改为jmp.[/b][/color]
004221E8 |. 6A 00 push 0x0 ; /lParam = 0
004221EA |. 68 60214200 push amped.00422160 ; |Callback = amped.00422160
004221EF |. FF15 50E14200 call dword ptr ds:[<&USER32.EnumWindows>>; \EnumWindows
004221F5 |. B8 01000000 mov eax,0x1
004221FA |. 5F pop edi
004221FB |. 8B8C24 B80200>mov ecx,dword ptr ss:[esp+0x2B8]
00422202 |. 33CC xor ecx,esp
00422204 |. E8 35010000 call amped.0042233E
00422209 |. 81C4 BC020000 add esp,0x2BC
0042220F |. C2 1000 retn 0x10

直接修改加粗的代码,jnz改je/jmp,运行两次游戏,第一次显示0,第二次显示183,还是失败。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值