Delphi-PRAXiS
Seite 2 von 3     12 3      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Netzwerke (https://www.delphipraxis.net/14-netzwerke/)
-   -   Delphi API: RecvFrom, SendTo etc gehookt - Programm crasht (https://www.delphipraxis.net/136039-api-recvfrom-sendto-etc-gehookt-programm-crasht.html)

Fridolin Walther 22. Jun 2009 18:17

Re: API: RecvFrom, SendTo etc gehookt - Programm crasht
 
Prinzipiell könntest Du periodisch die aktiven Verbindungen des Warcraft 3 Prozesses enumerieren und die Leitung einfach kappen, die Dir nicht passen. Das Endergebnis ist letztlich das Selbe (-> Spieler mit gebannten IPs können nicht mitspielen), kommt allerdings ohne Hooks aus und stellt für Warden keinen Banngrund da. Anders als lustige WinSock Hooks. Die mochte Warden in der Vergangenheit nicht sonderlich.

Ein IAT oder EAT Hook triggert übrigens die Hook Detection von WinSock und sorgt dafür, daß es nicht korrekt initialisiert.

[EDIT]Grad nach geschaut, weil ich mir selbst nicht mehr 100% sicher war. WinSock testet doch nur auf EAT Hooks. IAT Hooks sollten also möglich sein.[/EDIT]

napsterxx 22. Jun 2009 18:21

Re: API: RecvFrom, SendTo etc gehookt - Programm crasht
 
Danke dir schonmal!
Jetzt weis ich wenigstens, dass Hooks absolut auscheiden!
Kannst du einige mehr Informationen zu der von dir angesprochenen Methode liefern?

Fridolin Walther 22. Jun 2009 18:43

Re: API: RecvFrom, SendTo etc gehookt - Programm crasht
 
MSDN-Library durchsuchenGetExtendedTcpTable und MSDN-Library durchsuchenGetExtendedUdpTable wären dokumentierte Methoden ab Windows XP SP2 um an die Verbindungen der Prozesse zu kommen. Es existieren noch einige undokumentierte Möglichkeiten (AllocateAndGetTcpExTableFromStack, Enumerieren der Handles usw.). Code zum schließen eines Sockets von außerhalb des Prozesses hab ich letztens grade erst gesehen irgendwo. Aber ich hab vergessen wo. Ich such mal danach ...

Fridolin Walther 22. Jun 2009 18:55

Re: API: RecvFrom, SendTo etc gehookt - Programm crasht
 
Und mit MSDN-Library durchsuchenSetTcpEntry kannst Du die Verbindung dann schließen.

napsterxx 22. Jun 2009 19:03

Re: API: RecvFrom, SendTo etc gehookt - Programm crasht
 
Also meine Suche bezüglich GetExtendedTcpTable ergab diesen Fund:
http://www.magsys.co.uk/delphi/magiphlp.asp

Mal schauen, wie viel sich daraus nun rausholen lässt.

Danke soweit an alle, die nicht das "Böse" in mir gesehen haben 8)

Fridolin Walther 22. Jun 2009 19:05

Re: API: RecvFrom, SendTo etc gehookt - Programm crasht
 
Ich hab eh grad bisschen Zeit. Ich glaub ich bau einfach mal einen kleinen Netstat Nachbau mit der Option Verbindungen zu killen ;).

napsterxx 22. Jun 2009 19:32

Re: API: RecvFrom, SendTo etc gehookt - Programm crasht
 
Zitat:

Ich hab eh grad bisschen Zeit. Ich glaub ich bau einfach mal einen kleinen Netstat Nachbau mit der Option Verbindungen zu killen Wink.
oO Du machst mir Angst - wenn du das wirklich "einfach mal" nachbaust...

Fridolin Walther 22. Jun 2009 20:43

Re: API: RecvFrom, SendTo etc gehookt - Programm crasht
 
Wie versprochen eine kleine Unit mit der die von Dir gestellte Aufgabe recht schnell gelöst sein sollte:

Delphi-Quellcode:
unit EnumerateConnections;

interface

uses
  windows;

const
  PROTOCOL_TCP = 0;
  PROTOCOL_UDP = 1;

  TcpConnectionStates :
    array[0..12] of string =
    (
      '', 'CLOSED', 'LISTENING', 'SYN SENT', 'SYN RECIEVED', 'ESTABLISHED', 'FIN WAIT1', 'FIN WAIT2', 'CLOSE WAIT',
      'CLOSING', 'LAST ACKNOWLEDGMENT', 'TIME WAIT', 'DELETE TCP'
    );

type
  TConnection = record
    Protocol : Byte;
    ConnectionState: Cardinal;
    LocalAddress : Cardinal;
    LocalRawPort : Cardinal;
    RemoteAddress : Cardinal;
    RemoteRawPort : Cardinal;
    ProcessID : Cardinal;
  end;
  TConnectionArray = array of TConnection;

function GetConnections(var ConnectionArray : TConnectionArray) : boolean;
function CloseConnection(var Connection : TConnection) : boolean;
function IpAddressToString(IpAddress : DWORD) : string;
function ConvertRawPortToRealPort(RawPort : DWORD) : DWORD;

implementation

uses
  sysutils;

const
  TCPIP_OWNING_MODULE_SIZE = 16;
  AF_INET = 2;

type
  TTcpTableClass = (
    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) ;

  TUdpTableClass = (
    UDP_TABLE_BASIC,
    UDP_TABLE_OWNER_PID,
    UDP_TABLE_OWNER_MODULE );

  _MIB_TCPROW_OWNER_PID = packed record
    dwState: LongInt;
    dwLocalAddr: DWORD;
    dwLocalPort: DWORD;
    dwRemoteAddr: DWORD;
    dwRemotePort: DWORD;
    dwOwningPid: DWORD;
  end;
  TMibTcpRowOwnerPID = _MIB_TCPROW_OWNER_PID;
  PMibTcpRowOwnerPID = ^_MIB_TCPROW_OWNER_PID;

  _MIB_TCPTABLE_OWNER_PID = packed record
    dwNumEntries: DWORD;
    table: array[0..0] of TMibTcpRowOwnerPID;
  end;
  TMibTcpTableOwnerPID = _MIB_TCPTABLE_OWNER_PID;
  PMibTcpTableOwnerPID = ^_MIB_TCPTABLE_OWNER_PID;

  _MIB_UDPROW_OWNER_PID = packed record
    dwLocalAddr: DWORD;
    dwLocalPort: DWORD;
    dwOwningPid: DWORD;
  end;
  TMibUdpRowOwnerPID = _MIB_UDPROW_OWNER_PID;
  PMibUdpRowOwnerPID = ^_MIB_UDPROW_OWNER_PID;

  _MIB_UDPTABLE_OWNER_PID = packed record
    dwNumEntries: DWORD;
    table: Array[0..0] of TMibUdpRowOwnerPID;
  end;
  TMibUdpTableOwnerPID = _MIB_UDPTABLE_OWNER_PID;
  PMibUdpTableOwnerPID = ^_MIB_UDPTABLE_OWNER_PID;

  _MIB_TCPROW = packed record
    dwState: LongInt;
    dwLocalAddr: DWORD;
    dwLocalPort: DWORD;
    dwRemoteAddr: DWORD;
    dwRemotePort: DWORD;
  end;
  TMibTcpRow = _MIB_TCPROW;
  PMibTcpRow = ^_MIB_TCPROW;

function GetExtendedTcpTable(pTcpTable: Pointer; pdwSize: PDWORD; bOrder: BOOL; ulAf: LongWord;
  TableClass: TTcpTableClass; Reserved: LongWord): DWORD; stdcall; external 'iphlpapi.dll';

function GetExtendedUdpTable( pUdpTable: Pointer; pdwSize: PDWORD; bOrder: BOOL; ulAf: LongWord;
  TableClass: TUdpTableClass; Reserved: LongWord): LongInt; stdcall; external 'iphlpapi.dll';

function SetTcpEntry(pTcpRow : PMibTcpRow) : DWORD; stdcall; external 'iphlpapi.dll';

function GetTcpConnections(var ConnectionArray : TConnectionArray) : boolean; forward;
function GetUdpConnections(var ConnectionArray : TConnectionArray) : boolean; forward;

function GetConnections(var ConnectionArray : TConnectionArray) : boolean;
begin
  Result := GetTcpConnections(ConnectionArray) and GetUdpConnections(ConnectionArray);
end;

function GetTcpConnections(var ConnectionArray : TConnectionArray) : boolean;
var
  TcpTable : PMibTcpTableOwnerPID;
  Size : DWORD;
  i : Integer;
begin
  GetExtendedTcpTable(nil, @size, FALSE, AF_INET, TCP_TABLE_OWNER_PID_ALL, 0);
  GetMem(TcpTable, size);
  if GetExtendedTcpTable(TcpTable, @size, FALSE, AF_INET, TCP_TABLE_OWNER_PID_ALL, 0) = NO_ERROR then
    begin
      Result := TRUE;
      for i := 0 to TcpTable^.dwNumEntries - 1 do
        begin
          SetLength(connectionArray, Length(connectionArray) + 1);
          with connectionArray[Length(connectionArray) - 1] do
            begin
              Protocol := PROTOCOL_TCP;
              ConnectionState := TcpTable^.table[i].dwState;
              LocalAddress := TcpTable^.table[i].dwLocalAddr;
              LocalRawPort := TcpTable^.table[i].dwLocalPort;
              RemoteAddress := TcpTable^.table[i].dwRemoteAddr;
              RemoteRawPort := TcpTable^.table[i].dwRemotePort;
              ProcessID := TcpTable^.table[i].dwOwningPid;
            end;
        end;
    end else
      Result := FALSE;
  FreeMem(TcpTable);
end;

function GetUdpConnections(var ConnectionArray : TConnectionArray) : boolean;
var
  UdpTable : PMibUdpTableOwnerPID;
  Size : DWORD;
  i : Integer;
begin
  GetExtendedUdpTable(nil, @size, FALSE, AF_INET, UDP_TABLE_OWNER_PID, 0);
  GetMem(UdpTable, size);
  if GetExtendedUdpTable(UdpTable, @size, FALSE, AF_INET, UDP_TABLE_OWNER_PID, 0) = NO_ERROR then
    begin
      Result := TRUE;
      for i := 0 to UdpTable^.dwNumEntries - 1 do
        begin
          SetLength(connectionArray, Length(connectionArray) + 1);
          with connectionArray[Length(connectionArray) - 1] do
            begin
              Protocol := PROTOCOL_UDP;
              ConnectionState := 0;
              LocalAddress := UdpTable^.table[i].dwLocalAddr;
              LocalRawPort := UdpTable^.table[i].dwLocalPort;
              RemoteAddress := 0;
              RemoteRawPort := 0;
              ProcessID := UdpTable^.table[i].dwOwningPid;
            end;
        end;
    end else
      Result := FALSE;
  FreeMem(UdpTable);
end;

function IpAddressToString(IpAddress : DWORD) : string;
type
  TIpAddressAsArray = array[0..3] of byte;
  PIpAddressAsArray = ^TIpAddressAsArray;
begin
  Result := Format('%d.%d.%d.%d', [PIpAddressAsArray(@IpAddress)^[0], PIpAddressAsArray(@IpAddress)^[1],
    PIpAddressAsArray(@IpAddress)^[2], PIpAddressAsArray(@IpAddress)^[3]]);
end;

function CloseConnection(var Connection : TConnection) : boolean;
const
  MIB_TCP_STATE_DELETE_TCB = 12;
var
  ConnectionToDelete : TMibTcpRow;
begin
  if Connection.Protocol = PROTOCOL_TCP
    then
      begin
        ConnectionToDelete.dwState := MIB_TCP_STATE_DELETE_TCB;
        ConnectionToDelete.dwLocalAddr := Connection.LocalAddress;
        ConnectionToDelete.dwLocalPort := Connection.LocalRawPort;
        ConnectionToDelete.dwRemoteAddr := Connection.RemoteAddress;
        ConnectionToDelete.dwRemotePort := Connection.RemoteRawPort;
        Result := SetTcpEntry(@ConnectionToDelete) = NO_ERROR;
      end
    else Result := FALSE;
end;

function ConvertRawPortToRealPort(RawPort : DWORD) : DWORD;
begin
  Result := (RawPort div 256) + (RawPort mod 256) * 256;
end;


end.
Die Unit implementiert 3 Funktionen, deren Namen mehr oder weniger selbsterklärend sein sollten. Der größte Aufwand war die Strukturen von C nach Delphi zu übersetzen und dort hätte man wahrscheinlich bereits Konvertierungen gefunden, wenn ich gesucht hätte ;).

Ich werd als nächstes dann eine kleine Anwendung implementieren die die Unit nutzt, ist wahrscheinlich anschaulicher dann :). Übrigens benötigt CloseConnection Admin Rechte. Das nur als Hinweis.

napsterxx 22. Jun 2009 20:54

Re: API: RecvFrom, SendTo etc gehookt - Programm crasht
 
Zitat:

---------------------------
Project2.exe - Komponente nicht gefunden
---------------------------
Die Anwendung konnte nicht gestartet werden, weil iplpapi.dll nicht gefunden wurde. Neuinstallation der Anwendung könnte das Problem beheben.
---------------------------
OK
---------------------------
Diesen Fehler bekomme ich mit diesem Code:
Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
var
  Connections: TConnectionArray;
begin
  EnumerateConnections.GetConnections(Connections);

  // Lass ich diese Zeile weg, so bekomme ich keinen Fehler
  EnumerateConnections.CloseConnection(Connections[0]);

end;
Zudem gibt es denke ich ein Problem mit den Ports. Ich höre Livestream auf Port 8000, jedoch gibt mir die Unit auf nachfrage für diese IP den Remoteport 16415 zurück.

Ansonsten ABSOLUT TOP!!



Ich habe mir einmal erlaubt den Code so abzuändern, dass er bei mir funktioniert.

Fridolin Walther 22. Jun 2009 21:20

Re: API: RecvFrom, SendTo etc gehookt - Programm crasht
 
Ja sorry, kleiner Fehler meinerseits ...
Delphi-Quellcode:
function SetTcpEntry(pTcpRow : PMibTcpRow) : DWORD; stdcall; external 'iphlpapi.dll';
... muss es heißen.

Zitat:

Zitat von napsterxx
Zudem gibt es denke ich ein Problem mit den Ports. Ich höre Livestream auf Port 8000, jedoch gibt mir die Unit auf nachfrage für diese IP den Remoteport 16415 zurück.

Ja, die Port Nummern sind allgemein zu hoch. Mal schauen woran das liegt.


Alle Zeitangaben in WEZ +1. Es ist jetzt 06:28 Uhr.
Seite 2 von 3     12 3      

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz