一个破解游戏双开的问题
游戏名称:新热血英豪
将游戏丢进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_SUCCESSbreak;
}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,还是失败。
一个破解游戏双开的问题相关推荐
- 《教我兄弟学Android逆向03 破解第一个Android游戏 》
上一篇 <教我兄弟学Android逆向02 破解第一个Android程序 >我带着你破解了我们自己编的一个小程序 里面我分析并讲解的一些smali语法你都记住了 给你布置的课后作业你发 ...
- 如何使用数据包破解游戏 - 从这里开始
什么是包? 您的游戏客户端和服务器始终处于通信状态.从一个到另一个的每次传输称为一个数据包. 有时它是由一系列数据包组成的数据包"流",有时它只是一个具有个人用途的数据包. 游戏使 ...
- 为什么下载的破解游戏和软件经常会被报毒?
作者:qmwatcher 链接:https://www.zhihu.com/question/28029995/answer/39206383 来源:知乎 破解游戏和软件经常会被报毒? 转载答案: 一 ...
- python能制作游戏吗_如何用python写一个小游戏
广告关闭 腾讯云11.11云上盛惠 ,精选热门产品助力上云,云服务器首年88元起,买的越多返的越多,最高返5000元! 引言最近python语言大火,除了在科学计算领域python有用武之地之外,在游 ...
- 【转】【原创】某超级模块中游戏双开功能实现
[转]某超级模块中游戏双开功能实现 超级模块中有个双开功能,能够双开腾讯的大部分游戏,例如DNF.于是就下载模块下来分析了一下. 随便在网上找一个用超级模块写的双开工具.然后OD载入,下bp Dele ...
- 如何做到游戏双开??修改进程名可以吗?
如何做到游戏双开??修改进程名可以吗? Delphi / Windows SDK/API http://www.delphi2007.net/DelphiAPI/html/delphi_2006112 ...
- 使用chatgpt设计了一个rpg游戏7万字的手稿
引导句子 通过哪些方面去评价某个目标事件的好坏 通过哪些方面去评价游戏玩法的好坏 游戏玩法的好坏可以从下面几个方面来评价: 游戏平衡性:好的游戏玩法应该有良好的平衡性,意味着游戏中各种不同的玩法.角色 ...
- 用Unity和Playmaker创建一个限时游戏 Creating a Time Limit game with Unity and Playmaker
本课程结束时,您将拥有在Unity中使用Playmaker创建游戏的工具 你会学到: playmaker状态的基础以及它们如何与动作一起工作. 安装悬停车,可以在竞技场内行驶. 不同力度的射击地雷驱动 ...
- 手把手教你架构3d游戏引擎pdf_一个在游戏行业摸爬滚打了十几年的人,为何我对这本书情有独钟...
Big News!<游戏开发:世嘉新人培训教材>今日开始预售啦!经过漫长的等待,这次终于可以买到了.现在下单,你将在图书出印厂的第一时间收到书哦- 这本书由世嘉一线开发者执笔,并被选为世嘉 ...
最新文章
- juniper srx系列配置端口映射 转载
- 通过ArcCatalog连接ArcGIS Server的种种问题
- Android百度地图悬浮窗样式,JS百度地图搜索悬浮窗功能
- Eclipse 搭建struts2 spring3 hibernate3环境实战 待完善
- poj 1284 Primitive Roots(原根+欧拉函数)
- 在服务器虚拟化架构中有哪些技术功能和益处
- Python 科学计算库 Numpy(一)—— 概述
- 电脑音响怎么插_厦门汽车音响改装丰田RAV4改装德国HELIX,感受音乐的喜怒哀乐...
- vue-cli4入门
- nginx linux源码编译安装,Linux源码编译安装nginx
- C - Log Calculator FZU - 2036
- Vijos 1603 ----迷宫(矩阵乘法,矩阵快速幂)
- 文本的数据导入到数据库中 mysql
- selenium API
- MVC5+EF6之EF CRUD
- 代价函数详解(合页代价与softmax代价)
- python苹果版安装包_新手必看。关于Python3——windows安装与运行(详细版)
- C语言不支持函数重载的原因
- Python pandas,pandas.series,series的主要方法
- 在阿里云开源镜像站中下载centOS7