系统环境:win10 64位、win7 32 位
工具:吾爱专用OD、CE、代码注入器、火绒剑、VS2019
1.找到原程序exe去广告。
2.以两种方式实现辅助工具:MFC辅助、MFC静态链接库辅助。
3.功能:增加炸弹道具、无限道具、无限时间、单次消除、一键秒杀。
2.具体分析过程
¬2.1 去广告
打开qqllk.exe会连续弹两个窗然后才进入游戏
打开火绒剑观察,重新打开qqllk.exe发现会创建进的进程qqllk.ock
然后再创建kyodai.exe
那么kyodai.exe才是游戏的本体文件。直接把qqllk.ock拖进OD
在CreateProcess函数API下断点,发现这个进程创建的参数是挂起的
而且直接打开kyodai.exe是会报错的
而用qqllk.ock打开就会成功,那么我猜测肯定是修改了kyodai.exe什么数据才能让他成功打开。
所以再去下API断点WriteProcessMemory
果然断下了
那么观察到是在0x43817a基址下写入了一个字节的0x0
那么我们去OD把kyodai.exe里面改掉,再保存新的文件
去广告完毕!
2.2 指南针道具无限、无限时间
用CE找指南针的基址
发现指南针是两字节的 基址:0x0012AC5E
尝试修改,确实修改了,重开发现这个地址还可以用,那说明就是基址
CE右键->找出是什么改写了这个地址
找到如下代码:
把dec这行代码给nop掉,再运行,指南针数量就不减少了,其他道具也不减少了。
更改时间同理找到时间基址:0x0012A748
CE右键->找出是什么改写了这个地址
把这行代码nop掉。
搞定!
2.3 增加道具
先找到内存0x0012AC5E
观察使用道具、获得道具后内存的变化。
发现这样修改就有炸弹道具
2.4 单次消除
方法2:增加炸弹道具+无限道具+鼠标点击事件
代码如下:
1. HWND hWnd = ::FindWindow(NULL, L"QQ连连看");
2. if (hWnd == NULL)
3. {
4. MessageBox(L"没找到进程", 0, 0);
5. return;
6. }
7. WORD x = 704;
8. WORD y = 204;
9. DWORD dwPos = MAKELONG(x, y);
10.
11. //通过窗口句柄得到进程ID
12. DWORD pid = 0;
13. 这个函数很神奇,传入指针可以得到进程ID,返回值同事又是线程ID
14. DWORD dwThreadPid = GetWindowThreadProcessId(hWnd, &pid);
15. //通过进程ID得到进程句柄
16. HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, 0, pid);
17. //创建一个4字节的nop
18. BYTE* nopCode = new BYTE[4];
19. for (size_t i = 0; i < 4; i++)
20. {
21. nopCode[i] = 0x90;
22. }
23. //修改道具基址
24. DWORD dwProp = 0x0042AA9C;
25. WriteProcessMemory(hProcess, (LPVOID)dwProp, nopCode, 4, 0);
26.
27. WORD nopBOOMCode = 0xF4;
28. WORD nopCountCode = 220;
29.
30. //增加炸弹道具基址
31. DWORD dwBOOM = 0x0012AC8D;
32. //炸弹道具数量基址
33. DWORD dwBOOMCount = 0x0012AC8E;
34. WriteProcessMemory(hProcess, (LPVOID)dwBOOM, &nopBOOMCode, sizeof(WORD), 0);
35. WriteProcessMemory(hProcess, (LPVOID)dwBOOMCount, &nopCountCode, sizeof(WORD), 0);
36. //发送鼠标点击消息
37. ::PostMessage(hWnd, WM_LBUTTONDOWN, 0, dwPos);
38. ::PostMessage(hWnd, WM_LBUTTONUP, 0, dwPos);
方法2:找到道具CALL
我的方法是先找到连连看数组,因为我觉得道具CALL会访问这个数组
方块是随机的,我下个rand断点
在这里断下
这个函数很短,出去看看
外层是这个函数,发现参数没有找到有用的
看到下面有个memcpy,看看它的参数,
第一个参数,数据窗口跟随,是很有规律的数组,多跑几次发现就是我们想要的
选中内存,右键内存访问断点
然后ALT+K发现这里有很多CALL把这些CALL的地方都下断点,然后观察参数
感觉这个CALL是的话就写个汇编代码注入试试
最终找到这个
写了下面代码:
1. lea ecx,[0x0012A688]
2. push 0xF4
3. push 0
4. push 0
5. call 0x0041E691
注入成功!开始写代码
写mfc的dll直接注入汇编代码(会失败),所以我用注入之后改写窗口回调函数,注入之后再回到原来的窗口回调函数,这样是可行的。
关键代码如下:
1. //炸弹
2. if (Msg == WM_DATA3)
3. {
4. _asm
5. {
6. MOV ECX, 0X12A688; //this指针
7. PUSH 0XF4; //参数3
8. PUSH 0; //参数2
9. PUSH 0; //参数1
10. MOV EAX, 0X0041E691;
11. CALL EAX;//指南针函数
12. }
13. return CallWindowProc(g_OdlProc, hWnd, Msg, wParam, lParam);
14. }
2.4 一键秒杀
无论是鼠标点击,还是注入汇编代码,一个循环执行就行了呗。
定义 i = / 2;
然后循环
3.总结
我写了两种辅助工具的方法,MFC和MFC静态链接库,都是可行的