1、PING.EXE 十六进制源码分析车生兵 著中南林业科技大学计算机与信息工程学院2010 年 10 月 18 日PING.EXE 十六进制源码分析 中南林业科技大学计算机与信息工程学院 车生兵 著 严禁盗版2目录1 ping.exe 十六进制源码32 ping.exe 源码数据分析71、源码结构72、DOS 头结点73、DOS 文件体.74、PE 头结点84.1 PE 头结点结构84.2 PE 可选头部104.3 数 据 目录 .135 PE 文件段.156、ping.exe 加载后的内存数据映像.183 Ping.exe 的实现与原理分析.244.1 常用数据结构244.2 ping.asm
2、 源程序分析274.3、_ConsoleInit.asm 分析.354.4、_CmdLine.asm 分析.374.5、_CalcCheckSum.asm 分析414.6、测试结果举例.43PING.EXE 十六进制源码分析 中南林业科技大学计算机与信息工程学院 车生兵 著 严禁盗版31 ping.exe 十六进制源码在文件存储空间中,ping.exe 十六进制源码示例如下:;header00000000 4D 5A 90 00 03 00 00 00 04 00 00 00 FF FF 00 00 MZ?00000010 B8 00 00 00 00 00 00 00 40 00 00 00
3、 00 00 00 00 ?.00000020 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00000030 00 00 00 00 00 00 00 00 00 00 00 00 C0 00 00 00 ?00000040 0E 1F BA 0E 00 B4 09 CD 21 B8 01 4C CD 21 54 68 ?.?L?Th00000050 69 73 20 70 72 6F 67 72 61 6D 20 63 61 6E 6E 6F is program canno00000060 74 20 62 65 20 72 75 6E
4、20 69 6E 20 44 4F 53 20 t be run in DOS 00000070 6D 6F 64 65 2E 0D 0D 0A 24 00 00 00 00 00 00 00 mode$.00000080 A3 19 CD DB E7 78 A3 88 E7 78 A3 88 E7 78 A3 88 ?哇鐇 鐇 鐇00000090 E7 78 A3 88 FA 78 A3 88 84 5A 89 88 E6 78 A3 88 鐇 鷛 刏増鎥000000A0 52 69 63 68 E7 78 A3 88 00 00 00 00 00 00 00 00 Rich 鐇 00000
5、0B0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 000000C0 50 45 00 00 4C 01 03 00 C4 46 FA 3C 00 00 00 00 PEL.腇?000000D0 00 00 00 00 E0 00 0F 01 0B 01 05 0C 00 06 00 00 ?000000E0 00 0A 01 00 00 00 00 00 14 15 00 00 00 10 00 00 000000F0 00 20 00 00 00 00 40 00 00 10 00 00 00 02 00 00 . .00000100 0
6、4 00 00 00 00 00 00 00 04 00 00 00 00 00 00 00 00000110 00 40 01 00 00 04 00 00 00 00 00 00 03 00 00 00 .00000120 00 00 10 00 00 10 00 00 00 00 10 00 00 10 00 00 00000130 00 00 00 00 10 00 00 00 00 00 00 00 00 00 00 00 00000140 64 20 00 00 50 00 00 00 00 00 00 00 00 00 00 00 d P.00000150 00 00 00 00
7、 00 00 00 00 00 00 00 00 00 00 00 00 00000160 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00000170 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00000180 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00000190 00 00 00 00 00 00 00 00 00 20 00 00 64 00 00 00 . d.000001A0 00 00 00 00 00 00 00 0
8、0 00 00 00 00 00 00 00 00 000001B0 00 00 00 00 00 00 00 00 2E 74 65 78 74 00 00 00 .text.000001C0 F4 05 00 00 00 10 00 00 00 06 00 00 00 04 00 00 ?000001D0 00 00 00 00 00 00 00 00 00 00 00 00 20 00 00 60 000001E0 2E 72 64 61 74 61 00 00 EA 01 00 00 00 20 00 00 .rdata?. 000001F0 00 02 00 00 00 0A 00
9、00 00 00 00 00 00 00 00 00 00000200 00 00 00 00 40 00 00 40 2E 64 61 74 61 00 00 00 .data.00000210 66 07 01 00 00 30 00 00 00 02 00 00 00 0C 00 00 f000000220 00 00 00 00 00 00 00 00 00 00 00 00 40 00 00 C0 ?00000230 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00000240 00 00 00 00 00 00 00 00 00
10、00 00 00 00 00 00 00 00000250 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00000260 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00000270 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00000280 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00000290 00 00 00 00 00 00 00 00 00 00 00 00 00 00
11、00 00 000002A0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 000002B0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 000002C0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 000002D0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 000002E0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 000002F0
12、00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00000300 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00000310 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00000320 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00000330 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00000340 00 00 00 00 00
13、00 00 00 00 00 00 00 00 00 00 00 00000350 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00000360 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 PING.EXE 十六进制源码分析 中南林业科技大学计算机与信息工程学院 车生兵 著 严禁盗版400000370 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00000380 00 00 00 00 00 00 00 00 00 00 00 00 00
14、00 00 00 00000390 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 000003A0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 000003B0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 000003C0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 000003D0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 000003
15、E0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 000003F0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ;.text00000400 55 8B EC 83 C4 FC 60 C7 45 FC 00 00 00 00 E8 63 U 嬱兡黗荅?.鑓00000410 05 00 00 8B F0 FC AC 0A C0 74 20 3C 20 74 F7 4E .嬸 .纓 ; Ping.asm; 类似于 Windows 自带的 Ping.exe 程序,用 ICMP 协议实现 Ping
16、的功能; 使用 nmake 或下列命令进行编译和链接:; ml /c /coff Ping.asm; Link /SUBSYSTEM:CONSOLE Ping.obj;.386 ;本程序使用 386 指令集.model flat, stdcall ;本程序使用平坦内存模式,所有段共用 1 个 4GB 的空间option casemap :none ;程序对变量名的字母大小写不敏感; Include;include windows.inc ;窗口库 windows.dll,定义窗口操作函数include kernel32.inc ;32 位内核库 kernel32.dll,定义系统核心资源管理函
17、数includelib kernel32.lib ;导入库 kernel32.lib,定位 kernel32.dll 库函数include user32.inc ;32 位用户库 user32.dll,定义用户接口函数includelib user32.lib ;导入库 user32.lib,定位 user32.dll 库函数include wsock32.inc ;32 位 1.1 版本的套接字库 wsock32.dll,定义套接字函数includelib wsock32.lib ;导入库 wsock32.lib,定位 wsock32.dll 库函数PACKET_SIZE equ 32 ;缺
18、省包尺寸为 32 字节; 数据段;.data?szHostName db 100 dup (?) ;ping 后参数的存储空间szBuffer db 1024 dup (?) ;存放 ping 运行中显示的提示信息szBigBuffer db 65536 dup (?) ;接收 ICMP_REPLY 的大缓冲区stWsa WSADATA ; 代码段;.codeinclude _CmdLine.asm ;命令行参数处理子程序include _Console.asm ;控制台窗口处理子程序include _CheckSum.asm ;计算 ICMP 包的校验和; 函数 1:将主机名转换成 IP 地
19、址; 入口参数:_lpszHostName 保存主机名字符串地址; 出口参数:eax 保存 IP 地址;_HostnameToIP proc _lpszHostNamelocalszBuffer256:byte ;用于 IP 地址解析,存储显示信息localdwIP ;保存 IP 地址;将参数 1 直接转换成 IP 地址invoke inet_addr,_lpszHostName.if eax != INADDR_NONE ;地址转换成功,输入的是 IP 地址;*; 输入的是 IP 地址;*mov dwIP,eax ;保存 IP 地址invoke inet_ntoa,eax ;将 IP 地址转
20、换成字符串格式;在 szBuffer 中组合成显示字符串,例如:;Ping 202.106.185.203 with 32 bytes of data:invoke wsprintf,addr szBuffer,addr szPingOneIP,eax.else ;地址转换失败,输入的是主机名;*; 输入的是主机名称;*;根据主机名获取 hostent 结构地址invoke gethostbyname,_lpszHostName.if eax ;主机名有 IP 地址xor edi,edi ;用 edi 做计数器,统计主机名的 IP 地址数mov eax,eax+hostent.h_list ;
21、计算 IP 地址列表首地址PING.EXE 十六进制源码分析 中南林业科技大学计算机与信息工程学院 车生兵 著 严禁盗版29.while dword ptr eax ;有 IP 地址可取mov ebx,eax ;取出 IP 地址pushebx ;入栈保存inc edi ;计数器增 1add eax,4 ;指向下一个 IP 地址存储地址.endwpop eax ;取出找到的最后一个 IP 地址mov dwIP,eax ;存入dwIPinvoke inet_ntoa,eax ;将 IP 地址转换成字符串格式mov ebx,eax ;ebx 指向 IP 地址字符串.if edi = 1 ;主机对应一
22、个 IP 地址;在 szBuffer 中组合成显示字符串,例如:;The IP address of is 202.103.67.245invoke wsprintf,addr szBuffer,addr szHostOneIP,_lpszHostName,ebx;在szBuffer 中组合成显示字符串,例如:;Ping 202.103.67.245 with 32 bytes of data:;以后会从szBuffer 转移到 szBuffer 中invoke wsprintf,addr szBuffer,addr szPingOneIP,ebx.else ;主机对应多个 IP 地址;在
23、szBuffer 中组合成显示字符串,例如:;The host has 5 IP addresses:invoke wsprintf,addr szBuffer,addr szHostMoreIP,_lpszHostName,edi;显示第一个 IP 地址。例如:;202.106.185.203invoke lstrcat,addr szBuffer,ebx;在szBuffer 中组合成显示字符串,例如:;Ping first IP 202.106.185.203 with 32 bytes of data:;以后会从szBuffer 转移到 szBuffer 中invoke wsprint
24、f,addr szBuffer,addr szPingMoreIP,ebx.while edi 1 ;还有 IP 地址未处理;在上个地址后加上分隔符“ / ”invoke lstrcat,addr szBuffer,addr szSparpop eax ;取一个 IP 地址invoke inet_ntoa,eax ;转换成字符串invoke lstrcat,addr szBuffer,eax ;插入到上个 IP 地址后面dec edi ;IP 地址计数器减 1.endw.endif;将szBuffer 中字符串转移到 szBuffer 中,组成一个完整的字符串,如:;The host has
25、 5 IP addresses:;202.106.185.203 / 202.106.185.198 / 202.106.185.196 / 202.106.185.205 / 202.106.185.204;Ping first IP 202.106.185.203 with 32 bytes of data:invoke lstrcat,addr szBuffer,addr szBufferPING.EXE 十六进制源码分析 中南林业科技大学计算机与信息工程学院 车生兵 著 严禁盗版30.else ;主机名没有对应的 IP 地址;提示出错,例如:Unknown host abc.bcd.d
26、ef.efginvoke wsprintf,addr szBuffer,addr szErrHost,addr szHostName;在控制台中显示出错提示信息invoke _ConsolePrint,addr szBuffer;设置返回的 IP 地址值为 0000 0000Hxor eax,eaxret.endif.endif;在控制台中显示 szBuffer 中的提示信息invoke _ConsolePrint,addr szBuffer;返回参数 eax 保存 IP 地址mov eax,dwIPret_HostnameToIP endp; 函数 2:Ping 主程序; 入口参数:_dwI
27、P 保存 IP 地址; 出口参数:无;_Ping proc _dwIPlocalszBuffer256:byte ;组合要显示的测试结果提示信息localstDest:sockaddr_in ;目的端 IP 与端口号绑定的组合结构localstFrom:sockaddr_in ;源端 IP 与端口号绑定的组合结构localhSocket,dwSize ;本机端套接字localstFdSet:fd_set ;检测结构体localstTimeval:timeval ;指定检测的超时时间结构体localdwID:word,dwSeq:word ;ICMP 包的 ID 与 SEQ 域;得到目的端 IP
28、 与端口号绑定的组合结构stDestpushadmov stDest.sin_port,0 ;ICMP 不复用对方 IP,不设端口号mov stDest.sin_family,AF_INET ;地址类型push_dwIPpop stDest.sin_addr ;IP 地址;*; 初始化一个 socket 发送 ICMP 的 RAW 数据(即:原始套接字数据报文);*;创建原始套接字,使用 ICMP 协议,套接字默认工作方式为阻塞方式;没有消息响应invoke socket,AF_INET,SOCK_RAW,IPPROTO_ICMP.if eax = INVALID_SOCKET ;套接字创建失败;显示:Socket error.invoke _ConsolePrint,addr szErrSocket