ping.asm

来自「windows下汇编语言 学习汇编语言好助手」· 汇编 代码 · 共 305 行

ASM
305
字号
;*****************************
;文件:Ping.asm              *
;功能:Ping程序和RAW Socket  *
;*****************************
.386p
.model flat,stdcall
extrn MessageBoxA:proc
extrn ExitProcess:proc
extrn WSAStartup:proc
extrn htons:proc
extrn gethostbyname:proc
extrn getprotobyname:proc
extrn socket:proc
extrn connect:proc
extrn recv:proc
extrn recvfrom:proc
extrn closesocket:proc
extrn accept:proc
extrn _wsprintfA:proc
extrn send:proc
extrn sendto:proc
extrn bind:proc
extrn listen:proc
extrn GetTickCount:proc
extrn Sleep:proc
extrn WSASocketA:proc
extrn setsockopt:proc
extrn inet_ntoa:proc
extrn WriteConsoleA:proc
extrn SetConsoleTitleA:proc
extrn CreateConsoleScreenBuffer:proc
extrn CloseHandle:proc
extrn SetConsoleActiveScreenBuffer:proc
extrn GetCommandLineA:proc

NULL  = 0
MB_OK = 0
GENERIC_READ		equ	80000000H
GENERIC_WRITE		equ	40000000H
FILE_SHARE_READ		equ	00000001H
FILE_SHARE_WRITE	equ	00000002H
CONSOLE_TEXTMODE_BUFFER equ	1
INVALID_HANDLE_VALUE	equ	-1
IPPROTO_IP          =    0
IPPROTO_ICMP        =    1
AF_INET       =  2
PF_INET       =  AF_INET
SOCK_RAW      =  3
SOL_SOCKET   =   0ffffH
SO_SNDTIMEO     =1005H
SO_RCVTIMEO     =1006H
ICMP_ECHO  = 8
ICMP_ECHOREPLY = 0

IpHeader	struc
	len_ver		db ?
	tos		db ?
	total_len	dw ?
	ident		dw ?
	frag_and_flags	dw ?
	ttl		db ?
	proto		db ?
	checksum	dw ?

	sourceIP	dd ?
	destIP	dd ?
		ends

IcmpHeader	struc
  i_type	db ?
  i_code	db ?
  i_cksum	dw ?
  i_id		dw ?
  i_seq		dw ?
  timestamp	dd ?
  		ends
in_addr	struc
	s_addr	dd ?
	ends

hostent	struc
        h_name		dd ?
        h_aliases	dd ?
        h_addrtype	dw ?
        h_length	dw ?
        h_addr_list	dd ?
;h_addr  h_addr_list[0]          /* address, for backward compat */
	ends

protoent	struc
        p_name		dd ?
        p_aliases	dd ?
        p_proto		dw ?
	dw ?
	ends

sockaddr_in	struc
        sin_family	dw ?
        sin_port	dw ?
        sin_addr	dd ?
        sin_zero 	db 8 dup (?)
	ends

WSADESCRIPTION_LEN      = 256
WSASYS_STATUS_LEN       = 128
WSADATA	struc
        wVersion	dw ?
        wHighVersion	dw ?
        szDescription	db WSADESCRIPTION_LEN+1 dup (0)
        szSystemStatus	db WSASYS_STATUS_LEN+1	dup (0)
        iMaxSockets	dw ?
        iMaxUdpDg	dw ?
        lpVendorInfo	dd ?
	ends

.data
	Caption db 'Ping Application',0

	Text	db 100 dup (?)
	tmp		db '%d bytes from %s: icmp_seq = %d. time: %d ms',13,10,0
	align 4
	hCS		dd ?
	host	dd ?
	ph		dd ?
	sockRaw	dd ?
	timeout	dd ?
	fromlen dd ?
	wsaData	WSADATA<>
	from sockaddr_in<>
	desc sockaddr_in<>

ICMP_DATA_LEN = 500
ICMP_DATA_RECV_LEN = ICMP_DATA_LEN*2
	icmp_data	db ICMP_DATA_LEN dup (0)
	recvbuf		db ICMP_DATA_RECV_LEN dup (0)

.code
main:
 	call	SetConsoleTitleA ,offset Caption	;改变窗口标题
	call	CreateConsoleScreenBuffer,GENERIC_WRITE,FILE_SHARE_WRITE,NULL,CONSOLE_TEXTMODE_BUFFER,NULL
	cmp		eax,INVALID_HANDLE_VALUE			;建立失败?
	jz		Error
	mov		[hCS],eax
	call	SetConsoleActiveScreenBuffer,eax	;设置有效的制台screen buffer
;*****************************************************************
	;读命令行
	call	GetCommandLineA
	mov		esi,eax
	cld
load:
	lodsb
	cmp		al,' '
	jz		GetCommandLineNext
	cmp		al,0
	jz		GetCommandLineNext
	jmp		load
GetCommandLineNext:
	cmp		al,0
	jz		Error
load1:
	lodsb
	cmp		al,' '
	jz		load1
	dec		esi
	mov		host,esi

	call	WSAStartup,0201H,offset wsaData
	;建立Raw Socket
	call	WSASocketA,AF_INET,SOCK_RAW,IPPROTO_ICMP,NULL, 0,0
	mov		sockRaw,eax
	;设置超时
	mov		timeout,1000
	call	setsockopt,sockRaw,SOL_SOCKET,SO_RCVTIMEO,offset timeout,size timeout
	mov		timeout,1000
	call	setsockopt,sockRaw,SOL_SOCKET,SO_SNDTIMEO,offset timeout,size timeout
	
	call	gethostbyname, host
	mov		ph,eax
	or		eax,eax
	jz		Error
	movzx	ecx,[eax].h_length
	mov		edx,[eax].h_addr_list
	mov		edx,[edx]
	mov		ebx,offset desc
	add		ebx,sin_addr
	call	CopyMemory,ebx,edx,ecx
	
	mov		ebx,ph
	mov		ax,[ebx].h_addrtype
	mov		desc.sin_family,ax

	;填icmp包数据
	mov		icmp_data.i_type,ICMP_ECHO
	mov		icmp_data.i_code,0
	mov		icmp_data.i_id,1234H
	mov		icmp_data.i_seq,0
	mov		ebx,offset icmp_data
	add		ebx,size IcmpHeader
	call	SetMemory,ebx,'Q',ICMP_DATA_LEN - size IcmpHeader

pingagain:
	mov		icmp_data.i_cksum,0
	call	GetTickCount
	mov		icmp_data.timestamp,eax
	inc		icmp_data.i_seq
	call	CalcSum,offset icmp_data,ICMP_DATA_LEN
	mov		icmp_data.i_cksum,ax
	;送出包
	call	sendto,sockRaw,offset icmp_data,ICMP_DATA_LEN,0,offset desc,size desc
	cmp		eax,0
	js		Error
	mov		fromlen,size from
	;接收
	call	recvfrom,sockRaw,offset recvbuf,ICMP_DATA_RECV_LEN,0,offset from,offset fromlen
	cmp		eax,0
	js		Error
	;分析并打印包信息
	call	decode_resp,eax

	call	Sleep,1000	
	jmp		pingagain
Error:
MainEnd:
	call	CloseHandle,[hCS]	
	call	ExitProcess,0
;***********************************
CopyMemory proc des:DWORD,src:DWORD,len:DWORD
	mov		edi,des
	mov		esi,src
	mov		ecx,len
	cld
	rep		movsb
	ret
CopyMemory endp

SetMemory proc p:DWORD,b:DWORD,n:DWORD
	mov		edi,p
	mov		eax,b
	mov		ecx,n
	cld
	rep		stosb
	ret
SetMemory endp
;**************************************
;计算校验和
CalcSum proc buff:DWORD,len:DWORD
	mov		ecx,len
	mov		ebx,buff
	xor		eax,eax
	xor		esi,esi
calc:
	mov		si,[ebx]
	add		eax,esi
	add		ebx,2
	sub		ecx,2
	jnz		calc

	mov		ebx,eax
	shr		ebx,16
	movzx	eax,ax
	add		eax,ebx

	mov		ebx,eax
	shr		ebx,16
	add		eax,ebx

	not		ax
	ret
CalcSum endp
;分析并打印收到的包信息
decode_resp proc bytes:DWORD
	LOCAL databegin:DWORD
	mov		bl,recvbuf.len_ver
	and		bl,0fh
	movzx	ebx,bl
	shl		ebx,2
	add		ebx,offset recvbuf
	mov		databegin,ebx

	mov		ecx,offset from
	add		ecx,sin_addr
	mov		ecx,[ecx]
	call	inet_ntoa,ecx
	push	eax
	call	GetTickCount
	mov		ebx,databegin
	sub		eax,[ebx].timestamp
	pop		edx
	movzx	ecx,[ebx].i_seq
	call	_wsprintfA,offset Text,offset tmp,bytes,edx,ecx,eax
	add		esp,4*6
	call	print,offset Text,eax
	ret
decode_resp endp
;*********************************************
print proc what:DWORD,len:DWORD
	LOCAL	Written:DWORD
	lea		ebx,Written
	call	WriteConsoleA,[hCS],what,len,ebx,NULL
	ret
print endp

	ErrMsg db '错误!程序退出',0
	end main

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?