一、工具介绍
使用工具: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
附件:
KID
来源:oschina
链接:https://my.oschina.net/u/4385636/blog/4052430