发新话题
打印

[转载]记一游戏修改器的制作

[转载]记一游戏修改器的制作

文章作者: ProZel

使用工具:OllyDbg,金山游侠2002

用OD载入游戏(小提醒一下:最好打开OD后,把OD的优先级调低,再载入游戏,不然的话OD的分析时间太长了),
就会停在OEP上:
00463D30>$6A60push60;(initialcpuselection)//OD停在这里
00463D32.68F0316200pushSSS.006231F0
00463D37.E8E01A0000callSSS.0046581C
00463D3C.BF94000000movedi,94
00463D41.8BC7moveax,edi
00463D43.E878FEFFFFcallSSS.00463BC0
00463D48.8965E8movdwordptrss:[ebp-18],esp
00463D4B.8BF4movesi,esp
00463D4D.893Emovdwordptrds:[esi],edi
00463D4F.56pushesi;/pVersionInformation
00463D50.FF1578F05F00calldwordptrds:[<&KERNEL32.GetVersion>;\GetVersionExA

嗯,程序应该是没壳的,直接调试就可以了.
打开金山游戏侠后按OD的F9键,运行程序,
游戏开始后,按OD的暂停键,再用金山游侠找数字3(一开始是3条命的).
为什么要暂停游戏呢?因为此东西比较BT,呼出金山游戏侠后还不能暂停的,
我把这个情况说给我一个经常玩游戏的同学,他也说:"不是吧,这么厉害的游戏,金山游侠也停不住".
找到数字3后回到OD,继续游戏,等生命数少一次后再找,找了两次后,就找到这里了:

地址单字节双字节四字节
----------------------------------------------------------------------------------------------------
092EAD81[001][49921][3087909633]
092B119D[001][24321][1560633089]
06D6C2EC[001][00001][0000000001]
01488A88[001][21249][4244460289]
01488988[001][19457][4244458497]
01488888[001][17665][4244456705]
00CFCA50[001][00001][0000000001]

看到DWORD是1的只有两个,6D6C2EC和CFCA50,我直觉的想人物的生命值应该是个static常量,
应该是高一点的地址所以就试着更改6D6C2EC地址上面的数值,结果是成功的,可以修改生命数了,
之后在此地址上面下DWORD的ACCESS中断,继续游戏,
不到半秒后,游戏再次被断下:
0042AED7|.89742428movdwordptrss:[esp+28],esi
0042AEDB|.E8400B0300callSSS.0045BA20
0042AEE0|.E9D9010000jmpSSS.0042B0BE
0042AEE5|>399F94000000cmpdwordptrds:[edi+94],ebx;中断在此
0042AEEB|.0F8FA9000000jgSSS.0042AF9A
0042AEF1|.B9A0DE7200movecx,SSS.0072DEA0
0042AEF6|.E8858EFDFFcallSSS.00403D80
0042AEFB|.A144736A00moveax,dwordptrds:[6A7344]
0042AF00|.385841cmpbyteptrds:[eax+41],bl

即然是这里判断的,在CALL的尾改就可以
按翻页键,很快就找到此CALL的尾了:
0042B141|.8B1544736A00movedx,dwordptrds:[6A7344]
0042B147|.89B2F40C0000movdwordptrds:[edx+CF4],esi
0042B14D|.8BB794000000movesi,dwordptrds:[edi+94];第2次内存中断
0042B153|.B9A0DE7200movecx,SSS.0072DEA0
0042B158|.E8238CFDFFcallSSS.00403D80
0042B15D|.A144736A00moveax,dwordptrds:[6A7344]
0042B162|.89B0F80C0000movdwordptrds:[eax+CF8],esi
0042B168|.8BBF8C000000movedi,dwordptrds:[edi+8C]
0042B16E|.B9A0DE7200movecx,SSS.0072DEA0
0042B173|.E8088CFDFFcallSSS.00403D80
0042B178|.8B0D44736A00movecx,dwordptrds:[6A7344]
0042B17E|.89B9FC0C0000movdwordptrds:[ecx+CFC],edi
0042B184|.8B4C2420movecx,dwordptrss:[esp+20]
0042B188|.5Fpopedi
0042B189|.5Epopesi
0042B18A|.5Dpopebp
0042B18B|.64:890D00000>movdwordptrfs:[0],ecx
0042B192|.5Bpopebx
0042B193|.83C41Caddesp,1C
0042B196\.C3retn
0042B197CCint3
0042B198CCint3
0042B199CCint3
0042B19ACCint3
0042B19BCCint3
在42B14D断下后,寄存器的值是:
EAX00CFBD60
ECX059DFD18
EDX00CFBD60
EBX00000000
ESP059DFCF8
EBP0043FB10SSS.0043FB10
ESI00000000
EDI06D6B0A8
EIP0042B14DSSS.0042B14D

EDI是6D6B0A8,习惯性的看了一下堆栈:
059DFCF8059EA48C
059DFCFC06D6B0A8
059DFD000043FB10SSS.0043FB10
059DFD04059DFD68
059DFD0877FB7E64ntdll.77FB7E64
059DFD0C004784AARETURNtoSSS.004784AAfromntdll.RtlLeaveCriticalSection
059DFD1000CFBB14

[ESP+4]=EDI,一个很有利用价值的情报:D

按F8单步运行到42B188处,EDI已经被清0了,可是堆栈依然没变,
可以用堆栈的这个地址来改内存了:)
已经没有空间写代码了,所以直接往下跳,找到程序尾的空白处:
0042B188/E9C3331D00jmpSSS.005FE550
0042B18D|90nop
0042B18E|90nop
0042B18F|90nop
0042B190|90nop
0042B191|90nop
二进制码是E9C3331D009090909090

005FE54500db00
005FE54600db00;保存生命数
005FE54700db00
005FE54800db00;保存Level级数
005FE54900db00
005FE54A00db00
005FE54B00db00
005FE54C00db00
005FE54D00db00
005FE54E00db00
005FE54F00db00
005FE55060pushad;保存现场
005FE5519Cpushfd;保存现场
005FE5528B7C2428movedi,dwordptrss:[esp+28];把这个EDI=[ESP+4]的值取出,要注意PUSHAD和PUSHFD后堆栈的值
005FE55633C0xoreax,eax;EAX清0
005FE55833DBxorebx,ebx;EBX清0
005FE55AA046E55F00moval,byteptrds:[5FE546];生命数放入AL,要注意的是前面的EAX已经清0了
005FE55F8A1D48E55F00movbl,byteptrds:[5FE548];Level级数放入BL,要注意前面的EBX已经清0了
005FE56585FFtestedi,edi;测试EDI指针是否为空
005FE567740CjeshortSSS.005FE575;是空指针就不处理,跳走
005FE569898794000000movdwordptrds:[edi+94],eax;更改生命值
005FE56F899F80000000movdwordptrds:[edi+80],ebx;更改Level级数
005FE5759Dpopfd;恢复现场
005FE57661popad;恢复现场
005FE5775Fpopedi;到下面都是原来程序的代码
005FE5785Epopesi
005FE5795Dpopebp
005FE57A64:890D00000>movdwordptrfs:[0],ecx
005FE5815Bpopebx
005FE58283C41Caddesp,1C
005FE585C3retn
005FE58600db00
005FE58700db00

二进制码是609C8B7C242833C033DBA046E55F008A1D48E55F0085FF740C89879400000089
9F800000009D615F5E5D64890D000000005B83C41CC3

测试了一下,OK,成功;
这一次有别与上次,上一次修改类似游戏的方法是改EXE文件,
这一次就做个外挂吧,现在流行外挂:D
外挂的原理也不难,可以通过寻找窗口名的方法来找到游戏窗口,
再用GetWindowThreadProcessID()得到进程的ID,接着用OpenProcess()
打开进程,最后用WriteProcessMemory()改写内存数值就行了
这几个API最容易出错的是WriteProcessMemory()了,所以大家小心点:)

//定义一下要修改的内容
BYTEmem1[10]={0xE9,0xBF,0x33,0x1D,0x00,0x90,0x90,0x90,0x90,0x90};//0042B188
BYTEmem2[54]={0x60,0x9C,0x8B,0x7C,0x24,0x28,0x33,0xC0,0x33,0xDB,0xA0,
0x46,0xE5,0x5F,0x00,0x8A,0x1D,0x48,0xE5,0x5F,0x00,0x85,
0xFF,0x74,0x0C,0x89,0x87,0x94,0x00,0x00,0x00,0x89,0x9F,
0x80,0x00,0x00,0x00,0x9D,0x61,0x5F,0x5E,0x5D,0x64,0x89,
0x0D,0x00,0x00,0x00,0x00,0x5B,0x83,0xC4,0x1C,0xC3
};//005FE550

HWNDhWinWnd,hWinWnd1=0,hWinWnd2=0;
DWORDDWinProcID,DMemWrite1=0,DMemWrite2=0;
DWORDDaddr1=0x42B188,Daddr2=0x5FE550,DMemRead;
DWORDDKey[5]={0x4570AE,0x4570BF,0x4570D1,0x4570E2,0x4570F4};//更改键位,下面会说到的

hWinWnd1=::FindWindow(NULL,CSWinTitleJP);//分两种标题
hWinWnd2=::FindWindow(NULL,CSWinTitleCN);
if((hWinWnd1==NULL)&&(hWinWnd2==NULL))//如果两个标题都没有发现
{
MessageBox("无法找到窗口,游戏是否打开中?",NULL,MB_OK|MB_ICONSTOP);
PostQuitMessage(0);
}
else
{
hWinWnd1==NULL?hWinWnd=hWinWnd2:hWinWnd=hWinWnd1;//把不为NULL的标题赋与hWinWnd
GetWindowThreadProcessId(hWinWnd,&DWinProcID);//得到进程ID
hPrc=OpenProcess(PROCESS_ALL_ACCESS,FALSE,DWinProcID);//打开进程,注意要用PROCESS_ALL_ACCESS,不然的话有些内存区域不可改写的
if(hWinWnd!=NULL)::SetWindowText(hWinWnd,CSWinTitleCN);//更改窗口标题,后来加上去的

if(hPrc!=NULL)//如果打开进程成功的话就改写内存
{
WriteProcessMemory(hPrc,(void*)Daddr1,mem1,10,&DMemWrite1);
WriteProcessMemory(hPrc,(void*)Daddr2,mem2,54,&DMemWrite2);
//BYTEKey[5];//left,right,up,down,fire

WriteProcessMemory(hPrc,(void*)DKey[0],&left,1,&DMemRead);//这是更改键位的,下面会说到
WriteProcessMemory(hPrc,(void*)DKey[1],&right,1,&DMemRead);
WriteProcessMemory(hPrc,(void*)DKey[2],&up,1,&DMemRead);
WriteProcessMemory(hPrc,(void*)DKey[3],&down,1,&DMemRead);
WriteProcessMemory(hPrc,(void*)DKey[4],&fire,1,&DMemRead);
ShowKey();//显示按键
if(DMemWrite1!=10||DMemWrite2!=54)//看写入内存数据的SIZE对不对
{
MessageBox("写入内存出错",NULL,MB_OK|MB_ICONSTOP);
}
}
else
{
MessageBox("打开进程出错",NULL,MB_OK|MB_ICONSTOP);
PostQuitMessage(0);
}
}

改写生命数与Level数:
005FE55AA046E55F00moval,byteptrds:[5FE546];生命数放入AL,要注意的是前面的EAX已经清0了
005FE55F8A1D48E55F00movbl,byteptrds:[5FE548];Level级数放入BL,要注意前面的EBX已经清0了
生命数与Level数都放在这两个BYTE空间上面,更改的话改这两个地址就行了:
BOOLCSSSEditorDlg::Write(UINTiLife,UINTiLevel)
{
DWORDDadd1=0x5FE546,Dadd2=0x5FE548;
DWORDDMemWrite1=0,DMemWrite2=0;

WriteProcessMemory(hPrc,(void*)Dadd1,&iLife,1,&DMemWrite1);
WriteProcessMemory(hPrc,(void*)Dadd2,&iLevel,1,&DMemWrite2);

if(DMemWrite1!=1||DMemWrite2!=1)
{
returnFALSE;
}
elsereturnTRUE;

}

///////////////////////////////////////////////////////////////////////////////////
OK,生命数与Level数的更改都已完成了

第2个是解决键位不顺手的问题.
这个游戏比较BT,方向键是键盘的上下左右,shot键是空格,
这对于大部分国内游戏玩家来说是非常的不顺手,国内的玩家
习惯了ASDWJKL;这种键位,看来有必要改一下.
先来说OD的一个弱点,如下面的:
00444333.48deceax;Switch(cases1..2)
00444334.7448jeshortSSS.0044437E
00444336.48deceax
00444337.0F851F010000jnzSSS.0044445C
0044433D.8B462Cmoveax,dwordptrds:[esi+2C];Case2ofswitch00444333

没有办法找Switch(cases1..2)之类的注释,无奈,(很希望OD2.0会加入这样的注释搜寻功能)
全部导出代码后打开(千万不要想用Noteped打开,导出来的东西有27MB,我用EmEditor打开).
静下来想想后,发现如果是要判断按键的话应该用到虚拟键盘影射,如VK_LEFT之类的,
就在EM里面找VK_结果找到下面的:

004570AD|.6A25push25;/Key=VK_LEFT
004570AF|.FFD5callebp;\GetAsyncKeyState
004570B1|.84E4testah,ah
004570B3|.7909jnsshortSSS.004570BE
004570B5|.C74624FFFFF>movdwordptrds:[esi+24],-1
004570BC|.EB0FjmpshortSSS.004570CD
004570BE|>6A27push27
004570C0|.FFD5callebp
004570C2|.84E4testah,ah
004570C4|.790AjnsshortSSS.004570D0
004570C6|.C7462401000>movdwordptrds:[esi+24],1
004570CD|>897E08movdwordptrds:[esi+8],edi
004570D0|>6A26push26
004570D2|.FFD5callebp
004570D4|.84E4testah,ah
004570D6|.7909jnsshortSSS.004570E1
004570D8|.C74628FFFFF>movdwordptrds:[esi+28],-1
004570DF|.EB0FjmpshortSSS.004570F0
004570E1|>6A28push28
004570E3|.FFD5callebp
004570E5|.84E4testah,ah
004570E7|.790AjnsshortSSS.004570F3
004570E9|.C7462801000>movdwordptrds:[esi+28],1
004570F0|>897E08movdwordptrds:[esi+8],edi
004570F3|>6A20push20
004570F5|.FFD5callebp
004570F7|.84E4testah,ah
004570F9|.790BjnsshortSSS.00457106
004570FB|.8B462Cmoveax,dwordptrds:[esi+2C]
004570FE|.C644303001movbyteptrds:[eax+esi+30],1
00457103|.897E08movdwordptrds:[esi+8],edi
00457106|>6A0Dpush0D
00457108|.FFD5callebp
0045710A|.84E4testah,ah
0045710C|.790BjnsshortSSS.00457119

键盘影射表....到哪找啊,在GOOGLE找上半天没发现..郁闷,是不是我的寻找方法有问题啊...
在VisualStudio的H文件里面找吧..
一般常用的东西都是在winuser.h里面,就在这里面找吧,寻找以后发现这些:

/*
*VirtualKeys,StandardSet
*/
#defineVK_LBUTTON0x01
#defineVK_RBUTTON0x02
#defineVK_CANCEL0x03
#defineVK_MBUTTON0x04/*NOTcontiguouswithL&RBUTTON*/

#defineVK_BACK0x08
#defineVK_TAB0x09

#defineVK_CLEAR0x0C
#defineVK_RETURN0x0D

#defineVK_SHIFT0x10
#defineVK_CONTROL0x11
#defineVK_MENU0x12
#defineVK_PAUSE0x13
#defineVK_CAPITAL0x14

#defineVK_KANA0x15
#defineVK_HANGEUL0x15/*oldname-shouldbehereforcompatibility*/
#defineVK_HANGUL0x15
#defineVK_JUNJA0x17
#defineVK_FINAL0x18
#defineVK_HANJA0x19
#defineVK_KANJI0x19

#defineVK_ESCAPE0x1B

#defineVK_CONVERT0x1C
#defineVK_NONCONVERT0x1D
#defineVK_ACCEPT0x1E
#defineVK_MODECHANGE0x1F

#defineVK_SPACE0x20
#defineVK_PRIOR0x21
#defineVK_NEXT0x22
#defineVK_END0x23
#defineVK_HOME0x24
#defineVK_LEFT0x25
#defineVK_UP0x26
#defineVK_RIGHT0x27
#defineVK_DOWN0x28
#defineVK_SELECT0x29
#defineVK_PRINT0x2A
#defineVK_EXECUTE0x2B
#defineVK_SNAPSHOT0x2C
#defineVK_INSERT0x2D
#defineVK_DELETE0x2E
#defineVK_HELP0x2F

/*VK_0thruVK_9arethesameasASCII'0'thru'9'(0x30-0x39)*/
/*VK_AthruVK_ZarethesameasASCII'A'thru'Z'(0x41-0x5A)*/

#defineVK_LWIN0x5B
#defineVK_RWIN0x5C
#defineVK_APPS0x5D

不错的东西:)
004570AD|.6A25push25;/Key=VK_LEFT
004570AF|.FFD5callebp;\GetAsyncKeyState
004570B1|.84E4testah,ah
004570B3|.7909jnsshortSSS.004570BE
只要把push25改成push41('A'的ASCII码)就能把方向键左变为A了,下面的不顺手的按键同样是可以改的.
修改代码在上面已经有了,请往上看:)

3:激活隐藏人物
把该游戏放在网上给人下载玩的时候,听到有不少人抱怨说是游戏不能选用所有的人物,
我就觉得奇怪了,所有的10个人物我都能用啊,抱着试一试的心态把游戏COPY到另外一个
目录下,果然,除了第1个人物"このみ"可选的外,其它的人都是问号,且是不可选的.得想个办法解决.
想了一下子,即然游戏COPY到另一个目录下就会有人物不可全选的现象,那应该记录的地方不是在
注册表里面,不是在注册表里面,那就很有可能是在文件里面,试试下CreateFileA看看有没有什么东西可用的:
经过1个中断,断在一个很可疑的地方,此时的堆栈是:
0558FB9C0047B3B3/CALLtoCreateFileAfromSSS.0047B3AD
0558FBA00559B5D0|FileName="I:\ToHeart2XRATED\sys.sav"
0558FBA480000000|Access=GENERIC_READ
0558FBA800000001|ShareMode=FILE_SHARE_READ
0558FBAC00000000|pSecurity=NULL
0558FBB000000003|Mode=OPEN_EXISTING
0558FBB400000080|Attributes=NORMAL
0558FBB800000000\hTemplateFile=NULL

我的游戏目录明明是在i:\ToHeart2XRATED\sss\下面的,它干嘛要去上一层目录去找SAV文件啊,
按Alt+F9返回用户代码
0047B39C|>\53pushebx;/hTemplateFile
0047B39D|.6880000000push80;|Attributes=NORMAL
0047B3A2|.6A03push3;|Mode=OPEN_EXISTING
0047B3A4|.53pushebx;|pSecurity
0047B3A5|.6A01push1;|ShareMode=FILE_SHARE_READ
0047B3A7|.6800000080push80000000;|Access=GENERIC_READ
0047B3AC|.50pusheax;|FileName
0047B3AD|.FF1544F05F00calldwordptrds:[<&KERNEL32.CreateFile>;\CreateFileA
0047B3B3|.8BF8movedi,eax
0047B3B5|.83FFFFcmpedi,-1
0047B3B8|.0F8501030000jnzSSS.0047B6BF
0047B3BE|.50pusheax
0047B3BF|.53pushebx
0047B3C0|.8D4C243Cleaecx,dwordptrss:[esp+3C]

之后走出几个CALL后:
00454348|.8D4C2458leaecx,dwordptrss:[esp+58]
0045434C|.E86F740200callSSS.0047B7C0
00454351|.3BC7cmpeax,edi
00454353|.7433jeshortSSS.00454388
00454355|.8D4C243Cleaecx,dwordptrss:[esp+3C]

往下走几步后,发现这个比较可疑的:
004543B3|.8BF3movesi,ebx
004543B5|>8B44B414/moveax,dwordptrss:[esp+esi*4+14]
004543B9|.056E180000|addeax,186E
004543BE|.3BC7|cmpeax,edi
004543C0|.7325|jnbshortSSS.004543E7
004543C2|.395C8500|cmpdwordptrss:[ebp+eax*4],ebx
004543C6|.751F|jnzshortSSS.004543E7
004543C8|.85F6|testesi,esi
004543CA|.7C1B|jlshortSSS.004543E7
004543CC|.83FE0A|cmpesi,0A
004543CF|.7D16|jgeshortSSS.004543E7
004543D1|.B9A0DE7200|movecx,SSS.0072DEA0
004543D6|.E8A5F9FAFF|callSSS.00403D80
004543DB|.A144736A00|moveax,dwordptrds:[6A7344]
004543E0|.889C06210D00>|movbyteptrds:[esi+eax+D21],bl
004543E7|>46|incesi
004543E8|.83FE0A|cmpesi,0A
004543EB|.^7CC8\jlshortSSS.004543B5
004543ED|.8D4C243Cleaecx,dwordptrss:[esp+3C]

这一段有一行代码是很有可疑的
004543E8|.83FE0A|cmpesi,0A

因为人物是10个,它又刚好的循环0xA(10)次
004543C2|.395C8500|cmpdwordptrss:[ebp+eax*4],ebx
走到这一句时,EBX则为0,下面又有一个JNZ的条件跳转

004543DB|.A144736A00|moveax,dwordptrds:[6A7344]
004543E0|.889C06210D00>|movbyteptrds:[esi+eax+D21],bl
004543E7|>46|incesi;JNZ跳到这里


004543E0|.889C06210D00>|movbyteptrds:[esi+eax+D21],bl
走到这一句时,BL为1,貌似是把[esi+eax+D21]置为1,很可疑,EAX的值是个定数(上一行代码可知),
ESI就是一个人物个数的计数器,第1个人物时,ESI==1,第2个人物时,ESI==2;
把JNZ改为NOP,使它不跳,继续运行
发现这样以后人物都可以选择了,看来关键点就在这里;
可是很快又发现一个问题了,我写的是一个外挂,不是一个LOADER,所以在运行这个外挂
的时候这一句代码早就运行过了,不可能再次跳到这里运行了,
所以还得想另一种方法.
既然ESI+EAX+D21是一个static指针,那地址就应该是相对稳定的,
刚才还记录了第1个地址是0xCFCA82,直接在该地址上面下byte的断点
再次运行程序,在选择人物时程序中断在一个新的点上:
0040D8D3|.E8A864FFFFcallSSS.00403D80
0040D8D8|.A144736A00moveax,dwordptrds:[6A7344]
0040D8DD|.8A8430210D00>moval,byteptrds:[eax+esi+D21];断在这里
0040D8E4|.5Epopesi
0040D8E5|.C3retn
0040D8E6|>32C0xoral,al
0040D8E8|.5Epopesi
0040D8E9\.C3retn

retn后就是这里了:
0040FD80.8B8EBC000000movecx,dwordptrds:[esi+BC]
0040FD86.51pushecx
0040FD87.E834DBFFFFcallSSS.0040D8C0
0040FD8C.83C404addesp,4
0040FD8F.84C0testal,al
0040FD91.7507jnzshortSSS.0040FD9A
0040FD93.C7462425000>movdwordptrds:[esi+24],25
0040FD9A>8B4624moveax,dwordptrds:[esi+24]
0040FD9D.C1E004shleax,4

嗯,在40D8DD里面改就可以了;
一句老话,还要跳到空白代码上:
0040D8DD/E91E0D1F00jmpSSS.005FE600
0040D8E2|90nop
0040D8E3|90nop
0040D8E4|5Epopesi
0040D8E5|C3retn
其二进制代码是E91E0D1F009090

005FE5FF00db00
005FE600B001moval,1;AL置1
005FE602888430210D00>movbyteptrds:[eax+esi+D21],al;使人物变为可选
005FE60956pushesi;保存ESI指针
005FE60A50pusheax;保存EAX数据
005FE60BA144736A00moveax,dwordptrds:[6A7344];取得Static变量的地址
005FE61083C601addesi,1;人物指针+1
005FE613C68430210D00>movbyteptrds:[eax+esi+D21],1;激活人物
005FE61B58popeax;恢复EAX数据
005FE61C5Epopesi;恢复ESI指针
005FE61D5Epopesi;原代码
005FE61EC3retn;原代码
005FE61F00db00
其二进制代码是B001888430210D00005650A144736A0083C601C68430210D000001585E5EC3
不过这也有个缺点:在选择人物前就要更改代码了,不然的话还是没用,
不是loader真是受限制啊:(

VC中的代码:
voidCSSSEditorDlg::OnButtonactive()
{
BYTEmem[7]={0xE9,0x1E,0x0D,0x1F,0x00,0x90,0x90};
BYTEmem2[31]={0xB0,0x01,0x88,0x84,0x30,0x21,0x0D,0x00,0x00,0x56,
0x50,0xA1,0x44,0x73,0x6A,0x00,0x83,0xC6,0x01,0xC6,
0x84,0x30,0x21,0x0D,0x00,0x00,0x01,0x58,0x5E,0x5E,
0xC3
};

DWORDaddr=0x40D8DD,addr2=0x5FE600,DMemWrite;
MessageBox("在选择人物前就要激活","SSSEDitor",MB_OK|MB_ICONINFORMATION);
WriteProcessMemory(hPrc,(void*)addr,&mem,7,&DMemWrite);
WriteProcessMemory(hPrc,(void*)addr2,&mem2,31,&DMemWrite);
}

[KFC]fish(Pr0Zel)
编译好的修改器可以到这里下载:
http://www.keyfc.net/bbs/disp.asp?titleid=13592
游戏可以去MO上面下载www.mofile.com
提取码是4164151347219943
大小是19MB

BTW:有一个朋友对我说"21世纪有技术的年代,所以作弊也要选一种有技术的作弊方法",我倒.......




TOP

发新话题