RE: PE-File
Original von Gapa
Hallöle!
Ok also fassen wir zusammen:
Schritte:
1. Hauptprogramm in Hexeditor laden^^
2. PE suchen
3. Anzahl Sections auslesen
4. Letztes Sectionarray auslesen
5. virtual size ändern
6. virtual adress ändern <--- schön beim alten lassen (es ändert sich ja nur die größe
7. sizeofrawdata ändern
8. Characteristics auf 0x2000000 setzen <--- Das Bit (falls nicht gesetzt) setzen.
9. Injectionscode mit OEP einbetten
denn: 0x2000000 ist binär 10000000000000000000000000.b
durch bitweises OR kann man das Bit setzen (falls es nicht gesetzt wurde)
http://de.wikipedia.org/wiki/Bitmaske
denn: wie man aus der Doku entnimmt, handelt es sich nur um eine DWORD Zahl, die aber mehrere Informationen kodiert
- some of the flags in this are ;-
0x00000020 contains code
0x00000040 contains initialized data
0x00000080 contains uninitialized data
0x00000200 contains comments
0x02000000 can be discarded
0x10000000 This section is shareable.
0x20000000 This section is executable.
0x40000000 This section is readable.
0x80000000 The section is writeable.
es wäre ungünstig, diese Informationen zu "vernichten" in dem man das Ganze mit 0x20000000 überschreibt (dann ist die Section nicht mehr beschreibbar/lesbar).
Fragen
1. Angenommen, mein Code, welchen ich ins Hauptprogramm einfügen möchte, ist in C++ geproggt und gibt nur eine Messagebox aus - > Welche Funktionen muss ich dann vom Hauptprogramm mitbenutzen bzw. brauche ich aus der Winapi?
das kommt darauf an, was der C++ Kompiler so ausspuckt und automatisch einbindet.
außerdem hast Du das Problem, dass der Code nicht adressgebunden sein darf.
d.h entweder eine gute Kontrolle über den Kompiler haben oder den Injectionscode in Assembly schreiben. Ich weiß, dass es sehr enttäuschend ist und das auch schnell in ein Flamewar ausarten kann - aber C++ ist bei weitem nicht allmächtig (oder zumindest in manchen Bereichen schwer zu hanhaben)

.
API Nutzung: entweder muss die MessageBox schon vorhanden sein oder Du musst die Adresse der API herausbekommen.
a)Um die in der Anwendung vorhandene API zu nutzen muss man 1) die Imports auslesen - man scannt zuerst die Imports nach einem Eintrag mit dem Namen User32.dll. 2) dann die zu diesem Import zugehörige ImportTable (FirstThunk) nach "MessageBoxA" / "MessageBoxW" /"MessageBoxExA" oder "MessageBoxExW" absuchen. Hat man diese gefunden, merkt man sich die Adresse des Eintrags - hier wird nach dem Start der Executable die Adresse der MessageBox stehen.
Jetzt muss man nur diese Adresse in den zu injezierenden Code einfügen.
b) man kann stattdessen nach "LoadLibraryA" und "GetProcAddress" scannen - diese sind imho häufiger anzutreffen (besonders wenn man statt MessageBox andere APIs braucht).
c) man kann direkt die Kernel32.dll nach "LoadLibraryA" und "GetProcAddress" scannen
den Code gibts hier:
Masm32 Code patchen
(der HookInlinPatching Anhang - und ja, solche Methoden werden inzwischen eher von Crackern benutzt und ausgearbeitet, denn viele der heutigen "Vi
erenschreiben" (oder zumindest viele, die sich zu unrecht so schimpfen) haben nie etwas anders als ihre VB IDE oder Batcheditor gesehen

).
d) eine andere Methode wäre, die vorhandenenen Imports zu erweitern. Dazu müssten allerdings mindestens 20 Bytes nach dem letzen Import Eintrag frei sein. Und das ist nicht immer der Fall (Verschieben und Platzmachen ist etwas aufwendig).
Paar Sachen zu Imports:
http://win32assembly.online.fr/pe-tut6.html
mein Favorit
http://sandsprite.com/CodeStuff/Understanding_imports.html (hier wird FirstThunk als rvaImportAddressTable bezeichnet).
Code:
2. Welchen Teil meines Programms füge ich ins Hauptprogramm ein? Alles, oder nur die Sections?Wäre ja unlogisch, sonst stünde in der letzten Section des Hauptprogramms ja ein neuer MZ-Header bzw. PE-Header...
nur den adressunabhängigen Code. Mit dem Rest wird nämlich der PE-Loader nichts anfangen können. Er wird die ImportTabelle nicht ausfüllen und Deine Sections nicht initialisieren oder gar an richtige Adressen laden.
D.h Du kannst in Deinem Code erstmal keine API bzw. Fremd-DLL Aufrufe nutzen (siehe oben - zuerst LoadLibrary/GetProcess herausbekommen oder alternativ direkt die APIs der Anwendung mitbenutzen). Zudem darf der Code nicht adressabhängig sein - fügt man blind den vom Compiler generierten Code ein, hat man garantiert mehrere Probleme - z.B werden globale Variablen oder Konstanten aus der Data Section geladen, die natürlich eine vom Compiler zugewiesene virtuelle Adresse hat - die aber bei einer Injection gar nicht stimmt (es verschiebt sich alles). Außerdem gibt es "automatisch generierten" Code, z.B um die an die Main übergebene Argumente abzufragen, Abhängigkeiten von Runtimedlls und andere Späße.
3. Habe ich irgendeinen Schritt vergessen bzw. muss ich noch etwas beachten?
da kann ich nur hierauf verweisen:
code von exe an code von anderen exe hängen? (c++)
(da war ich noch halbwegs in Form bezüglich PE Format

).