Hallo,
ich habe mich des öfteren mit Microsofts
PE-Format beschäftigt und deswegen dachte ich mir das ich mal eine
Unit mache die die Arbeit mit dem
PE-Format erleichtern sollte
. Die
Unit wird von mir täglich mit neuen Funktionen erweitert!
Unit Version: 1.3
Funktionen:
- Allgemeines
- LoadFromFile - Laden einer Datei.
- SaveToFile - Speichern einer Datei.
- ValidHeaders - Überprüft ob die DOS + NTHEADERS in ordnung sind.
- ReadPeHeaders - Ließt alle Sektionen und Header ein.
- Align - Align .
- SectionToString - Gibt den Namen einer Sektion in String zurück.
- StringToSection - Setzt einen neuen Namen einer Sektion.
- SetAddressOfEntryPoint - Setzt einen Neuen EntryPoint.
- SetImageBase - Setzt eine neue ImageBase.
- CopyMemoryToBuffer - Damit kann man den Speicher der geladenen Datei ändern.
- CopyMemoryFromBuffer - Damit kann man aus dem Speicher der geladenen Datei lesen.
Umrechnungen
- RvaToFileOffset - Berechnet die Relative Virtuelle Adresse in die Physikalische Adresse um.
- FileOffsetToRva - Berechnet die Physikalische in die Relative Virtuelle Adresse um.
- VaToFileOffset - Berechnet die Virtuelle Adresse in unserem Speicher in die Physikalische Adresse um.
- FileOffsetToVa - Berechnet die Physikalische Adresse in die Virtuelle Adresse in unserem Speicher um.
- VaToRva - Berechnet die Virtuelle Adresse in unserem Speicher in die Relative Virtuelle Adresse.
- RvaToVa - Berechnet die Relative Virtuelle Adresse in der Virtuellen Adresse in unserem Speicher.
- RvaToSection - Liefert anhand der Relativen Virtuellen Adresse die Nummer der Sektion in der sie sich befindet.
- FileOffsetToSection - Liefer anhand der Physikalischen Adresse die Nummer der Sektion in der sie sich befindet.
Hinzufügen/Entfernen
- InsertBytes - Fügt x Bytes im Speicher der Datei.
- DeleteBytes - Löscht x Bytes im Speicher der Datei.
- FindCodeCaves - Sucht nach sogenannten "Code-Höhlen" (0-Bytes) im Speicher der Datei.
Sektionen
- AddSection - Fügt eine neue Sektion hinzu. Hier wird jedoch geprüft ob noch Platz für eine neue Sektion vorhanden ist, falls nein wird neuer angelegt.
- DeleteSection - Löscht eine bestimmte Sektion aus der PE Datei.
- GetCharacteristics - Liefert die Characteristics in String einer Sektion.
- GetCodeSection - Liefert die Nummer der Sektion in der sich die Code-Sektion befindet.
- GetDataSection - Liefert die Nummer der Sektion in der sich die Data-Sektion befindet.
- GetResourceSection - Liefer die Nummer der Sektion in der sich die Ressourcen-Sektion befindet.
- GetImportAddressTable - Liefert alle Importe einer Datei (Zurzeit Normale IAT, Delayed IAT, Bound IAT).
- GetExportsAddressTable - Liefert die Exports einer Datei.
- GetThreadLocalStorage - Liefert Informationen zu TLS.
- GetResources - Liefert alle Ressourcen der Datei (Ressourcen-Typen, Resourcen-Namen).
- GetDebugDirectory - Liefert Informationen zu der Debug Directory.
- GetLoadConfigDirectory - Liefert Informationen zu der Load Config Directory.
- GetEntryExceptionDirectory - Liefert Informationen zu Entry Exception Directory.
- DumpSection - Damit kann man eine Sektion auf der Festplatte speichern.
- GetHighestSectionSize - Liefert die "größte"/letzte Sektion (also PointerToRawData + SizeOfRawData).
- GetDataFromEOF - Damit kann man die Daten die sich nach Ende aller Sektionen befinden auslesen und zwischenspeichern.
- RecalcImageSize - Damit lässt sich die SizeOfImage neu berechnen.
- ResizeSection - Damit kann man einzelne Sektionen vergrößern! Achtung: Ressourcen (OffsetToData) werden angepasst!
- CalcChecksum - Damit wird die Check-Summe der PE Datei berechnet.
- RecalcCheckSum - Berechnet automatisch die Check-Summe und ändert diese gleich in den Headern.
- WriteImageSectionHeader - Schreibt alle ImageSections in dem Speicher!
Neu Dabei
- AddSection - RawSize hinzugefügt, VirtualSize entfernt - wird automatisch von RecalcImageSize berechnet,
lpData und dwDataLength hinzugefügt (das heißt, dass man die neue Sektion gleich mit Daten füllen kann).
- DeleteSection - ImageSize wird über RecalcImageSize berechnet, ruft RecalcCheckSum am Ende der funktion auf!
- ResizeSection - Damit kann man einzelne Sektionen vergrößern! Achtung: Ressourcen (OffsetToData) werden angepasst!
- GetResources - Überarbeitet (RVA wurde falsch berechnet!), neue Struktur (enthält größe des Entries)
- Resources Beispiel - Angepasst an die neue Struktur und Dump funktion hinzugefügt!
- CalcChecksum - Damit wird die Check-Summe der PE Datei berechnet.
- RecalcCheckSum - Berechnet automatisch die Check-Summe und ändert diese gleich in den Headern.
- WriteImageSectionHeader - Schreibt alle ImageSections in dem Speicher!
Beispiele
- IAT - Ein Beispiel Programm um die Imports einer Anwendung auszulesen und auszugeben.
- EAT - Ein Beispiel Programm um die Exports einer DLL-Datei auszulesen und auszugeben.
- Resources - Ein Beispiel Programm um die Ressourcen einer Anwendung auszulesen und auszugeben. Man kann auch die ausgewählte Ressource dumpen!
- Sections - Ein Beispiel Programm um die Sektionen einer Anwendung auszulesen und auszugeben.
- ExeLoader - Ein ganz kleiner Exe-Loader der die Code-Sektion mittels XOR verschlüsselt. Er fügt einen neuen Loader in einer neuen Sektion hinzu,der zur Laufzeit die Code-Sektion entschlüsselt und zum Original Entry Point springt.
Beispiel-Aufruf:
Delphi-Quellcode:
uses untPeFile;
...
procedure TForm1.FormCreate(Sender: TObject);
var
PE: TPeFile;
x: Word;
Imports: TImportsArray;
const
sSection = '
Name: %s' + #13#10 +
'
Sektion: %d/%d' + #13#10 +
'
Start der Sektion: %d' + #13#10 +
'
Größe der Sektion: %d';
sImports = '
Bound Import Lib: %s';
begin
PE := TPeFile.Create;
// Datei Laden ..
if PE.LoadFromFile('
C:\WINDOWS\Notepad.exe')
then
begin
// Alle Sektionen ausgeben
for x := Low(
PE.ImageSections)
to High(
PE.ImageSections)
do
ShowMessage(Format(sSection, [
PE.SectionToString(
PE.ImageSections[x]), x,
PE.NumberOfSections -1,
PE.ImageSections[x].PointerToRawData,
PE.ImageSections[x].SizeOfRawData]));
// Imports Auslesen
PE.GetImportAddressTable(Imports);
// Nur die Bound IAT ausgeben
for x := Low(Imports)
to High(Imports)
do
if Imports[x].ImportType = itBound
then
ShowMessage(Format(sImports, [Imports[x].LibraryName]));
// Neue Sektion anlegen
PE.AddSection('
NewSec', $200);
// Die angelegte Sektion wieder entfernen
PE.DeleteSection(
PE.NumberOfSections -1);
// Speichern ...
PE.SaveToFile('
C:\NOTEPAD_TMP.exe');
end;
// Freigeben...
PE.Free;
end;
Falls ihr Verbesserungsvorschläge habt, dann nur her damit!