Ir al contenido


Foto

[MULTILENGUAJE] Matar un proceso a la escucha en un determinado puerto.


  • Por favor identifícate para responder
7 respuestas en este tema

#1 escafandra

escafandra

    Advanced Member

  • Administrador
  • 4.107 mensajes
  • LocationMadrid - España

Escrito 14 noviembre 2011 - 08:01

Se me planteó la necesidad de tener que matar un proceso a la escucha en un determinado puerto. Para ello desarrollé un código en C++ que me permitiese localizar el proceso que pone un socket a la escucha en un determinado puerto y luego matarlo.

Pensando que este truco puede ser de utilidad a atros, he implementado un ejemplo para socket TCP y UDP pudiendo elegir entre uno, otro o los dos.

El código que expongo está escrito en C++ Builder 5 y delphi 7. Para ambos compiladores he tenido que declarar ciertas estructuras y constantes que no estaban incluidas en ellos, pero es posible que en versiones mas modernas lo estén. Con objeto de dejar el código compatible con esas versiones modernas, las declaraciones que he añadido están extraídas de http://msdn.microsoft.com. En el caso de delphi es posible que los nombres varíen un poco, en ese caso no será difícil adaptar el código. En el caso de C++ no habrá ningún problema.

Como último apunte decir que para matar algunos procesos y aquellos pertenecientes a otro usuario, es necesario desponer de privilegio "SeDebugPrivilege", con lo que habrá que ajustar dicho privilegio previamente al uso de la función objeto del presente truco.

Comienzo con la versión C++ del código.


cpp
  1. #include <windows.h>
  2. #include <winsock2.h>
  3. #include <iphlpapi.h>
  4.  
  5.  
  6. // TCP
  7. typedef struct _MIB_TCPROW_OWNER_PID {
  8.   DWORD        dwState;
  9.   DWORD        dwLocalAddr;
  10.   DWORD        dwLocalPort;
  11.   DWORD        dwRemoteAddr;
  12.   DWORD        dwRemotePort;
  13.   DWORD        dwOwningPid;
  14. } MIB_TCPROW_OWNER_PID, *PMIB_TCPROW_OWNER_PID;
  15.  
  16. typedef struct {
  17.   DWORD                  dwNumEntries;
  18.   MIB_TCPROW_OWNER_PID table[ANY_SIZE];
  19. } MIB_TCPTABLE_OWNER_PID, *PMIB_TCPTABLE_OWNER_PID;
  20.  
  21. typedef enum  {
  22.   TCP_TABLE_BASIC_LISTENER,
  23.   TCP_TABLE_BASIC_CONNECTIONS,
  24.   TCP_TABLE_BASIC_ALL,
  25.   TCP_TABLE_OWNER_PID_LISTENER,
  26.   TCP_TABLE_OWNER_PID_CONNECTIONS,
  27.   TCP_TABLE_OWNER_PID_ALL,
  28.   TCP_TABLE_OWNER_MODULE_LISTENER,
  29.   TCP_TABLE_OWNER_MODULE_CONNECTIONS,
  30.   TCP_TABLE_OWNER_MODULE_ALL
  31. } TCP_TABLE_CLASS, *PTCP_TABLE_CLASS;
  32.  
  33. //UDP
  34. typedef enum  {
  35.   UDP_TABLE_BASIC,
  36.   UDP_TABLE_OWNER_PID,
  37.   UDP_TABLE_OWNER_MODULE
  38. } UDP_TABLE_CLASS, *PUDP_TABLE_CLASS;
  39.  
  40. typedef struct _MIB_UDPROW_OWNER_PID {
  41.   DWORD dwLocalAddr;
  42.   DWORD dwLocalPort;
  43.   DWORD dwOwningPid;
  44. } MIB_UDPROW_OWNER_PID, *PMIB_UDPROW_OWNER_PID;
  45.  
  46. typedef struct _MIB_UDPTABLE_OWNER_PID {
  47.   DWORD                dwNumEntries;
  48.   MIB_UDPROW_OWNER_PID table[ANY_SIZE];
  49. } MIB_UDPTABLE_OWNER_PID, *PMIB_UDPTABLE_OWNER_PID;
  50.  
  51. typedef DWORD (__stdcall *PGetExtendedTcpTable)(PVOID pTcpTable, PDWORD pdwSize, BOOL bOrder, ULONG ulAf, TCP_TABLE_CLASS TableClass, ULONG Reserved);
  52. typedef DWORD (__stdcall *PGetExtendedUdpTable)(PVOID pUdpTable, PDWORD pdwSize, BOOL bOrder, ULONG ulAf, UDP_TABLE_CLASS TableClass, ULONG Reserved);
  53.  
  54.  
  55. #define TCP  0x1
  56. #define UDP  0x2
  57.  
  58. // Termina un proceso a la escucha de un determinado puerto
  59. bool TerminateProcessByPort(int Port, int IPProto)
  60. {
  61.   PMIB_TCPTABLE_OWNER_PID TCPTablePID;
  62.   PMIB_UDPTABLE_OWNER_PID UDPTablePID;
  63.   DWORD Size = 0;
  64.   bool Result = false;
  65.  
  66.   // TCP
  67.   PGetExtendedTcpTable GetExtendedTcpTable = (PGetExtendedTcpTable)GetProcAddress(LoadLibrary("Iphlpapi.dll"), "GetExtendedTcpTable");
  68.   if(GetExtendedTcpTable && (IPProto & TCP)){
  69.     GetExtendedTcpTable(0, &Size, TRUE, AF_INET, TCP_TABLE_OWNER_PID_LISTENER, 0);
  70.     TCPTablePID = (PMIB_TCPTABLE_OWNER_PID)VirtualAlloc(0, Size, MEM_COMMIT, PAGE_READWRITE);
  71.     GetExtendedTcpTable(TCPTablePID, &Size, TRUE, AF_INET, TCP_TABLE_OWNER_PID_LISTENER, 0);
  72.     for(DWORD i = 0; i< TCPTablePID->dwNumEntries; i++){
  73.       if(ntohs((u_short)TCPTablePID->table[i].dwLocalPort) == Port && TCPTablePID->table.dwState == MIB_TCP_STATE_LISTEN){
  74.         HANDLE Process = OpenProcess(PROCESS_TERMINATE, false, TCPTablePID->table.dwOwningPid);
  75.         Result |= TerminateProcess(Process, 0);
  76.         CloseHandle(Process);
  77.         break;
  78.       }
  79.     }
  80.     VirtualFree(TCPTablePID, 0, MEM_RELEASE);
  81.   }
  82.  
  83.   // UDP
  84.   PGetExtendedUdpTable GetExtendedUdpTable = (PGetExtendedUdpTable)GetProcAddress(LoadLibrary("Iphlpapi.dll"), "GetExtendedUdpTable");
  85.   if(GetExtendedUdpTable && (IPProto & UDP)){
  86.     GetExtendedUdpTable(0, &Size, TRUE, AF_INET, UDP_TABLE_OWNER_PID, 0);
  87.     UDPTablePID = (PMIB_UDPTABLE_OWNER_PID)VirtualAlloc(0, Size, MEM_COMMIT, PAGE_READWRITE);
  88.     GetExtendedUdpTable(UDPTablePID, &Size, TRUE, AF_INET, UDP_TABLE_OWNER_PID, 0);
  89.     for(DWORD i = 0; i< UDPTablePID->dwNumEntries; i++){
  90.       if(ntohs((u_short)UDPTablePID->table.dwLocalPort) == Port){
  91.         HANDLE Process = OpenProcess(PROCESS_TERMINATE, false, UDPTablePID->table.dwOwningPid);
  92.         Result |= TerminateProcess(Process, 0);
  93.         CloseHandle(Process);
  94.         break;
  95.       }
  96.     }
  97.     VirtualFree(UDPTablePID, 0, MEM_RELEASE);
  98.   }
  99.  
  100.   return Result;
  101. }

Un ejemplo de uso:


cpp
  1. TerminateProcessByPort(5000, TCP | UDP);


Por organizar un poco el tema y no mezclar mucho termino aquí este mensaje y dejo para el siguiente la versión delphi.
Espero que este truco sea de utilidad como lo ha sido para mi.


Saludos.
  • 0

#2 escafandra

escafandra

    Advanced Member

  • Administrador
  • 4.107 mensajes
  • LocationMadrid - España

Escrito 14 noviembre 2011 - 08:02

No voy a dejaros sin la versión para delphi, ahora es su turno:


delphi
  1. uses
  2.   Windows, winsock;
  3.  
  4. // TCP
  5. type
  6. MIB_TCPROW_OWNER_PID = record
  7.   dwState:          DWORD;
  8.   dwLocalAddr:      DWORD;
  9.   dwLocalPort:      DWORD;
  10.   dwRemoteAddr:      DWORD;
  11.   dwRemotePort:      DWORD;
  12.   dwOwningPid:      DWORD;
  13. end;
  14. PMIB_TCPROW_OWNER_PID = ^MIB_TCPROW_OWNER_PID;
  15.  
  16. MIB_TCPTABLE_OWNER_PID = record
  17.   dwNumEntries: DWORD;
  18.   table:        array[0..0] of MIB_TCPROW_OWNER_PID;
  19. end;
  20. PMIB_TCPTABLE_OWNER_PID = ^MIB_TCPTABLE_OWNER_PID;
  21.  
  22. TCP_TABLE_CLASS = (
  23.   TCP_TABLE_BASIC_LISTENER,
  24.   TCP_TABLE_BASIC_CONNECTIONS,
  25.   TCP_TABLE_BASIC_ALL,
  26.   TCP_TABLE_OWNER_PID_LISTENER,
  27.   TCP_TABLE_OWNER_PID_CONNECTIONS,
  28.   TCP_TABLE_OWNER_PID_ALL,
  29.   TCP_TABLE_OWNER_MODULE_LISTENER,
  30.   TCP_TABLE_OWNER_MODULE_CONNECTIONS,
  31.   TCP_TABLE_OWNER_MODULE_ALL
  32. );
  33. PTCP_TABLE_CLASS = ^TCP_TABLE_CLASS;
  34.  
  35. MIB_TCP_STATE = (
  36.   MIB_TCP_STATE_CLOSED = 1,
  37.   MIB_TCP_STATE_LISTEN,
  38.   MIB_TCP_STATE_SYN_SENT,
  39.   MIB_TCP_STATE_SYN_RCVD,
  40.   MIB_TCP_STATE_ESTAB,
  41.   MIB_TCP_STATE_FIN_WAIT1,
  42.   MIB_TCP_STATE_FIN_WAIT2,
  43.   MIB_TCP_STATE_CLOSE_WAIT,
  44.   MIB_TCP_STATE_CLOSING,
  45.   MIB_TCP_STATE_LAST_ACK,
  46.   MIB_TCP_STATE_TIME_WAIT,
  47.   MIB_TCP_STATE_DELETE_TCB
  48. );
  49.  
  50. // UDP
  51. MIB_UDPROW_OWNER_PID = record
  52.   dwLocalAddr: DWORD;
  53.   dwLocalPort: DWORD;
  54.   dwOwningPid: DWORD;
  55. end;
  56. PMIB_UDPROW_OWNER_PID = ^MIB_UDPROW_OWNER_PID;
  57.  
  58. MIB_UDPTABLE_OWNER_PID = record
  59.   dwNumEntries: DWORD;
  60.   table:        array[0..0] of MIB_UDPROW_OWNER_PID;
  61. end;
  62. PMIB_UDPTABLE_OWNER_PID = ^MIB_UDPTABLE_OWNER_PID;
  63.  
  64. UDP_TABLE_CLASS = (
  65.   UDP_TABLE_BASIC,
  66.   UDP_TABLE_OWNER_PID,
  67.   UDP_TABLE_OWNER_MODULE
  68. );
  69. PUDP_TABLE_CLASS = ^UDP_TABLE_CLASS;
  70.  
  71. function GetExtendedTcpTable(lpTable: Pointer; lpSize: PCardinal; bOrder: LongBool; ulAf: ULONG; TableClass: TCP_TABLE_CLASS; Reserved: Cardinal): Cardinal; stdcall; external 'Iphlpapi.dll';
  72. function GetExtendedUdpTable(lpTable: Pointer; lpSize: PCardinal; bOrder: LongBool; ulAf: ULONG; TableClass: UDP_TABLE_CLASS; Reserved: Cardinal): Cardinal; stdcall; external 'Iphlpapi.dll';
  73.  
  74. //--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  75.  
  76.  
  77. const
  78.   TCP: integer = $1;
  79.   UDP: integer = $2;
  80.  
  81.  
  82. // Buscar aplicacion a la escucha del puerto y matarla.
  83. function TerminateProcessByPort(Port: integer; IPProto: integer): boolean;
  84. var
  85. TCPTablePID: PMIB_TCPTABLE_OWNER_PID;
  86. UDPTablePID: PMIB_UDPTABLE_OWNER_PID;
  87. Size, i: DWORD;
  88. hProcess: THandle;
  89. begin
  90. Size:= 0;
  91. Result:= false;
  92.  
  93. if (IPProto and TCP)<>0 then
  94. begin
  95. GetExtendedTcpTable(nil, @Size, TRUE, AF_INET, TCP_TABLE_OWNER_PID_LISTENER, 0);
  96. TCPTablePID:= VirtualAlloc(nil, Size, MEM_COMMIT, PAGE_READWRITE);
  97. GetExtendedTcpTable(TCPTablePID, @Size, TRUE, AF_INET, TCP_TABLE_OWNER_PID_LISTENER, 0);
  98. for i:= 0 to TCPTablePID.dwNumEntries-1 do
  99. begin
  100. if (ntohs(TCPTablePID.table[i].dwLocalPort) = Port) and (TCPTablePID.table[i].dwState = DWORD(MIB_TCP_STATE_LISTEN)) then
  101. begin
  102. hProcess:= OpenProcess(PROCESS_TERMINATE, false, TCPTablePID.table[i].dwOwningPid);
  103. Result:= Result or Windows.TerminateProcess(hProcess, 0);
  104. CloseHandle(hProcess);
  105. break;
  106. end;
  107. end;
  108. VirtualFree(TCPTablePID, 0, MEM_RELEASE);
  109. end;
  110. if (IPProto and UDP)<>0 then
  111. begin
  112. GetExtendedUdpTable(nil, @Size, TRUE, AF_INET, UDP_TABLE_OWNER_PID, 0);
  113. UDPTablePID:= VirtualAlloc(nil, Size, MEM_COMMIT, PAGE_READWRITE);
  114. GetExtendedUdpTable(UDPTablePID, @Size, TRUE, AF_INET, UDP_TABLE_OWNER_PID, 0);
  115. for i:= 0 to UDPTablePID.dwNumEntries-1 do
  116. begin
  117. if ntohs(UDPTablePID.table[i].dwLocalPort) = Port then
  118. begin
  119. hProcess:= OpenProcess(PROCESS_TERMINATE, false, UDPTablePID.table[i].dwOwningPid);
  120. Result:= Result or Windows.TerminateProcess(hProcess, 0);
  121. CloseHandle(hProcess);
  122. break;
  123. end;
  124. end;
  125. VirtualFree(UDPTablePID, 0, MEM_RELEASE);
  126. end;
  127. end;

Un ejemplo de uso:

delphi
  1. TerminateProcessByPort(5000, TCP or UDP);

Espero que este truco sea de utilidad como lo ha sido para mi.


Saludos.
  • 0

#3 enecumene

enecumene

    Webmaster

  • Administrador
  • 7.419 mensajes
  • LocationRepública Dominicana

Escrito 14 noviembre 2011 - 08:11

Excelente mi estimado  :| (y)
  • 0

#4 Wilson

Wilson

    Advanced Member

  • Moderadores
  • PipPipPip
  • 2.137 mensajes

Escrito 14 noviembre 2011 - 08:23

Como de costumbre, GENIAL. (y)


Gracias maestro.
  • 0

#5 seoane

seoane

    Advanced Member

  • Administrador
  • 1.259 mensajes
  • LocationEspaña

Escrito 14 noviembre 2011 - 01:30

La curiosidad me mata  ^o| ¿que tenias en contra de ese proceso? y ¿por que no lo matabas por nombre? ... si se puede saber  :)
  • 0

#6 escafandra

escafandra

    Advanced Member

  • Administrador
  • 4.107 mensajes
  • LocationMadrid - España

Escrito 14 noviembre 2011 - 06:25

La curiosidad me mata 

Si, sabía que este código generaría ciertas suspicacias, seoane. :D :D :D

  ¿que tenias en contra de ese proceso? y ¿por que no lo matabas por nombre? ... si se puede saber 
 

En ese momento era una cuestión de supervivencia.  *-)  Había que matar, de forma automática, al proceso que ponía cierto puerto a la escucha en un determinado PC remoto, sin importar demasiado el nombre de dicho proceso. Simplemente no tenía que estar ahí.  ^o| :D :D :D


Saludos.

  • 0

#7 egostar

egostar

    missing my father, I love my mother.

  • Administrador
  • 14.448 mensajes
  • LocationMéxico

Escrito 14 noviembre 2011 - 09:19

Como se nota quien es quien, unos nos asombramos con el código y otro lo mata la curiosidad :D :D :D

Pues lo dicho, son unos masters :)

Salud OS
  • 0

#8 seoane

seoane

    Advanced Member

  • Administrador
  • 1.259 mensajes
  • LocationEspaña

Escrito 15 noviembre 2011 - 07:34

:D Si hay que matar, cualquier manera es buena.
  • 0




IP.Board spam blocked by CleanTalk.