经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » 程序设计 » 游戏设计 » 查看文章
C++基础之:扫雷破解
来源:cnblogs  作者:优梦创客  时间:2019/8/14 10:04:35  对本文有异议

版权声明:

  • 本文原创发布于博客园"优梦创客"的博客空间(网址:http://www.cnblogs.com/raymondking123/)以及微信公众号"优梦创客"
  • 您可以自由转载,但必须加入完整的版权声明!

内存扫描

使用Cheat Engine这款软件对扫雷的进程的内存进行扫描。查找与游戏获胜相关的内存区域。
扫描结果如下:

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <CheatTable CheatEngineTableVersion="26">
  3. <CheatEntries>
  4. <CheatEntry>
  5. <ID>0</ID>
  6. <Description>"棋盘首地址"</Description>
  7. <LastState Value="15" RealAddress="01005361"/>
  8. <VariableType>Byte</VariableType>
  9. <Address>扫雷.exe+5361</Address>
  10. </CheatEntry>
  11. <CheatEntry>
  12. <ID>1</ID>
  13. <Description>"玩家未确定的地雷数"</Description>
  14. <LastState Value="10" RealAddress="01005194"/>
  15. <VariableType>Byte</VariableType>
  16. <Address>扫雷.exe+5194</Address>
  17. </CheatEntry>
  18. </CheatEntries>
  19. <UserdefinedSymbols/>
  20. </CheatTable>

代码跟踪

使用x32dbg工具调试扫雷的进程,追踪扫雷代码。发现扫雷的判断条件是内存0x010057A4和0x010057A0值是否相等。
判定代码在代码段的0x0100359c区域。

破解

获取扫雷窗口句柄
获取扫雷进程号
获取扫雷进程句柄
修改代码段内存的保护属性
修改判定代码

详细代码
Injection.h

  1. #pragma once
  2. #include <string>
  3. #include <Windows.h>
  4. //#define ___DEBUG
  5. class Injection
  6. {
  7. public:
  8. Injection(const char*);
  9. bool Init();
  10. bool DoInjection();
  11. void UnInit();
  12. private:
  13. std::wstring className;
  14. HWND hw;
  15. DWORD pid;
  16. HANDLE hp;
  17. SIZE_T wr;
  18. };

Injection.cpp

  1. #include "stdafx.h"
  2. #include "Injection.h"
  3. #include <comutil.h>
  4. #pragma comment(lib, "comsuppw.lib")
  5. Injection::Injection(const char * className)
  6. :hw(0), pid(0), hp(0), wr(0)
  7. {
  8. _bstr_t tmp = className;
  9. this->className = (wchar_t*)tmp;
  10. }
  11. bool Injection::Init()
  12. {
  13. hw = FindWindow(this->className.c_str(), NULL);
  14. if (hw) printf("找到目标进程窗口,窗口句柄:%X\n", hw);
  15. else return false;
  16. GetWindowThreadProcessId(hw, &pid);
  17. if(pid) printf("成功获取目标进程号:%d\n", pid);
  18. else return false;
  19. hp = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid);
  20. if (hp) printf("成功获取目标进程句柄:%X\n", hp);
  21. else return false;
  22. return true;
  23. }
  24. // 0x010057A4
  25. // 0x010057A0
  26. // 0x0100359c
  27. bool Injection::DoInjection()
  28. {
  29. #ifndef ___DEBUG
  30. if (VirtualProtectEx(hp, (int*)0x0100359c, 5, PAGE_EXECUTE_READWRITE, &wr))
  31. printf("成功修改代码段内存保护属性\n");
  32. else return false;
  33. // mov eax, dword ptr ds : [0x010057A0]
  34. char a[] = { 0xA1, 0xA0, 0x57, 0x00, 0x01 };
  35. if (WriteProcessMemory(hp, (int*)0x0100359c, a, 5, &wr))
  36. printf("成功修改内存\n");
  37. else return false;
  38. #endif
  39. return true;
  40. }
  41. void Injection::UnInit()
  42. {
  43. CloseHandle(hp);
  44. }

main.cpp

  1. #include"Injection.h"
  2. void main(int argc, char *argv[])
  3. {
  4. #ifndef ___DEBUG
  5. if (!argc)
  6. return;
  7. Injection inj(argv[1]);
  8. #else
  9. Injection inj("扫雷");
  10. #endif // !1
  11. if (inj.Init()) printf("Init Success!\n");
  12. else return;
  13. inj.DoInjection();
  14. inj.UnInit();
  15. }

原文链接:http://www.cnblogs.com/raymondking123/p/11337854.html

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号