
Como obtener puertos abiertos y el programa o servicio asociado
#1
Escrito 25 junio 2014 - 11:15
Estoy haciendo un software para auditoría informatica y necesito saber como puedo mostrar los puertos abiertos en la PC y que programa o servicio lo está usando
#3
Escrito 25 junio 2014 - 03:21

Archivos adjuntos
#4
Escrito 26 junio 2014 - 05:12
Basado en el código expuesto aquí, he preparado un ejemplo simple que lista los puertos usados, los procesos que lo abren, direcciones IP y su estado. Ejecutado como administrador nos da, también, la ruta completa del proceso.
program Project1; {$APPTYPE CONSOLE} uses Windows, SysUtils, winsock, tlhelp32; // TCP type MIB_TCPROW_OWNER_PID = record dwState: DWORD; dwLocalAddr: DWORD; dwLocalPort: DWORD; dwRemoteAddr: DWORD; dwRemotePort: DWORD; dwOwningPid: DWORD; end; PMIB_TCPROW_OWNER_PID = ^MIB_TCPROW_OWNER_PID; MIB_TCPTABLE_OWNER_PID = record dwNumEntries: DWORD; table: array[0..0] of MIB_TCPROW_OWNER_PID; end; PMIB_TCPTABLE_OWNER_PID = ^MIB_TCPTABLE_OWNER_PID; TCP_TABLE_CLASS = ( TCP_TABLE_BASIC_LISTENER, TCP_TABLE_BASIC_CONNECTIONS, TCP_TABLE_BASIC_ALL, TCP_TABLE_OWNER_PID_LISTENER, TCP_TABLE_OWNER_PID_CONNECTIONS, TCP_TABLE_OWNER_PID_ALL, TCP_TABLE_OWNER_MODULE_LISTENER, TCP_TABLE_OWNER_MODULE_CONNECTIONS, TCP_TABLE_OWNER_MODULE_ALL ); PTCP_TABLE_CLASS = ^TCP_TABLE_CLASS; MIB_TCP_STATE = ( MIB_TCP_STATE_CLOSED = 1, MIB_TCP_STATE_LISTEN, MIB_TCP_STATE_SYN_SENT, MIB_TCP_STATE_SYN_RCVD, MIB_TCP_STATE_ESTAB, MIB_TCP_STATE_FIN_WAIT1, MIB_TCP_STATE_FIN_WAIT2, MIB_TCP_STATE_CLOSE_WAIT, MIB_TCP_STATE_CLOSING, MIB_TCP_STATE_LAST_ACK, MIB_TCP_STATE_TIME_WAIT, MIB_TCP_STATE_DELETE_TCB ); // UDP MIB_UDPROW_OWNER_PID = record dwLocalAddr: DWORD; dwLocalPort: DWORD; dwOwningPid: DWORD; end; PMIB_UDPROW_OWNER_PID = ^MIB_UDPROW_OWNER_PID; MIB_UDPTABLE_OWNER_PID = record dwNumEntries: DWORD; table: array[0..0] of MIB_UDPROW_OWNER_PID; end; PMIB_UDPTABLE_OWNER_PID = ^MIB_UDPTABLE_OWNER_PID; UDP_TABLE_CLASS = ( UDP_TABLE_BASIC, UDP_TABLE_OWNER_PID, UDP_TABLE_OWNER_MODULE ); PUDP_TABLE_CLASS = ^UDP_TABLE_CLASS; function GetExtendedTcpTable(lpTable: Pointer; lpSize: PCardinal; bOrder: LongBool; ulAf: ULONG; TableClass: TCP_TABLE_CLASS; Reserved: Cardinal): Cardinal; stdcall; external 'Iphlpapi.dll'; function GetExtendedUdpTable(lpTable: Pointer; lpSize: PCardinal; bOrder: LongBool; ulAf: ULONG; TableClass: UDP_TABLE_CLASS; Reserved: Cardinal): Cardinal; stdcall; external 'Iphlpapi.dll'; var StateStr: array[1..12] of String = ('CLOSED', 'LISTEN', 'SYN_SENT', 'SYN_RCVD', 'ESTAB', 'FIN_WAIT1', 'FIN_WAIT2', 'CLOSE_WAIT', 'CLOSING', 'LAST_ACK', 'TIME_WAIT', 'DELETE_TCB'); function EnablePrivilege(name: String; Enable: boolean): boolean; var hToken: Cardinal; priv: TOKEN_PRIVILEGES; begin priv.PrivilegeCount:= 1; priv.Privileges[0].Attributes:= 0; if Enable then priv.Privileges[0].Attributes:= SE_PRIVILEGE_ENABLED; LookupPrivilegeValue(nil, PCHAR(name), priv.Privileges[0].Luid); OpenProcessToken(GetCurrentProcess, TOKEN_ADJUST_PRIVILEGES, hToken); AdjustTokenPrivileges (hToken, FALSE, priv, sizeof(priv), nil, PDWORD(nil)^); Result:= (GetLastError = ERROR_SUCCESS); CloseHandle (hToken); end; function GetExeNameByProcessId(dwProcessId: DWORD): string; var snp: THandle; lppe: TProcessEntry32; begin Result := ''; snp := CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); lppe.dwSize:= sizeof(lppe); if Process32First(snp, lppe) then begin repeat if lppe.th32ProcessID = dwProcessId then begin Result := lppe.szExeFile; Break; end; until not(Process32Next(snp, lppe)); CloseHandle(snp); end; end; function GetProcessImageFileName(PId: DWORD): String; var hSnapshot: THANDLE; ModuleEntry: MODULEENTRY32 ; begin ModuleEntry.dwSize:= sizeof(MODULEENTRY32); Result:= ''; hSnapshot:= CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, PId); if hSnapshot <> THANDLE(-1) then begin if Module32First(hSnapshot, ModuleEntry) then Result:= ModuleEntry.szExePath; CloseHandle(hSnapshot); end; end; function GetProcessProcessName(PId: DWORD): String; begin Result:= GetProcessImageFileName(PId); if Result = '' then Result:= GetExeNameByProcessId(PId); end; var TCPTablePID: PMIB_TCPTABLE_OWNER_PID; UDPTablePID: PMIB_UDPTABLE_OWNER_PID; Size, i: DWORD; hProcess: THandle; begin EnablePrivilege('SeDebugPrivilege', true); Size:= 0; // Listando los puertos TCP GetExtendedTcpTable(nil, @Size, TRUE, AF_INET, TCP_TABLE_OWNER_PID_ALL, 0); TCPTablePID:= VirtualAlloc(nil, Size, MEM_COMMIT, PAGE_READWRITE); GetExtendedTcpTable(TCPTablePID, @Size, TRUE, AF_INET, TCP_TABLE_OWNER_PID_ALL, 0); for i:= 0 to TCPTablePID.dwNumEntries-1 do begin with TCPTablePID.table[i] do begin WriteLn('TCP'); WriteLn('Pid: ', IntToStr(dwOwningPid)); WriteLn('Puerto: ', IntToStr(ntohs(dwLocalPort))); WriteLn('Estado: ', StateStr[dwState]); WriteLn('Direccion local: ' + inet_ntoa(in_addr(dwLocalAddr)), ' - Direccion remota: ' + inet_ntoa(in_addr(dwRemoteAddr))); WriteLn(GetProcessProcessName(dwOwningPid)); WriteLn; end; end; VirtualFree(TCPTablePID, 0, MEM_RELEASE); // Listado de los puertos UDP GetExtendedUdpTable(nil, @Size, TRUE, AF_INET, UDP_TABLE_OWNER_PID, 0); UDPTablePID:= VirtualAlloc(nil, Size, MEM_COMMIT, PAGE_READWRITE); GetExtendedUdpTable(UDPTablePID, @Size, TRUE, AF_INET, UDP_TABLE_OWNER_PID, 0); for i:= 0 to UDPTablePID.dwNumEntries-1 do begin with UDPTablePID.table[i] do begin WriteLn('UDP'); WriteLn('Pid: ', IntToStr(dwOwningPid)); WriteLn('Puerto: ', IntToStr(ntohs(dwLocalPort))); WriteLn('Direccion local: ' + inet_ntoa(in_addr(dwLocalAddr))); WriteLn(GetProcessProcessName(dwOwningPid)); WriteLn; end; end; VirtualFree(UDPTablePID, 0, MEM_RELEASE); Readln; end.
Probado en WinXP
PD/ probado también en Win8
Saludos.
#5
Escrito 26 junio 2014 - 10:12
[DCC Error] Project1.dpr(93): E2033 Types of actual and formal var parameters must be identical
Y surge en esta linea:
function EnablePrivilege(name: String; Enable: boolean): boolean; var hToken: Cardinal; priv: TOKEN_PRIVILEGES; begin priv.PrivilegeCount:= 1; priv.Privileges[0].Attributes:= 0; if Enable then priv.Privileges[0].Attributes:= SE_PRIVILEGE_ENABLED; LookupPrivilegeValue(nil, PCHAR(name), priv.Privileges[0].Luid); [b]OpenProcessToken(GetCurrentProcess, TOKEN_ADJUST_PRIVILEGES, hToken);[/b] AdjustTokenPrivileges (hToken, FALSE, priv, sizeof(priv), nil, PDWORD(nil)^); Result:= (GetLastError = ERROR_SUCCESS); CloseHandle (hToken); end;
Alguna idea? Windows 7 Pro, Delphi XE2 Update 4 Hot fix 1
#6
Escrito 26 junio 2014 - 10:48
Yo use delphi7 que no tiene bien "tipados" ciertos tipos. No puedo reproducir el error.
Prueba así:
function EnablePrivilege(name: String; Enable: boolean): boolean; var hToken: THANDLE; priv: TOKEN_PRIVILEGES; begin priv.PrivilegeCount:= 1; priv.Privileges[0].Attributes:= 0; if Enable then priv.Privileges[0].Attributes:= SE_PRIVILEGE_ENABLED; LookupPrivilegeValue(nil, PCHAR(name), priv.Privileges[0].Luid); OpenProcessToken(GetCurrentProcess, TOKEN_ADJUST_PRIVILEGES, hToken); AdjustTokenPrivileges (hToken, FALSE, priv, sizeof(priv), nil, PDWORD(nil)^); Result:= (GetLastError = ERROR_SUCCESS); CloseHandle (hToken); end;
Saludos.
#7
Escrito 26 junio 2014 - 10:58
Compilo a la primera.
Gracias!!
#8
Escrito 26 junio 2014 - 11:23
Probaré los codigos y despues les digo que tal me resultó

#9
Escrito 26 junio 2014 - 01:51
Un cordial saludo.
#10
Escrito 27 junio 2014 - 11:03

Muchas gracias, con eso resolví mi problema

#11
Escrito 26 agosto 2015 - 03:07
Despues de tanto tiempo, no se si reabrir el hilo o crear otro
Pues he querido ampliar las funcionalidades de mi soft para que funcione para toda la red local, y por eso quisiera saber como podria hacer esto mismo, pero a cualquier equipo conectado a mi red, ya sea dando el IP o el nombre DNS
#12
Escrito 27 agosto 2015 - 05:02
Se me ocurre usar el código para una máquina local y comunicarlo por red, puedes basarte en este ejemplo que ya conoces.
Saludos.
#13
Escrito 07 marzo 2017 - 12:17
Yo use delphi7 que no tiene bien "tipados" ciertos tipos. No puedo reproducir el error.
Prueba así:
delphi
function EnablePrivilege(name: String; Enable: boolean): boolean; var hToken: THANDLE; priv: TOKEN_PRIVILEGES; begin priv.PrivilegeCount:= 1; priv.Privileges[0].Attributes:= 0; if Enable then priv.Privileges[0].Attributes:= SE_PRIVILEGE_ENABLED; LookupPrivilegeValue(nil, PCHAR(name), priv.Privileges[0].Luid); OpenProcessToken(GetCurrentProcess, TOKEN_ADJUST_PRIVILEGES, hToken); AdjustTokenPrivileges (hToken, FALSE, priv, sizeof(priv), nil, PDWORD(nil)^); Result:= (GetLastError = ERROR_SUCCESS); CloseHandle (hToken); end;
Saludos.
Pues de nuevo lo que me funciono bien en Delphi7, ahora no funciona en XE7
AdjustTokenPrivileges (hToken, FALSE, priv, sizeof(priv), nil, PDWORD(nil)^);
Me da el error:
[dcc32 Error] scanpuertos.dpr(94): E2250 There is no overloaded version of 'AdjustTokenPrivileges' that can be called with these arguments
#14
Escrito 07 marzo 2017 - 12:50
function SetPrivilege(const PrivilegeName: string; const Enabled: Boolean): Boolean; var TokenPrivileges, RequestedPrivileges: TTokenPrivileges; TokenHandle: THandle; ReturnLength: DWORD; begin Result := False; OpenProcessToken(GetCurrentProcess, TOKEN_ADJUST_PRIVILEGES or TOKEN_QUERY, TokenHandle); RequestedPrivileges.PrivilegeCount := 1; if LookupPrivilegeValue(nil, PWideChar(PrivilegeName), RequestedPrivileges.Privileges[0].LUID) then begin if Enabled then RequestedPrivileges.Privileges[0].Attributes := SE_PRIVILEGE_ENABLED else RequestedPrivileges.Privileges[0].Attributes := 0; ReturnLength := 0; Result := AdjustTokenPrivileges(TokenHandle, False, RequestedPrivileges, SizeOf(TokenPrivileges), TokenPrivileges, ReturnLength); end; CloseHandle(TokenHandle) end;
Fuente
#15
Escrito 07 marzo 2017 - 01:17
Pues de nuevo lo que me funciono bien en Delphi7, ahora no funciona en XE7
delphi
AdjustTokenPrivileges (hToken, FALSE, priv, sizeof(priv), nil, PDWORD(nil)^);
Me da el error:
Pues a mi me compila perfectamente en Berlin y, además, funciona.
Mira a ver como está declarada la API AdjustTokenPrivileges en XE7
Saludos.
#16
Escrito 07 marzo 2017 - 01:29
Muchas gracias Agustin, cambiando la funcion, ahora si me funciona
#17
Escrito 07 marzo 2017 - 01:34
Pues a mi me compila perfectamente en Berlin y, además, funciona.
Mira a ver como está declarada la API AdjustTokenPrivileges en XE7
Saludos.
Respondiendo a Agustin, no habia visto tu respuesta
Segun Winapi.Windows esta declarado así:
function AdjustTokenPrivileges(TokenHandle: THandle; DisableAllPrivileges: BOOL; const NewState: TTokenPrivileges; BufferLength: DWORD; var PreviousState: TTokenPrivileges; var ReturnLength: DWORD): BOOL; external advapi32 name 'AdjustTokenPrivileges';
#18
Escrito 07 marzo 2017 - 02:39
A mi tambien me funciona bien en Berlin. Aunque ese casteo raro sobre PDWORD no me gusta nada, se supone que la funcion escribe en los parametros var la long. del retorno y el token o estado anterior anterior
Esto por ej produce errores access violation, si bien compila:
uses Winapi.Windows; procedure Test(var Value: DWORD); begin Value := 5; end; var Value: DWORD; begin Value := 3; Writeln(Value); Test(Value); Writeln(Value); Test(PDWORD(nil)^); // accesss violation Test(PDWORD(Value)^); // accesss violation Writeln(Value); Readln; end.
Por otro lado, la API AdjustTokenPrivileges te permite pasar null en los dos ultimos parametros, pero en los dos al mismo tiempo!
#19
Escrito 07 marzo 2017 - 03:50
A mi tambien me funciona bien en Berlin. Aunque ese casteo raro sobre PDWORD no me gusta nada, se supone que la funcion escribe en los parametros var la long. del retorno y el token o estado anterior anterior
Esto por ej produce errores access violation, si bien compila:
delphi
uses Winapi.Windows; procedure Test(var Value: DWORD); begin Value := 5; end; var Value: DWORD; begin Value := 3; Writeln(Value); Test(Value); Writeln(Value); Test(PDWORD(nil)^); // accesss violation Test(PDWORD(Value)^); // accesss violation Writeln(Value); Readln; end.
Por otro lado, la API AdjustTokenPrivileges te permite pasar null en los dos ultimos parametros, pero en los dos al mismo tiempo!
El tema es que delphi cambia la declaración original de la API que no usa referencias sino punteros:
BOOL WINAPI AdjustTokenPrivileges( _In_ HANDLE TokenHandle, _In_ BOOL DisableAllPrivileges, _In_opt_ PTOKEN_PRIVILEGES NewState, _In_ DWORD BufferLength, _Out_opt_ PTOKEN_PRIVILEGES PreviousState, _Out_opt_ PDWORD ReturnLength );
PDWORD(nil)^ realmente está pasando un puntero nulo. Como no me interesa ningún resultado, y los dos últimos parámetros son nulos, cono dice msdn, me permito la licencia que, por otro lado, uso con la API de Windows y delphi muy a menudo sin el más mínimo inconveniente ahorrándome declarar variables incómodas e innecesarias.
AdjustTokenPrivileges (hToken, FALSE, priv, sizeof(priv), nil, PDWORD(nil)^);
Si he observado que aveces hay dos declaraciones, sobrecargadas de la misma API. Como no dispongo de todas las versiones de delphi, no puedo jugar con estas cosas, y no creas, rabia me da.
Saludos.