看过这里有的大大是断下send后,去找调用send的CALL,找到这个CALL再找上一次的CALL,这样去找关键CALL,但是,有的游戏这样是找不来的,所以,如果有的游戏不能这样找回去,那怎么办呢,这就要先说说原理了。
  要说找CALL的原理,我们应该想想游戏的运行机制。也就是说游戏的控制方式是怎么样的。
  不说费话,其实大多数的游戏都是这样的,来个买药的例子吧:
  点击买药后:
  1、客户端产生一个买药行为 并调用买物品的过程,如:BuyGoods(s:string,n:integer); //参数s为物品种类 n为数量
        2、这个行为会产生一个发送给服务器的数据信息 MakeInfoString;
   比如:36 00 01 .........
  3、数据出来要进行一次或N次的加密。
  4、加密后通过send或WSASend函数将这个信息发给服务器处理。
  5、等待服务器处理返回。
  6、服务器返回购买成功的信息。
  7、客户端响应这个信息,并调用本地动作行为。
  这样,基本上就构成了游戏的一般的控制方式。
  写出程序大概可能为:
主程序
....
....
BuyGoods(LifeMedicine,10);  //行为产生后调用买物品过程
....
....
主程序

procedure BuyGoods(s:string,n:integer);  //买物品的过程
begin
  send(Encrypt(MakeInfoString(s,n)));
end;
当然写法也可以是:
MakeInfoString;
Encrypt;
send;

不管怎么样方法都是差不多的。
  了解了程序的大至写法,那么我们逆向起来就有个思路了:
    bp send
        返回向回找,先找到Encrypt,再向回找,能找到MakeInfoString(也就是找到明码部分),再向上找,就是调用这些东西的BuyGoods(s:string,n:integer)了。

  我来找一个游戏说明一下吧,比如说有个什么名状的游戏。
  这个游戏有个出征和休息待卫的功能,也就是放出和休息宝宝了。就拿这个CALL来讲吧。
  这个游戏我用一般的思路往回找无法找出来这个出征的CALL,别的CALL没试,主要用是讲个例子。那么我就用另一个方法:
  1,我先下bp send,返回看到这里,不用说就是send函数了。
     0069FFBF  |.  E8 82A11000  call    <jmp.&WS2_32.#19>
  ,2,给send的BUF区下硬键访问断点,来到这里,看出是这里向Send函数的BUF区放数据的。
     0069FB43  |.  F3:A5        rep    movs dword ptr es:[edi], dword ptr [e>; |
  3,给esi下断分析,发现加密函数。
     0069FB64  |.  E8 67060000  call    006A01D0                ; \封包加密函数
  4,好,我们在这个加密函数下个断。然后点击“出征”,断下来后执行到返回。可以看到调用它的CALL。
     0069DD14  .  E8 471D0000  call    0069FA60
  5,下断,再往回找,看到上一级的调用CALL。
     0069DEFC  |.  E8 BFFDFFFF  call    0069DCC0
  6,下断,再往回找。
     006DBDFB  |.  FF50 0C      call    [eax+C]              
  7,下断,再找。
     0065CB89  |.  8B4D 08      mov    ecx, [ebp+8]
     0065CB8C  |.  33C0          xor    eax, eax
     0065CB8E  |.  66:8B46 21    mov    ax, [esi+21]
     0065CB92  |.  6A 32        push    32                            ; /Arg3 = 00000032
     0065CB94  |.  50            push    eax                            ; |Arg2
     0065CB95  |.  51            push    ecx                            ; |Arg1
     0065CB96  |.  8D8D E4FBFFFF lea    ecx, [ebp-41C]                ; |
     0065CB9C  |.  C745 FC 00000>mov    dword ptr [ebp-4], 0          ; |
     0065CBA3  |.  E8 88F10700  call    006DBD30                      ; \TheWarlo.006DBD30    
   8,再放上,是这里,看到红色这个CALL了吗,它就是“出征”的CALL了。

    004101B2 |. 83F8 14 cmp eax, 14
004101B5 |. 8B45 08 mov eax, [ebp+8]
004101B8 |. 73 06 jnb short 004101C0
004101BA |. 83F8 01 cmp eax, 1
004101BD |. 7E 01 jle short 004101C0
004101BF |. 48 dec eax
004101C0 |> 8B4486 04 mov eax, [esi+eax*4+4]
004101C4 |. B9 58E88000 mov ecx, 0080E858
004101C9 |. 50 push eax ; /Arg1
004101CA |. E8 81C82400 call 0065CA50 ; \TheWarlo.0065CA50
004101CF |. 5E pop esi
004101D0 |. 5D pop ebp
004101D1 \. C2 0400 retn 4
   9,再上就是GuiDll的领空了。
   这两个都可以,
  给大家这个例子,是想告诉大家,什么是BPSEND的原理,我的意思是如果你都分析不清楚一个游戏或程序的运行方法,那你无论如何是不可能找到这些的。当然,如果有别人给的一些实际操作的例子除外。
  好了,也差不了多少。也不知道我说的这些对大家有没有用,欢迎大家批评指正。
posted on 2010-10-08 15:03  jasonM  阅读(1753)  评论(1编辑  收藏  举报