聚仙过心跳包分析(一)
首先,进入游戏(进入游戏是指要到打怪界面,如果连打怪界面不知道的话,下面就不用看了……才发现自己废话这么多的),当然是OD附加游戏进程了,看了后核心模块用得是RekNet,这里顺便简单介绍下这个多用于网游的网络库:RakNet是一个基于UDP网络传输协议的C++网络库,允许程序员在他们自己的程序中实现高效的网络传输服务。通常情况下用于游戏,但也可以用于其它项目。
Raknet有以下好处:
1、高性能 在同一台计算机上,Radnet可以实现在两个程序之间每秒传输25,000条信息;
2、容易使用 Raknet有在线用户手册,视频教程。每一个函数和类都有详细的讲解,每一个功能都有自己的例程
3、跨平台,当前Raknet支持Windows, Linux, Macs,可以建立在Visual Studio, GCC, Code: Blocks, DevCPP 和其它平台上
4、在线技术支持 RakNet有一个活跃的论坛,邮件列表,你只要给他们发信,他们可以在几小时之内回复你。
5、安全的传输 RakNet在你的代码中自动使用SHA1, AES128, SYN,用RSA避免传输受到攻击
6、音频传输 用Speex编码解码,8位的音频只需要每秒500字节传输。
7、远程终端 用RakNet,你能远程管理你的程序,包括程序的设置,密码的管理和日志的管理。
8、目录服务器 目录服务器允许服务器列举他们自己需要的客户端,并与他们连接。
9、Autopatcher Autopatcher系统将限制客户端传输到服务端的文件,这样是为了避免一些不合法的用户将一些不合法的文件传输到服务端。
10、对象重载系统
11、网络数据压缩 BitStream类允许压缩矢量,矩阵,四元数和在-1到1之间的实数。
12、远程功能调用强健的通信层 可以保障信息按照不同的信道传输
13、RakNet支持两种版权,如果你是做免费游戏,RakNet将是免费的。相反,你必须支付一定的费用。
上面介绍了这个网络库,它是基于UDP协议的,那如果我们分析发包数据,下断send或WSASend函数是没用的,所以我们考虑下断sendto或其它的发包函数,我们这就先下断sendto函数,在游戏中无任何自己的操作动作,断下了,根据经验来说这样的游戏多数是带了心跳包(这样的话只要找到判断关键跳转的地方改成强行跳转就可以,也就是反汇编中类似jb、jnz、jnb等实现跳转的指令改为 jmp ,通常这样就可以跳过心跳包),所以去之……如果还问为何要去之,这里也简单说下,我们在分析功能CALL时,都要经过发包来分析,如果游戏中没任何自己的操作动作也会断下的话,不去掉这个检验是不行的,这是必须的工作,分析代码:
下面是下断sendto函数断下的代码:
71A22C69 >8BFF MOV EDI,EDI ; bp sendto 后断在这里
71A22C6B 55 PUSH EBP
71A22C6C 8BEC MOV EBP,ESP
71A22C6E 83EC 10 SUB ESP,10
71A22C71 56 PUSH ESI
71A22C72 57 PUSH EDI
71A22C73 33FF XOR EDI,EDI
71A22C75 813D 2840A371 4>CMP DWORD PTR DS:,WS2_32.71A29>
71A22C7F 0F85 7B680000 JNZ WS2_32.71A29500
71A22C85 393D 2C40A371 CMP DWORD PTR DS:,EDI
71A22C8B 0F84 6F680000 JE WS2_32.71A29500
71A22C91 FF35 2040A371 PUSH DWORD PTR DS:
71A22C97 FF15 AC11A271 CALL DWORD PTR DS:[<&KERNEL32.TlsGetValu>; kernel32.TlsGetValue
71A22C9D 3BC7 CMP EAX,EDI
71A22C9F 8945 F8 MOV DWORD PTR SS:,EAX
71A22CA2 0F84 58680000 JE WS2_32.71A29500
71A22CA8 897D FC MOV DWORD PTR SS:,EDI
71A22CAB FF75 08 PUSH DWORD PTR SS:
71A22CAE E8 8EFEFFFF CALL WS2_32.71A22B41
71A22CB3 8BF0 MOV ESI,EAX
71A22CB5 3BF7 CMP ESI,EDI
71A22CB7 0F84 F5890000 JE WS2_32.71A2B6B2
71A22CBD 8B45 10 MOV EAX,DWORD PTR SS:
71A22CC0 53 PUSH EBX
71A22CC1 8D4D FC LEA ECX,DWORD PTR SS:
71A22CC4 51 PUSH ECX
71A22CC5 FF75 F8 PUSH DWORD PTR SS:
71A22CC8 8D4D 08 LEA ECX,DWORD PTR SS:
71A22CCB 57 PUSH EDI
71A22CCC 57 PUSH EDI
71A22CCD FF75 1C PUSH DWORD PTR SS:
71A22CD0 8945 F0 MOV DWORD PTR SS:,EAX
71A22CD3 FF75 18 PUSH DWORD PTR SS:
71A22CD6 8B45 0C MOV EAX,DWORD PTR SS:
71A22CD9 FF75 14 PUSH DWORD PTR SS:
71A22CDC 8945 F4 MOV DWORD PTR SS:,EAX
71A22CDF 8B46 0C MOV EAX,DWORD PTR DS:
71A22CE2 51 PUSH ECX
71A22CE3 6A 01 PUSH 1
71A22CE5 8D4D F0 LEA ECX,DWORD PTR SS:
71A22CE8 51 PUSH ECX
71A22CE9 FF75 08 PUSH DWORD PTR SS:
71A22CEC FF50 6C CALL DWORD PTR DS:
71A22CEF 8BCE MOV ECX,ESI
71A22CF1 8BD8 MOV EBX,EAX
71A22CF3 E8 2EFEFFFF CALL WS2_32.71A22B26
71A22CF8 3BDF CMP EBX,EDI
71A22CFA 5B POP EBX
71A22CFB 0F85 A3890000 JNZ WS2_32.71A2B6A4
71A22D01 8B45 08 MOV EAX,DWORD PTR SS:
71A22D04 5F POP EDI
71A22D05 5E POP ESI
71A22D06 C9 LEAVE
71A22D07 C2 1800 RETN 18下断后接下来的事就是返回或者叫回朔,这里你怎么理解就怎么叫了,我这通常都叫“返回”:
CTRL+F9,F8 返回7次来到这里,
1004CBE0 55 PUSH EBP
1004CBE1 8BEC MOV EBP,ESP
1004CBE3 83EC 10 SUB ESP,10
1004CBE6 8B45 08 MOV EAX,DWORD PTR SS:
1004CBE9 8945 F0 MOV DWORD PTR SS:,EAX
1004CBEC 8B4D F0 MOV ECX,DWORD PTR SS:
1004CBEF C641 05 01 MOV BYTE PTR DS:,1
1004CBF3 8B55 F0 MOV EDX,DWORD PTR SS: ; 循环头
1004CBF6 0FB642 04 MOVZX EAX,BYTE PTR DS:
1004CBFA 85C0 TEST EAX,EAX
1004CBFC 75 66 JNZ SHORT RakNet.1004CC64
1004CBFE C745 F8 0000000>MOV DWORD PTR SS:,0
1004CC05 C745 FC 0000000>MOV DWORD PTR SS:,0
1004CC0C C745 F4 0000000>MOV DWORD PTR SS:,0
1004CC13 8B4D F0 MOV ECX,DWORD PTR SS:
1004CC16 83B9 1C060000 0>CMP DWORD PTR DS:,0
1004CC1D 74 1C JE SHORT RakNet.1004CC3B
1004CC1F 8B55 F0 MOV EDX,DWORD PTR SS:
1004CC22 8B82 20060000 MOV EAX,DWORD PTR DS:
1004CC28 50 PUSH EAX
1004CC29 8B4D F0 MOV ECX,DWORD PTR SS:
1004CC2C 51 PUSH ECX
1004CC2D 8B55 F0 MOV EDX,DWORD PTR SS:
1004CC30 8B82 1C060000 MOV EAX,DWORD PTR DS:
1004CC36 FFD0 CALL EAX
1004CC38 83C4 08 ADD ESP,8
1004CC3B 8B4D F4 MOV ECX,DWORD PTR SS:
1004CC3E 33D2 XOR EDX,EDX
1004CC40 52 PUSH EDX
1004CC41 51 PUSH ECX
1004CC42 8B45 FC MOV EAX,DWORD PTR SS:
1004CC45 50 PUSH EAX
1004CC46 8B4D F8 MOV ECX,DWORD PTR SS:
1004CC49 51 PUSH ECX
1004CC4A 8B4D F0 MOV ECX,DWORD PTR SS:
1004CC4D E8 CEDEFFFF CALL RakNet.?RunUpdateCycle@RakPeer@RakN>
1004CC52 6A 0A PUSH 0A ; 返回7次后来以这里
1004CC54 8B4D F0 MOV ECX,DWORD PTR SS:
1004CC57 81C1 24060000 ADD ECX,624
1004CC5D E8 0E520200 CALL RakNet.?WaitOnEvent@SignaledEvent@R>
1004CC62^ EB 8F JMP SHORT RakNet.1004CBF3 ; 跳到循环头
1004CC64 8B55 F0 MOV EDX,DWORD PTR SS:
1004CC67 C642 05 00 MOV BYTE PTR DS:,0
1004CC6B 33C0 XOR EAX,EAX
1004CC6D 8BE5 MOV ESP,EBP
1004CC6F 5D POP EBP
1004CC70 C2 0400 RETN 4看上面的反汇编代码,起初我以为心跳包应该在这里,但仔细看了这有个死循环,才想到这里是启动了线程实现的。按照“正向思路法”——按照CALL的执行顺序划分。所以心跳包应该是被CALL RakNet.?RunUpdateCycle@RakPeer@RakN>所调用的,所以在OD中右键跟随这个地址来到下面的代码:
1004AB20 >55 PUSH EBP ; 在这里F2下断
1004AB21 8BEC MOV EBP,ESP
1004AB23 B8 08120000 MOV EAX,1208
1004AB28 E8 73FB0300 CALL RakNet.1008A6A0
1004AB2D 56 PUSH ESI
1004AB2E 898D 38EEFFFF MOV DWORD PTR SS:,ECX
1004AB34 8D4D D8 LEA ECX,DWORD PTR SS:
1004AB37 E8 5446FFFF CALL RakNet.??0SystemAddress@RakNet@@QAE>
1004AB3C E8 5F2DFDFF CALL RakNet.?GetSocketLayerOverride@Sock>
1004AB41 85C0 TEST EAX,EAX
1004AB43 0F84 E6000000 JE RakNet.1004AC2F ; 线程函数经过,跳实现
………………
………………
1004AC2F 8B8D 38EEFFFF MOV ECX,DWORD PTR SS:
1004AC35 81C1 1C040000 ADD ECX,41C
1004AC3B E8 30290000 CALL RakNet.?PopInaccurate@?$ThreadsafeA>
1004AC40 8945 F4 MOV DWORD PTR SS:,EAX
1004AC43 837D F4 00 CMP DWORD PTR SS:,0
1004AC47 0F84 06010000 JE RakNet.1004AD53 ; 线程函数经过,跳实现
………………
………………
1004AD53 8B8D 38EEFFFF MOV ECX,DWORD PTR SS:
1004AD59 81C1 C8030000 ADD ECX,3C8
1004AD5F E8 0C280000 CALL RakNet.?PopInaccurate@?$ThreadsafeA>
1004AD64 8945 D4 MOV DWORD PTR SS:,EAX
1004AD67 837D D4 00 CMP DWORD PTR SS:,0
1004AD6B 0F84 D7020000 JE RakNet.1004B048 ; 线程函数经过,跳实现
……………………
……………………
1004B048 8B8D 38EEFFFF MOV ECX,DWORD PTR SS:
1004B04E 81C1 A0030000 ADD ECX,3A0
1004B054 E8 47D00200 CALL RakNet.?IsEmpty@?$Queue@VRakString@>
1004B059 0FB6C0 MOVZX EAX,AL
1004B05C 85C0 TEST EAX,EAX
1004B05E 0F85 7C090000 JNZ RakNet.1004B9E0 ; 线程函数经过,跳实现
…………………………
…………………………
1004B9E0 C745 CC 0000000>MOV DWORD PTR SS:,0
1004B9E7 EB 09 JMP SHORT RakNet.1004B9F2
1004B9E9 8B45 CC MOV EAX,DWORD PTR SS:
1004B9EC 83C0 01 ADD EAX,1
1004B9EF 8945 CC MOV DWORD PTR SS:,EAX
1004B9F2 8B8D 38EEFFFF MOV ECX,DWORD PTR SS:
1004B9F8 8B55 CC MOV EDX,DWORD PTR SS:
1004B9FB 3B91 FC020000 CMP EDX,DWORD PTR DS:
1004BA01 0F83 72100000 JNB RakNet.1004CA79 ; 1线程函数经过,跳未实现,过心跳包的关键点有可能是这里
1004BA07 8B85 38EEFFFF MOV EAX,DWORD PTR SS:
1004BA0D 8B88 F8020000 MOV ECX,DWORD PTR DS:
1004BA13 8B55 CC MOV EDX,DWORD PTR SS:
1004BA16 8B0491 MOV EAX,DWORD PTR DS:
1004BA19 8945 EC MOV DWORD PTR SS:,EAX
1004BA1C 8B4D EC MOV ECX,DWORD PTR SS:
1004BA1F 83C1 04 ADD ECX,4
1004BA22 51 PUSH ECX
1004BA23 8D4D D8 LEA ECX,DWORD PTR SS:
1004BA26 E8 F532FFFF CALL RakNet.??4SystemAddress@RakNet@@QAE>; 心跳包函数???
1004BA2B 8B55 08 MOV EDX,DWORD PTR SS:
1004BA2E 0B55 0C OR EDX,DWORD PTR SS:
1004BA31 75 27 JNZ SHORT RakNet.1004BA5A ; 2线程函数经过,跳未实现,过心跳包的关键点有可能是这里
1004BA33 E8 78DEFDFF CALL RakNet.?GetTimeUS@RakNet@@YA_KXZ ; 心跳包函数????
1004BA38 8945 08 MOV DWORD PTR SS:,EAX
1004BA3B 8955 0C MOV DWORD PTR SS:,EDX
1004BA3E 6A 00 PUSH 0
1004BA40 68 E8030000 PUSH 3E8
1004BA45 8B45 0C MOV EAX,DWORD PTR SS:
1004BA48 50 PUSH EAX
1004BA49 8B4D 08 MOV ECX,DWORD PTR SS:
1004BA4C 51 PUSH ECX
1004BA4D E8 EEE90300 CALL RakNet.1008A440 ; 心跳包函数????
1004BA52 33D2 XOR EDX,EDX
1004BA54 8945 10 MOV DWORD PTR SS:,EAX
1004BA57 8955 14 MOV DWORD PTR SS:,EDX
1004BA5A 8B45 EC MOV EAX,DWORD PTR SS:
1004BA5D 8985 18EEFFFF MOV DWORD PTR SS:,EAX
1004BA63 8B8D 18EEFFFF MOV ECX,DWORD PTR SS:
1004BA69 8B55 14 MOV EDX,DWORD PTR SS:
1004BA6C 3B91 54100000 CMP EDX,DWORD PTR DS: ; 比较
1004BA72 0F82 EC000000 JB RakNet.1004BB64 ; 3线程函数经过,跳未实现,过心跳包的关键点有可能是这里
1004BA78 77 15 JA SHORT RakNet.1004BA8F
1004BA7A 8B85 18EEFFFF MOV EAX,DWORD PTR SS:
1004BA80 8B4D 10 MOV ECX,DWORD PTR SS:
1004BA83 3B88 50100000 CMP ECX,DWORD PTR DS:
1004BA89 0F86 D5000000 JBE RakNet.1004BB64
1004BA8F 8B55 EC MOV EDX,DWORD PTR SS:
1004BA92 8B45 10 MOV EAX,DWORD PTR SS:
1004BA95 2B82 50100000 SUB EAX,DWORD PTR DS:
1004BA9B 8B4D 14 MOV ECX,DWORD PTR SS:
1004BA9E 1B8A 54100000 SBB ECX,DWORD PTR DS:
1004BAA4 8B95 38EEFFFF MOV EDX,DWORD PTR SS:
1004BAAA 8B92 0C050000 MOV EDX,DWORD PTR DS:
1004BAB0 D1EA SHR EDX,1
1004BAB2 33F6 XOR ESI,ESI
1004BAB4 8985 10EEFFFF MOV DWORD PTR SS:,EAX
1004BABA 898D 14EEFFFF MOV DWORD PTR SS:,ECX
1004BAC0 8995 08EEFFFF MOV DWORD PTR SS:,EDX
1004BAC6 89B5 0CEEFFFF MOV DWORD PTR SS:,ESI
1004BACC 8B85 14EEFFFF MOV EAX,DWORD PTR SS:
1004BAD2 3B85 0CEEFFFF CMP EAX,DWORD PTR SS:
1004BAD8 0F82 86000000 JB RakNet.1004BB64 ; 4线程函数经过,跳未实现,过心跳包的关键点有可能是这里
1004BADE 77 0E JA SHORT RakNet.1004BAEE
1004BAE0 8B8D 10EEFFFF MOV ECX,DWORD PTR SS:
1004BAE6 3B8D 08EEFFFF CMP ECX,DWORD PTR SS:
1004BAEC 76 76 JBE SHORT RakNet.1004BB64
1004BAEE 8B55 EC MOV EDX,DWORD PTR SS:
1004BAF1 83BA 80100000 0>CMP DWORD PTR DS:,7
1004BAF8 75 6A JNZ SHORT RakNet.1004BB64
1004BAFA 8D85 40F7FFFF LEA EAX,DWORD PTR SS:
1004BB00 50 PUSH EAX
1004BB01 8B4D EC MOV ECX,DWORD PTR SS:
1004BB04 81C1 F8000000 ADD ECX,0F8
1004BB0A E8 A1F00000 CALL RakNet.1005ABB0 ; 心跳包函数????
1004BB0F 8945 FC MOV DWORD PTR SS:,EAX
1004BB12 8B4D FC MOV ECX,DWORD PTR SS:
1004BB15 83B9 C8000000 0>CMP DWORD PTR DS:,0
1004BB1C 75 46 JNZ SHORT RakNet.1004BB64 ; 5线程函数经过,跳未实现,过心跳包的关键点有可能是这里
1004BB1E 6A 02 PUSH 2
1004BB20 6A 01 PUSH 1
1004BB22 83EC 14 SUB ESP,14
1004BB25 8BD4 MOV EDX,ESP
1004BB27 8B45 D8 MOV EAX,DWORD PTR SS:
1004BB2A 8902 MOV DWORD PTR DS:,EAX
1004BB2C 8B4D DC MOV ECX,DWORD PTR SS:
1004BB2F 894A 04 MOV DWORD PTR DS:,ECX
1004BB32 8B45 E0 MOV EAX,DWORD PTR SS:
1004BB35 8942 08 MOV DWORD PTR DS:,EAX
1004BB38 8B4D E4 MOV ECX,DWORD PTR SS:
1004BB3B 894A 0C MOV DWORD PTR DS:,ECX
1004BB3E 8B45 E8 MOV EAX,DWORD PTR SS:
1004BB41 8942 10 MOV DWORD PTR DS:,EAX
1004BB44 8B8D 38EEFFFF MOV ECX,DWORD PTR SS:
1004BB4A E8 21B9FFFF CALL RakNet.?PingInternal@RakPeer@RakNet>
1004BB4F 8B4D EC MOV ECX,DWORD PTR SS:
1004BB52 8B55 10 MOV EDX,DWORD PTR SS:
1004BB55 8991 50100000 MOV DWORD PTR DS:,EDX
1004BB5B 8B45 14 MOV EAX,DWORD PTR SS:
1004BB5E 8981 54100000 MOV DWORD PTR DS:,EAX
1004BB64 8B4D EC MOV ECX,DWORD PTR SS:
1004BB67 81C1 74100000 ADD ECX,1074
1004BB6D E8 0E70FEFF CALL RakNet.?Size@?$CircularLinkedList@P>
1004BB72 8B48 28 MOV ECX,DWORD PTR DS:
1004BB75 51 PUSH ECX
1004BB76 8B4D EC MOV ECX,DWORD PTR SS:
1004BB79 81C1 74100000 ADD ECX,1074
1004BB7F E8 FC6FFEFF CALL RakNet.?Size@?$CircularLinkedList@P>
1004BB84 0FB750 24 MOVZX EDX,WORD PTR DS:
1004BB88 52 PUSH EDX
1004BB89 68 F8111110 PUSH RakNet.101111F8
……………………………………
……………………………………先吃饭去过会儿接着分析……饭后来了,哎……
我们常说做任何事都要理论结合实际,没有实践精神是不行的,对我们程序员来说多数时间都要实践,下面就来说说实践……
大家看了上面的反汇编代码不难看出,线程启动后在地址1004AB20里断下,我们F8单步,经过比较后跳转的地方有两种情况,一是直接跳过,二是跳未实现(这里又是废话了),直接跳过的地方我们就不用管了(比如:1004AB43、1004AC47、1004AD6B、1004B05E等地方),而对于标注为“线程函数经过,跳未实现,过心跳包的关键点有可能是这里”的地方,我们要特别留意,这些个地方往往就是突破口。
下面来插个话题:说说"反向思路法"——也可以说成“函数返回法”,这里是指我们在发包函数(或收包函数)下断断下后,返回的上一级函数(CALL)的方法,在OD里有的叫返回,有的叫回朔,同样你怎么理解就怎么叫。当然也不外呼就这些叫法了。
好了,刚才提到这个方法,下面我们就来实践下了,同样是进游戏后bp sendto 断下,前面我们提到返回7次就到了死循环地方,也就是线程函数里,那这次我们只用返回6次就到了CALL RakNet.?RunUpdateCycle@RakPeer@RakN>函数的执行代码的1004BBDC地址,也就是这个CALL的内部执行部分,如下面代码所示:
1004BB84 0FB750 24 MOVZX EDX,WORD PTR DS:
1004BB88 52 PUSH EDX
1004BB89 68 F8111110 PUSH RakNet.101111F8
1004BB8E 8B85 38EEFFFF MOV EAX,DWORD PTR SS:
1004BB94 05 94030000 ADD EAX,394
1004BB99 50 PUSH EAX
1004BB9A 8B8D 38EEFFFF MOV ECX,DWORD PTR SS:
1004BBA0 8B91 20050000 MOV EDX,DWORD PTR DS:
1004BBA6 52 PUSH EDX
1004BBA7 8B45 0C MOV EAX,DWORD PTR SS:
1004BBAA 50 PUSH EAX
1004BBAB 8B4D 08 MOV ECX,DWORD PTR SS:
1004BBAE 51 PUSH ECX
1004BBAF 8B55 EC MOV EDX,DWORD PTR SS:
1004BBB2 8B82 70100000 MOV EAX,DWORD PTR DS:
1004BBB8 50 PUSH EAX
1004BBB9 8D4D D8 LEA ECX,DWORD PTR SS:
1004BBBC 51 PUSH ECX
1004BBBD 8B4D EC MOV ECX,DWORD PTR SS:
1004BBC0 81C1 74100000 ADD ECX,1074
1004BBC6 E8 B56FFEFF CALL RakNet.?Size@?$CircularLinkedList@PAUInternalPacket@Rak>
1004BBCB 8B10 MOV EDX,DWORD PTR DS:
1004BBCD 52 PUSH EDX
1004BBCE 8B4D EC MOV ECX,DWORD PTR SS:
1004BBD1 81C1 F8000000 ADD ECX,0F8
1004BBD7 E8 64C50000 CALL RakNet.10058140
1004BBDC 8B4D EC MOV ECX,DWORD PTR SS: ; bp sendto 后6次返回到这里
1004BBDF 81C1 F8000000 ADD ECX,0F8
1004BBE5 E8 86EF0000 CALL RakNet.1005AB70
1004BBEA 0FB6C0 MOVZX EAX,AL
1004BBED 85C0 TEST EAX,EAX
1004BBEF 0F85 0F010000 JNZ RakNet.1004BD04
1004BBF5 8B4D EC MOV ECX,DWORD PTR SS:
1004BBF8 83B9 80100000 0>CMP DWORD PTR DS:,1
1004BBFF 74 0C JE SHORT RakNet.1004BC0D
1004BC01 8B55 EC MOV EDX,DWORD PTR SS:
1004BC04 83BA 80100000 0>CMP DWORD PTR DS:,2
1004BC0B 75 19 JNZ SHORT RakNet.1004BC26
1004BC0D 8B4D EC MOV ECX,DWORD PTR SS:
1004BC10 81C1 F8000000 ADD ECX,0F8
1004BC16 E8 B5D70000 CALL RakNet.100593D0
1004BC1B 0FB6C0 MOVZX EAX,AL
1004BC1E 85C0 TEST EAX,EAX
1004BC20 0F84 DE000000 JE RakNet.1004BD04
1004BC26 8B4D EC MOV ECX,DWORD PTR SS:
1004BC29 83B9 80100000 0>CMP DWORD PTR DS:,3
1004BC30 75 3B JNZ SHORT RakNet.1004BC6D
1004BC32 8B4D EC MOV ECX,DWORD PTR SS:
1004BC35 81C1 F8000000 ADD ECX,0F8
1004BC3B E8 D0D70000 CALL RakNet.10059410
那为何我们要用到“正向思路法”和“反向思路法”呢?通常情况下我们用得是后者,也就是下断发包函数后返回,而在返回过程中,你觉得可疑的地方你就可以在些执行代码头下F2断点来分析,所以两者有必要结合应用。看了上面的反汇编代码也不难想了,我们的两种思路法,都是在同一个CALL的执行内部,也就是在同一个执行函数内,那么,我们分析心跳包的关键地址就在1004AB20~1004BBDC这个范围内,除掉前面提到过的几个单步标注为“线程函数经过,跳实现”的地方,那地址范围又缩小了,在1004B9E0~1004BBDC之间。
好的,下面我们来分析标注为“线程函数经过,跳未实现,过心跳包的关键点有可能是这里”,上面我们标注了5个这样的地方。现在看第一个:
1004BA01 0F83 72100000 JNB RakNet.1004CA79 ; 1线程函数经过,跳未实现,过心跳包的关键点有可能是这里我们在OD的反汇编栏目中双点鼠标,把JNB RakNet.1004CA79 改为 jmp 1004CA79 ,但改后游戏提示断线(注:这里不可以游戏中执行任何操作),那说明这个判断跳不是我们要找的心跳包的关键地方。呵呵没办法,重新登陆游戏账号再进入打怪界面……
下面看第二个:
1004BA31 75 27 JNZ SHORT RakNet.1004BA5A ; 2线程函数经过,跳未实现,过心跳包的关键点有可能是这里
用同样的方法得到同样的结果,重新来过吧……以此类推到了:
1004BAD8 0F82 86000000 JB RakNet.1004BB64 ; 4线程函数经过,跳未实现,过心跳包的关键点有可能是这里当我们改了地址1004BAD8中的 JB->JMP 游戏没掉线了,那说明心跳包的关键跳转找到了,下面我们就来看看这个跳转下面的几个CALL:
1004BB0A E8 A1F00000 CALL RakNet.1005ABB0 ; 心跳包函数????
…………
1004BB4A E8 21B9FFFF CALL RakNet.?PingInternal@RakPeer@RakNet>
…………仔细看下上面两个地址中还有个关键跳:
1004BB1C 75 46 JNZ SHORT RakNet.1004BB64 ; 5线程函数经过,跳未实现,过心跳包的关键点有可能是这里和上面我们改的目标地址是一个,那我们可以排除CALL RakNet.1005ABB0 不是心跳包的关键CALL,这样以来我们只有一个CALL是心跳包了……
另外我们所修改的地址1004BAD8(到这里别再问我修改成啥了……)到我们返回的函数地址不远,那说明关键心跳包执行的地方就是这里,我们改了便可以,通常这方法都叫“爆破”,如下代码所示:
1004BAD8 /0F82 86000000 JB RakNet.1004BB64 ;这里改为 jmp 1004BB64
1004BADE |77 0E JA SHORT RakNet.1004BAEE
1004BAE0 |8B8D 10EEFFFF MOV ECX,DWORD PTR SS:
1004BAE6 |3B8D 08EEFFFF CMP ECX,DWORD PTR SS:
1004BAEC |76 76 JBE SHORT RakNet.1004BB64
1004BAEE |8B55 EC MOV EDX,DWORD PTR SS:
1004BAF1 |83BA 80100000 0>CMP DWORD PTR DS:,7
1004BAF8 |75 6A JNZ SHORT RakNet.1004BB64
1004BAFA |8D85 40F7FFFF LEA EAX,DWORD PTR SS:
1004BB00 |50 PUSH EAX
1004BB01 |8B4D EC MOV ECX,DWORD PTR SS:
1004BB04 |81C1 F8000000 ADD ECX,0F8
1004BB0A |E8 A1F00000 CALL RakNet.1005ABB0
1004BB0F |8945 FC MOV DWORD PTR SS:,EAX
1004BB12 |8B4D FC MOV ECX,DWORD PTR SS:
1004BB15 |83B9 C8000000 0>CMP DWORD PTR DS:,0
1004BB1C |75 46 JNZ SHORT RakNet.1004BB64
1004BB1E |6A 02 PUSH 2
1004BB20 |6A 01 PUSH 1
1004BB22 |83EC 14 SUB ESP,14
1004BB25 |8BD4 MOV EDX,ESP
1004BB27 |8B45 D8 MOV EAX,DWORD PTR SS:
1004BB2A |8902 MOV DWORD PTR DS:,EAX
1004BB2C |8B4D DC MOV ECX,DWORD PTR SS:
1004BB2F |894A 04 MOV DWORD PTR DS:,ECX
1004BB32 |8B45 E0 MOV EAX,DWORD PTR SS:
1004BB35 |8942 08 MOV DWORD PTR DS:,EAX
1004BB38 |8B4D E4 MOV ECX,DWORD PTR SS:
1004BB3B |894A 0C MOV DWORD PTR DS:,ECX
1004BB3E |8B45 E8 MOV EAX,DWORD PTR SS:
1004BB41 |8942 10 MOV DWORD PTR DS:,EAX
1004BB44 |8B8D 38EEFFFF MOV ECX,DWORD PTR SS:
1004BB4A |E8 21B9FFFF CALL RakNet.?PingInternal@RakPeer@RakNet@@IAEXUSystemAddress>
1004BB4F |8B4D EC MOV ECX,DWORD PTR SS:
1004BB52 |8B55 10 MOV EDX,DWORD PTR SS:
1004BB55 |8991 50100000 MOV DWORD PTR DS:,EDX
1004BB5B |8B45 14 MOV EAX,DWORD PTR SS:
1004BB5E |8981 54100000 MOV DWORD PTR DS:,EAX
1004BB64 \8B4D EC MOV ECX,DWORD PTR SS:
1004BB67 81C1 74100000 ADD ECX,1074
1004BB6D E8 0E70FEFF CALL RakNet.?Size@?$CircularLinkedList@PAUInternalPacket@Rak>
1004BB72 8B48 28 MOV ECX,DWORD PTR DS:
1004BB75 51 PUSH ECX
1004BB76 8B4D EC MOV ECX,DWORD PTR SS:
1004BB79 81C1 74100000 ADD ECX,1074
1004BB7F E8 FC6FFEFF CALL RakNet.?Size@?$CircularLinkedList@PAUInternalPacket@Rak>
1004BB84 0FB750 24 MOVZX EDX,WORD PTR DS:
1004BB88 52 PUSH EDX
1004BB89 68 F8111110 PUSH RakNet.101111F8
1004BB8E 8B85 38EEFFFF MOV EAX,DWORD PTR SS:
1004BB94 05 94030000 ADD EAX,394
1004BB99 50 PUSH EAX
1004BB9A 8B8D 38EEFFFF MOV ECX,DWORD PTR SS:
1004BBA0 8B91 20050000 MOV EDX,DWORD PTR DS:
1004BBA6 52 PUSH EDX
1004BBA7 8B45 0C MOV EAX,DWORD PTR SS:
1004BBAA 50 PUSH EAX
1004BBAB 8B4D 08 MOV ECX,DWORD PTR SS:
1004BBAE 51 PUSH ECX
1004BBAF 8B55 EC MOV EDX,DWORD PTR SS:
1004BBB2 8B82 70100000 MOV EAX,DWORD PTR DS:
1004BBB8 50 PUSH EAX
1004BBB9 8D4D D8 LEA ECX,DWORD PTR SS:
1004BBBC 51 PUSH ECX
1004BBBD 8B4D EC MOV ECX,DWORD PTR SS:
1004BBC0 81C1 74100000 ADD ECX,1074
1004BBC6 E8 B56FFEFF CALL RakNet.?Size@?$CircularLinkedList@PAUInternalPacket@Rak>
1004BBCB 8B10 MOV EDX,DWORD PTR DS:
1004BBCD 52 PUSH EDX
1004BBCE 8B4D EC MOV ECX,DWORD PTR SS:
1004BBD1 81C1 F8000000 ADD ECX,0F8
1004BBD7 E8 64C50000 CALL RakNet.10058140
1004BBDC 8B4D EC MOV ECX,DWORD PTR SS: ; bp sendto 后5次返回到这里
1004BBDF 81C1 F8000000 ADD ECX,0F8
总结:实际上心跳包分析和大家常听到的找CALL没区别,关键点就是改个判断就成,好了,终于完成了……
我试过了还是不行呀,一会就断,游戏掉线
页:
[1]