分析消息循环后面的一个最重要的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一下就把所有信息画到了游戏前台了。 分析完。 (责任编辑:科锐软件教育机构) |