GameRes游资网

 找回密码
 立即注册
查看: 42248|回复: 30

传奇世界写屏

[复制链接]
发表于 2005-11-9 18:38:00 | 显示全部楼层 |阅读模式
源代码在这个帖子里:
http://hack.gameres.com/showthread.asp?threadid=41620
完成图:

看过不少游戏内挂的文章,自己也来胡乱的写点,大家不要见笑.

第一步:我们要找到传奇世界的写屏函数的地址.
聪明点的人可能已经发现了,在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);

以上是屏幕显示部分--------------------------------------------------------------------------------------------------------
[em11] [em11] [em11] [em11] [em11] [em11] [em11] [em11] [em11] [em11] [em11] [em11] [em11] [em11] [em11] [em11] [em11] [em11] [em11] [em11] [em11] [em11] [em11] [em11] [em11] [em11] [em11] [em11] [em11] [em11] [em11] [em11]
以下是聊天窗口部分---------------------------------------------------------------------------------------------------------

用以上方法接着分析聊天窗口的部分,在查找UNICODE里面找到
“被组队人不允许组队!”这一句,看看附近的语句
多次调试确定,我们需要的语句在这里
0046A62B    .  8B4424 14       mov eax,dword ptr ss:[esp+14]
0046A62F    .  83C4 14           add esp,14
0046A632    .  83F8 FE           cmp eax,-2  
0046A635    .  6A 01              push 1
0046A637    .  68 FF000000    push 0FF
0046A63C    .  6A 2C              push 2C
0046A63E    .  6A 00              push 0
0046A640    .  6A 00              push 0
0046A642    .  6A 01              push 1
0046A644    .  68 FF380000    push 38FF
0046A649    .  75 07              jnz short woool.0046A652
0046A64B    .  68 B01F5B00    push woool.005B1FB0        
0046A650    .  EB 1D              jmp short woool.0046A66F
0046A652    >  83F8 FC          cmp eax,-4
0046A655    .  75 07              jnz short woool.0046A65E
0046A657    .  68 981F5B00    push woool.005B1F98         
0046A65C    .  EB 11              jmp short woool.0046A66F
0046A65E    >  83F8 FD         cmp eax,-3
0046A661    .  75 07              jnz short woool.0046A66A
0046A663    .  68 7C1F5B00    push woool.005B1F7C         
0046A668    .  EB 05              jmp short woool.0046A66F
0046A66A    >  68 701F5B00  push woool.005B1F70         
0046A66F    >  8B0D 5868D700   mov ecx,dword ptr ds:[D76858]
0046A675    .  E8 C6E90000    call woool.00479040
0046A67A    .  8BC8               mov ecx,eax
0046A67C    .  E8 6FDC0000    call woool.004782F0
取出我们需要的几句:
   push 1
   push 0FF
   push 2C
   push 0
   push 0
   push 1
   push 38FF                                    //颜色
   push woool.005B1FB0                   //字符串首地址
   mov ecx,dword ptr ds:[D76858]
   call woool.00479040
   mov ecx,eax
   call woool.004782F0
写个函数:
void sendtext()
{
   DWORD dwP=0x479040;
   DWORD dwP1=0x4782F0;
   char p[255];
   sprintf(p,"%s","终于成功了,庆祝一下!");
   DWORD address=(DWORD)&p[0];
   _asm
   {
     push ds
     push 1
     push 0xFF
     push 0x4E                         
     push 0
     push 0
     push 1
     push 0xFA                          // 颜色相关
     push address                        //字符内存地址
     mov ecx,dword ptr ds:[0xD76858]
     call dwP
     mov ecx,eax
     call dwP1
     pop ds
    }
}
效果如图:

全文完,希望能对一些未入门的朋友有所帮助.
发表于 2005-11-9 19:04:00 | 显示全部楼层

Re:传奇世界写屏

很不错, 支持
另:flyODBG第二版中的  Ultra 字符串参考插件可能不在右键中, 在上面的插件菜单中
发表于 2005-11-9 20:55:00 | 显示全部楼层

Re:传奇世界写屏

不错
字符串插件pediy有个仁兄改了一下老罗的那个  好像可以直接添加注释的
发表于 2005-11-9 21:33:00 | 显示全部楼层

Re:传奇世界写屏

HELLO的帖子就是棒 支持
发表于 2005-11-9 22:02:00 | 显示全部楼层

Re:传奇世界写屏



支持一下!
发表于 2005-11-10 19:21:00 | 显示全部楼层

Re:传奇世界写屏

不错,支持一下!呵呵
发表于 2005-11-11 18:20:00 | 显示全部楼层

Re:传奇世界写屏

UP
发表于 2005-11-12 01:55:00 | 显示全部楼层

Re: [原创]传奇世界写屏

acfg12: [原创]传奇世界写屏

完成图:

看过不少游戏内挂的文章,自己也来胡...


我的VC++6.0,一写汇编就死掉。
 楼主| 发表于 2005-11-13 16:33:00 | 显示全部楼层

Re:传奇世界写屏

有空把代码整理了发上来
发表于 2005-11-14 14:11:00 | 显示全部楼层

Re: Re: [原创]传奇世界写屏

hiver: Re: [原创]传奇世界写屏



我的VC++6.0,一写汇编就死掉。

是vc6的bug 也是我不用vc6的原因
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|广告投放|信息发布|关于本站|手机版|GameRes游资网 ( 闽ICP备05005107-1 )

GMT+8, 2018-1-21 17:02

快速回复 返回顶部 返回列表