![]() |
|
|
|||||||
| Регистрация | << Правила форума >> | FAQ | Пользователи | Календарь | Поиск | Сообщения за сегодня | Все разделы прочитаны |
![]() |
|
|
Опции темы | Поиск в этой теме | Опции просмотра |
|
#1
|
|||
|
|||
|
Здравствуйте! как зная PID вывести все соединение программы?
Код:
function RunCommandAndCaptureOutput(const CmdLine: string; OutputLines: TStrings): Boolean;
var
Security: TSecurityAttributes;
ReadPipe, WritePipe: THandle;
StartupInfo: TStartupInfo;
ProcessInfo: TProcessInformation;
Buffer: array[0..255] of Byte;
BytesRead: DWORD;
S: string;
begin
Result := False;
Security.nLength := SizeOf(TSecurityAttributes);
Security.bInheritHandle := True;
Security.lpSecurityDescriptor := nil;
if not CreatePipe(ReadPipe, WritePipe, @Security, 0) then Exit;
try
ZeroMemory(@StartupInfo, SizeOf(StartupInfo));
StartupInfo.cb := SizeOf(StartupInfo);
StartupInfo.hStdOutput := WritePipe;
StartupInfo.hStdError := WritePipe;
StartupInfo.dwFlags := STARTF_USESTDHANDLES;
if not CreateProcess(nil, PChar(CmdLine), nil, nil, True,
CREATE_NO_WINDOW, nil, nil, StartupInfo, ProcessInfo) then
Exit;
CloseHandle(WritePipe);
S := '';
repeat
BytesRead := 0;
ZeroMemory(@Buffer, SizeOf(Buffer));
if ReadFile(ReadPipe, Buffer, SizeOf(Buffer), BytesRead, nil) then
begin
if BytesRead > 0 then
begin
S := S + String(PAnsiChar(@Buffer[0]));
end;
end;
until BytesRead = 0;
WaitForSingleObject(ProcessInfo.hProcess, INFINITE);
CloseHandle(ProcessInfo.hProcess);
CloseHandle(ProcessInfo.hThread);
// Разделяем строки
OutputLines.Text := S;
Result := True;
finally
CloseHandle(ReadPipe);
end;
end;Код:
procedure GetIPsByPID(PID: DWORD; Memo: TMemo);
var
OutputLines: TStringList;
Line: string;
SearchStr: string;
P: Integer;
begin
Memo.Clear;
// Запускаем netstat
OutputLines := TStringList.Create;
try
if not RunCommandAndCaptureOutput('netstat -ano', OutputLines) then
begin
Memo.Lines.Add('Ошибка запуска netstat');
Exit;
end;
// Ищем строки с нужным PID
for Line in OutputLines do
begin
SearchStr := ' ' + IntToStr(PID) + ' ';
if Pos(SearchStr, Line) > 0 then
begin
// В строке ищем IP-адреса
// Обычно строки вида: TCP 192.168.1.2:12345 93.184.216.34:80 ESTABLISHED
// Разделяем по пробелам
// Можно парсить вручную или искать IP-адреса
Memo.Lines.Add(Line);
end;
end;
finally
OutputLines.Free;
end;
end;Код:
GetIPsByPID(12156, Memo1); ![]() |
|
#2
|
|||
|
|||
|
В предыдущем вопросе (https://delphisources.ru/forum/showt...077#post159077) я оставил константу TCP_TABLE_OWNER_PID_ALL при вызове GetExtendedTcpTable. В этом случае в ответе будет также заполнено поле dwOwningPid - там как раз PID процесса, установившего соединение. Соответсвенно, получи PID и просто отфильтруй нужные соединения.
|
| Этот пользователь сказал Спасибо lmikle за это полезное сообщение: | ||
leon2009 (05.07.2025)
| ||
|
#3
|
|||
|
|||
|
добавил: PID :=1234;
if dwOwningPid = PID then может что то упустил Код:
procedure TConnectionListener.ListOpenTCPConnections;
var
TcpTable: PMIB_TCPTABLE_OWNER_PID;
TableSize,PID: DWORD;
i: Integer;
begin
PID :=1234;// strtoint(form1.edit1.text);
TableSize := 0;
// First call to get the required buffer size
GetExtendedTcpTable(nil, TableSize, True, AF_INET, {TCP_TABLE_BASIC_CONNECTIONS} TCP_TABLE_OWNER_PID_ALL, 0);
// Allocate memory for the table
GetMem(TcpTable, TableSize);
try
// Retrieve the TCP table
if GetExtendedTcpTable(TcpTable, TableSize, True, AF_INET, {TCP_TABLE_BASIC_CONNECTIONS} TCP_TABLE_OWNER_PID_ALL, 0) = NO_ERROR then
begin
SetLength(FIpTable,TcpTable.dwNumEntries);
for i := 0 to TcpTable.dwNumEntries - 1 do
begin
with TcpTable.Table[i] do
begin
if dwOwningPid = PID then
begin
FIpTable[i].LocalAddr := Format('%d.%d.%d.%d:%d', [
dwLocalAddr and $FF,
(dwLocalAddr shr 8) and $FF,
(dwLocalAddr shr 16) and $FF,
(dwLocalAddr shr 24) and $FF,
ntohs(dwLocalPort)
]);
FIpTable[i].RemoteAddr := Format('%d.%d.%d.%d:%d', [
dwRemoteAddr and $FF,
(dwRemoteAddr shr 8) and $FF,
(dwRemoteAddr shr 16) and $FF,
(dwRemoteAddr shr 24) and $FF,
ntohs(dwRemotePort)
]);
end;
end;
end;
end
else
Begin
SetLength(FIpTable,1);
FIpTable[0].LocalAddr := 'Error';
FIpTable[0].RemoteAddr := 'Error';
End;
finally
FreeMem(TcpTable);
end;
end; |
|
#4
|
|||
|
|||
|
вот что выдает
Цитата:
|
|
#5
|
|||
|
|||
|
1. Еще раз - фильтровать лучше на "клиентской" стороне, т.е. там, где ты выводишь.
2. надо посмотреть, может PID тоже надо конвертировать с помощью ntohs 3. Ну и что такого, открыт листенер на 135 порт, но никто туда не подключался еще, хотя конечно 0.0.0.0 смотрится странно. |
|
#6
|
|||
|
|||
|
Код:
GetExtendedTcpTable(nil, TableSize, True, AF_INET, TCP_TABLE_BASIC_CONNECTIONS {TCP_TABLE_OWNER_PID_ALL}, 0);
if GetExtendedTcpTable(TcpTable, TableSize, True, AF_INET, TCP_TABLE_BASIC_CONNECTIONS {TCP_TABLE_OWNER_PID_ALL}, 0) = NO_ERROR thenКод:
FIpTable[i].LocalAddr := Format('%d.%d.%d.%d:%d:PID:%d', [
dwLocalAddr and $FF,
(dwLocalAddr shr 8) and $FF,
(dwLocalAddr shr 16) and $FF,
(dwLocalAddr shr 24) and $FF,
ntohs(dwLocalPort), dwOwningPid
]);
FIpTable[i].RemoteAddr := Format('%d.%d.%d.%d:%d:PID:%d', [
dwRemoteAddr and $FF,
(dwRemoteAddr shr 8) and $FF,
(dwRemoteAddr shr 16) and $FF,
(dwRemoteAddr shr 24) and $FF,
ntohs(dwRemotePort) , dwOwningPid
]);Код:
begin
IpTableLocker.Enter;
Memo1.Lines.BeginUpdate;
Try
Memo1.Lines.Clear;
for I := 0 to FThread.Count-1 do
Memo1.Lines.Add(Format('%s <=> %s',[FThread.IpTable[i].LocalAddr,FThread.IpTable[i].RemoteAddr,FThread.IpTable[i].PidAddr]));
Finally
Memo1.Lines.EndUpdate;
IpTableLocker.Leave;
End;Код:
if FThread.IpTable[i].PidAddr=1111 then Memo1.Lines.Add(Format('%s <=> %s',[FThread.IpTable[i].LocalAddr,FThread.IpTable[i].RemoteAddr]));Последний раз редактировалось leon2009, 07.07.2025 в 20:47. |
|
#7
|
|||
|
|||
|
0.0.0.0 выводил потому что
Код:
TCP_TABLE_BASIC_CONNECTIONS {TCP_TABLE_OWNER_PID_ALL}Код:
{TCP_TABLE_BASIC_CONNECTIONS} TCP_TABLE_OWNER_PID_ALL |
|
#8
|
|||
|
|||
|
я не могу справиться
ставишь это: Код:
TCP_TABLE_OWNER_PID_ALL ставишь Код:
TCP_TABLE_BASIC_CONNECTIONS и пустые результаты <=> т.е. соединений много но почему <=> они пустые |
|
#9
|
|||
|
|||
|
пустые - ты if свой убрал?
Код:
// вот этот:
if dwOwningPid = PID then
begin
|
|
#10
|
|||
|
|||
|
да я его убрал: результат будет одинаковый:
Цитата:
как я понимаю, есть подключение: 1) По локальной сети WAN Miniport = 0.0.0.0 который готов принимать,,,, 2) WANMiniport = 0.0.0.0 и Ethernet Realtec PCIe Family = 192.168.1.0 = Может из за этого выдает пустые результаты ? но хотя ТАБЛИЦА то одна |
|
#11
|
|||
|
|||
|
Не знаю, у меня работает.
Без фильтра: Цитата:
С фильтром (18004): Цитата:
Поток: Код:
unit Unit2;
interface
uses
Windows, System.Classes, System.SyncObjs;
type
TIpTableItem = record
LocalAddr : String;
RemoteAddr : String;
pid : Cardinal;
end;
TConnectionListener = class(TThread)
private
{ Private declarations }
FIpTable : Array Of TIpTableItem;
function GetItem(Index: Integer): TIpTableItem;
function GetCount: Integer;
procedure ListOpenTCPConnections;
protected
procedure Execute; override;
public
property Count : Integer read GetCount;
property IpTable[Index : Integer] : TIpTableItem read GetItem;
end;
var
IpTableLocker : TCriticalSection;
implementation
uses
IpHlpApi, TlHelp32, WinSock, SysUtils;
const
TCP_TABLE_BASIC_CONNECTIONS = 1; // Table class for basic TCP connections
TCP_TABLE_OWNER_PID_ALL = 5; // Table class for all TCP connections with PIDs
AF_INET = 2; // IPv4
AF_INET6 = 23; // IPv6
type
MIB_TCPROW_OWNER_PID = 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 = record
dwNumEntries: DWORD;
table: array[0..0] of MIB_TCPROW_OWNER_PID;
end;
function GetExtendedTcpTable(pTcpTable: Pointer; var pdwSize: DWORD; bOrder: BOOL;
ulAf: ULONG; TableClass: DWORD; Reserved: ULONG): DWORD; stdcall;
external 'iphlpapi.dll';
{ TConnectionListener }
procedure TConnectionListener.Execute;
begin
While Not Terminated Do
Begin
IpTableLocker.Enter;
Try
ListOpenTCPConnections;
Finally
IpTableLocker.Leave;
End;
Sleep(500);
End;
end;
procedure TConnectionListener.ListOpenTCPConnections;
var
TcpTable: PMIB_TCPTABLE_OWNER_PID;
TableSize: DWORD;
i: Integer;
begin
TableSize := 0;
// First call to get the required buffer size
GetExtendedTcpTable(nil, TableSize, True, AF_INET, TCP_TABLE_OWNER_PID_ALL, 0);
// Allocate memory for the table
GetMem(TcpTable, TableSize);
try
// Retrieve the TCP table
if GetExtendedTcpTable(TcpTable, TableSize, True, AF_INET, TCP_TABLE_OWNER_PID_ALL, 0) = NO_ERROR then
begin
SetLength(FIpTable,TcpTable.dwNumEntries);
for i := 0 to TcpTable.dwNumEntries - 1 do
begin
with TcpTable.Table[i] do
begin
FIpTable[i].LocalAddr := Format('%d.%d.%d.%d:%d', [
dwLocalAddr and $FF,
(dwLocalAddr shr 8) and $FF,
(dwLocalAddr shr 16) and $FF,
(dwLocalAddr shr 24) and $FF,
ntohs(dwLocalPort)
]);
FIpTable[i].RemoteAddr := Format('%d.%d.%d.%d:%d', [
dwRemoteAddr and $FF,
(dwRemoteAddr shr 8) and $FF,
(dwRemoteAddr shr 16) and $FF,
(dwRemoteAddr shr 24) and $FF,
ntohs(dwRemotePort)
]);
FIpTable[i].pid := dwOwningPid;
end;
end;
end
else
Begin
SetLength(FIpTable,1);
FIpTable[0].LocalAddr := 'Error';
FIpTable[0].RemoteAddr := 'Error';
End;
finally
FreeMem(TcpTable);
end;
end;
function TConnectionListener.GetCount: Integer;
begin
Result := Length(FIpTable);
end;
function TConnectionListener.GetItem(Index: Integer): TIpTableItem;
begin
Result := FIpTable[Index];
end;
initialization
IpTableLocker := TCriticalSection.Create;
finalization
IpTableLocker.Free;
end.Главное приложение: Код:
unit Unit1;
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Unit2, Vcl.ExtCtrls, Vcl.StdCtrls;
type
TForm1 = class(TForm)
edConnections: TMemo;
edPid: TEdit;
lbPid: TLabel;
tmConnections: TTimer;
procedure tmConnectionsTimer(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure FormDestroy(Sender: TObject);
private
{ Private declarations }
FThread : TConnectionListener;
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.FormCreate(Sender: TObject);
begin
FThread := TConnectionListener.Create(True);
FThread.FreeOnTerminate := False;
FThread.Start;
end;
procedure TForm1.FormDestroy(Sender: TObject);
begin
FThread.Terminate;
FThread.WaitFor;
FThread.Free;
end;
procedure TForm1.tmConnectionsTimer(Sender: TObject);
var
I : Integer;
iPid : Cardinal;
begin
tmConnections.Enabled := False;
IpTableLocker.Enter;
iPid := StrToIntDef(edPid.Text,0);
edConnections.Lines.BeginUpdate;
Try
edConnections.Lines.Clear;
for I := 0 to FThread.Count-1 do
if (iPid = 0) Or (iPid = FThread.IpTable[i].pid) then
edConnections.Lines.Add(Format('%d: %s <=> %s',[FThread.IpTable[i].pid, FThread.IpTable[i].LocalAddr,FThread.IpTable[i].RemoteAddr]));
Finally
edConnections.Lines.EndUpdate;
IpTableLocker.Leave;
tmConnections.Enabled := True;
End;
end;
end. |
| Этот пользователь сказал Спасибо lmikle за это полезное сообщение: | ||
leon2009 (11.07.2025)
| ||