一、工具介绍
使用工具:Ollydbg,PEID,ImpREC,Cheat Engine,火绒剑
实现功能:除去广告,游戏秒杀。
二、除去广告
1、初始判断
点击开始游戏,弹出窗口,点击继续,弹出游戏界面。

查看火绒剑进程信息,发现了创建了两个进程,为以下创建关系。
qqllk.exe -> qqllk.ocx -> kyodai.exe
直接运行kyodai.exe,程序奔溃。
直接运行qqllk.ocx(需修改后缀名),可运行。判断qqllk.ocx 对了kyodai.exe进行某些操作。
2、脱壳
对qqllk.ocx(需修改后缀名)进行信息查看
通过PEID 可以看出,程序加了ASPack壳
通过ESP定律,OD插件OllyDump,ImpREC, 脱除
脱除效果:
3、去广告
在脱壳后程序下API断点:CreateProcessA
查看堆栈信息,发现kyodai.exe进程在创建时被挂起
ctrl+F8自动步过,发现进行了一系列的循环操作,猜测在修改kyodai.exe的进程数据
下API断点:ResumeThread
发现进程恢复后游戏启动
可推断qqllk.ocx进程 创建 kyodai.exe进程并挂起
再对 kyodai.exe进程 进行了数据解密恢复
接着恢复进程运行游戏
恢复进程时,OD附加kyodai.exe进程,在OEP下断,并dump进程,完成去广告。
4、总结:
一共创建了三个进程,分别对应qqllk.exe -> qqllk.ocx -> kyodai.exe 程序。
kyodai.exe 程序数据被加密,需要qqllk.ocx进程解密恢复运行。
三、秒杀游戏
1、初始判断
通过连连看的试玩,猜测存储地图图标元素,是个地图数组
存储道具列表元素,是个道具数据列表
目标:得到雷的类型数据,
得到道具列表位置,
修改道具数据列表
实现模拟点击
完成秒杀
2、目标逐步完成
雷数据类型:
猜测地图数组需要随机初始化,在OD下API断点:rand
在断下来的地方,进行回溯逆向分析,
找到地图数组
随机初始化数组后,得到雷的数据类型。
随机初始化后地图数组
道具列表:
用CE附加进程,找到道具列表的雷数 数据地址,
进而锁定道具数据列表
模拟点击坐标:
通过回调函数,下右键点击 消息断点LBUTTONDOWN,获取坐标。
3、实现方案
- 修改道具y数据列表
- 实现模拟点击
完成秒杀游戏
4、功能代码
//实现代码:
//找到进程
HANDLE ReProcess = 0;
PROCESSENTRY32 pe32;
pe32.dwSize = sizeof(pe32);
HANDLE hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
BOOL bMore = ::Process32First(hProcessSnap, &pe32);
//多字节转宽字节
WCHAR proname[10] = {};
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);
}
HANDLE process;
process = OpenProcess(PROCESS_ALL_ACCESS, FALSE, 0xeb4);
////修改堆数据
//修改雷类型
BYTE leitype = 0xF4;
SIZE_T num = 0;
WriteProcessMemory(ReProcess, (LPVOID)0x12ac7d, &leitype, 1, &num);
//修改雷数
BYTE leishu = 0x99;
SIZE_T shu = 0;
WriteProcessMemory(ReProcess, (LPVOID)0x12ac7e, &leishu, 1, &shu);
HWND window = FindWindowA(NULL, "QQ连连看");
//发送模拟点击
for (int i = 0; i < 100; i++)
{
Sleep(50);
PostMessage(window, WM_LBUTTONDOWN, MK_LBUTTON, MAKELPARAM(681, 200));
printf("发送%d次\n", i);
}
////完成
四、附加:升级提升
1、缺陷改进
可见地图数组 和 道具数据列表 是堆空间,一旦重启电脑 或 更换电脑,数据地址将变化,外挂代码失效。
两种决解方案:1. Hook往道具列表赋值的指令,获取寄存器的值,从而实时获取堆空间地址。
2.修改往道具列表赋值的指令,实现按自己的意愿修改道具列表
这里采用第2种方案:
在道具数据列表 下硬件写入断点,回溯分析到 道具判断的地方。
2、改进功能代码
//实现代码:
//找到进程
HANDLE ReProcess = 0;
PROCESSENTRY32 pe32;
pe32.dwSize = sizeof(pe32);
HANDLE hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
BOOL bMore = ::Process32First(hProcessSnap, &pe32);
//多字节转宽字节
WCHAR proname[10] = {};
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 attibute;
VirtualProtectEx(ReProcess, (LPVOID)0x0041de2e, 0x7, PAGE_READWRITE, &attibute);
//cmp bl,0x0
BYTE OPecode1[] = { \'\x66\', \'\xc7\', \'\x40\', \'\x01\', \'\xf4\', \'\x99\' ,\'\x90\' };
DWORD num;
WriteProcessMemory(ReProcess, (LPVOID)0x0041de2e, OPecode1, 7, &num);
VirtualProtectEx(ReProcess, (LPVOID)0x0041de2e, 0x7, attibute, &attibute);
CloseHandle(ReProcess);
HWND window = FindWindowA(NULL, "QQ连连看");
//发送模拟点击消息
for (int i = 0; i < 100; i++)
{
Sleep(50);
PostMessage(window, WM_LBUTTONDOWN, MK_LBUTTON, MAKELPARAM(681, 200));
printf("发送%d次\n", i);
}
////完成
五、效果
完成除去广告,秒杀游戏
个人总结:我比较喜欢内联HOOK
附件:
QQ连连看外挂.exe
KIDofot