游戏辅助工具开发教程-从入门到精通之A2_2篇

十二 6th, 2009 | Filed under GameCheat

作者:Figo

讲了这么多天理论知识有的同学可能有些迷茫和厌倦了,你看,教室后门那个穿夹克的同学都睡着了。所以今天我们来小小的演习一下,囿于目前大家的知识储备,下面的练习只能归为局部演习,等你们羽翼丰满的时候我会领着大家实战。千万记住:欲速则不达。

首先我们需要自己编一个小游戏:玩家和怪物打斗,通过文字输出战斗情况。代码如下:
1
执行界面如下,怪物和玩家的血量依次递减:
2
包括以后真正的实战,我们要非常明确自己的目标:这里的目标是把玩家血量改为递增,即玩家被怪物攻击一次血量增加一个伤害值大小的数值。在上节教程,我们讲过与CPU交互的数据主要存储在内存中,那我们要做的就是找到内存中存储玩家血量数据的地址,因为CPU是通过地址总线来定位数据,这也就是我们第一步要做的事情:找地址,工具使用大家耳熟能详的CheatEngine。步骤如下:

视频中的相关代码和程序打包下载:点击下载
视频的清晰版下载:点击下载

下面讲解一下外挂程序的细节:
3
需要讲解的函数有2个:OpenProcessWriteProcessMemory
1、OpenProcess(dwDesiredAccess,bInheritHandle,dwProcessId)
第一个参数:对被打开进程的访问权,设置为PROCESS_ALL_ACCESS,即所有访问权;
第二个参数:打开进程创建的子进程是否可以继承该访问权限,设置为NULL;
第三个参数:要打开的进程的ID值,即我们在任务管理器里看到的PID(看不到的同学,通过查看->选择列->勾选PID)。
此函数执行成功的话我们就得到了目标进程的句柄,你可以暂时把句柄理解系统为进程指定的身份证号。
2、WriteProcessMemory(hProcess,lpBaseAddress,lpBuffer,nSize,lpNumberOfBytesWritten)
第一个参数:要写入内存的目标进程句柄,已经通过上面函数得到了;
第二个参数:要写入内存的地址指针,就是我们通过OllyDbg得到的那个地址;
第三个参数:要写入的数据,即我们修改sub指令为add指令;
第四个参数:要写入数据的大小;
第五个参数:可选参数,与本处无关,设置为NULL。

本节我们给出了一个完整的Demo演示,实战中不会这么顺利很简单。希望这篇教程能够提起大家的兴趣,以迎接真正的挑战:当你掌握了足够技术后,如果说还有什么能够阻挡你,只有你的想象力!

转载请注明出处:http://www.figoyao.com/blog/2009/12/06/135/

标签: , ,
  1. 迈克
    十二 8th, 200922:01

    我有个问题一直都不明白就是用writeprocessmemory改地址00401063处的代码,改的应该是内存代码,而不是程序代码,我一直以来都这么理解,程序代码处是2b,内存代码处是70,你那编挂的代码应该是改了内存代码70吧

  2. 迈克
    十二 8th, 200922:12

    关于上面的问题我自己弄清楚了,刚才看错了,呵呵

  3. Figo
    十二 8th, 200922:53

    @迈克
    有问题先自己思考,这个习惯很好:)

  4. Jonny_yue
    十二 12th, 200907:38

    呜呜 从A2_2就开始看不懂了 我的基础知识太弱了 `~~~~~

  5. Figo
    十二 12th, 200909:35

    @Jonny_yue
    没关系,这可能因为你对内存的机制不很了解,我后面会讲的。这节的内容是有点提前。迈克可能必要的知识储备,所以他明白了。继续加油~

  6. ty80style
    十二 30th, 200922:19

    orz…视频的清晰版下不动

  7. ty80style
    十二 31st, 200910:50

    楼主给下回复谢谢..

  8. Figo
    十二 31st, 200911:56

    @ty80style
    我重新找个网盘上传,随后会发地址。

  9. sec
    一 5th, 201000:34

    Dear Figo,
    在修改攻击力的练习中遇到了问题。
    如下:
    代码中的BYTE bData = 03;
    如果03为74 6B,即带有空格(不知道术语是什么),应该怎么定义?
    谢谢~

  10. Figo
    一 5th, 201010:52

    @sec
    BYTE类型为一个字节8bit,范围是0~255,你那个74 6B是十六进制编辑器中显示的数,如果是两个字节的话,它的实际值是0×6B74,即十进制的27508,超出了BYTE能表示的范围,应该使用unsigned short或BYTE数组来表示,如果这样的话,相应的内存写入函数的参数也要改变。关于数值转换详细规则参考汇编语言相关章节。

  11. langker
    一 27th, 201020:28

    呃,老大问下你这个有写完吗?
    今天从第一章看起,
    花了将近20分钟看到了这章(前面的早就会了),
    感觉还不错,所以想问问

  12. Figo
    一 27th, 201021:24

    @langker
    这个属于业余时间写的,提纲在开始就列举了,还没写完,马上该讲DLL注入和API钩子了。已经提供了红警和魔兽的辅助工具源码。

  13. HessoW
    二 2nd, 201022:44

    Figo,阁下的清晰版视频还是不能看.

  14. Figo
    二 3rd, 201015:14

    @HessoW
    介个问题我尽快解决

  15. xlty
    三 4th, 201000:18

    相当喜欢你的教程啊

    今天先看到这里了

    自己改了下代码

    // printf(”Input ProcessID:”);
    // scanf(”%d”,&dwPID);
    HWND hWnd=::FindWindow(NULL,”C:\\GameDemo.exe”);

    GetWindowThreadProcessId(hWnd,&dwPID);

  16. Figo
    三 4th, 201009:27

    @xlty
    系统一定装在C盘吗?如果一定要找的话枚举进程ID是不是好些?当时没有讲到太多Win编程的知识,因此我才让手动输入的:)

  17. Kent
    四 22nd, 201015:46

    Figo 大哥

    你提供的视频能否放一个清晰版本的,看不清楚。幸苦了!

  18. Figo
    四 22nd, 201017:02

    @Kent
    文中提供了清晰版的下载地址,由于存放视频的服务器供应商正在改版,所以文件暂时不可下载,你可以过几天再试试。

  19. feedk
    五 10th, 201016:57

    我用GCC编绎的,第二个参数发现个错误,改为
    hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwPID);

    CE还是不太会用,找到两个地址,绿色的才是吧。
    不能发图??

  20. feedk
    五 10th, 201017:29

    终于都弄明白了。 谢谢Figo

  21. 小星
    五 12th, 201012:54

    很喜欢你。哈哈
    要是你是MM就好了。