工具:吾爱专用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静态链接库,都是可行的
