乱弹《是男人就下一百层》之外挂分析
【标题】乱弹《是男人就下一百层》之外挂分析【作者】fatwolf08
【主页】http://hi.baidu.com/fatwolf08
【工具】OD
【平台】WinXP
------------------------------------------------------------------------
【分析过程】
以前玩过这个游戏,可惜始终没到过一百层。看了xiaobaozi49老兄的扫雷外挂制作的文章,学到了不少东西,动手实践实践,才有了这篇菜文,因水平有限只能乱弹。
浮躁的2009就要过去了,不知道来年是不是还这么浮躁,每个人总要经历那么几个阶段。闲言少叙,言归正传。
首先找窗口的过程函数,根据xiaobaozi49老兄的方法,找到RegisterClass函数来确定过程函数地址,BP RegisterClassA下断点,断下后,ALT+F9,返回到下面的代码:
00401C10 8D45 D8 lea eax, dword ptr
00401C13 50 push eax
00401C14 FF15 7C514900 call dword ptr [<&user32.#535>] ; USER32.RegisterClassA
00401C1A 0FB7C0 movzx eax, ax
CALL之前入栈的EAX中的值就是WNDCLASS类的指针:0012FEC8,窗口类偏移四个字节保存的就是窗口过程函数,我这是:401C96。跳转到401C96,向下拖动,找到消息判断的代码:
00401F72 837D F8 06 cmp dword ptr , 6 ;
00401F76 0F87 1F000000 ja 00401F9B
00401F7C^ 0F84 E6FDFFFF je 00401D68
00401F82 837D F8 01 cmp dword ptr , 1
00401F86^ 0F84 0BFEFFFF je 00401D97
00401F8C 837D F8 02 cmp dword ptr , 2
00401F90^ 0F84 2AFEFFFF je 00401DC0
00401F96^ E9 B7FFFFFF jmp 00401F52
00401F9B 817D F8 0001000>cmp dword ptr , 100 ; WM_KEYDOWN
00401FA2 0F87 15000000 ja 00401FBD
00401FA8^ 0F84 54FEFFFF je 00401E02
00401FAE 837D F8 0F cmp dword ptr , 0F ;
00401FB2^ 0F84 FCFEFFFF je 00401EB4
00401FB8^ E9 95FFFFFF jmp 00401F52
00401FBD 817D F8 1101000>cmp dword ptr , 111 ; WM_COMMAND
00401FC4 0F87 18000000 ja 00401FE2
00401FCA^ 0F84 03FEFFFF je 00401DD3
00401FD0 817D F8 0101000>cmp dword ptr , 101 ; WM_KEYUP
00401FD7^ 0F84 52FEFFFF je 00401E2F
00401FDD^ E9 70FFFFFF jmp 00401F52
00401FE2 817D F8 0102000>cmp dword ptr , 201 ; WM_LBUTTONDOWN
00401FE9 0F87 18000000 ja 00402007
00401FEF^ 0F84 67FEFFFF je 00401E5C
00401FF5 817D F8 1301000>cmp dword ptr , 113 ; WM_TIMER
00401FFC^ 0F84 F4FEFFFF je 00401EF6
00402002^ E9 4BFFFFFF jmp 00401F52
00402007 817D F8 1002000>cmp dword ptr , 210
0040200E 0F87 18000000 ja 0040202C
00402014^ 0F84 ADFEFFFF je 00401EC7
0040201A 817D F8 0202000>cmp dword ptr , 202 ; WM_LBUTTONUP
00402021^ 0F84 62FEFFFF je 00401E89
00402027^ E9 26FFFFFF jmp 00401F52
0040202C 817D F8 0F03000>cmp dword ptr , 30F
00402033^ 0F84 E5FEFFFF je 00401F1E
00402039 817D F8 1103000>cmp dword ptr , 311
00402040^ 0F84 C7FEFFFF je 00401F0D
00402046 817D F8 B903000>cmp dword ptr , 3B9
0040204D^ 0F84 DFFEFFFF je 00401F32
00402053^ E9 FAFEFFFF jmp 00401F52
00402058 5F pop edi
00402059 5E pop esi
0040205A 5B pop ebx
0040205B C9 leave
0040205C C2 1000 retn 10
在VC查找各个消息值代表的宏,几个有用的我已经标出来了。游戏有简单、一般、困难三个级别,通过菜单来选定,通过玩游戏我们可以知道,不同的级别,出现的障碍物的数量不一样,物体移动的速度也不一样,障碍物的类型应该是通过游戏的级别来算出的。
我们来看一下级别保存在哪里。我们在WM_COMMAND下断点,跟随跳转来到下面的代码:
00401DD3 8B45 10 mov eax, dword ptr ; WM_COMMAND
00401DD6 C1E8 10 shr eax, 10
00401DD9 25 FFFF0000 and eax, 0FFFF
00401DDE 0FB7C0 movzx eax, ax
00401DE1 50 push eax
00401DE2 8B45 14 mov eax, dword ptr
00401DE5 50 push eax
00401DE6 8B45 10 mov eax, dword ptr 菜单序号
00401DE9 25 FFFF0000 and eax, 0FFFF
00401DEE 50 push eax 入栈做参数
00401DEF 8B45 FC mov eax, dword ptr
00401DF2 50 push eax
00401DF3 E8 17090000 call 0040270F 关键CALL,F7跟进
00401DF8 83C4 10 add esp, 10
00401DFB 33C0 xor eax, eax
跟随来到下面的代码:
0040283A 816D FC 419C000>sub dword ptr , 9C41
00402841 837D FC 14 cmp dword ptr , 14
00402845 0F87 5E000000 ja 004028A9
0040284B 8B45 FC mov eax, dword ptr
0040284E FF2485 55284000 jmp dword ptr 向上跳转
跟随跳转来到下面代码:
00402792 8B45 0C mov eax, dword ptr 所选菜单序号
00402795 50 push eax
00402796 8B45 08 mov eax, dword ptr
00402799 50 push eax 某个基址
0040279A E8 FA5F0000 call 00408799 关键CALL,F7跟进
0040279F 83C4 08 add esp, 8
004027A2 E9 02010000 jmp 004028A9
F7跟进来到下面:
00408799 55 push ebp
0040879A 8BEC mov ebp, esp
0040879C 53 push ebx
0040879D 56 push esi
0040879E 57 push edi
0040879F 8B45 0C mov eax, dword ptr
004087A2 2D 459C0000 sub eax, 9C45 ; 选择菜单序号减去上级菜单序号,得出选择的是第几个
004087A7 8B4D 08 mov ecx, dword ptr
004087AA 8981 08130000 mov dword ptr , eax ; 存放所选级别标志序号
004087B0 8B45 08 mov eax, dword ptr
004087B3 50 push eax
到此我们可以知道dword ptr 存放的是所选择的级别,ECX存放的是一个基址,对的地址下内存访问断点,可以找到下面的代码:
004054C3 8B80 08130000 mov eax, dword ptr ; 取选定的级别
004054C9 50 push eax
004054CA E8 B0E2FFFF call 0040377F ; 通过级别来算出下一个是什么类型,结果放在EAX
004054CF 83C4 0C add esp, 0C
004054D2 8B4D DC mov ecx, dword ptr
004054D5 8D0C49 lea ecx, dword ptr
004054D8 8B55 08 mov edx, dword ptr
004054DB 8984CA 98110000 mov dword ptr , eax ; 存放下一个出现的类型代表序号
004054E2 E8 73E2FFFF call 0040375A ; 算下个物体水平位置
004054E7 8B4D DC mov ecx, dword ptr
004054EA 8D0C49 lea ecx, dword ptr
004054ED 8B55 08 mov edx, dword ptr
004054F0 8984CA 9C110000 mov dword ptr , eax 存放水平位置
CALL是算下一个出现的类型的代表序号:0-实体版,1-逆时针转动链条,2-顺时针转动链条,3-弹簧板,4-带刺的板,5-翻转墙,当人工改为其他值时,
就出现乱画面。我们只要修改上面两个CALL,就可以实现出现的物体的类型和水平位置。
同样的方法,跟踪WM_KEYUP消息,来到下面:
00401E02 8B45 14 mov eax, dword ptr ; 按键
00401E05 C1E8 10 shr eax, 10
00401E08 25 FFFF0000 and eax, 0FFFF
00401E0D 0FB7C0 movzx eax, ax
00401E10 50 push eax
00401E11 0FBF45 14 movsx eax, word ptr
00401E15 50 push eax
00401E16 6A 01 push 1
00401E18 8B45 10 mov eax, dword ptr ; 所按下键的ASCII值
00401E1B 50 push eax
00401E1C 8B45 FC mov eax, dword ptr ; 基址
00401E1F 50 push eax
00401E20 E8 800C0000 call 00402AA5 关键CALL跟进
F7跟进上面的关键CALL:
00402AA5 55 push ebp
00402AA6 8BEC mov ebp, esp
00402AA8 53 push ebx
00402AA9 56 push esi
00402AAA 57 push edi
00402AAB 837D 0C 25 cmp dword ptr , 25 ; 判断是不是按下左方向键
00402AAF 0F85 23000000 jnz 00402AD8
00402AB5 837D 10 00 cmp dword ptr , 0
00402AB9 0F84 0F000000 je 00402ACE
00402ABF 8B45 08 mov eax, dword ptr
00402AC2 8388 EC120000 0>or dword ptr , 1 ; 存放按下左方向键的标记:1
00402AC9 E9 0A000000 jmp 00402AD8
00402ACE 8B45 08 mov eax, dword ptr
00402AD1 83A0 EC120000 F>and dword ptr , FFFFFFFE
00402AD8 837D 0C 27 cmp dword ptr , 27 ; 判断是不是按下有方向键
00402ADC 0F85 23000000 jnz 00402B05
00402AE2 837D 10 00 cmp dword ptr , 0
00402AE6 0F84 0F000000 je 00402AFB
00402AEC 8B45 08 mov eax, dword ptr
00402AEF 8388 EC120000 0>or dword ptr , 2 ; 存放按下右方向键的标记:2
00402AF6 E9 0A000000 jmp 00402B05
00402AFB 8B45 08 mov eax, dword ptr
00402AFE 83A0 EC120000 F>and dword ptr , FFFFFFFD
00402B05 837D 0C 5A cmp dword ptr , 5A ; 判断是不是按下Z字母键
00402B09 0F85 23000000 jnz 00402B32
00402B0F 837D 10 00 cmp dword ptr , 0
00402B13 0F84 0F000000 je 00402B28
00402B19 8B45 08 mov eax, dword ptr
00402B1C 8388 EC120000 0>or dword ptr , 4 ; 存放标记
00402B23 E9 0A000000 jmp 00402B32
00402B28 8B45 08 mov eax, dword ptr
00402B2B 83A0 EC120000 F>and dword ptr , FFFFFFFB
00402B32 837D 0C 58 cmp dword ptr , 58 ; 判断是不是按下X字母键
00402B36 0F85 23000000 jnz 00402B5F
00402B3C 837D 10 00 cmp dword ptr , 0
00402B40 0F84 0F000000 je 00402B55
00402B46 8B45 08 mov eax, dword ptr
00402B49 8388 EC120000 0>or dword ptr , 8 ; 存放标记
通过跟踪调试得出,当按键时,会在dword ptr 存放标记,1-左方向键,2-有方向键,4-Z键,8-X键,后两个是在两个人时才有效。
我们在这个内存地址下内存访问断点,点击“开始”,首先断在下面代码,是初始化参数的:
0040825D 8B45 08 mov eax, dword ptr
00408260 C780 EC120000 0>mov dword ptr , 0 ; 初始化为0
然后断在下面位置:
00405DB8 8B45 08 mov eax, dword ptr
00405DBB F680 EC120000 0>test byte ptr , 1 ; 左方向键
00405DC2 0F84 1C000000 je 00405DE4
00405DC8 8B45 08 mov eax, dword ptr
00405DCB 83A8 58110000 0>sub dword ptr , 8 ; 水平位置减少8
00405DD2 8B45 08 mov eax, dword ptr
00405DD5 C780 60110000 F>mov dword ptr , -1
00405DDF E9 39000000 jmp 00405E1D
00405DE4 8B45 08 mov eax, dword ptr
00405DE7 F680 EC120000 0>test byte ptr , 2 ; 右方向键
00405DEE 0F84 1C000000 je 00405E10
00405DF4 8B45 08 mov eax, dword ptr
00405DF7 8380 58110000 0>add dword ptr , 8 ; 水平位置加8
00405DFE 8B45 08 mov eax, dword ptr
00405E01 C780 60110000 0>mov dword ptr , 1
00405E0B E9 0D000000 jmp 00405E1D
00405E10 8B45 08 mov eax, dword ptr
00405E13 C780 60110000 0>mov dword ptr , 0
00405E1D 8B45 08 mov eax, dword ptr
00405E20 F680 10130000 0>test byte ptr , 2
00405E27 0F84 65000000 je 00405E92
00405E2D 8B45 08 mov eax, dword ptr
00405E30 F680 EC120000 0>test byte ptr , 4 ; Z键
00405E37 0F84 1C000000 je 00405E59
00405E3D 8B45 08 mov eax, dword ptr
00405E40 83A8 78110000 0>sub dword ptr , 8 ; 水平位置加8
00405E47 8B45 08 mov eax, dword ptr
00405E4A C780 80110000 F>mov dword ptr , -1
00405E54 E9 39000000 jmp 00405E92
00405E59 8B45 08 mov eax, dword ptr
00405E5C F680 EC120000 0>test byte ptr , 8 ; X键
00405E63 0F84 1C000000 je 00405E85
00405E69 8B45 08 mov eax, dword ptr
00405E6C 8380 78110000 0>add dword ptr , 8 ; 水平位置加8
00405E73 8B45 08 mov eax, dword ptr
00405E76 C780 80110000 0>mov dword ptr , 1
由此我们可以得出dword ptr 存放的就是人物的水平位置,通过就改增减的数字就可以控制人物的移动速度。
接下来我们查找血量的存放位置,由于不会用CE这些工具,也没学做外挂分析,还是用熟悉的OD自己找吧。我们知道
当人物遇到不同的物体时会发出不同的声音,我就从此入手,一般游戏播放声音,用的是PlaySound这个API,我就下这个
断点,断下后,ALT+F9返回,来到下面的代码:
004062F8 6A 01 push 1
004062FA 6A 6E push 6E
004062FC 8B45 08 mov eax, dword ptr
004062FF 50 push eax
00406300 E8 F8090000 call 00406CFD ; 上面的刺
00406305 83C4 0C add esp, 0C
00406308 8B45 F4 mov eax, dword ptr
0040630B C1E0 05 shl eax, 5
0040630E 8B4D 08 mov ecx, dword ptr
00406311 83AC08 70110000>sub dword ptr , 5 ; 血量减5
00406319 8B45 F4 mov eax, dword ptr
0040631C C1E0 05 shl eax, 5
0040631F 8B4D 08 mov ecx, dword ptr
00406322 C78408 68110000>mov dword ptr , 10 ; 闪烁时间
0040632D 8B45 08 mov eax, dword ptr
00406330 50 push eax
00406331 E8 70E7FFFF call 00404AA6
。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。
。。
。。省略很多代码
..
.............................................................................
004065FF 0F84 10000000 je 00406615
00406605 6A 01 push 1
00406607 6A 6E push 6E
00406609 8B45 08 mov eax, dword ptr
0040660C 50 push eax
0040660D E8 EB060000 call 00406CFD ; 上面的刺
00406612 83C4 0C add esp, 0C
00406615 8B45 F4 mov eax, dword ptr
00406618 C1E0 05 shl eax, 5
0040661B 8B4D 08 mov ecx, dword ptr
0040661E 83AC08 70110000>sub dword ptr , 5 ; 血量减5
00406626 8B45 F4 mov eax, dword ptr
00406629 C1E0 05 shl eax, 5
0040662C 8B4D 08 mov ecx, dword ptr
0040662F C78408 68110000>mov dword ptr , 10
0。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。
。。
。。省略很多代码
..
.............................................................................
004068A4 8B55 08 mov edx, dword ptr
004068A7 898411 6C110000 mov dword ptr , eax
004068AE 8B45 F8 mov eax, dword ptr
004068B1 8D0440 lea eax, dword ptr
004068B4 8B4D 08 mov ecx, dword ptr
004068B7 83BCC1 98110000>cmp dword ptr , 3
004068BF 0F85 25000000 jnz 004068EA
004068C5 8B45 08 mov eax, dword ptr
004068C8 83B8 18130000 0>cmp dword ptr , 0 ; 判断有没有音效
004068CF 0F84 10000000 je 004068E5
004068D5 6A 01 push 1
004068D7 6A 6D push 6D
004068D9 8B45 08 mov eax, dword ptr
004068DC 50 push eax
004068DD E8 1B040000 call 00406CFD ; 弹簧
004068E2 83C4 0C add esp, 0C
004068E5 E9 31010000 jmp 00406A1B
004068EA 8B45 F8 mov eax, dword ptr
004068ED 8D0440 lea eax, dword ptr
004068F0 8B4D 08 mov ecx, dword ptr
004068F3 83BCC1 98110000>cmp dword ptr , 2
004068FB 0F84 17000000 je 00406918
00406901 8B45 F8 mov eax, dword ptr
00406904 8D0440 lea eax, dword ptr
00406907 8B4D 08 mov ecx, dword ptr
0040690A 83BCC1 98110000>cmp dword ptr , 1
00406912 0F85 25000000 jnz 0040693D
00406918 8B45 08 mov eax, dword ptr
0040691B 83B8 18130000 0>cmp dword ptr , 0
00406922 0F84 10000000 je 00406938
00406928 6A 01 push 1
0040692A 6A 6C push 6C
0040692C 8B45 08 mov eax, dword ptr
0040692F 50 push eax
00406930 E8 C8030000 call 00406CFD ; 链条
00406935 83C4 0C add esp, 0C
00406938 E9 DE000000 jmp 00406A1B
0040693D 8B45 F8 mov eax, dword ptr
00406940 8D0440 lea eax, dword ptr
00406943 8B4D 08 mov ecx, dword ptr
00406946 83BCC1 98110000>cmp dword ptr , 4
0040694E 0F85 4A000000 jnz 0040699E
00406954 8B45 08 mov eax, dword ptr
00406957 83B8 18130000 0>cmp dword ptr , 0
0040695E 0F84 10000000 je 00406974
00406964 6A 01 push 1
00406966 6A 6E push 6E
00406968 8B45 08 mov eax, dword ptr
0040696B 50 push eax
0040696C E8 8C030000 call 00406CFD ; 带刺的板
00406971 83C4 0C add esp, 0C
00406974 8B45 F4 mov eax, dword ptr
00406977 C1E0 05 shl eax, 5
0040697A 8B4D 08 mov ecx, dword ptr
0040697D C78408 68110000>mov dword ptr , 10 ; 闪烁时间
00406988 8B45 F4 mov eax, dword ptr
0040698B C1E0 05 shl eax, 5
0040698E 8B4D 08 mov ecx, dword ptr
00406991 83AC08 70110000>sub dword ptr , 6 ; 血量减6
00406999 E9 7D000000 jmp 00406A1B
0040699E 8B45 F8 mov eax, dword ptr
004069A1 8D0440 lea eax, dword ptr
004069A4 8B4D 08 mov ecx, dword ptr
004069A7 83BCC1 98110000>cmp dword ptr , 5
004069AF 0F85 46000000 jnz 004069FB
004069B5 8B45 08 mov eax, dword ptr
004069B8 83B8 18130000 0>cmp dword ptr , 0
004069BF 0F84 10000000 je 004069D5
004069C5 6A 01 push 1
004069C7 6A 6F push 6F
004069C9 8B45 08 mov eax, dword ptr
004069CC 50 push eax
004069CD E8 2B030000 call 00406CFD ; 翻转板
004069D2 83C4 0C add esp, 0C
004069D5 8B45 F4 mov eax, dword ptr
004069D8 C1E0 05 shl eax, 5
004069DB 8B4D 08 mov ecx, dword ptr
004069DE 8B8408 6C110000 mov eax, dword ptr
004069E5 8D0440 lea eax, dword ptr
004069E8 8B4D 08 mov ecx, dword ptr
004069EB C784C1 A8110000>mov dword ptr , 1 此处修改为0,板子就不会翻转
004069F6 E9 20000000 jm069FB 8B45 08 mov eax, dword ptr
004069FE 83B8 18130000 0>cmp dword ptr , 0
00406A05 0F84 10000000 je 00406A1B
00406A0B 6A 01 push 1
00406A0D 6A 6B push 6B
00406A0F 8B45 08 mov eax, dword ptr
00406A12 50 push eax
00406A13 E8 E5020000 call 00406CFD ; 实体板
00406A18 83C4 0C add esp, 0C
00406A1B 8B45 F4 mov eax, dword ptr
00406A1E C1E0 05 shl eax, 5
00406A21 8B4D 08 mov ecx, dword ptr
00406A24 83BC08 70110000>cmp dword ptr , 0C ; 判断血量是不是大于12
00406A2C 0F8D 10000000 jge 00406A42
00406A32 8B45 F4 mov eax, dword ptr
00406A35 C1E0 05 shl eax, 5
00406A38 8B4D 08 mov ecx, dword ptr
00406A3B FF8408 70110000 inc dword ptr ; 血量加一
00406A42 8B45 08 mov eax, dword ptr
00406A45 50 push eax
00406A46 E8 5BE0FFFF call 00404AA6
00406A4B 83C4 04 add esp, 4
通过上面的代码我们得出dword ptr 处存放的就是血量,当遇到上面的刺时,血量减4,遇到带刺的板,减4,其他的加一。
通过修改上面的数值,就可以使血量不减少。也可以使翻转板不再翻转,也可以修改音乐效果。
通过上面的分析,我们就可以实现下面三个外挂功能:
1、控制出现的物体的类型,实现只出现一种类型;
2、增加或减小移动的速度;
3、实现血量不减少
------------------------------------------------------------------------
【疑问】
在编写修改软件时,用ReadProcessMemory读出的内存数据竟然跟OD里显示的不一样,也不知道是什么原因,还请各位看官赐教。
-----------------------------------------------------------------------
【版权声明】本文纯属技术交流, 转载请注明作者信息并保持文章的完整, 谢谢! 顶上 研究研究,谢谢分享
页:
[1]