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

Posted 紫郢剑侠

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了MASM32编写TcpStatC再进阶 显示PID和对应进程说明符相关的知识,希望对你有一定的参考价值。

上周改写的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

以上是关于MASM32编写TcpStatC再进阶 显示PID和对应进程说明符的主要内容,如果未能解决你的问题,请参考以下文章

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

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

我用的是win7 32位系统,使用汇编语言编写程序的时候,输入输出字符串的汇编程序可以顺利执行

masm32基本配置与写出第一个汇编程序

32 位 MASM 模式与 64 位有何不同?

sysInfo-用MASM32编写的Windows系统软件硬件网络信息收集程序