2012写的netViewG,因为该程序所调用的Windows API 函数在Windows 7以上系统不再支持,所以只能在Windows XP下运行,为了更新它,需要重新用新的Windows API来重写。
首先参考了微软官网MIB_TCPTABLE (tcpmib.h) - Win32 apps | Microsoft Docshttps://docs.microsoft.com/en-us/windows/win32/api/tcpmib/ns-tcpmib-mib_tcptable上的公开的例子,把它用MASM32代码来实现为TcpStatC.asm,主要功能是显示当前的的 TCP 连接数量,以及每个连接的本地IP地址:端口、远程IP地址:端口和状态。
文件信息如下:
文件说明符 : K:\TcpStatC.exe
属性 : A---
数字签名:否
PE文件:是
创建时间 : 2022-7-31 0:6:2
修改时间 : 2022-7-31 17:29:23
大小 : 4096 字节 4.0 KB
MD5 : 88bba78a2dcb50633fa9b61c408bcf8f
SHA1: 91C6B6B531BE9A082641249910035C46B39D6D3B
CRC32: 67fb983f
运行效果如下:
跟 netstat命令执行的结果是相似的:
虽然都是定义数据结构和调用Windows API,但在转换过程中,由于MASM32的一些特性,有几处代码并不能转换,整理如下:
一、结构体的转换
以MIB_TCPROW为例,c++的定义如下:
- typedef struct _MIB_TCPROW {
- union {
- DWORD dwState;
- MIB_TCP_STATE State;
- };
- DWORD dwLocalAddr;
- DWORD dwLocalPort;
- DWORD dwRemoteAddr;
- DWORD dwRemotePort;
- } MIB_TCPROW, *PMIB_TCPR
转换成MASM32代码的理论定义如下:
- MIB_TCPROW struct
- union
- dwState DWORD ?
- State MIB_TCP_STATE ?
- ends
- dwLocalAddr DWORD ?
- dwLocalPort DWORD ?
- dwRemoteAddr DWORD ?
- dwRemotePort DWORD ?
- MIB_TCPROW ends
- PMIB_TCPROW typedef ptr MIB_TCPROW
但是用这个定义来对另外一个结构体MIB_TCPTABLE进行定义会出现问题。
MIB_TCPTABLE结构体的c++定义代码为:
- typedef struct _MIB_TCPTABLE {
- DWORD dwNumEntries;
- MIB_TCPROW table[ANY_SIZE];
- } MIB_TCPTABLE, *PMIB_TCPTABLE;
转换为MASM32定义代码为:
- MIB_TCPTABLE struct
- dwNumEntries DWORD ?
- table MIB_TCPROW ANY_SIZE dup(<?>)
- MIB_TCPTABLE ends
由于MIB_TCPTABLE的成员table的类型是结构体MIB_TCPROW,在汇编过程中将会收到两个错误:
TcpStatC.asm(94) : error A2138: invalid data initializer
TcpStatC.asm(94) : error A2036: too many initial values for structure
解决的办法是采用下面的代码来定义结构体MIB_TCPROW:
- MIB_TCPROW struct
- ;union
- dwState DWORD ?
- ;State MIB_TCP_STATE ?
- ;ends
- dwLocalAddr DWORD ?
- dwLocalPort DWORD ?
- dwRemoteAddr DWORD ?
- dwRemotePort DWORD ?
- MIB_TCPROW ends
- PMIB_TCPROW typedef ptr MIB_TCPROW
因为我们在程序中实际上只访问了MIB_TCPROW结构体中的成员dwState,没有用到成员State。
二、获取和输出本地和远程IP地址和端口,以本地IP地址和端口为例
示例中的c++代码如下:
- IpAddr.S_un.S_addr = (u_long) pTcpTable->table[i].dwLocalAddr;
- strcpy_s(szLocalAddr, sizeof (szLocalAddr), inet_ntoa(IpAddr));
-
- printf("\tTCP[%d] Local Addr: %s\n", i, szLocalAddr);
-
- printf("\tTCP[%d] Local Port: %d \n", i,
- ntohs((u_short)pTcpTable->table[i].dwLocalPort));
转换为MASM32代码中没有一对一转换,而是用了以下代码:
- GetIp proc ipaddr: dword, pIP: LPSTR
- local nipaddr: dword
-
- ;pushad
- invoke htonl, ipaddr
-
- mov ebx, eax
- mov ecx, eax
- mov edx, eax
-
- and eax, 0ffh
-
- shr ebx, 8
- and ebx, 0ffh
-
- shr ecx, 16
- and ecx, 0ffh
-
- shr edx, 24
- and edx, 0ffh
-
- invoke wsprintf, pIP, addr g_szFmtIP, edx, ecx, ebx, eax
- ;popad
-
- ret
- GetIp endp
-
-
- getPort proc
- ;invoke printEax
- invoke ntohs, eax
- movzx eax, ax
- ;invoke printEax
-
- ret
- getPort endp
-
- ……
-
- ; Get Local port
- mov eax, (MIB_TCPROW ptr [esi]).dwLocalPort
- invoke getPort
- mov dwPort, eax
-
- ; Get Local Addr ip
- ;mov esi, pTable
- invoke GetIp, (MIB_TCPROW ptr [esi]).dwLocalAddr, offset g_szBuf128a
-
- ; Print NO-TCP-LocalAddrIp:Port
- pop eax
- push eax
- inc eax
- invoke wsprintf, offset g_szBuf128b, offset g_szFmtNoTcpLocalAddrPort\
- , eax, offset g_szBuf128a, dwPort
- invoke StdOut, offset g_szBuf128b