Klar schaut es mit vordefinierten Headern lesbarer und schöner aus. Aber soo viele Datenstrukturen braucht man nun auch wieder nicht (bei Buildern sowieso) - und da kann man entweder die direkten Positionsangaben nutzen oder selber definieren
Hier ist PE Format als "Bytepositionen" aufgelistet PE executable file format offsets
d.h man kann einfach stumpf im Code "abzählen".
TrueCrypt/RAR/Zip Passwort vergessen und das Bruten dauert ewig? Oder brauchst du fein abgestimmte Wortlisten? Hilf dir selbst mit WLML - Word List Markup Language
Gib Stoned/Mebroot/Sinowal und anderen Bootkits keine Chance: Anti Bootkit v 0.8.5
Sooooo. Ich habe jetzt eine etwas längere Autofahrt (als Beifahrer versteht sich ) hinter mir und habe mir die Zeit mit dem Lösen dieses kleinen Problems beschäftigt, dass PHP eigentlich nicht dafür ausgelegt ist .EXE-Dateien zu parsen.
Dabei habe ich eine Art struct-Engine geschrieben, die in der Lage ist structs zu emulieren. Erfolg ist der, dass man nun sehr einfach Structs auf Basis von Bytes, Words, Dwords, Strings (Nullterminiert, oder Binär, wahlweise auch mit einer festen Länge), sowie Arrays definieren kann.
Eine struct kann wiederum als Teil einer weiteren struct verwendet werden (darauf bin ich stolz ).
Beispiel, wie man IMAGE_NT_HEADERS definiert:
PHP-Code:
class IMAGE_NT_HEADERS extends Struct { public function __construct() { $structdef = array( Struct::entry("Signature", new Dword), Struct::entry("FileHeader", new IMAGE_FILE_HEADER), Struct::entry("OptionalHeader", new IMAGE_OPTIONAL_HEADER) );
parent::__construct($structdef); } }
Man beachte, dass hier auch IMAGE_FILE_HEADER und IMAGE_OPTIONAL_HEADER definiert sein müssen.
Um die Idee zu Demonstieren, habe ich einen kleinen PoC-Code geschrieben, der einem alle Sections von kernel32.dll auslistet, sowie einen Ausschnitt der darin enthaltenen exportierten Funktionen ausgibt (kann auch alle ausgeben... lasse die Schleife dafür aber nach 12 Funktionen abbrechen, da es sonst unübersichtlich wird).
P.S.: die structs haben auch einen (
ungetesteten!) bind-Support. Soll heißen, dass man den Inhalt zu dem Bytestream binden kann, von dem der Inhalt gelesen wurde. Und zwar an der selben Position, von der gelesen wurde. Das heißt: ändert man Werte in der struct, werden die auch im Bytesteam (BinReader-Objekt) geändert.
Man müsste also nur noch den privaten Member $stream von BinReader in eine Datei schreiben und schon hätte man seine Datei modifiziert.
MfG. BlackBerry
EDIT:
Okay, ich habe nun write-Support hinzugefügt (waren doch einige Bugs drin xD) und den _Array-Support verbessert.
Nun ist es auch möglich Member mit dem =-Operator zu ändern. Diese werden automatisch im Bytestream geupdatet (es sei denn, man ruft Struct::bindInput(false); auf).
Array Member werden nun über _INDEX erfasst, da ich mir den =-Operator sonst nicht hätte "reinhacken" können.
Als Beispiel für Arrays diene der Teil zum Export-Dir auflisten im Source.
Außerdem habe ich den Code noch darum erweitert, kernel32.dll's ImageBase auf 0xDEADBEEF zu ändern und dann als kernel32new.bin im momentanen Workingdir abzuspeichern.
Falls diese Datei vorhanden ist, wird diese im Weiteren als Quelle benutzt. D.h. das Skript zeigt beim nächsten Aufruf auch die geänderte ImageBase an (das dient natürlich nur als Demontration, dass es funktioniert... einen praktischen Nutzen hat das in diesem Fall nicht).
Geändert von blackberry (05.09.2010 um 01:56 Uhr)
Grund: Bugfixes + write-Support
PDFTT cr3w a.E. — ReiDC0Re, lindor, Sera, berry please do feed the trolls crewand elk Ehrenwerte Mitglieder im Ruhestand: OpCodez, SFX. "Was sich blackberry gerade denkt" — Vorsicht! Frei laufender Wahnsinn!
Zitat von fuckinghot19: "PS: Blackberry ist auf FH der Trollkönig ^^."
An dieser Stelle danke ich all meinen Fans und Hatern gleichermaßen ^.^
Bisher dachte ich echt ich könnte gut Php Scriptn, als ich dein Code gesehn hatte..dachte ich nur "wtf"...ich glaube bis ich den Code verstehe bin ich Alt und hab ein langen Bart :lol Aber echt Übel das du da so viel Arbeit reingesteckt hast, Top!