MASM32编写TcpStatC再进阶 显示PID和对应进程说明符

30 篇文章 0 订阅
23 篇文章 0 订阅

 

上周改写的TcpStatC,使用了API函数 GetTcpTable,不能显示网络端口关联的进程ID和进程名或进程对应文件说明符。周末抽空改进了一下。

要获取和显示网络端口关联的进程ID和进程名,可以改用API函数GetExtendedTcpTable,获取MIB_TCPROW_OWNER_PID 或 MIB_TCPTABLE_OWNER_MODULE,但是MASM32中没有对这两个结构体进行预定义。需要DIY:

MIB_TCPROW_OWNER_PID 的相关定义如下:

 ; typedef struct _MIB_TCPROW_OWNER_PID {
 ;   DWORD dwState;
 ;   DWORD dwLocalAddr;
 ;   DWORD dwLocalPort;
 ;   DWORD dwRemoteAddr;
 ;   DWORD dwRemotePort;
 ;   DWORD dwOwningPid;
 ; } MIB_TCPROW_OWNER_PID, *PMIB_TCPROW_OWNER_PID;

MIB_TCPROW_OWNER_PID struct
  dwState      DWORD ?
  dwLocalAddr  DWORD ?
  dwLocalPort  DWORD ?
  dwRemoteAddr DWORD ?
  dwRemotePort DWORD ?
  dwOwningPid  DWORD ? ;进程ID
MIB_TCPROW_OWNER_PID ends
PMIB_TCPROW_OWNER_PID typedef ptr MIB_TCPROW_OWNER_PID


 ; typedef struct _MIB_TCPTABLE_OWNER_PID {
 ;   DWORD                dwNumEntries;
 ;   MIB_TCPROW_OWNER_PID table[ANY_SIZE];
 ; } MIB_TCPTABLE_OWNER_PID, *PMIB_TCPTABLE_OWNER_PID;
 ; 

MIB_TCPTABLE_OWNER_PID struct
  dwNumEntries DWORD ?
  table        MIB_TCPROW_OWNER_PID ANY_SIZE dup(<?>)
MIB_TCPTABLE_OWNER_PID ends
PMIB_TCPTABLE_OWNER_PID typedef ptr MIB_TCPTABLE_OWNER_PID

MIB_TCPROW_OWNER_PID中的成员dwOwningPid包含了端口对应的进程ID。

MIB_TCPTABLE_OWNER_MODULE 的相关定义如下: 

 ; typedef struct _MIB_TCPROW_OWNER_MODULE {
 ;   DWORD         dwState;
 ;   DWORD         dwLocalAddr;
 ;   DWORD         dwLocalPort;
 ;   DWORD         dwRemoteAddr;
 ;   DWORD         dwRemotePort;
 ;   DWORD         dwOwningPid;
 ;   LARGE_INTEGER liCreateTimestamp;
 ;   ULONGLONG     OwningModuleInfo[TCPIP_OWNING_MODULE_SIZE];
 ; } MIB_TCPROW_OWNER_MODULE, *PMIB_TCPROW_OWNER_MODULE

MIB_TCPROW_OWNER_MODULE struct
    dwState           DWORD ?
    dwLocalAddr       DWORD ?
    dwLocalPort       DWORD ?
    dwRemoteAddr      DWORD ?
    dwRemotePort      DWORD ?
    dwOwningPid       DWORD ? ;进程ID
    liCreateTimestamp LARGE_INTEGER <>
    OwningModuleInfo  ULONGLONG  TCPIP_OWNING_MODULE_SIZE dup(?)
MIB_TCPROW_OWNER_MODULE ends
PMIB_TCPROW_OWNER_MODULE  typedef ptr MIB_TCPROW_OWNER_MODULE

 ; typedef struct _MIB_TCPTABLE_OWNER_MODULE {
 ;   DWORD                   dwNumEntries;
 ;   MIB_TCPROW_OWNER_MODULE table[ANY_SIZE];
 ; } MIB_TCPTABLE_OWNER_MODULE, *PMIB_TCPTABLE_OWNER_MODULE

MIB_TCPTABLE_OWNER_MODULE struct
    dwNumEntries DWORD ?
    table        MIB_TCPROW_OWNER_MODULE ANY_SIZE dup(<?>)
MIB_TCPTABLE_OWNER_MODULE ends

PMIB_TCPTABLE_OWNER_MODULE typedef ptr MIB_TCPTABLE_OWNER_MODULE

MIB_TCPROW_OWNER_MODULE 中的成员dwOwningPid包含了端口对应的进程ID。

先试试MIB_TCPROW_OWNER_PID。

        invoke GetExtendedTcpTable, g_pTcpTable, addr dwSize, TRUE, AF_INET, TCP_TABLE_OWNER_PID_ALL, 0

取得PID后,通过依次调用API函数 OpenProcess、EnumProcessModules、GetModuleBaseName来获取进程名。

如果要取得进程对应的文件说明符,可以将GetModuleBaseName改为另外一个API函数GetModuleFileNameEx。

我是先尝试GetModuleFileNameEx,如果不成功,再使用GetModuleBaseName。代码如下:

;=================================================
;Function: Get process name with process id
; Input:  dwPid: process id
; Output: if eax = 0 then fail
; else eax = the length of the string copied to the buffer
;==================================================
getProcNameById proc dwPid:DWORD
    local hMod, hProc: HANDLE
    local dwNeeded: DWORD

    invoke OpenProcess, PROCESS_QUERY_INFORMATION or PROCESS_VM_READ, FALSE, dwPid
    .if eax!=NULL
        mov    hProc, eax
        invoke GetModuleFileNameEx, hProc, NULL, offset g_szProcFileSpec, sizeof g_szProcFileSpec
        .IF eax==0
            invoke EnumProcessModules, hProc, addr hMod, sizeof hMod, addr dwNeeded
            .if eax!=0
                invoke GetModuleBaseName, hProc, hMod, offset g_szProcFileSpec,  sizeof g_szProcFileSpec;
            .endif
        .ENDIF
        push   eax
        invoke CloseHandle, hProc
        pop    eax
    .endif

    ret
getProcNameById endp

在Windows 10上运行时,会发现有不少进程不能获取文件说明符,解决的办法是一要以具有管理员权限的帐号来运行程序,二要提升程序的特权,我尝试了获取SeDebugPrivilege,代码如下:

;=================================================
;Function: Let current process get the privilege
; Input: (none)
; Output: eax = 0 Success
; eax = 1 , fail to OpenProcessToken
; eax = 2 , fail to LookupPrivilegeValue
;==================================================
EnableDebugPriv proc
    LOCAL hToken: HANDLE
    ;LOCAL sedebugnameValue: LUID ;An LUID is a 64-bit value
    LOCAL sedebugnameValue[2]: DWORD
    LOCAL tkp: TOKEN_PRIVILEGES

    invoke GetCurrentProcess
    mov ebx, eax

    invoke OpenProcessToken, ebx, TOKEN_ADJUST_PRIVILEGES or TOKEN_QUERY, addr hToken
    .if (eax == 0)
        mov eax, 1
        ret
    .endif

    invoke LookupPrivilegeValue, NULL, offset g_szSE_DEBUG_NAME, addr sedebugnameValue
    .if (eax == 0)
        invoke CloseHandle, hToken
        mov eax, 2
        ret
    .endif

    mov tkp.PrivilegeCount, 1
    lea eax, tkp.Privileges
    m_m2m [eax], sedebugnameValue
    m_m2m [eax+4], [sedebugnameValue+1]

    mov ( LUID_AND_ATTRIBUTES ptr [eax]).Attributes, SE_PRIVILEGE_ENABLED

    invoke AdjustTokenPrivileges, hToken, FALSE, addr tkp, sizeof tkp, NULL, NULL
    .if (eax == 0)
        invoke CloseHandle, hToken
    .endif

    xor eax, eax
    ret
EnableDebugPriv endp

生成的EXE文件信息如下:


文件说明符 : K:\TcpStatC.exe
属性 : A---
数字签名:否
PE文件:是
获取文件版本信息大小失败!
创建时间 : 2022-8-14 22:13:51
修改时间 : 2022-8-14 22:18:8
大小 : 5120 字节 5.0 KB
MD5 : a17a53ab06707808ba456ba90374a9ee
SHA1: 156A74E1E5BB56D00383E926F9983D8DBE480753
CRC32: 901593e7

下载地址:http://endurer.ys168.com/  tools工具/网络工具 下

程序运行效果如下:

  netstat 命令显示如下:

参考:

枚举所有进程 - Win32 apps | Microsoft Docs

GetModuleFileNameExA function (psapi.h) - Win32 apps | Microsoft Docs

EnumProcessModules function (psapi.h) - Win32 apps | Microsoft Docs

GetModuleBaseNameA function (psapi.h) - Win32 apps | Microsoft Docs

TCP,UDP服务端口,HMODULE hIpDLL = LoadLibrary( "iphlpapi.dll"); if ( !hIpDLL) return; PMIB_TCPTABLE_OWNER_PID pTcpTable(NULL); DWORD dwSize(0); PGet_Extended_TcpTable pGetExtendedTcpTable = NULL; pGetExtendedTcpTable = (PGet_Extended_TcpTable) GetProcAddress(hIpDLL, "GetExtendedTcpTable"); if(pGetExtendedTcpTable==NULL) { FreeLibrary(hIpDLL); return; } if(pGetExtendedTcpTable(pTcpTable, &dwSize, TRUE, AF_INET, TCP_TABLE_OWNER_PID_ALL, 0) == ERROR_INSUFFICIENT_BUFFER) pTcpTable = (MIB_TCPTABLE_OWNER_PID *)new char[dwSize];//重新分配缓冲区 if (pGetExtendedTcpTable(pTcpTable, &dwSize, TRUE, AF_INET, TCP_TABLE_OWNER_PID_ALL, 0) != NO_ERROR) { delete pTcpTable; return; } CString sTemp; m_PortList.DeleteAllItems(); int nNum = (int)pTcpTable->dwNumEntries; //TCP连接的数目 // nNum = 0; for (int i = 0; itable[i].dwLocalAddr))); sTemp.Format("%u",htons((WORD)pTcpTable->table[i].dwLocalPort)); m_PortList.SetItemText(i,4,sTemp); m_PortList.SetItemBgColor(i,4,RGB(210,0,0)); m_PortList.SetItemText(i,5,FormatNumToIpv4(htonl(pTcpTable->table[i].dwRemoteAddr))); sTemp.Format("%u",htons((WORD) pTcpTable->table[i].dwRemotePort)); m_PortList.SetItemText(i,6,sTemp); sTemp.Format("%u",pTcpTable->table[i].dwOwningPid); m_PortList.SetItemText(i,8,sTemp); //ProcessPidToName(pTcpTable->table[i].dwOwningPid,i); ProcessPidToNameX(pTcpTable->table[i].dwOwningPid,i); switch (pTcpTable->table[i].dwState) { case MIB_TCP_STATE_CLOSED: m_PortList.SetItemText(i,2,"CLOSED"); break; case MIB_TCP_STATE_LISTEN: m_PortList.SetItemText(i,2,"LISTEN"); break; case MIB_TCP_STATE_SYN_SENT: m_PortList.SetItemText(i,2,"SYN
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

紫郢剑侠

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

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

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

打赏作者

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

抵扣说明:

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

余额充值