Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Win32/Win64 API (native code) (https://www.delphipraxis.net/17-win32-win64-api-native-code/)
-   -   Nachträglich Code in EXe einbauen (https://www.delphipraxis.net/100129-nachtraeglich-code-exe-einbauen.html)

Luckie 22. Sep 2007 19:59


Nachträglich Code in EXe einbauen
 
Liste der Anhänge anzeigen (Anzahl: 1)
Ich habe folgendes Programm (siehe Anhang) gerade hier im Forum gefunden. Meine Frage ist nun, wie funktioniert das? Das Prinzip ist klar: Er hängt Code an die Exe-Datei an und biegt den Einsprungspunkt um, dann wird sein Code ausgeführt und der origianl Einsprungspunkt angesprungen. Aber er muss ja irgendwie kompilierten, ausführbaren Code an die Exe hängen und das hab eich nicht verstanden, wie er das macht.

brechi 22. Sep 2007 20:19

Re: Nachträglich Code in EXe einbauen
 
Der Code ist doch dabei? Sein Code wird ausgeführt und dnan springt er zum richtigen EntryPoint.

Luckie 22. Sep 2007 20:23

Re: Nachträglich Code in EXe einbauen
 
Ja, das ist klar. Aber es muss ja compilierter Code sein. Ich kann doch keine Funktionsaufrufe im Klartext in die Exe schreiben und dann erwarten, dass diese ausgeführt werden.

Ich sehe gerade, er hat ja kompilierten Code in der AttacheProc. Aber warum macht er das so umständlich:
Delphi-Quellcode:
type
  TGetProcAddress       = function(hModule:HMODULE;lpProcName:LPCSTR):Pointer;stdcall;
  TLoadLibrary          = function(lpLibFileName:PChar):HMODULE;stdcall;
  TFreeLibrary          = function(hLibModule:HMODULE):BOOL;stdcall;
  TExitProcess          = procedure(uExitCode:UINT);stdcall;
  TGetModuleHandle      = function(lpModuleName:PChar):HMODULE;stdcall;
  TGetMessage           = function(var lpMsg:TMsg;hWnd:HWND;wMsgFilterMin,wMsgFilterMax:UINT):BOOL;stdcall;
  // ...;
  // ...;
Und
Delphi-Quellcode:
type
  PAttachData=^TAttachData;
  TAttachData=packed record
    hLibUser32:               HMODULE;
    hLibGDI32:                HMODULE;
    _GetProcAddress:          TGetProcAddress;
    _LoadLibrary:             TLoadLibrary;
    _FreeLibrary:             TFreeLibrary;
    _ExitProcess:          TExitProcess;
    _GetModuleHandle:          TGetModuleHandle;
    // ...;
    // ...;
    szLibUser32:          array[0..6] of Char; //   "user32"
    szLibGDI32:             array[0..5] of Char; //   "gdi32"

    szLoadLibrary:          array[0..12] of Char; //   "LoadLibraryA"
    szFreeLibrary:          array[0..11] of Char; //   "FreeLibrary"
    szExitProcess:          array[0..11] of Char; //   "ExitProcess"
    szGetModuleHandle:        array[0..16] of Char; //   "GetModuleHandleA"
    szlstrlen:                array[0..8] of Char; // "lstrlenA"

    szGetMessage:          array[0..11] of Char; //   "GetMessageA"
    szTranslateMessage:       array[0..16] of Char; //   "TranslateMessage"
    szDispatchMessage:        array[0..16] of Char; //   "DispatchMessageA"
Könnte man nicht einfach eine Exe nehmen und diese an die original Exe hängen, den EntryPoint umbiegen? Allerdings wie ruft man dann den original EntryPoint auf?

sirius 23. Sep 2007 09:18

Re: Nachträglich Code in EXe einbauen
 
Zitat:

Zitat von Luckie
Könnte man nicht einfach eine Exe nehmen und diese an die original Exe hängen, den EntryPoint umbiegen? Allerdings wie ruft man dann den original EntryPoint auf?

Nein, das fängt ja indem Moment an, wenn du den Code in die andere Exe einfügen willst. Da musst du die Exe ja neu in Code-, Data-, Import-, und ggf. noch weitere Sections unterteilen und diese dann clever einbauen. Eine Exe besteht ja nicht nur aus Code und Einsprungpunkt :zwinker:

Edit:
Am einfachsten bastelst du alles in ein Record:
-Platz für Pointer zu WIN-API-funktionen
-Platz für daten (die kurzen char-arrays)
-Platz für eigene compilierte Funktionen (lange char-arrays)
Dadurch kannst du über Die Refrenz des Records alle Daten und Funktionen bequem erreichen.

OldGrumpy 23. Sep 2007 12:32

Re: Nachträglich Code in EXe einbauen
 
Natürlich kann man ("Rucksackverfahren") den EP einfach auf eigenen Code umbiegen, in der Sectiontable legt man dazu einfach eine zusätzliche Section an mit passenden Accessflags (read/write/executable/usw.) und schreibt da seinen Code rein. Der grosse Knackpunkt dabei ist aber: Allein dadurch wird die Exe ja kein bissl sicherer.

Also geht man hin und verschlüsselt Teile der Exe... Uh-oh. In dem Moment wo Du Code verschlüsselst, musst Du mehr oder weniger zwangsläufig auch API-Aufrufe verschlüsseln. Und da tut sich nun das eigentliche Problem auf: Im Normalfall gibts in der Exe eine Tabelle in der die Adressen von Systemfunktionen stehen, die aus user32.dll, kernel32.dll usw. usw. kommen. Beim Laden einer Exe durch das Betriebssystem werden hier die symbolischen Namen ("GetProcAddressA", "LoadLibraryA" und unzählige andere) durch die aktuell für das jeweilige Windows gültigen Adressen ergänzt, das Programm holt sich danach nicht mehr jedes Mal mühsam über GetProcAddress eine API-Einsprungsadresse sondern springt über eine Sprungtabelle direkt dorthin, diese Sprungtabelle wird ja vom BS beim Laden gefüllt und sieht recht häufig unterschiedlich aus (kleiner Exkurs: Genau an dieser Stelle crashen dann schlechte Cracks *ggg* weil Adressen hardgecoded in der Exetabelle abgelegt wurden die nicht zum momentanen OS passen).

Ein weiteres Problem sind die Fixups. Eine Exe wird zwar seit ewigen Zeiten eigentlich immer an die gleiche Adresse (0x00400000) geladen, prinzipiell könnte eine Exe aber ebenso wie eine DLL auch an anderen Adressen abgelegt werden. Damit die absoluten Sprünge im Code trotzdem funktionieren, gibts eine weitere Tabelle die vom Betriebssystem beim Laden der Exe ausgewertet wird und Offsets enthält - ungefähr so wie "an der Adresse x muss Startadresse der Exe plus y als Wert eingetragen werden". Wenn ich jetzt meine Exe verschlüssele ist ja noch alles in Ordnung, aber wenn ich nach dem Laden der Exe durch die Fixups des Betriebssystems auf einmal andere Werte in der Exe stehen habe, geht die Entschlüsselung an der Stelle schief und das Programm schmiert im besten Falle "problemlos" ab ;)

Exepacker haben durchaus die gleichen Probleme... Die Lösung dafür heisst: Originaltabellen irgendwo in Sicherheit bringen und im PE-Header auf "Null" stellen damit das Betriebssystem die Exe nicht kaputtmacht beim Laden. Danach muss dann der Entpacker/Entschlüssler alle diese Schritte die das BS sonst macht in Eigenregie durchführen. Danach ist die Exe dann (hoffentlich) wieder lauffähig :)

Zacherl 23. Sep 2007 13:22

Re: Nachträglich Code in EXe einbauen
 
Ist es auf diese Weise eigentlich auch möglich die Resourcen Section zu verschlüsseln?

gabneo 23. Sep 2007 13:31

Re: Nachträglich Code in EXe einbauen
 
Hi,
aufbauend auf Zacherls frage: Wenn man die Ressourcen so verschlüsseln könnte/kann dann würden Sie ja auch nicht mehr [Edit]so einfach zumindest[/Edit] Extrahiert werden können, oder?
Das wäre echt geil!
greez
gabneo

PS: :dp:

Luckie 23. Sep 2007 13:47

Re: Nachträglich Code in EXe einbauen
 
Dsa heißt also seine Methode ist doch, obwohl es anders anmutet die einfachere. Hm, OK, ich glaube das wird mich dann wohl einige Tage kosten, seinen Code durchzuarbeiten und zu verstehen. :?

Es geht mir nicht darum die Exe zu packen oder zu verschlüsseln. Es geht mir nur darum rauszufinden,w ei so etwas funktionieren könnte. Allerdings so ganz ohne ist das natürlich nicht, den früher haben die Viren wahrscheinlich nichts anderes gemacht, wenn sie andere ausführbare Dateien infiziert haben.

OldGrumpy 23. Sep 2007 16:04

Re: Nachträglich Code in EXe einbauen
 
Also das Umleiten an sich ist super simpel, im Prinzip nichts anderes als bei den WindowProcs wo Du Dir den Pointer holst, nen eigenen Wert reinschreibst, Dein Ding machst und am Ende die alte Proc aufrufst. Trickreich wirds erst wenn Dein Code halt Systemfunktionen aufrufen will. Dafür gibts mehrere Möglichkeiten:

a) Dein Code macht das alles zu Fuss (hat seine eigene Importtable die beim Start erstmal gefüllt wird)
b) Dein Exepatcher untersucht die Imports der Zielexe und benutzt die vorhandene Importtable für seinen eigenen Code ebenfalls. Falls der eigene Code APIs braucht die noch nicht in der Importtable stehen, lässt sich diese auch erweitern.

a) klingt schon nach viel Aufwand, ist aber noch wesentlich einfacher als b) zu programmieren wenn man nicht jeden Tag in den Innereien des PE-Formates rumwühlt *g*

Dein Exepatcher muss dann nur noch den Entrypoint (EP) aus dem PE-Header auslesen, den Wert durch den Einsprungspunkt des eigenen Codes ersetzen und am Ende des eigenen Codes per JMP an den EP springen. Sowas in Delphi zu programmieren wäre mir persönlich allerdings zu umständlich, meine kleinen Patcher hab ich bisher immer direkt in Assembler gestrickt ;) (Und eh jetzt wieder jemand was von Cracker schreit, es handelte sich bei den Dingern um ganz legale Programme die im Zuge meiner damaligen Entwicklertätigkeit notwendig wurden.)

sirius 23. Sep 2007 16:07

Re: Nachträglich Code in EXe einbauen
 
Falls du noch ein anderes (unübersichtliches) CodeBeispiel brauchst :mrgreen::

DP


Alle Zeitangaben in WEZ +1. Es ist jetzt 11:23 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