Einzelnen Beitrag anzeigen

Benutzerbild von sirius
sirius

Registriert seit: 3. Jan 2007
Ort: Dresden
3.443 Beiträge
 
Delphi 7 Enterprise
 
#13

Re: PE DATA und CODE Section dumpen / modifizieren / hinzufü

  Alt 24. Jun 2007, 09:50
Ich wollte grad ein paar Codebeispiele (wie man in eine EXE etwas einfügt) von mir einblenden, aber das wird zu viel und zu undurchsichtig.
Hier also eine "kurze" Variante von dem umfangreichen Thema.


Folgende Vorgehensweise schlage ich vor (habe ich mal benutzt):
1. Datei in einem TMemoryStream laden (ich habe gleich eine Klasse davon abgeleitet)

2. Header lesen
Die einzelnen Header sind schon als Record in der Unit Windows definiert.
Delphi-Quellcode:
pDosHeader:PImageDosHeader //siehe unit windows
pNTHeader:PImageNtHeaders
//...


//das sieht dann in etwa so aus.
pdosheader:=mpos(0);
if pdosheader^.e_magic<>'MZthen exit;
pNTHeader:=mpos(pDOSHEADER^.e_lfanew);
//usw.... Ich nehme mal an du kennst den Aufbau des PE-Kopfes
//(die SectionHeader kommen am Ende des PE-Headers)

//mpos liefert nur den Pointer aus einer bestimmten Position von TMemorystream.Memory
function TPEReader.mpos(position: Cardinal):pointer;
begin
  result:=pointer(cardinal(memory)+position);
end;
Wenn du die ganzen einzelnen recordpointer positioniert hast, kannst du auch problemlos die einzelnen Eigenschaften lesen.
Du kannst auch den Headerteil aus memory herauskopieren:
Delphi-Quellcode:
NTHeader:TImageNTHeader;
//...
move(mpos(pDOSHEADER^.e_lfanew),NTHeader,sizeof(NTHeader));
//Achtung: das system.move klappt so nicht ganz!!
Damit bekommst du alle Infos aus dem Header.


3. Daten ändern
Hierzu brauchst du nur in deinem Stream rumschreiben und ihn schließlich wieder speichern.
Den Headerteil kannst du recht simpel über die RecordPointer aus Schritt zwei ändern.
Beim ändern einer Section (inkl. Vergrößern/verkleinern) musst du natürlich darauf achten, dass
- die Section sich jetzt nicht mit anderen sections überschneidet
- Eigenschaft SizeOfRawdata anpassen
- Eigenschaft VirtualSize anpassen
- Eigenschaft SizeOf(Un)InitializedData oder SizeofCode anpassen
- Eigenschaft SizeOfImage anpassen
- auf Sectionalignment und Filealignment achten
Mein Code um Daten im TMemorystream einzufügen:
Delphi-Quellcode:
procedure TPEReader.insert(text: string; pos: Integer);
var i,s,os:integer;
    source,dest:pbyte;
    p:pointer;
begin
  s:=length(text);
  os:=size;
  size:=size+s; //Tmemorystream.size vergrößern
  source:=mpos(os-1);
  dest:=mpos(size-1);
  for i:=1 to s+(os-pos) do begin
    dest^:=source^;
    dec(dest);
    dec(source);
  end;
  p:=mpos(pos);
  system.move(text[1],p^,s);
end;
Das Einfügen einer Section habe ich selber noch nicht gemacht. Aber abgesehen davon, dass du einen kompletten Sectionheader erstellen musst, musst du natürlich auch wieder sizeofImage etc. anpassen (und natürlich numberofSections)


4. Was du wahrscheinlich noch beachten musst, ist das umrechnen von virtuellen Adressen in DateiOffset und umgekehrt. Die eine Richtung sieht bei mir so aus:
Delphi-Quellcode:
function TPereader.RVA2Offset(Adr:cardinal):cardinal;
var i:integer;
//sectionheader ist ein array of TImageSectionHeader
//numberofSections kommt aus dem fileHeader
begin
   i:=numberofsections-1;
   result:=0;
   while i>=0 do begin
     if (adr>=sectionsheader[i].VirtualAddress)and
        (adr<sectionsheader[i].VirtualAddress+sectionsheader[i].SizeOfRawData) then begin
       result:=adr-sectionsheader[i].VirtualAddress;
       inc(result,sectionsheader[i].PointerToRawData);
     end;
     dec(i);
   end;
end;
Wie gesagt, dass ist nur ein kleiner Teil, der vielleicht den Einstieg erleichtert. Es ist aber u.a. recht hilfreich, wenn man ohne Probleme mit Hilfe eines Hex-Editors o.ä. den Aufbau einer EXE lesen kann. Hier muss man sehr vorsichtig sein und braucht viel Geduld und Übung (wenn man es zum ersten Mal macht; aber das ist ja beim programmieren generell so ).

PS: Keine Gewähr für die Codebeispiele (ich hatte mir damals die records z.B. selber definiert, weil ich nicht wusste, dass sie in der Unit windows existieren; deswegen können Unstimmigkeiten auftreten)
Dieser Beitrag ist für Jugendliche unter 18 Jahren nicht geeignet.
  Mit Zitat antworten Zitat