游戏名称:新热血英豪
将游戏丢进OD,然后分析后发现使用了CreateMutex创建互斥体来防止游戏躲开,遂按照这个思路走下去。
思路1:
编写注入程序A.exe和hook.dll,A中包含远程注入代码和创建游戏进程代码,hook.dll中使用了inlinehook将CreateMutex挂载到自己写的函数CreateMutexG去。
CreateFile函数是为了方便查看函数的返回信息。
运行注入程序,点击按钮进行创建和注入进程,第一次1.txt的信息返回值为0(ERROR_SUCCESS),第二次返回是183(ERROR_ALREADY_EXISTS),失败!
直接修改加粗的代码,jnz改je/jmp,运行两次游戏,第一次显示0,第二次显示183,还是失败。
将游戏丢进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,还是失败。