连连看去广告及秒杀外挂
本帖最后由 Payload_82 于 2018-4-15 16:40 编辑最近在学习逆向破解,用连连看来练习。有什么错误的地方请大家批评指正
这里感谢15PB的老师和同学对我的帮助
样本概况
QQ连连看单机版,软件带广告,关闭后会弹网页广告。
行为分析
第一层程序qqllk.exe
找到创建第二层程序的地址即可,目的是为了知道第2层程序是哪个
第二层程序qqllk.ocx
运行qqllk.ocx是无法打开的,修改后缀名为exe后再次运行
用PEiD扫描发现程序加了ASPack壳
脱壳后运行,在CreateProcess处继续下断点
发现是以挂起方式创建的新进程,路径是"C:\Users\15pb-win7\Desktop\qq连连看单机版[作业]\qq连连看单机版\kyodai.exe"
第三层程序kyodai.exe
双击运行kyodai.exe,程序是无法运行的
说明kyodai.exe的代码可能被第2层程序加密了,结合这个进程是被挂起方式创建的,在后面应该有解密代码的操作。这里可以取巧一下,再打开一个OD,附加新创建的kyodai.exe进程,等代码被解密完成后,直接跳转到OEP再dump文件就可以了。
如果这里深入探索一下程序是如何解密代码的。继续跟CreateProcessA函数后面的代码,发现这些代码很杂,而且是在不停的计算,发现继续跟下去要花很长时间。
那么思考一个问题:一个进程如何修改另一个进程中的代码?就是调用WriteProcessMemory函数,不论这些代码解密了多少数据,最终都得写入到目标进程中去。所以在WriteProcessMemory上下断点,结果发现那么多代码都是没用的代码。只是将目标进程中0x43817A地址上的1个字节修改为0x00。
所以用010Editor直接打开kyodai.exe找到文件偏移为0x3817A的地方,将0x01修改为0x00后再次运行程序,就可以运行了。
接下来就是分析游戏,找到突破点开始写外挂。
通过试玩游戏,发现道具地雷是可以通过消除雷获取的,使用一次地雷道具就可以直接消除2个方块。那么找到保存道具地雷的位置,修改数量就能无限使用,达到秒杀游戏的效果。
在开始游戏时道具栏是没有地雷的,那么可以先尝试找到现有的道具,看看这些道具是否保存在一起。第1个道具是指南针,作用是找到2个可以消除的方块。既然能找到可以消除的方块,说明肯定有遍历地图数组的操作。那么首先需要找到游戏保存方块的数组,在数组中下断点,再使用指南针道具,就可以断在指南针的函数位置。
那么如何找数组在内存中的位置,游戏中方块的位置是随机的,那么就在rand函数下断点。点击“练习”程序断在了rand函数上。打开调用堆栈窗口我们逐层查看,先进入41CAF2
进入0x41CAF2后按Ctrl+A分析一下可以看到rand后是调用memcpy函数,在内存中转到src地址上,可以看到这段空间已经生成了许多01的值,那么可以猜测有01的位置后面应该会设置成不同的方块值,0的位置应该是留空。这里要记住dest的位置是0x12BB50
继续运行程序再次断在rand,在“调用堆栈”窗口查看调用情况,逐层向上查看到第2层
可以看到是memcpy函数下面的函数,这是我们可以直接运行到CALL kyodai.00428F0E指令的下一行。这时dest指向的地址中已经被全部写成不同的值了。
随便在内存中一个位置上“0x11”处下硬件访问断点,发现无法断下来。尝试下内存访问断点,点击“指南针”道具,程序断下来了
打开“调用堆栈”窗口,这里我们就得逐层尝试,观察调用函数的参数是什么,是不是有关地址或者下标之类的数组。先看4292B8。在这个地址下断点,参数不是我们要的,再向上一层
在地址0041E76C上 CALL kyodai.0042923F下断点,再次运行到这里,发现2个参数是都是栈地址
运行到下一行指令,发现返回值是“10,3”和“7,1”2组数字,猜测这应该是寻找到的可以消除的2个方块的坐标。
在游戏中看一下果然是可以消除的方块,说明返回值是2个POINT结构体,其实找到这里就是一种编写外挂的途径。只需要不断调用这个函数获取返回值,再找到转换坐标的函数模拟发送点击消息就可以完成秒杀。
但是找到雷道具的位置就能更简单的完成秒杀游戏的功能。从“调用堆栈”找到上一层函数,观察到前面有一些比较——跳转的指令
那么猜测这些比较指令是不是在判断道具数量或者种类的指令?通过反复使用道具再观察和值的变化,发现 保存的是道具类型,保存的就是使用的道具的数量。找到EAX指向的内存地址,调整位置可以看出其中的规律
为了印证我们的猜想,在调用堆栈找到上层函数下断点,再使用道具。看到参数是:0和FFFFFFFh
进入函数内分析,分析完地址0041DE1C上的 CALL <kyodai.获取点击的道具所在内存位置>函数, kyodai.0041DE09函数的第1个参数0表示的是道具窗口中的第几个道具,见下图。
函数<kyodai.获取点击的道具所在内存位置>就是根据kyodai.0041DE09的参数1算出该道具在内存中的数据地址
通过消除方块获取到雷道具后再对比道具内存,我们就知道了雷是F4,现在把数量1改为99尝试一下,就可以无限使用雷了。
每次修改内存位置是不太保险的,因为这段内存是栈空间。为了能在所有平台上都能使用外挂,这里有2种解决方法:
1.HOOK向道具列表复制的指令,获取寄存器的值,从而实时获取内存空间地址
2.修改往道具列表复制的指令,实现按自己的意愿修改道具类型和数量。
这里采用第2种方法,分析<kyodai.0041DE09>函数中的代码,发现有3行代码可以修改的,
修改为:mov word ptr , 0x99F4,效果如下:
现在只要找到回调函数,写代码模拟发送点击消息就可以完成外挂了
在TranslateMessage下条件断点,条件为“[+4]==WM_LBUTTONDOWN”,点击雷道具程序中断,在栈中就可以看到鼠标点击位置
编写代码:
HANDLE ReProcess = 0;
PROCESSENTRY32 pe32;
pe32.dwSize = sizeof(pe32);
HANDLE hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
BOOL bMore = Process32First(hProcessSnap, &pe32);
//多字节转宽字节
WCHAR proname = { 0 };
MultiByteToWideChar(CP_ACP, MB_COMPOSITE, "kyodai.exe", 10, proname, 10);
while (bMore)
{
if (wcscmp(pe32.szExeFile, proname) == 0)
{
ReProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pe32.th32ProcessID);
break;
}
bMore = Process32Next(hProcessSnap, &pe32);
}
//修改指令
DWORD attribute = 0;
VirtualProtectEx(ReProcess, (LPVOID)0x0041de2e, 0x7, PAGE_READWRITE, &attribute);
//cmp bl,0x0
BYTE OPecode1[] = { '\x66', '\xc7', '\x40', '\x01', '\xf4', '\x99' ,'\x90' };
DWORD num = 0;
WriteProcessMemory(ReProcess, (LPVOID)0x0041de2e, OPecode1, 7, &num);
VirtualProtectEx(ReProcess, (LPVOID)0x0041de2e, 0x7, attribute, &attribute);
CloseHandle(ReProcess);
HWND hWnd = FindWindowA(NULL, "QQ连连看");
//发送模拟点击消息
for (int i = 0; i < 100; i++)
{
Sleep(50);
PostMessage(hWnd, WM_LBUTTONDOWN, MK_LBUTTON, MAKELPARAM(677, 202));
PostMessage(hWnd, WM_LBUTTONUP, MK_LBUTTON, MAKELPARAM(677, 202));
printf("发送%d次\n", i);
}
秒杀效果
连连看文件链接: https://pan.baidu.com/s/1zn0XDR44oqn3wnSNuN3Cvg 密码: dmpu
lzhzy597 发表于 2018-4-22 20:42
如果连这种游戏都要开挂的话,那就不是你玩游戏了,而是游戏玩你了
破解这个游戏只是为了练习游戏破解,学习逆向破解肯定先从简单的开始。反正平时让我玩都不想玩这个。
教程很详细感谢分享 什么时候我也能 写出这样的一个外挂就好了最后的外挂效果 强 大涨见识 支持大佬 。太牛了 谢谢分享。 感谢分享,学习 数学不好,软件还破解不了呢 谢谢楼主分享!秒杀好牛啊! 谢谢楼主分享! 如果连这种游戏都要开挂的话,那就不是你玩游戏了,而是游戏玩你了 厉害厉害,但是这样的话就失去了游戏的意义
页:
[1]
2