本文主要是介绍一篇传奇世界写屏文章,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
作者: acfg12
看过不少游戏内挂的文章,自己也来胡乱的写点,大家不要见笑.
第一步:我们要找到传奇世界的写屏函数的地址.
聪明点的人可能已经发现了,在woool/data/woool.dat实际上是一个可执行文件,不知道的话就用OllyDbg调入woool/woool.exe分析也可以得到。
好了,把woool/data/woool.dat改名woool.exe,可直接正常进入游戏。
用PEID看看woool.exe是否有壳
没有壳,正好省去一大步,HOHO.
直接OD加载,点右键,选择查找UNICODE
然后按CTRL+F查找 攻城区
双击来到这里
初步判断这个CALL应该是游戏的显示函数;
依葫芦画瓢,我们写一个函数
void DispText(CString string)
{
char dstring[255];
sprintf(dstring,"%s",string);
DWORD _address=(DWORD)&dstring[0];
_asm
{
push ds
mov ecx,dword ptr ds:[0xD76840]
mov eax,dword ptr ds:[ecx]
push 0
push 0
push 0
push 1
push 0xFF00FF00 //颜色
push _address //字符串的地址
push 0xC0 //Y坐标
push 0x160 //X坐标
call dword ptr ds:[eax+0x18]
pop ds
}
}
我们再写个调用他的函数
void DispFunc()
{
DispText("大家好,我在这里!");
}
下面要考虑怎么调用这个函数了,我们知道游戏里屏幕是不断更新的,我们要是只是写上去一次,下次更新就会把上次写的抹去了,我们必须把这个函数加到游戏的一个循环里面去,让游戏自动调用我们写的函数。
观察游戏后发现左下角的显示地图名字和坐标的文字,我们可以把函数加到显示地图名字和坐标的那个函数那里,这样,每显示一次地图名字和坐标就会自动调用我们的函数了。
用OD加载程序,我们发现显示地图坐标的格式是X:Y,打开查找UNICODE,然后在里面搜索%d:%d,找到不少,一个一个动态分析后,终于找到这个CALL:
图中黄色那条正是调用显示的那个CALL
这里不好下手,我们把目标放到下面0x522627的那个CALL
把这里改成先执行我们自己的函数,然后执行原来的CALL最后返回到下面语句继续执行
先把0x522627处的CALL修改掉,变成CALL我们自己的函数,代码如下:
FARPROC p=(FARPROC)_DispFunc;
DWORD dwP=(DWORD)p-0x522627-0x5;
DWORD dwOldFlag;
VirtualProtect((void*)0x522628,4,PAGE_READWRITE,&dwOldFlag);
*((DWORD*)0x522628)=(DWORD)dwP;
VirtualProtect((void*)0x522628,4,dwOldFlag,&dwOldFlag);
这里p是我们的函数的地址,0x522627是要修改的CALL的首地址,0x5是要修改的地址的机器码长度,具体为什么要这样写,可以参考加密解密2里面关于jmp和call指令汇编的解释,好了,接下来我们要写个函数,先调用我们自己的写字函数,然后跳转到原来CALL的地址,代码如下:
const DWORD conaddress=0x479190;
__declspec(naked) _DispFunc()
{
_asm
{
push ds
push eax
push edx
push ecx
//调用自己的函数
call DispFunc
//调用完毕恢复寄存器
pop ecx
pop edx
pop eax
pop ds
jmp conaddress //跳转到原来CALL的地址
}
}
最后退出是要把数据改回,避免程序跳转到不可用的地址,造成程序崩溃。
DWORD dwP=0x479190-0x522627-0x5;
DWORD dwOldFlag;
VirtualProtect((void*)0x522628,4,PAGE_READWRITE,&dwOldFlag);
*((DWORD*)0x522628)=dwP;
VirtualProtect((void*)0x522628,4,dwOldFlag,&dwOldFlag);
全文完,希望能对一些未入门的朋友有所帮助.
这篇关于一篇传奇世界写屏文章的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!