Delphi-PRAXiS
Seite 2 von 2     12   

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Win32/Win64 API (native code) (https://www.delphipraxis.net/17-win32-win64-api-native-code/)
-   -   Delphi PE DATA und CODE Section dumpen / modifizieren / hinzufügen (https://www.delphipraxis.net/94434-pe-data-und-code-section-dumpen-modifizieren-hinzufuegen.html)

lbccaleb 24. Jun 2007 00:41

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

ich weiß nicht wie das bei delphi 2005 ist, aber gibts da nicht annähernd die selben demos wie auch in delphi 7???
wenn ja hilft dir nicht das demo vom resexplorer (\delphi\Demos\ResXplor) weiter?? da dürftest du doch alles drin finden was du zum auslesen und dumpen der sectionen benötigst???!!!

Neotracer64 24. Jun 2007 02:04

Re: PE DATA und CODE Section dumpen / modifizieren / hinzufü
 
Hier hab ich etwas in der Richtung gesehen:
http://www.buha.info/board/showthread.php?t=52783

sirius 24. Jun 2007 09:50

Re: PE DATA und CODE Section dumpen / modifizieren / hinzufü
 
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<>'MZ' then 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 :mrgreen: ).

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)

Zacherl 24. Jun 2007 12:28

Re: PE DATA und CODE Section dumpen / modifizieren / hinzufü
 
Vielen Dank! :thumb: Den Beitrag auf buha.info hab ich auch schon gefunden, aber die Unit ist sehr überladen. Da sind hier die Beispielcodes wirklich sehr hilfreich!


Alle Zeitangaben in WEZ +1. Es ist jetzt 17:05 Uhr.
Seite 2 von 2     12   

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