![]() |
Inline Assembler
Hallo,
ich habe eine DLL die als AntiCheat-Schutz in einem Spiel dienen soll. Für dieses Spiel gibt es sehr viele Packet Editors (oder eher gesagt Packet Senders), die eine bestimmte Adresse aufrufen. Um zu verhinden dass die Cheater nun ihre PEs injizieren möchte ich bei dieser Adresse gerne prüfen, ob der Aufruf aus der Haupt-EXE oder aus einer geladenen DLL kommt.
Delphi-Quellcode:
Mein eigentliches Ziel habe ich erreicht - der Name steht in der Textdatei. Leider geht dabei irgendwas kaputt und die Pakete werden vom Spiel nicht mehr weiterverarbeitet :?
function GetModuleFromAddress(Address: Pointer): string;
var Res: HMODULE; Name: array[0..100] of AnsiChar; begin GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, Address, Res); GetModuleBaseName(GetCurrentProcess, Res, Name, 100); Result := string(AnsiString(Name)); end; procedure OnSendPacket(Ret: Pointer); stdcall; var F: TextFile; begin AssignFile(F, 'C:\test.txt'); Append(F); Writeln(F, GetModuleFromAddress(Ret)); CloseFile(F); end; procedure SendPacket; stdcall; asm mov eax, [ebp] mov eax, [eax+$04] push eax call OnSendPacket mov eax,$00BF0044 jmp dword ptr [SendPacketRet] end; [...] hier wird noch der Speicher modifiziert und ein JMP zu SendPacket() erstellt. Ich habs leider mit Assembler nicht so, ich vermute das geschieht durch den Aufruf der Delphi-Funktion OnSendPacket, welche dann irgendwelche Register verändert? Zur Info, das Paket was der Client dann verarbeiten soll wird in ecx gespeichert. |
AW: Inline Assembler
Delphi-Quellcode:
Bernhard
asm lea ecx, Quelle end;
|
AW: Inline Assembler
Ohne jetzt auf die Assemblerfrage weiter einzugehen, möchte ich nur kurz deine gesamte Vorgehensweise infrage stellen.
Es gibt auch sog. "cavity injection". Da du an einer AC-Engine arbeitest, setze ich mal voraus, daß du Grundkenntnisse über den Aufbau von PE-Dateien besitzt. Du weißt also, daß eine PE-Datei auf Platte und im Speicher (meist) anders aussehen. Im Speicher haben sie oft - zumeist am Ende von Sektionen - ein "Loch", nämlich die Bytes welche bis zur Ausrichtung im Speicher noch fehlen um die Seite/Sektion (o.ä.) vollzumachen. Entsprechend kann ein cleverer "Angreifer" (i.e. Cheater) mal eben ein Trampolin oder komplexeren Shellcode da einbauen. Dann kommt der Aufruf also ggf. "aus deinem PE-Abbild" im Speicher, obwohl nur stimmt, daß der Aufruf aus dem Bereich zwischen Basisadresse und Basisadresse+Größe stammt. Dein Ansatz geht also am Problem leicht vorbei ;) Diese Methode wird schon seit Jahren bei Malware eingesetzt, so auch bei KM-Rootkits, wo die Antimalware-Lösung bspw. versucht auch anhand der Adresse festzustellen ob die SSDT gehookt wurde ;) |
AW: Inline Assembler
Mal als naiven Vorschlag:
Da man ja nicht wie einem Anti-Malware-Programm viele Prozesse überwachen muss, könnte man doch zusätzlich regelmäßig die Codesektionen mit denen aus der PE-Datei (+Anti-Cheat-Tool-Hooks) vergleichen und Lücken mit Schrott/NOPs ausfüllen. Eventuelle von der Anwendung "legal" änderbare Sektionen könnte man ja davon ausnehmen. |
AW: Inline Assembler
Zitat:
Abgesehen davon könnte ich dann ggf. auch den Code der PE auslagern (bspw. indem ich die PE-Datei nochmal im Prozeßraum als MMF lade und selber reloziere) und einfach alle PE-Sektionen (des originalen Abbilds) dafür benutze mein eigenes Ding zu machen ... Kommt immer drauf an welche Rechte der Angreifer schon hat. Am Ende hat der Angreifer gegen unendlich viele Möglichkeiten einen Angriff zu machen, während der Verteidiger dieses Privileg nicht genießt - u.a. wird ein Rootkit-Autor oft nicht auf Stabilität achten müssen, solange ihm das Rootkit als Teil eines Bots auf genügend anderen Rechnern etwas einbringt; der Verteidiger muß auf Stabilität achten. |
AW: Inline Assembler
Zitat:
Zitat:
Darauf muß man erst mal kommen :shock: Zitat:
|
AW: Inline Assembler
Zitat:
Zitat:
Zitat:
|
AW: Inline Assembler
Nur um das klarzustellen, das soll keine aufwändige Anti-Cheat-Engine werden. Nur eine kleine Bibliothek die LoadLibrary hookt, das laden von einigen einschlägigen Trainern verhindert und eben das Senden von Paketen durch anderes injiziertes Zeugs verhindert. Das soll auch nur für diese ganzen Noobs sein, die die Cheats benutzen aber keine Ahnung haben wie das ganze funktioniert. Wenn jemand da wirklich cheaten will und auch Erfahrung darin hat ist mir klar, dass man ihn nicht davon abhalten kann. Das schaffen ja auch die professionellen Anwendungen in den meisten Fällen nicht.
Nun aber zurück zu meinem Problem. Wo soll ich dieses lea ecx benutzen und was bringt es mir, ist ecx nicht in dem Fall das Ziel? Dann müsste ich ja vorher erst was in Quelle laden. |
AW: Inline Assembler
Zitat:
Zitat:
Was ist denn SendPacketRet (Funktion oder nur Zeiger?) und wo kommt es her, wo wird es gesetzt. Abgesehen davon dürfte der Spaß im Disassembler unter Umständen nicht mehr ganz so aussehen wie du es erwartest. Außerdem scheinst du sozusagen auf dem Rasen der gehookten Funktion herumzutrampeln. Jedenfalls erschließt sich mir:
Code:
nicht, wenn man annimmt, daß die gehookte Funktion (und so sollte es ja sein) auch stdcall benutzt.
mov eax,$00BF0044
jmp dword ptr [SendPacketRet] |
AW: Inline Assembler
![]() Die 5 Bytes bei 4BC877 ersetze ich mit einem jmp zu meiner SendPacket Methode. Das mov eax,00b... ist also nur der originale Opcode und dann wird der originale Code weiter ausgeführt (SendPacketRet: Cardinal = $4BC877 + 5). Mehr weiß ich leider auch nicht, außer dass ecx einen Pointer auf einen record mit dem Paket enthält. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 07:49 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz