咨询电话 027-87678580 金老师 QQ 2056813683倪老师 QQ 1564396558

在线留言 提交作业 联系我们

游戏分析之控制处理

admin

继续分析示例游戏的控制处理流程,围绕背景星星、子弹运动、飞机移动及碰撞判断展开,并结合反汇编代码说明各部分的执行关系。

分析消息循环后面的一个最重要的call    00403400,它处理游戏中子弹,背景星星,飞机的运动,和它们的碰撞等。理解了这些做外挂就不成问题了(比如:炸不死的飞机,甚至可以让飞机自动躲子弹)。

流程概述

  1. 显示一闪一闪的星星
  2. 控制子弹的运行,控制子弹和飞机的碰撞
  3. 飞机位移,方向,姿势的控制。

流程分析

004034C1  |.  8B3D FC694000 mov     edi, dword ptr [4069FC]
004034C7  |.  8BD0          mov     edx, eax
004034C9  |.  C1E2 06       shl     edx, 6
004034CC  |.  8D1492        lea     edx, dword ptr [edx+edx*4]
004034CF  |.  8B0D 006A4000 mov     ecx, dword ptr [406A00]
004034D5  |.  03D1          add     edx, ecx
004034D7  |.  B9 F0000000   mov     ecx, 0F0
004034DC  |.  2BC8          sub     ecx, eax
004034DE  |.  8BC1          mov     eax, ecx
004034E0  |.  C1E0 06       shl     eax, 6
004034E3  |.  8D0480        lea     eax, dword ptr [eax+eax*4]
004034E6  |.  85C0          test    eax, eax
004034E8  |.  7E 0B         jle     short 004034F5
004034EA  |>  8A0A          /mov     cl, byte ptr [edx]
004034EC  |.  880F          |mov     byte ptr [edi], cl
004034EE  |.  42            |inc     edx
004034EF  |.  47            |inc     edi
004034F0  |.  48            |dec     eax
004034F1  |.  85C0          |test    eax, eax
004034F3  |.^ 7F F5         \jg      short 004034EA

4069FC里面放的变量就是前面CreateDIBSection创建的可绘图内存的首地址,上面的操作就是把计算好的星星的位置放入这个可给图内存里(这个内存的DC可以用BitBlt直接贴到前台游戏画面上去)。

004035FB  |> \BA 002C0100   mov     edx, 12C00
00403600  |.  A1 FC694000   mov     eax, dword ptr [4069FC]
00403605  |.  E8 4AEBFFFF   call    00402154
0040360A  |>  E8 ADF9FFFF   call    00402FBC

4069FC->可绘图内存,call    00402154是用来清除屏幕的,如果没这个函数的话我们看到的子弹(还有飞机)将的一条线状的慢慢地被拉的很长。

call    00402FBC是用来控制子弹的

跟进去:00402FD2  |.  C70424 106E40>mov     dword ptr [esp], 00406E10把子弹信息数组的首地址传给了局部变量。

00403040  |> \8B1424        |mov     edx, dword ptr [esp]
00403043  |.  8B0424        |mov     eax, dword ptr [esp]
00403046  |.  8B0D 806D4000 |mov     ecx, dword ptr [406D80]
0040304C  |.  8B1A          |mov     ebx, dword ptr [edx]
0040304E  |.  8B50 04       |mov     edx, dword ptr [eax+4]
00403051  |.  C1EA 06       |shr     edx, 6
00403054  |.  C1EB 06       |shr     ebx, 6
00403057  |.  83EA 04       |sub     edx, 4
0040305A  |.  83EB 04       |sub     ebx, 4
0040305D  |.  85C9          |test    ecx, ecx
0040305F  |.  895424 04     |mov     dword ptr [esp+4], edx
00403063     /0F85 D0000000 jnz     00403139

把子弹的坐标信息提取出来。mov     ebx, dword ptr [edx]提取X坐标,mov     edx, dword ptr [eax+4]提取Y坐标。这里的坐标信息是压缩的。通过位移来还原。

00403046  |.  8B0D 806D4000 |mov     ecx, dword ptr [406D80]是把全局变量的标识传给了ecx在下面做了判断。这个变量就是用来标识飞机是否死的。如果把上面的jnz改为jmp这个飞机就永远死不了了。

我们顺带把子弹的信息格式说一下:

一共15个字节:前4个是X坐标信息,接着4个字节是Y坐标信息,接着1个字节是方向信息。

在下面也会判断飞机是否死亡然后给死亡标识变量,赋值:

00403115  |. /73 12         |jnb     short 00403129
00403117  |. |FF05 0C6E4000 |inc     dword ptr [406E0C]
0040311D  |. |EB 0A         |jmp     short 00403129
0040311F  |> |C705 0C6E4000>|mov     dword ptr [406E0C], 1

_______________________________________________________________________________

004030D9  |.  8B1424        |mov     edx, dword ptr [esp]
004030DC  |.  C642 09 00    |mov     byte ptr [edx+9], 0
004030E0  |.  FF0D B46D4000 |dec     dword ptr [406DB4]
004030E6  |.  A1 B46D4000   |mov     eax, dword ptr [406DB4]
004030EB  |.  85C0          |test    eax, eax
004030ED  |.  74 4A         |je      short 00403139
004030EF  |.  0105 B86D4000 |add     dword ptr [406DB8], eax
004030F5  |.  C705 046E4000>|mov     dword ptr [406E04], 64
004030FF  |.  8B5424 0C     |mov     edx, dword ptr [esp+C]
00403103  |.  8B0D 086E4000 |mov     ecx, dword ptr [406E08]
00403109  |.  3BD1          |cmp     edx, ecx
0040310B  |.  73 12         |jnb     short 0040311F
0040310D  |.  A1 0C6E4000   |mov     eax, dword ptr [406E0C]
00403112  |.  83F8 0A       |cmp     eax, 0A
00403115  |.  73 12         |jnb     short 00403129
00403117  |.  FF05 0C6E4000 |inc     dword ptr [406E0C]
0040311D  |.  EB 0A         |jmp     short 00403129

上面拿飞机和子弹的坐标进行对比。碰撞就在全局标识里赋值了。

这里子弹的运动就是程序上面在子弹信息数组里完成的。

0040328E  |.  8B35 FC694000 |mov     esi, dword ptr [4069FC]
00403294  |.  C1E0 06       |shl     eax, 6
00403297  |.  03F3          |add     esi, ebx
00403299  |.  8D5424 10     |lea     edx, dword ptr [esp+10]
0040329D  |.  8D0480        |lea     eax, dword ptr [eax+eax*4]
004032A0  |.  03F0          |add     esi, eax
004032A2  |.  33FF          |xor     edi, edi
004032A4  |>  8B4424 04     |/mov     eax, dword ptr [esp+4]
004032A8  |.  03C7          ||add     eax, edi
004032AA  |.  85C0          ||test    eax, eax
004032AC  |.  72 33         ||jb      short 004032E1
004032AE  |.  3D F0000000   ||cmp     eax, 0F0
004032B3  |.  73 2C         ||jnb     short 004032E1
004032B5  |.  33C0          ||xor     eax, eax
004032B7  |>  8A0A          ||/mov     cl, byte ptr [edx]
004032B9  |.  84C9          |||test    cl, cl
004032BB  |.  74 14         |||je      short 004032D1
004032BD  |.  8BC8          |||mov     ecx, eax
004032BF  |.  03CB          |||add     ecx, ebx
004032C1  |.  85C9          |||test    ecx, ecx
004032C3  |.  72 0C         |||jb      short 004032D1
004032C5  |.  81F9 40010000 |||cmp     ecx, 140
004032CB  |.  73 04         |||jnb     short 004032D1
004032CD  |.  8A0A          |||mov     cl, byte ptr [edx]
004032CF  |.  880E          |||mov     byte ptr [esi], cl
004032D1  |>  46            |||inc     esi
004032D2  |.  42            |||inc     edx
004032D3  |.  40            |||inc     eax
004032D4  |.  83F8 04       |||cmp     eax, 4
004032D7  |.^ 7C DE         ||\jl      short 004032B7
004032D9  |.  81C6 3C010000 ||add     esi, 13C

[4069FC]是游戏的可绘图内存。这样就把子弹的信息画到了内存位图里去了

00403659  |.  A1 7C6D4000   mov     eax, dword ptr [406D7C]
0040365E  |.  A8 08         test    al, 8
00403660  |.  0F95C2        setne   dl
00403663  |.  83E2 01       and     edx, 1

前面在消息循环里说明了当收到方向按键的时候会操作406D7C里面的变量。在这里把它取出来用于控制飞机的运动和姿势。。。。。。下面代码又有一个switch….case用来根据按键方向来选择飞机的姿势的。可以在OD数据区里查看一下00405b20里的东西会发现可以看到各种飞机飞行或爆炸的姿势

00403775  |> \0115 6C6D4000 add     dword ptr [406D6C], edx            Default case of switch 0040368A
0040377B  |.  0105 706D4000 add     dword ptr [406D70], eax
00403781  |.  A1 6C6D4000   mov     eax, dword ptr [406D6C]

将控制方向偏移量(固定的)与飞机当前坐标合成。

004037E5  |> \8B0D 706D4000 mov     ecx, dword ptr [406D70]
004037EB  |.  8B3D FC694000 mov     edi, dword ptr [4069FC]
004037F1  |.  C1E1 06       shl     ecx, 6
004037F4  |.  A1 6C6D4000   mov     eax, dword ptr [406D6C]
004037F9  |.  03F8          add     edi, eax
004037FB  |.  8D0C89        lea     ecx, dword ptr [ecx+ecx*4]
004037FE  |.  03F9          add     edi, ecx
00403800  |.  33F6          xor     esi, esi
00403802  |>  33C0          /xor     eax, eax
00403804  |>  8A0A          |/mov     cl, byte ptr [edx]
00403806  |.  84C9          ||test    cl, cl
00403808  |.  74 02         ||je      short 0040380C
0040380A  |.  880F          ||mov     byte ptr [edi], cl
0040380C  |>  47            ||inc     edi
0040380D  |.  42            ||inc     edx
0040380E  |.  40            ||inc     eax
0040380F  |.  83F8 10       ||cmp     eax, 10
00403812  |.^ 7C F0         |\jl      short 00403804
00403814  |.  81C7 30010000 |add     edi, 130
0040381A  |.  46            |inc     esi
0040381B  |.  83FE 10       |cmp     esi, 10
0040381E  |.^ 7C E2         \jl      short 00403802
00403820  |.  33F6          xor     esi, esi

4069FC是可绘图内存首地址。就这样把飞机的姿势按飞机坐标复制到绘图内存中去了。

00403A87  |> \68 2000CC00   push    0CC0020                           /ROP = SRCCOPY
00403A8C  |.  6A 00         push    0                                 |YSrc = 0
00403A8E  |.  6A 00         push    0                                 |XSrc = 0
00403A90  |.  8B0D E0694000 mov     ecx, dword ptr [4069E0]           |
00403A96  |.  51            push    ecx                               |hSrcDC => NULL
00403A97  |.  68 F0000000   push    0F0                               |Height = F0 (240.)
00403A9C  |.  68 40010000   push    140                               |Width = 140 (320.)
00403AA1  |.  6A 00         push    0                                 |YDest = 0
00403AA3  |.  6A 00         push    0                                 |XDest = 0
00403AA5  |.  53            push    ebx                               |hDestDC
00403AA6  |.  E8 3D0E0000   call    <jmp.&GDI32.BitBlt>               \BitBlt

最后BitBlt一下就把所有信息画到了游戏前台了。

分析完。

返回技术交流