从编写TcpStatC谈c++代码改写为masm32代码的两个需要注意的地方

138 篇文章 0 订阅
23 篇文章 0 订阅
本文介绍了将一个依赖于Windows XP API的程序更新到支持Windows 7以上系统的进程,通过参考微软官方文档,使用MASM32汇编语言重写了TCP连接状态监控工具。文章详细展示了结构体转换、IP地址和端口处理的代码示例,并解释了解决转换过程中遇到的问题和解决方案。
摘要由CSDN通过智能技术生成

2012写的netViewG,因为该程序所调用的Windows API 函数在Windows 7以上系统不再支持,所以只能在Windows XP下运行,为了更新它,需要重新用新的Windows API来重写。

首先参考了微软官网MIB_TCPTABLE (tcpmib.h) - Win32 apps | Microsoft Docsicon-default.png?t=O83Ahttps://docs.microsoft.com/en-us/windows/win32/api/tcpmib/ns-tcpmib-mib_tcptable上的公开的例子,把它用MASM32代码来实现为TcpStatC.asm,主要功能是显示当前的的 TCP 连接数量,以及每个连接的本地IP地址:端口、远程IP地址:端口和状态。

下载地址:TcpStatC.zip-网络监控文档类资源-CSDN文库

文件信息如下:

文件说明符 : 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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

紫郢剑侠

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值