« 1 2» Pages: ( 1/2 total )
本页主题: [传贴][教程]yes2斑斑地修改器制作傻瓜教程(有例子) 打印 | 加为IE收藏 | 复制链接 | 收藏主题 | 上一主题 | 下一主题

游戏之王
级别: *


精华: *
发帖: *
威望: * 点
金钱: * 胜利币
贡献值: * 点
在线时间:(小时)
注册时间:*
最后登录:*

 [传贴][教程]yes2斑斑地修改器制作傻瓜教程(有例子)

0
此铁偶传于yes2斑斑的教程由于某些原因所以我就代替斑斑铁出来了.
不过这是一篇很好的教程如果用心看一定可以收获不少.
反正偶有时间就帮yes2斑斑铁出来咯.

http://bbs.winsong.org/read-htm-tid-137584.html

日志标题:游戏修改(一)——概述
发表时间:2005-6-23 16:21:16
 很久以前就有一个想法——让所有的游戏玩家(哪怕是最PP的MM)都学会修改!目标似乎很幼稚且不切实际,那么至少让欣赏我的人和想学习的人共享我的修改心得吧。
修改工具强烈推荐金山游侠,以下默认使用金山游侠。如果游侠搞不定的话,推荐使用独孤求败互补(不是开玩笑的,真的有这个修改器,用起来还不错)。金山游侠下载地址:http://soft.ttdown.com/SoftView/SoftView_5601.html 独孤求败比较不好找,有需要的自己努力吧

首先我们需要认清修改的本质:找到我们想要的地址,然后修改或是锁定。最重要的环节就是找到地址,修改或是锁定交给修改软件就是了。

那么如何找到地址呢?两种方法,一种是通过某种渠道比如金手指或是游戏攻略,得到该地址,由金山游侠的“内存编辑”直接进入内存,输入地址,定位。这种没什么技术性可言,介绍到次为止;另一种就是搜索,这是修改游戏不可不用的,以下详细介绍:搜索。

搜索的真谛就是:通过游戏数据的变化多次搜索确定地址。比如说,想找到HP的地址,那么先输入当前HP比如90,那么初次搜索完之后必定会有很多结果,因为内存中数值为90的一定是海量的。这么多结果我们不可能一个一个试的,试完孩子都出来了。那么只有回到游戏,使HP变化,比如吃个补HP的,HP+5,那么现在再搜索95,估计剩余结果也不会很少,再回到游戏,找怪物打一架,HP剩80了,那么呼出修改器,搜索80。就这样不断变化不断搜索,最终一定会使搜索结果在5个以内。这个时候就直接把剩余结果全给改了就好了。以上就是为了说明,搜索是建立在数据变化的基础上的,如果数据不变化,想找到结果很难。当然也有特例,比如DiabloII的经验值,到后期数值很大而且不规律,像是65123465之类的,基本上搜索一次剩余结果就很少了。

找到一个地址之后该干什么?修改它的值,然后就结束了吗?不!我们应该顺藤摸瓜,从这个地址找到和它关联的地址。比如上文我们找到了HP的地址是0x45AB000,那么点“内存编辑”进入内存,定位到0x45AB000,看看附近,有没有什么可疑的东西?假如当前HP/HPMAX = 80/100,MP/MPMAX = 60/70,内存数值一般都是以16进制显示的,那么拿出我们的计算器,算算看这几个数对应的16进制数是多少。80/100 = 0x50/0x64,60/70 = 0x3C/0x46。也就是说,找找附近有没有50,64,3C,46,应该会有所发现的。这一段是告诉大家,找到一个地址,要看看附近是否能找到更多地址。

上一篇:无

下一篇:游戏修改(二)——工具


日志标题:游戏修改(二)——工具
发表时间:2005-7-1 16:27:40
 
先扫盲,讲一下修改游戏最基本的搜索过程以熟悉金山游侠的使用,会的可以跳过。实验游戏就是windos自带的“桌上弹球”(好象win98没有,那就自己想象吧)。游戏规则及玩法自己研究,这个不在鄙人解说范围之内。



如上图。打开游戏,F2开局,空格键开球,随便得点分,F3暂停(直接用游侠中断也可以,反正这个游戏自带暂停功能,不用白不用),‘*’键呼出,现在分数是3500,搜索3500,出来10个结果。如下图:


回到游戏,F3继续,再得几分,F3暂停,搜索。这次搜索5000。可以看到,这次只剩下2个结果了。如果你想精确一点的话可以再多搜索几次直到最后只剩一个结果,不过这个游戏似乎怎么搜都会剩下这两个。



下面讲处理方法。

1)两个都直接修改为你所需要的高分。



2)进入内存修改。





这两种方法是最基本的,也是用到最后的。

哎呀,改图好累呀,搞半天才讲了这么一点。下次再说吧。。。记得不要把数值改得太高,一旦分数超过999999999就会从0开始的。其他游戏也可能有类似的情况,所以凡事不要太贪:)

上一篇:游戏修改(一)——概述

下一篇:游戏修改(三)——基础
本帖最近评分记录:
  • 金钱:10 (By yes2) | 理由: 辛苦了
  • 顶端 Posted: 2006-06-21 12:29 | 马来西亚电信 [楼 主]
    游戏之王
    级别: *


    精华: *
    发帖: *
    威望: * 点
    金钱: * 胜利币
    贡献值: * 点
    在线时间:(小时)
    注册时间:*
    最后登录:*

     

    日志标题:游戏修改(三)——基础
    发表时间:2005-7-5 16:11:13
     
    上一篇“工具”中,对于金山游侠的使用介绍并不是很深入本质,主要是因为本质方面还要牵扯到内存以及10进制<->16进制的问题,今天就介绍一下这个。

    先说16进制。我们平时接触的10进制,一共是10个计数的阿拉伯数字0,1,2……9,是逢10进一,就是数到9的时候,再往上数就是10,10怎么来的呢?就是9的高位进1,变成19,而原位9归0,成为10;而16进制呢,计数的字母为0,1,2……9,A,B,C,D,E,F一共16个,逢16进一,(通常标志是前面有个“0x”,不过只是描述的时候才这样用,像金山游侠的内存编辑上面显示的就是16进制的,但是没有“0x”)就是数到9的时候,往上数是0xA,再往上0xB,依次类推,到0xF,也就是15的时候,再往上就往0xF的高位进1,变成0x1F,而原位F归0,成为0x10,也就是说,10进制的0-9和16进制的0-9还是相等的,往后10对应0xA,11对应0xB,……16对应0x10。

    至于如何转换,windows自带的计算器就可以,不过要用科学型的,从菜单项“查看”->“科学型”就OK了,转换公式懒得说了,网上有,想要的自己查吧(主要是我也半桶水,平时都是用计算器转换的)。

    然后说一下内存。游戏运行的时候,系统会为游戏程序分配4G的内存空间,然后游戏中的数据像是HP,MP什么的都是在这内存空间里面。搜索的时候就是游戏修改器扫描这些内存(其实修改器只是扫描了一部分,不过暂时和我们没关系)。游戏中的人物参数像HP,MP,攻,防什么的往往是在一个数据结构里面,也就是说,当我们找到其中一个的时候,其他的可能就在附近了。所以我们要学习如何内存修改,这样有的时候就不用每一个参数都要搜索一次了;另外有的游戏部分数据不那么好找,我们可以通过搜索其他的数据,然后顺藤摸瓜在内存附近说不定有我们想要的那个数据。

    还有就是,很重要的一点,内存修改一定要注意数据在内存中的排列顺序。下面结合例子讲一讲。比如在地址0x410000处是HP,数值是1000吧,拿出计算器按一下,得到它对应的16进制数值为0x3E8,作为四字节的时候就是0x000003E8,那么在地址0x410000处的排列顺序是:E8 03 00 00。所以如果想把数值改高点,改哪一位最大呢?答案是00左边那一位。

    但是实际上,未必真的会这么排列。这个牵扯到编程的问题,这里不说那么深,讲讲表面的道理。上一段提到的“16进制数值为0x3E8,作为四字节的时候就是0x000003E8”,句中有个词叫“四字节”,就是指在16进制表示下,00是一个字节00是一个字节03是一个字节E8是一个字节,一共四个。但是有的时候,上帝(其实是游戏制作者)觉得你的HP没必要再高了,给你的这1000点就够了,不可能会让你再多了。那么看看HP处的数据排列顺序:E8 03 00 00,有效字节只有E8和03,而00和00则是浪费了。上帝不愿意浪费,他把MP的地址指向00这里,并且也规定不超过1000,于是现在是这样排列的:E8 03 E8 03。大家现在回忆一下,HP的数值变了吗?没有,还是1000,为什么从E8 03 00 00变成E8 03 E8 03了呢?答案已经呼之欲出了,就是在于把这个数值规定为几个字节(“规定”这个过程由上帝去做,我们所要做的事情就是找出这个数到底是几字节的)。

    为什么要罗嗦这么多呢?因为一旦我们判断错误,可能会引起数据错误甚至游戏退出!很严重的哦。假如,上帝规定,刚才那HP和MP不会超过1000,所以这样排列:E8 03 E8 03,;但是我判断错误,我认为HP只有一个字节,那么一个字节改到最大也就是0xFF了,也就是说,改完可能变成这样:FF 00 E8 03,这样的结果无伤大雅,最多就是你HP变少了被怪物日死。而另一种情况,当我误以为这是四字节的(当我是白痴啊?E8 03 E8 03对应的真实数值是0x03E803E8=65537000,我HP有那么多就发了,肯定是E8 03,0x03E8=1000才对,所以正确答案是“两个字节”),那么当我把他改成1000的时候(管你原来是不是1000,我喜欢改你管我),1000作为四字节的时候就是0x000003E8,那么改完后排列顺序是:E8 03 00 00,OH MY GOD!MP变成0了!这些都是小意思,当某个重要数据被覆盖的时候,你就等着跳出游戏吧。所以大家记住,一定要研究清楚数据占用的字节数,宁可算少不可算多!




    如上图,当“长度”选为“四字节”的时候,“范围”显示“0-4294967295”,这是10进制表示的,如果换成16进制则是 0xFF FF FF FF。当你在“数值”中输入超过“范围”时,并且下面的“修改超出范围时警告”的对勾也勾上了,那么游侠会警告你,超过了还要改吗?如果你对自己的判断有把握的话,不用理会这个警告,改之;如果没有把握,那么还是仔细想想好了。

    上一篇:游戏修改(二)——工具

    下一篇:游戏修改(四)——搜索的艺术

    日志标题:游戏修改(四)——搜索的艺术
    发表时间:2005-7-7 14:17:55
     
    今天讲讲游戏修改中搜索的技巧。

    前面讲过,搜索最基本的就是搜索,数据变化,再搜索,这是搜索的本质,万变不离其宗。下面的要讲的技巧,就是以这个本质为基础,发扬青出于蓝而胜于蓝的精神,结合我多年的修改经验总结而成的。没有这些技巧会怎么样?轻者搜索效率过低,重者搜索不到正确结果。不是危言耸听,这是多年的惨烈修改让我得出的结论。

    下面就以windows自带的计算器为例子进行讲解,最后要达到的目标如图:



    不要鄙视,不要说这不是游戏修改,游戏修改的最高境界就是:无所不改!

    从图中可以看出,我们的入口处可以有两个:一是内部的数据,修改内部数据之后由计算器自己刷新到结果框;另一个就是修改刷新后的数据。假如这是游戏,要把HP从1改成100。使用第一种,结果是内部数据HP的确变成了100但是显示出来的时候我们看到的仍然是1,因为没有刷新,这时候可以找个怪砍你一下,就刷新出来了;而使用第二种呢,我们看到的是100了,但是实际上还是1,这时怪物砍你一下你就死了。所以在游戏中,我们一般是两者都改的。但是这里不是游戏,我选择第二种,有兴趣的可以试试第一种。

    这里要说明的一点是,计算器输出的是字符而不是数字,比如我们按下5的时候,计算器内部得到一个数字5,而显示给我们看的时候是字符‘5’,再按下6,计算器内部更新为数字56,再显示给我们字符串“56”。说这个的意思是,我们要搜索的应该是字符而不是数字。这些字符在内存中是怎么存放的呢?靠的是他们对应的二进制数,字符‘0’,‘1’。。。‘9’对应的就是0x30,0x31。。。0x39,相应的10进制数是48,49。。。57。好了,不明白不要紧,本章重点不在这里。

    好了开始了!看图:



    输入9,搜索的是字符‘9’,也就是0x39,换成10进制为57搜索也一样,金山游侠支持16进制数的输入,所以可以直接搜0x39。下个图:



    剩下两个结果,试试就知道,第二个是正确的。进内存看看是怎么排列的:



    可以看出来,每个数字对应两个字节,最后那个00 00是结束符。我们要做的就是把内存改成这样并加以锁定(锁定是必须的,要不然看不到效果就被刷掉了):



    然后回到计算器,按几下,是不是已经锁定了?上面的made。。。对应的数值可以去网上查,简单的方法就是直接在右边输入。

    上面的图示是最普通的方法,下面开始讲技巧型的方法。

    一。既然知道了内存中的排列方法,那么可以这样:



    在计算器上按下3465(随意的,不要是1234就好,有规律的组合可能会和计算器内部数据相同),我们可以猜到,内存中应该是这样排列的:33 00 34 00 36 00 35 00,所以我们输入“0x33,0,0x34,0,0x36,0,0x35,0”(或者搜索“51,0,52,0,54,0,53,0”),注意要把图中的“数据对齐”选成“单字节”,因为我们是一个字节一个字节算的。上图是一次搜索的结果,只有3个。如果把“数据对齐”选成“双字节”,内存排列相当于:33 00 34 00 36 00 35 00,那么就应该输入“0x0033,0x0034,0x0036,0x0035”(或者搜索“51,52,54,53”)进行搜索;如果把“数据对齐”选成“四字节”,内存排列相当于:33 00 34 00 36 00 35 00,那么就应该输入“0x00340033,0x00350036”(或者搜索“3407923,3473462”)进行搜索。事实上,上面的内存排列并没有变化,变的只是我们看待他的方法而已。

    而在上面对“made by yes2”的内存进行锁定的时候,这种看法依然有效:





    一次锁定4个字节,相比一次锁定一个字节能省多大事?自己研究吧。其实本质是一样的,不过有的时候用起来确实有优劣之分。

    上一篇:游戏修改(三)——基础

    下一篇:游戏修改(五)——修改器的制作
    顶端 Posted: 2006-06-21 12:36 | 马来西亚电信 1 楼
    游戏之王
    级别: *


    精华: *
    发帖: *
    威望: * 点
    金钱: * 胜利币
    贡献值: * 点
    在线时间:(小时)
    注册时间:*
    最后登录:*

     

    日志标题:游戏修改(五)——修改器的制作-MFC篇
    发表时间:2005-7-20 18:00:56
     
    最近有活干,没什么时间更新,今天终于忙完了,抽空写点东西吧。

    今天讲讲修改器是怎样练成的。其实很简单啦,就是几个API的调用罢了,它的灵魂还是搜索到的地址。下面就以上次的计算器锁定为一直显示“yes2”来演示,环境为VC6+MFC。

    先讲一下流程。一:搜索地址,已经在上一篇完成了;二:建立修改器的工程,照下面的图,建立一个工程以及摆好修改器的外壳;

    1`新建,MFC程序;



    2`选择dialog based,意思是生成的程序是个对话框;



    3`默认,不用改;



    4`选择as a statically linked library,意思是不需要MFC环境也可以运行(大概吧),然后点‘完成’;



    5`开始摆控件了,把默认的这三个控件删除:选中,按delete键。



    6`放一个自己的按钮空间上去,选中,按‘回车键’看它的属性,IDC_aButton是它的标识,可以更改。“有个按钮”是按钮的文本,会显示出来,也可以更改;




    7`改好之后,双击该按钮,出现下面的对话框,不用改,直接点“OK”就可以了。



    8`这时候就进入代码编辑界面了,不给图了。下面就是“有个按钮”的响应函数:

    void CTestDlg::OnaButton()
    {
    // TODO: Add your control notification handler code here
    //这是双击按钮之后的样子,一会的代码就写在这两个大括号之间;
    }


    三:开始添加代码。我们的目标是锁定内存,但是所谓的锁定,大部分是靠短时间内不断修改内存来实现的,我们就用这种简单的方法——定时器。而修改内存的动作就在定时器的响应函数里面,所以“有个按钮”的响应函数中所需要做的就是设置一个定时器。

    1`下面给“有个按钮”的响应函数添加设置定时器的代码:

    void CTestDlg::OnaButton()
    {
    // TODO: Add your control notification handler code here
    SetTimer(1 , 55 , NULL);
    }
    就是这一句,SetTimer是一个函数,用来设置一个定时器;括号里面的是这个函数的参数,1表示这次设置的定时器标号为1,当我们设置多个定时器的时候就用这个进行区分了;55表示每隔55毫秒进行一次响应,就是说定时器的响应函数会55毫秒执行一次,理论上来说;NULL表示我们不自己写响应函数,使用MFC提供的,自己写比较麻烦,所以还是用现成的吧。

    2`添加定时器的响应函数。上面提到,我们使用MFC提供的,下面就进行添加操作:

    按“Ctrl+W”打开ClassWizard,在messages中找到WM_TIMER,双击;下面的member functions中就会出现“OnTimer   ON_WM_TIMER”:



    3`在“OnTimer   ON_WM_TIMER”上双击,进入编辑界面,下面就是定时器的响应函数了:

    void CTestDlg::OnTimer(UINT nIDEvent)
    {
    // TODO: Add your message handler code here and/or call default
    //在这里加入代码;
    CDialog::OnTimer(nIDEvent);
    }

    4`添加代码。前面讲到,我们这次的“锁定”其实是短时间内不断的写入内存,于是我们需要知道写内存的函数:

    WriteProcessMemory(HANDLE hProcess , LPVOID lpBaseAddress , LPVOID lpBuffer , DWORD nSize , LPDWORD lpNumberOfBytesWritten);

    第一个参数是目标程序的进程句柄,放后面讲;第二个参数是我们要修改的地址,可以定义一个变量 DWORD dwAdr = 0x1014E84(上一篇教程得到的),第三个参数是一个指针,指向的数据就是我们要求锁定的结果,可以定义一个数组 BYTE sWrite[26] = {0x6D,0, 0x61,0, 0x64,0, 0x65,0, 0x20,0, 0x62,0, 0x79,0, 0x20,0, 0x79,0, 0x65,0, 0x73,0, 0x32,0, 0,0};,第四个参数是要求修改的字节,数数看,是26个,可以定义一个变量DWORD dwSize = 26;,最后一个参数用来接收实际写入的字节数,可以不要,设置为NULL,最后这个函数就是这个样子: WriteProcessMemory(hProc , (LPVOID)dwAdr , (LPVOID)sWrite , dwSize , NULL);

    下面来研究第一个参数,hProc是我们定义的变量,类型是HANDLE,作为目标程序的进程句柄,怎么得到呢?可以先通过 FindWindow 得到目标程序的窗口句柄,该窗口句柄作为参数执行 GetWindowThreadProcessId 函数得到进程ID,把进程ID作为参数执行 OpenProcess 函数,返回值就是我们所要的进程句柄。下面看代码:

    HWND hCalc = ::FindWindow("SciCalc" , "计算器");
    DWORD pID;
    GetWindowThreadProcessId(hCalc , &pID);
    HANDLE hProc = OpenProcess(PROCESS_ALL_ACCESS | PROCESS_VM_OPERATION | PROCESS_VM_READ | PROCESS_VM_WRITE , FALSE , pID);

    讲讲上面三个函数。首先,::FindWindow("SciCalc" , "计算器");,第一个参数是目标程序的窗口类,第二个参数是目标程序的窗口标题,可以用VC的spy++察看。看图:





    返回值就是计算器的窗口句柄了,存到hCalc中;GetWindowThreadProcessId(hCalc , &pID);,第一个参数就是计算器的窗口句柄了,第二个参数,在pID的前面加个‘&’符号表示pID的地址,这个函数得到pID的地址是用来把进程ID储存到pID中;HANDLE hProc = OpenProcess(PROCESS_ALL_ACCESS | PROCESS_VM_OPERATION | PROCESS_VM_READ | PROCESS_VM_WRITE , FALSE , pID);,第一个参数是打开这个进程,我们要求得到什么权限,“PROCESS_ALL_ACCESS | PROCESS_VM_OPERATION | PROCESS_VM_READ | PROCESS_VM_WRITE”表示读写权限我们都要,第二个参数似乎是问我们,当我们得到进程句柄之后要不要给子进程继承,我们用不到,使用FALSE,第三个参数就是进程ID了,上个函数得到的,就是这里要用。返回值就是进程句柄,OK了。

    基本上就是这样了,看完成的代码:

    void CTestDlg::OnTimer(UINT nIDEvent)
    {
    // TODO: Add your message handler code here and/or call default
    DWORD dwAdr = 0x001014E84;
    DWORD dwSize = 26;
    BYTE sWrite[26] = {0x6D,0, 0x61,0, 0x64,0, 0x65,0, 0x20,0, 0x62,0, 0x79,0, 0x20,0, 0x79,0, 0x65,0, 0x73,0, 0x32,0, 0,0};
    HWND hCalc = ::FindWindow("SciCalc" , "计算器");
    DWORD pID;
    GetWindowThreadProcessId(hCalc , &pID);
    HANDLE hProc = OpenProcess(PROCESS_ALL_ACCESS | PROCESS_VM_OPERATION | PROCESS_VM_READ | PROCESS_VM_WRITE , FALSE , pID);
    WriteProcessMemory(hProc , (LPVOID)dwAdr , (LPVOID)sWrite , dwSize , NULL);
    CDialog::OnTimer(nIDEvent);
    }

    这样的代码并不是很好,虽然他在正常情况下可以使用,但是还是有必要进行一些修改的,比如出错处理,效率问题之类的。修改后的代码在文章结尾提供下载。

    编译执行按“Ctrl+F5”,可以先选择编译版本再进行编译,下图为如何选择编译版本:


    debug版本是调试用的,release版本是发行用的,一般来说如果做好修改器了要给别人用的话都是编译成release版本的。操作就是:选择“test - Win32 Release”点“OK”,然后按“Ctrl+F5”进行编译,生成的文件就在 \test\release\文件夹里面。


    源代码下载

    上一篇:游戏修改(四)——搜索的艺术

    下一篇:游戏修改(六)——修改器的制作-SDK篇
    顶端 Posted: 2006-06-21 12:42 | 马来西亚电信 2 楼
    游戏之王
    级别: *


    精华: *
    发帖: *
    威望: * 点
    金钱: * 胜利币
    贡献值: * 点
    在线时间:(小时)
    注册时间:*
    最后登录:*

     

    日志标题:游戏修改(六)——修改器的制作-SDK篇
    发表时间:2005-7-25 17:02:52

    如果MFC用习惯的话,还是很方便的,但是可能会让你觉得很多时候不知道代码往哪里写,或者是写这些代码是什么意思。今天讲的还是制作上次那个修改器,不过这次是使用SDK+API,条理比较清晰。好,开始了!

    新建工程:



    这次建立的“Win32 Application”,下一步:



    选择“A simple Win32 application”,点“Finish”完成。



    再次新建,建立“Resource Script”,名字随便起都行,这里起个名字叫rc,那么会生成一个rc.rc的文件(看这挺别扭的,早知道换一个名字了)。




    双击生成的rc.rc文件,右边窗口出现一个像文件夹一样的东西,右键单击,选择“Insert...”,出现一个对话框:



    双击“Dialog”建立一个对话框,该对话框按照上一篇教程的方法生成“有个按钮”。这时候对话框看着不太好看,改一下对话框的属性:



    在对话框的空白处单击右键,选择“Properties”,出现一个属性对话框,选择“Font...”可以选择字体,我改成“宋体”10号字。下面该把新建的对话框资源文件添加进来了:



    照上图把新生成的resource.h文件加入。下面开始进行代码编辑了。

    双击test2.cpp,进入编辑状态,该文件所有代码就是这么几句:
    #include "stdafx.h"

    int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
    {
    // TODO: Place code here.

    return 0;
    }
    加上一行#include "resource.h",就把刚才做的对话框加进来了,不加的话刚才的努力就相当于没有了-_-~~~
    #include "stdafx.h"
    #include "resource.h"

    int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
    {
    // TODO: Place code here.

    return 0;
    }
    要把刚才建立的对话框显示出来,需要使用函数DialogBoxParam(HINSTANCE hInstance , LPCTSTR lpTemplateName , HWND hWndParent , DLGPROC lpDialogFunc , LPARAM dwInitParam),该函数用来生成模态对话框。第一个参数HINSTANCE hInstance,直接使用WinMain函数的第一个参数即可;第二个参数LPCTSTR lpTemplateName,使用MAKEINTRESOURCE(IDD_DIALOG1),IDD_DIALOG1就是刚才建立的对话框的ID,MAKEINTRESOURCE()是一个宏,作用似乎是把资源ID转为某个整数值;第三个参数HWND hWndParent,是指生成对话框的父窗口,我们直接使用对话框,所以不存在父窗口,使用NULL;第四个参数DLGPROC lpDialogFunc,是对话框处理函数,没有这个函数的话对话框出来之后就会像个煞笔。一会再写这个函数的代码,先起个名字吧,就叫DlgProc,那么这里就使用DlgProc;第五个参数LPARAM dwInitParam,对话框初始化的时候传递给它的参数,我们没有这方面的需求,使用0就好了。于是现在代码是:
    #include "stdafx.h"
    #include "resource.h"

    int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
    {
    // TODO: Place code here.
    DialogBoxParam(hInstance , MAKEINTRESOURCE(IDD_DIALOG1) , NULL , DlgProc , 0);
    return 0;
    }
    下面就要写对话框处理函数DlgProc了,查MSDN可以看到对话框处理函数的规范,下面就是函数的骨架:
    BOOL CALLBACK DlgProc(HWND hWnd , UINT uMsg , WPARAM wParam , LPARAM lParam)
    {
    switch (uMsg)
    {
    case WM_XXX:
    xxx...
    break; //记得要写break;

    default:
    return FALSE; //不做处理的返回FALSE
    }
    return TRUE; //自己处理的消息break之后返回TRUE
    }
    这个函数处理系统发过来的消息。当我们按下“有个按钮”的时候,函数会收到一条消息WM_COMMAND,然后wParam的低16位存放的就是按钮的ID,所以加入这条判断:
    case WM_COMMAND:
    if(LOWORD(wParam) == IDC_aButton)
    {
      /*条件成立的话说明按下了“有个按钮”,
      把上个程序中的响应代码抄过来就是了*/
      HWND hCalc = FindWindow("SciCalc" , "计算器");
      if(!hCalc)
      {
      MessageBox(hWnd , "目标程序没有运行" , "错误" , MB_OK);
      break;
      }
      DWORD pID;
      GetWindowThreadProcessId(hCalc , &pID);
      hProc = OpenProcess(PROCESS_ALL_ACCESS | PROCESS_VM_OPERATION | PROCESS_VM_READ | PROCESS_VM_WRITE , FALSE , pID);
      if(!hProc)
      {
      MessageBox(hWnd , "打开目标程序出错" , "错误" , MB_OK);
      break;
      }
      SetTimer(hWnd , 1 , 55 , NULL);
    }
    break;
    这里使用的FindWindow前面没有::了,因为这里不使用MFC,所以不会和MFC提供的函数混淆,所以就不用加::来区分;而MessageBox的参数则变多了,这是因为上一次用的是MFC提供的对话框类中的成员函数,现在使用的是API函数,只是函数名字相同而已;同样,SetTimer和下文的KillTimer也是这个道理,多了一个参数,使用DlgProc的第一个参数即可。
    由于不使用MFC,所以SetTimer的响应也是要我们自己干了。SetTimer设置定时器之后,系统会在时间间隔之后发送一个WM_TIMER消息,我们需要处理,所以加一个分支:
    case WM_TIMER:
    if(!FindWindow("SciCalc" , "计算器"))
    {
      KillTimer(hWnd , 1);
      MessageBox(hWnd , "目标程序已关闭" , "错误" , MB_OK);
    }
    WriteProcessMemory(hProc , (LPVOID)dwAdr , (LPVOID)sWrite , dwSize , NULL);
    break;
    还要处理窗口关闭消息,又加一个分支:
    case WM_CLOSE:
    EndDialog(hWnd , 0);
    break;
    还要记得在WinMain函数之前写上全局变量的声明和对话框处理函数的声明,完成后如下(“。。。”表示省略详细代码):
    HANDLE hProc = NULL;
    DWORD dwAdr = 0x001014E84;
    DWORD dwSize = 26;
    BYTE sWrite[26] = {0x6D,0,0x61,0,0x64,0,0x65,0,0x20,0,0x62,0,0x79,0,0x20,0,0x79,0,0x65,0,0x73,0,0x32,0,0,0};

    BOOL CALLBACK DlgProc(HWND hWnd , UINT uMsg , WPARAM wParam , LPARAM lParam);

    int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
    {
    。。。
    }
    BOOL CALLBACK DlgProc(HWND hWnd , UINT uMsg , WPARAM wParam , LPARAM lParam)
    {
    。。。
    }
    编译执行,看看效果~

    源代码下载
    上一篇:游戏修改(五)——修改器的制作-MFC篇

    下一篇:未完成
    顶端 Posted: 2006-06-21 12:46 | 马来西亚电信 3 楼
    yes2
    级别: 善男信女


    精华: 4
    发帖: 110
    威望: 16 点
    金钱: 1366 胜利币
    贡献值: 0 点
    在线时间:53(小时)
    注册时间:2006-04-05
    最后登录:2008-12-30

     

    多谢帮忙~辛苦你了,致敬~
    顶端 Posted: 2006-06-21 12:52 | 4 楼
    xlb@+3000
    级别: 胜利星级会员


    精华: 2
    发帖: 5032
    威望: 126 点
    金钱: 4412 胜利币
    贡献值: 68 点
    在线时间:1487(小时)
    注册时间:2004-08-21
    最后登录:2008-11-10

     

    PC改区以开,以后可去那发,我帮你转过去

    顶端 Posted: 2006-06-21 12:54 | 5 楼
    yes2
    级别: 善男信女


    精华: 4
    发帖: 110
    威望: 16 点
    金钱: 1366 胜利币
    贡献值: 0 点
    在线时间:53(小时)
    注册时间:2006-04-05
    最后登录:2008-12-30

     

    徒弟=。=
    没想过,如果有人想交流经验的话可以来论坛或者进QQ群,这种方式比收徒弟好多了,一来算是师傅多,二来也可以集各家之长
    顶端 Posted: 2006-06-21 16:19 | 6 楼
    woyaoxiugai
    级别: 初入江湖


    精华: 0
    发帖: 6
    威望: 1 点
    金钱: -2 胜利币
    贡献值: 0 点
    在线时间:0(小时)
    注册时间:2006-07-07
    最后登录:2006-07-08

     

    偶菜鸟,之前的能看懂,后面的就抓瞎了!
    顶端 Posted: 2006-07-07 12:34 | 7 楼
    liudi129
    级别: 家徒四壁


    精华: 0
    发帖: 28
    威望: 1 点
    金钱: -2 胜利币
    贡献值: 0 点
    在线时间:10(小时)
    注册时间:2005-06-23
    最后登录:2007-10-25

     

    强人强人!!
    顶端 Posted: 2007-10-13 10:47 | 8 楼
    fengyunz
    级别: 家徒四壁


    精华: 0
    发帖: 5
    威望: 1 点
    金钱: 5 胜利币
    贡献值: 0 点
    在线时间:5(小时)
    注册时间:2007-10-17
    最后登录:2008-09-27

     

    我用汇编写了一个小的修改器,不过进入战斗的时候一调用WriteProcessMemory就会跳菜c0000005非法操作,然后就退出去了。估计是和原来的代码有访问冲突,比较头疼,有没有好的办法可以解决啊
    顶端 Posted: 2007-10-17 23:20 | 9 楼
    « 1 2» Pages: ( 1/2 total )
    帖子浏览记录 版块浏览记录
    胜利之歌超级论坛 » PC修改专区


    浙ICP备05022506号
    Total 0.133799(s) query 5, Time now is:01-09 15:31, Gzip enabled
    Powered by PHPWind v6.3.2 Certificate Code © 2003-08 PHPWind.com Corporation