Delphi-PRAXiS

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)

napsterxx 22. Jun 2009 16:22


API: RecvFrom, SendTo etc gehookt - Programm crasht
 
Juten Tach!
Ich habe mir mal etwas zusammen gebastelt: Eine DLL welche in einen fremnden Prozess injected wird, und anschließend verschiedene API-Funktionen Hook. An der Funktion wird nichts verändert, lediglich in eine Textdatei geschrieben, ob die Funktion ausgeführt wurde - sprich in der Text Datei steht folgendes:

Zitat:

SendTo
RecvFrom
RecvFrom
RecvFrom
Send
SendTo
Recv
Recv
Die DLL habe ich zu Testzwecken in PidGin injectet - und alles funktioniert einwandfrei. Da ich vorhabe, Warcraft 3 Packete von bestimmten IP Adressen zu blockieren, sodass diese meinem Spiel nicht mehr beitreten können - sprich eine Art Banlist - dachte ich, ich injecte die DLL einfach mal in Warcraft 3.
Gesagt getan.

Nachdem eine der obigen Funktionen ausgeführt wurde, steht diese auch in der Textdatei, jedoch stürtzt danach sofort Warcraft 3 ab.



Frage: Warum stürtzt Pidgin nicht ab - Warcraft 3 hingegen sofort nachdem eine Funktion ausgeführt wurde?

mkinzler 22. Jun 2009 16:23

Re: API: RecvFrom, SendTo etc gehookt - Programm crasht
 
@napsterxx: Du hast unsere Nutzungsbedingungen immer noch nicht Gelesen/Verstanden?

napsterxx 22. Jun 2009 16:38

Re: API: RecvFrom, SendTo etc gehookt - Programm crasht
 
Wo ist denn das Problem?
Gehören, Injections und Hooks etwa zur "dunklen Seite der Macht"?

Keyboard Hooks und alles wird hier freizügig verteilt (Keylogger) ...
Bei ServerSocket und ClientSocket hilft jeder - aber man kann damit auch bööse Sachen anstellen (RAT)...

Hätte ich gesagt, ich injiziere die DLL in eins meiner Programme und darauf hin crasht es, so hätte ich alle Antworten bekommen die ich brauche. Muss ich erst anfangen meine Beiträge Tagelang à la "Social Engeneering" zu verschleiern?


Ich möchte eine Banlist programmieren - keine Manipulation tätigen. Ich habe extra den Source für mich behalten, es gibt bestimmt Kinder die ihn kopieren und vielleicht etwas damit manipulieren. Wenn man genau hinsieht, bekommt man jegliche Informationen über das erstellen eines Trojaners - hier im Forum!

:twisted: :twisted:

Mithrandir 22. Jun 2009 16:47

Re: API: RecvFrom, SendTo etc gehookt - Programm crasht
 
Hat er nicht ganz unrecht mit, Markus.. ;)

napsterxx 22. Jun 2009 17:02

Re: API: RecvFrom, SendTo etc gehttp:hookt - Programm crasht
 
Seit dem 02.05.2008 beschäftige ich mich mit Sniffern. Mein Anliegen ist, für die Spieleplattform eine Konfortable Banlist für das Spiel Warcraft 3 zu entwickeln - nur auf Grund dieser Idee, sitze ich schon mehr als ein Jahr dahinter. Ich habe einen Sniffer programmiert welcher mir alle Warcraft 3 Pakete analysiert und formatiert den Inhalt ausgibt - und das war weis Gott nicht einfach!
Ich hänge lediglich daran, gebannten Spielern den Zugang zu meinem Spiel zu verwehren. Zunächst dachte ich, ich sende ein eigenes Paket, was jedoch nach etlichen Versuchen fehl schlug.
Ich entschloss mich andere Wege zu suchen und bin letztenendes bei den Hooks stehen geblieben. Nach weiterer sehr langen Suche bin ich endlich so weit, das ich die API Calls hooken kann.

Das einzig seltsame ist - und das möchte ich bitte beantwortet kommen, warum stürtzt das Spiel ab?
Delphi-Quellcode:
Function Hook_SendTo( *****: *****; *****, *****, *****: *****; *****: *****; *****: *****): *****; StdCall;
Begin  
  WriteToFile('Hook_SendTo');
  Result := HookNew_SendTo( *****, *****, *****, *****, *****, *****);
End;
Ich hoffe ich habe nicht vergessen etwas zu zensieren :roll:

Wie dem auch sei, verändere ich den Code in der Hinsicht:

Delphi-Quellcode:
Result := 1;
So stürtzen die Programme erst beim "Unhooken" ab.

Aphton 22. Jun 2009 17:45

Re: API: RecvFrom, SendTo etc gehookt - Programm crasht
 
Wie sieht WriteToFile aus?

MfG

napsterxx 22. Jun 2009 17:52

Re: API: RecvFrom, SendTo etc gehookt - Programm crasht
 
An der Funktion kann es nicht liegen, wenn ich die Aufrufe dieser Funktion auskommentiere stürtzt Warcraft 3 dennoch ab.

Fridolin Walther 22. Jun 2009 18:04

Re: API: RecvFrom, SendTo etc gehookt - Programm crasht
 
Wie hookst Du? Code Overwriting? IAT? EAT? Winsock hat einige spezielle Checks ob Hooks aktiv sind oder nicht, die bestimmte Hookarten erkennen. Daher die Frage.
Wie sehen die Funktionsdefinitionen aus? Unhooking ist übrigens auch eine relativ schlechte Idee. Es gibt dutzende Stolperfallen durch Threading etc.. Ich würd da von abraten.

Deine Log Funktion ist übrigens nicht Thread Safe.

Prinzipiell sollte man die Funktionalität die Du anstrebst übrigens auch komplett ohne Hooks implementieren können. Sofern Du das denn möchtest ...

napsterxx 22. Jun 2009 18:10

Re: API: RecvFrom, SendTo etc gehookt - Programm crasht
 
Ich möchte einen Paketversand zu einer IP XY blockieren - wie dies nun geschiet ist mir gleichgültig, jedoch scheidet das versenden von eigenen Paketen aus. Hooks oder nicht? => Keine Ahnung was eine gute Lösung ist.

IAT habe ich mir überlegt.

Hook wird via uAllHook getätigt.

Delphi-Quellcode:
  @HookOrg_SendTo := GetProcAddress(LoadLibrary('ws2_32.dll'),'sendto');
  HookCode(@HookOrg_SendTo, @Hook_SendTo,@HookNew_SendTo);

brechi 22. Jun 2009 18:16

Re: API: RecvFrom, SendTo etc gehookt - Programm crasht
 
Wie sieht:
HookOrg_SendTo, Hook_SendTo, HookNew_SendTo aus?

Welchen Virenscanner hast du? Bzw. kannst du mal einen Dump von SendTo in Ollydbg machen? Ansonsten versuch mal zuerst nen Import hook.

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.

Fridolin Walther 22. Jun 2009 21:49

Re: API: RecvFrom, SendTo etc gehookt - Programm crasht
 
Liste der Anhänge anzeigen (Anzahl: 1)
Hier eine kleine Demo Anwendung. Schnell zusammen geklickt. Aber man sieht wie die Unit zu verwenden ist, darauf kommts ja an. Das Problem mit den Ports ist auch behoben. Es ist noch eine kleine Umrechnung nötig. Wieso Microsoft das verschweigt in seiner Doku, weiß ich allerdings auch nicht so recht ... [EDIT: Es ist natürlich dokumentiert ... man muss nur halt mal genau lesen ... ich werd alt :(]

Der oben gepostete Quellcode der Unit ist übrigens aktualisiert ;). Vor Verwendung sollte die unit aber um gescheites Fehlerhandling erweitert werden. Das überlass ich als Aufgabe dem geneigten Leser ;).

napsterxx 22. Jun 2009 22:03

Re: API: RecvFrom, SendTo etc gehookt - Programm crasht
 
Also wenn du deine Unit verbessert hast, muss ich nicht meine editierte posten :D

Danke nocheinmal!

Fridolin Walther 22. Jun 2009 22:05

Re: API: RecvFrom, SendTo etc gehookt - Programm crasht
 
Vergiss nicht das Du die Ports von Network Byte Order umrechnen musst in normale Byte Order. Dazu gibts eine kleine Funktion ConvertRawPortToRealPort (die im Nachhinein total beschissen heißt, weil mir der Begriff Network Byte Order beim Schreiben der Unit nicht eingefallen ist :().

napsterxx 22. Jun 2009 22:17

Re: API: RecvFrom, SendTo etc gehookt - Programm crasht
 
Habe die Funktion direkt implementiert und den Record auf RemotePort erweitert. RemotePort ist dann der schon umgerechnete Port.

intika 5. Mai 2012 06:47

AW: API: RecvFrom, SendTo etc gehookt - Programm crasht
 
Thanks a million for your sharing !!!


Alle Zeitangaben in WEZ +1. Es ist jetzt 10:55 Uhr.

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