通过套接字端口获取应用程序路径 [英] Get app path by socket port

查看:167
本文介绍了通过套接字端口获取应用程序路径的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

假设您有一个应用程序打开用于通信目的的套接字端口。
如何通过知道其端口来获取此应用的路径?
我想做netstat -b做的。它列出打开的所有套接字端口和打开套接字的应用程序。
我正在使用delphi 2010.
通过知道应用程序打开,我的端口我能够杀死该应用程序。
请注意,我需要一个delphi代码,而不是一个Dos命令或者说如何使用netstat。

解决方案

拉斐尔,您可以使用 GetExtendedTcpTable 函数,此函数检索包含TCP连接可用性列表的表。



首先必须检查记录通过此功能返回,并检查 dwLocalPort dwRemotePort (根据您需要检查的端口),那么你可以获取应用程序的pid,检查 dwOwningPid 字段,并使用Windows API函数(如 GetModuleFileNameEx



检查示例应用程序,显示所有tcp连接,如netstat。您可以修改此样本以符合您的要求。

 使用
PsAPI,
WinSock,
Windows,
SysUtils;

const
ANY_SIZE = 1;
iphlpapi ='iphlpapi.dll';
TCP_TABLE_OWNER_PID_ALL = 5;

MIB_TCP_STATE:
数组[1..12]的string =('CLOSED','LISTEN','SYN-SENT','SYN-RECEIVED','ESTABLISHED',' FIN-WAIT-1',
'FIN-WAIT-2','CLOSE-WAIT','CLOSING','LAST-ACK','TIME-WAIT','删除TCB');

type
TCP_TABLE_CLASS =整数;

PMibTcpRowOwnerPid = ^ TMibTcpRowOwnerPid;
TMibTcpRowOwnerPid =打包记录
dwState:DWORD;
dwLocalAddr:DWORD;
dwLocalPort:DWORD;
dwRemoteAddr:DWORD;
dwRemotePort:DWORD;
dwOwningPid:DWORD;
结束


PMIB_TCPTABLE_OWNER_PID = ^ MIB_TCPTABLE_OWNER_PID;
MIB_TCPTABLE_OWNER_PID =打包记录
dwNumEntries:DWord;
表:数组[0..ANY_SIZE - 1] OF TMibTcpRowOwnerPid;
结束

var
GetExtendedTcpTable:function(pTcpTable:Pointer; dwSize:PDWORD; bOrder:BOOL; lAf:ULONG; TableClass:TCP_TABLE_CLASS; Reserved:ULONG):DWord;标准




函数GetPathPID(PID:DWORD):string;
var
句柄:THandle;
begin
结果:='';
句柄:= OpenProcess(PROCESS_QUERY_INFORMATION或PROCESS_VM_READ,False,PID);
如果Handle<> 0 then
try
SetLength(Result,MAX_PATH);
if GetModuleFileNameEx(Handle,0,PChar(Result),MAX_PATH)> 0然后
SetLength(Result,StrLen(PChar(Result)))
else
结果:='';
finally
CloseHandle(Handle);
结束
结束


程序ShowCurrentTCPConnections;
var
错误:DWORD;
TableSize:DWORD;
i:integer;
IpAddress:in_addr;
RemoteIp:string;
LocalIp:string;
FExtendedTcpTable:PMIB_TCPTABLE_OWNER_PID;
begin
TableSize:= 0;
错误:= GetExtendedTcpTable(nil,@TableSize,False,AF_INET,TCP_TABLE_OWNER_PID_ALL,0);
如果错误<> ERROR_INSUFFICIENT_BUFFER然后
退出;

GetMem(FExtendedTcpTable,TableSize);
尝试
如果GetExtendedTcpTable(FExtendedTcpTable,@TableSize,TRUE,AF_INET,TCP_TABLE_OWNER_PID_ALL,0)= NO_ERROR然后
为i:= 0到FExtendedTcpTable.dwNumEntries - 1 do
if { (FExtendedTcpTable.Table [i] .dwOwningPid = Pid)和}(FExtendedTcpTable.Table [i] .dwRemoteAddr<> 0)那么//这里你可以检查特定端口
begin
IpAddress.s_addr := FExtendedTcpTable.Table [i] .dwRemoteAddr;
RemoteIp:= string(inet_ntoa(IpAddress));
IpAddress.s_addr:= FExtendedTcpTable.Table [i] .dwLocalAddr;
LocalIp:= string(inet_ntoa(IpAddress));
Writeln(GetPathPID(FExtendedTcpTable.Table [i] .dwOwningPid));
Writeln(格式('% - 16s%-6d%-16s%-6d%s',[LocalIp,FExtendedTcpTable.Table [i] .dwLocalPort,RemoteIp,FExtendedTcpTable.Table [i] .dwRemotePort,MIB_TCP_STATE [ FETPENDTCPTable.Table [i] .dwState]]));
结束
finally
FreeMem(FExtendedTcpTable);
结束
结束

var
libHandle:THandle;
begin
try
ReportMemoryLeaksOnShutdown = = DebugHook<> 0;
libHandle:= LoadLibrary(iphlpapi);
GetExtendedTcpTable:= GetProcAddress(libHandle,'GetExtendedTcpTable');
ShowCurrentTCPConnections;
除了
在E:Exception do
Writeln(E.ClassName,':',E.Message);
结束

readln;
结束。


Lets assume you have a app that opens a socket port for comunication purpose. How can i get the path of this app only by knowing its port? I wanna do what netstat -b does. It lists all socket ports opened and the app that opened the socket. I am using delphi 2010. By knowing wich app opened wich port i am able to kill the app. Note that i need a delphi code, not an Dos command or an explanation of how to use netstat.

解决方案

Rafael, you can use the GetExtendedTcpTable function, this function retrieves a table that contains a list of TCP connections availables.

first you must inspect the records returned by this function, and check the dwLocalPortor dwRemotePort (depending of what port your need to check), then you can get the pid of the application checking the dwOwningPid field and resolve the exe name using a windows api function like GetModuleFileNameEx

Check this sample application which show all tcp connections like netstat. you can modify this sample to fit with your requirements.

uses
      PsAPI,
      WinSock,
      Windows,
      SysUtils;

    const
       ANY_SIZE = 1;
       iphlpapi = 'iphlpapi.dll';
       TCP_TABLE_OWNER_PID_ALL = 5;

       MIB_TCP_STATE:
       array[1..12] of string = ('CLOSED', 'LISTEN', 'SYN-SENT ','SYN-RECEIVED', 'ESTABLISHED', 'FIN-WAIT-1',
                                 'FIN-WAIT-2', 'CLOSE-WAIT', 'CLOSING','LAST-ACK', 'TIME-WAIT', 'delete TCB');

    type
       TCP_TABLE_CLASS = Integer;

      PMibTcpRowOwnerPid = ^TMibTcpRowOwnerPid;
      TMibTcpRowOwnerPid  = packed record
        dwState     : DWORD;
        dwLocalAddr : DWORD;
        dwLocalPort : DWORD;
        dwRemoteAddr: DWORD;
        dwRemotePort: DWORD;
        dwOwningPid : DWORD;
        end;


      PMIB_TCPTABLE_OWNER_PID  = ^MIB_TCPTABLE_OWNER_PID;
      MIB_TCPTABLE_OWNER_PID = packed record
       dwNumEntries: DWord;
       table: array [0..ANY_SIZE - 1] OF TMibTcpRowOwnerPid;
      end;

    var
       GetExtendedTcpTable:function  (pTcpTable: Pointer; dwSize: PDWORD; bOrder: BOOL; lAf: ULONG; TableClass: TCP_TABLE_CLASS; Reserved: ULONG): DWord; stdcall;




    function GetPathPID(PID: DWORD): string;
    var
      Handle: THandle;
    begin
      Result := '';
      Handle := OpenProcess(PROCESS_QUERY_INFORMATION or PROCESS_VM_READ, False, PID);
      if Handle <> 0 then
        try
          SetLength(Result, MAX_PATH);
            if GetModuleFileNameEx(Handle, 0, PChar(Result), MAX_PATH) > 0 then
              SetLength(Result, StrLen(PChar(Result)))
            else
              Result := '';
        finally
          CloseHandle(Handle);
        end;
    end;


    procedure ShowCurrentTCPConnections;
    var
       Error        : DWORD;
       TableSize    : DWORD;
       i            : integer;
       IpAddress    : in_addr;
       RemoteIp     : string;
       LocalIp      : string;
       FExtendedTcpTable : PMIB_TCPTABLE_OWNER_PID;
    begin
      TableSize := 0;
      Error := GetExtendedTcpTable(nil, @TableSize, False, AF_INET, TCP_TABLE_OWNER_PID_ALL, 0);
      if Error <> ERROR_INSUFFICIENT_BUFFER then
         Exit;

      GetMem(FExtendedTcpTable, TableSize);
      try
       if GetExtendedTcpTable(FExtendedTcpTable, @TableSize, TRUE, AF_INET, TCP_TABLE_OWNER_PID_ALL, 0) = NO_ERROR then
          for i := 0 to FExtendedTcpTable.dwNumEntries - 1 do
          if {(FExtendedTcpTable.Table[i].dwOwningPid=Pid) and} (FExtendedTcpTable.Table[i].dwRemoteAddr<>0) then //here you can check the particular port
          begin
             IpAddress.s_addr := FExtendedTcpTable.Table[i].dwRemoteAddr;
             RemoteIp  := string(inet_ntoa(IpAddress));
             IpAddress.s_addr := FExtendedTcpTable.Table[i].dwLocalAddr;
             LocalIp          := string(inet_ntoa(IpAddress));
             Writeln(GetPathPID(FExtendedTcpTable.Table[i].dwOwningPid));
             Writeln(Format('%-16s %-6d %-16s %-6d %s',[LocalIp,FExtendedTcpTable.Table[i].dwLocalPort,RemoteIp,FExtendedTcpTable.Table[i].dwRemotePort,MIB_TCP_STATE[FExtendedTcpTable.Table[i].dwState]]));
          end;
      finally
         FreeMem(FExtendedTcpTable);
      end;
    end;

    var
       libHandle : THandle;
    begin
      try
        ReportMemoryLeaksOnShutdown:=DebugHook<>0;
        libHandle           := LoadLibrary(iphlpapi);
        GetExtendedTcpTable := GetProcAddress(libHandle, 'GetExtendedTcpTable');
        ShowCurrentTCPConnections;
      except
        on E: Exception do
          Writeln(E.ClassName, ': ', E.Message);
      end;

      readln;
    end.

这篇关于通过套接字端口获取应用程序路径的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆