AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Win32/Win64 API (native code) Delphi code section lesen bzw. ram editor
Thema durchsuchen
Ansicht
Themen-Optionen

code section lesen bzw. ram editor

Ein Thema von Arnulf · begonnen am 19. Jun 2008 · letzter Beitrag vom 2. Jul 2008
Antwort Antwort
Arnulf

Registriert seit: 28. Okt 2004
Ort: Wien
271 Beiträge
 
#1

code section lesen bzw. ram editor

  Alt 19. Jun 2008, 12:43
Hallo
Ich pfusch wiedermal irgendwo im pe-header herum.
Ich würde mich gerne an einer art ram editor versuchen.

Erstmal will ich nur die code section bzw. das reine image eines programms auslesen.
Mich interessieren also die dinge im data directory wie import oder export table nicht besonders.
es geht nur um das reine image der executeable im ram.

wo finde ich das bzw. wie kann ich das auslesen.
Eine simple string suche würde erstmal reichen.

Muss ich dazu den ganzen section header lesen und alle sections durchsuchen?
oder liegt das entpackte image ( upx oder morphine ) irgendwo als ganzes vor?

lg
Arnulf
  Mit Zitat antworten Zitat
Benutzerbild von nicodex
nicodex

Registriert seit: 2. Jan 2008
Ort: Darmstadt
286 Beiträge
 
Delphi 2007 Professional
 
#2

Re: code section lesen bzw. ram editor

  Alt 19. Jun 2008, 14:40
Ich habe für ein Spiel einen Trainer-Prototypen mit entsprechenden Basisklassen entworfen, welche dir als Vorlage oder Inspiration dienen könnten.
WitchLDM-0.0.0.2.zip (insbesondere die ImgUtils.pas)

Der entsprechende Thread ist hier zu finden: The Witcher: Trainer-Wettbewerb
(rein informativ und hat nichts mit deiner Fragestellung zu tun)

Gruß Nico
  Mit Zitat antworten Zitat
Arnulf

Registriert seit: 28. Okt 2004
Ort: Wien
271 Beiträge
 
#3

Re: code section lesen bzw. ram editor

  Alt 20. Jun 2008, 10:43
Hi
Soweit ich die sourcen auseinander gepfriemelt habe durchsuchst du in einem prozess alle module bzw. deren codesection nach einem "command".

Ich denke ich kann mir schon irgendwie zusammenbastelnd die sections eines programms bzw. einer .dll zu durchsuchen aber warum durchsuchst du nur die readable sections?

Delphi-Quellcode:
        if (Section.Size >= NameSize) and Section.IsReadable and
          not Section.IsWriteable and not Section.IsExecutable then
bzw. war auch die eigentliche Frage welche sections muss ich durchsuchen um nur die code section eines programms zu durchsuchen.
Also wie finde ich code section bzw. data section oder den heap - wie unterscheide ich das.
Die frage mag etwas seltsam anmuten, aber ich bring hier theorie und praxis nicht unter einen Hut.
Vielleicht war das oben auch schon die Antwort auf die Frage - dh. reine code sections sind einfach nur readable und nicht writeable.
aber warum dann nicht executeable??

lg
Arnulf
edit:
eine Theorie hab ich noch.
Strings sind hier string literale und werden vielleicht in der data section abgelegt.
Damit könnte es natürlich sein, dass ich alle sections durchsuchen muss die readable sind aber nicht writeable und executeable???
  Mit Zitat antworten Zitat
Benutzerbild von nicodex
nicodex

Registriert seit: 2. Jan 2008
Ort: Darmstadt
286 Beiträge
 
Delphi 2007 Professional
 
#4

Re: code section lesen bzw. ram editor

  Alt 20. Jun 2008, 12:07
Zitat von Arnulf:
warum durchsuchst du nur die readable sections?
Es gibt (theoretisch) Speicherbereiche, welche nicht lesbar sind (zum Beispiel nur schreibbar).

Zitat von Arnulf:
welche sections muss ich durchsuchen um nur die code section eines programms zu durchsuchen.
Das hängt von dem Programm ab, um das es geht.
Grundsätzlich alle, die "ausführbar" sind.

Zitat von Arnulf:
Also wie finde ich code section bzw. data section oder den heap - wie unterscheide ich das.
Anhand der Eigenschaften des Speicherbereichs.
Wenn du genauere Informationen zu den Speicherbereichen des Moduls benötigst (die Klasse interessiert sich für nichts anderes, also auch kein Heap, etc), dann darfst du den PE-Header im Speicher auslesen (die RVAs wurden vom Windows-Loader bereits in VAs "übersetzt").

Zitat von Arnulf:
dh. reine code sections sind einfach nur readable und nicht writeable.
Sie muss nur "ausführbar" sein.
Wenn man den Bereich untersuchen will, dann braucht man natürlich auch die Möglichkeit den Bereich lesen zu können
Es gibt genug Beispiele in denen Code-Sections schreibbar sind (bzw. Copy-on-Write).

Zitat von Arnulf:
Strings sind hier string literale und werden vielleicht in der data section abgelegt.
Damit könnte es natürlich sein, dass ich alle sections durchsuchen muss die readable sind aber nicht writeable und executeable?
Grundsätzlich wirst du alle lesbaren Bereiche untersuchen müssen. Auch "ausführbare" Bereiche enthalten (sehr oft konstante) Daten.


ps: Es handelt sich ingesamt um ein komplexes Thema, welches bei jedem Projekt neue Fragen aufwirft und entsprechend andere Lösungen erfordert. Der Prototyp diente nur als eine Vorlage, um die grundlegenden Mittel zur Verfügung zu haben, die man in solchen Fällen öfter braucht. Alles außer der ImgUtils.pas bezieht sich nur auf The Witcher - und selbst diese Unit ist teilweise spezialisiert, weil sie diverse Informationen nicht zur Verfügung stellt.
  Mit Zitat antworten Zitat
Arnulf

Registriert seit: 28. Okt 2004
Ort: Wien
271 Beiträge
 
#5

Re: code section lesen bzw. ram editor

  Alt 20. Jun 2008, 16:01
Ich habe die hälfte deiner klassen nur rudimentär verstanden, deshalb hab ich einfach selbst einmal versucht die section header zu finden.

Eindeutig verwirrend war für mich, dass ich vom prozess einen offset brauchte um den pe header zu bekommen
(getoffset function ist ein module snapshot und liefert den hmodule)

Das funktioniert scheinbar - wie lese ich allerdings jetzt den speicher der section header aus und kann den dann nach strings durchsuchen?

Auch bin ich mir nicht sicher ob das tatsächlich funktioniert....

Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
var
    pid : cardinal;
    IDH: PImageDosHeader;
    INH: PImageNtHeaders;
    SHD: PImageSectionHeader;
    procHandle : Dword;
    pr : THandle;
    i,s : integer;
    name : string;
    buf1 : Pointer;
    offset : Cardinal;
    read : cardinal;
begin
  // pointer to executeable handle
  pid := FindProcess(pchar('notepad.exe'));
  //memlesen(pid);
  pr := OpenProcess(PROCESS_ALL_ACCESS, false, pid);

  buf1 := VirtualAlloc(nil,$1000,MEM_COMMIT,PAGE_EXECUTE_READWRITE);
  offset := getoffset('notepad.exe',pid);
  form1.Memo1.Lines.Add('module: ' + inttostr(offset) + ' file:' + inttostr(pr));
  ReadProcessMemory(pr,pointer(offset),buf1,$1000,read);

  IDH := Pointer(buf1);
  // not an windows executealbe - exit
  if (isBadReadPtr(IDH,SizeOf(TImageDosHeader))
  or (IDH^.e_magic <> IMAGE_DOS_SIGNATURE))
  then begin memo1.Lines.Add('dos header not found'); exit; end;

  // pointer to nt header
  INH := Pointer(Cardinal(IDH) + Cardinal(IDH^._lfanew));
  // not an nt header - exit
  If (isBadreadPtr(INH,SizeOf(TImageNtHeaders))
  or (INH^.Signature <> IMAGE_NT_SIGNATURE))
  then Exit;

  SHD := Pointer (Cardinal(INH) + Cardinal(SizeOf(IMAGE_NT_HEADERS)));
  for i := 1 to INH^.FileHeader.NumberOfSections-1 do
  begin
       for s := 0 to 7 do
       begin
            name := name + chr(SHD^.Name[s]);
       end;
       memo1.Lines.Add(name + '1');
       SHD := Pointer (Cardinal(SHD) + Cardinal(SizeOf(IMAGE_NT_HEADERS)));
  end;
  VirtualFree(buf1,$1000,MEM_DECOMMIT);
end;
Arnulf
  Mit Zitat antworten Zitat
Benutzerbild von nicodex
nicodex

Registriert seit: 2. Jan 2008
Ort: Darmstadt
286 Beiträge
 
Delphi 2007 Professional
 
#6

Re: code section lesen bzw. ram editor

  Alt 20. Jun 2008, 16:14
Zitat von Arnulf:
Eindeutig verwirrend war für mich, dass ich vom prozess einen offset brauchte um den pe header zu bekommen
(getoffset function ist ein module snapshot und liefert den hmodule)
Du kannst froh sein, dass Windows bei normalen Prozessen den Datei-Header überhaupt in den Speicher kopiert
Unter Windows ist der Wert eines Modul-Handles identisch mit seiner Basisadresse im jeweiligen Adressraum (falls es nicht als Datendatei geladen wurde).

Zitat von Arnulf:
wie lese ich allerdings jetzt den speicher der section header aus
Die Section-Einträge folgenden direkt auf den 'optionalen' Header (FileHeader.SizeOfOptionalHeader).
Siehe: http://www.microsoft.com/whdc/system...re/PECOFF.mspx
  Mit Zitat antworten Zitat
Arnulf

Registriert seit: 28. Okt 2004
Ort: Wien
271 Beiträge
 
#7

Re: code section lesen bzw. ram editor

  Alt 26. Jun 2008, 15:13
Ich hab es noch nicht ganz da ich nie sicher bin, dass es so stimmt.

kurzfassung:
Delphi-Quellcode:
// pointer to nt header
  INH := Pointer(Cardinal(IDH) + Cardinal(IDH^._lfanew));
// pointer to sectionheader
  SHD := pointer(cardinal(@(INH^.OptionalHeader)) + INH^.FileHeader.SizeOfOptionalHeader);
ich dachte eigentlich ich müsste nur den image_nt_header überspringen und wäre dirrekt bei den section header...
SHD := Pointer (Cardinal(INH) + Cardinal(SizeOf(IMAGE_NT_HEADERS))); sollte ich jedenfalls endgültig an den richtigen section header sein
wollte ich noch wissen wie ich jetzt wirklich an die daten komme
SHD^.VirtualAddress liefert die virtuelle adresse vom image base - aber welche image base?
die im optional header als image base angegeben wird oder der ursprüngliche .exe basis?
INH^.OptionalHeader.ImageBase ich versuch wirklich schlau zu werden aus den pcoff trotzdem bin ich absolut unsicher was ich da mache.

lg
Arnulf
  Mit Zitat antworten Zitat
Arnulf

Registriert seit: 28. Okt 2004
Ort: Wien
271 Beiträge
 
#8

Re: code section lesen bzw. ram editor

  Alt 30. Jun 2008, 14:22
Ich versuche jetzt die sections nach lesbaren strings zu durchsuchen.
Allerdings bekomme ich ständig 'Access violation'
ich kann kleinere bereiche lesen, aber nicht wenn es über ca. 14000 bytes geht.

wenn es kopletter unsinn ist was ich mache könnts ihr mir das ruhig sagen ....
in wirklichkeit hab ich immer noch den eindruck ich lese einfach irgend etwas aus...


Delphi-Quellcode:
begin
  readstream := TmemoryStream.Create;

  // pointer to executeable handle
  pid := FindProcess(pchar('notepad.exe'));
  pr := OpenProcess(PROCESS_ALL_ACCESS, false, pid);

  buf1 := VirtualAlloc(nil,$1000,MEM_COMMIT,PAGE_EXECUTE_READWRITE);
  offset := getoffset('notepad.exe',pid);
  ReadProcessMemory(pr,pointer(offset),buf1,$1000,read);

  IDH := Pointer(buf1);
  // not an windows executealbe - exit
  if (isBadReadPtr(IDH,SizeOf(TImageDosHeader))
  or (IDH^.e_magic <> IMAGE_DOS_SIGNATURE))
  then begin memo1.Lines.Add('dos header not found'); exit; end;

  // pointer to nt header
  INH := Pointer(Cardinal(IDH) + Cardinal(IDH^._lfanew));
  // not an nt header - exit
  If (isBadreadPtr(INH,SizeOf(TImageNtHeaders))
  or (INH^.Signature <> IMAGE_NT_SIGNATURE))
  then Exit;

  // pointer zu optional header und diesen überspringen
  SHD := pointer(cardinal(@(INH^.OptionalHeader)) + INH^.FileHeader.SizeOfOptionalHeader);

  for i := 0 to INH^.FileHeader.NumberOfSections-1 do
  begin
       for s := 0 to 7 do
       begin
            name := name + chr(SHD^.Name[s]);
       end;

       rawCodePosition := SHD^.PointerToRawData;
       virtualCodeSize := SHD^.Misc.VirtualSize;
       //virtualCodeSize := SHD^.SizeOfRawData;//->Misc.VirtualSize;
       startpos := cardinal(buf1) + rawCodePosition;

       readstream.WriteBuffer (pointer(startpos),virtualCodeSize);
       readstream.Position := 0;
       
       // bytestream to readable char
       for t := 0 to readstream.Size-1 do
       begin
       readstream.ReadBuffer(myint,1);
       mystring := mystring + buffertostring(myint);
       end;

       // string und infos ausgeben
       memo1.Lines.Add(mystring);
       memo1.Lines.Add(inttostr( cardinal(SHD^.VirtualAddress)));
       memo1.Lines.Add('vmiscsize:' + inttostr( cardinal(SHD^.Misc.VirtualSize)));
       memo1.Lines.Add('vrawsize:' + inttostr( virtualCodeSize));
       memo1.Lines.Add(' header name:' + name);

       // nextheader
       SHD := Pointer (Cardinal(SHD) + Cardinal(SizeOf(IMAGE_SECTION_HEADER)));
       name := '';
  end;
  VirtualFree(buf1,$1000,MEM_DECOMMIT);
end;
Hoffe es kann mir noch jemand helfen
lg
Arnulf
  Mit Zitat antworten Zitat
Arnulf

Registriert seit: 28. Okt 2004
Ort: Wien
271 Beiträge
 
#9

Re: code section lesen bzw. ram editor

  Alt 2. Jul 2008, 13:34
Ok dann will ich es mal so halbwegs selbst beantworten - soweit es eben stimmt.
das hier dürfte als so halbwegs stimmen um die position der section zu bestimmen
Delphi-Quellcode:
       rawCodePosition := SHD^.PointerToRawData;
       virtualCodeSize := SHD^.Misc.VirtualSize;
wobei sich der startpointer dann so berechnet:

startpos := offset + rawCodePosition; offset ist in dem fall einfach der begin des dos header wie man ihn von moduleentry32 bekommt.

lesen kann man also einfach so:
Delphi-Quellcode:
  for i := 0 to INH^.FileHeader.NumberOfSections-1 do
  begin
       rawCodePosition := SHD^.PointerToRawData;
       virtualCodeSize := SHD^.Misc.VirtualSize;
       repeat
       if ReadProcessMemory(pr,pointer(startpos),@puffer,Sizeof(puffer),read) then
       begin
            counter := counter + read;
            startpos := startpos + read;
       ........
       until counter >= virtualCodeSize;
       .......
  end;
wobei ich diesmal als puffer
puffer : Array [0..4095] of Byte; genommen habe.

für mich bleibt nur noch die frage wie man den puffer am bessten durchsucht.
ich hab das alles mal in einen memory stream geschreiben.
allerdings stellt sich mir die frage wie ich das am bessten nach strings durchsuche.
die meißten sachen dürften widestrings sein und damit hab ich wenig erfahrung.

wenn darauf jemand eine antwort hat oder einen tip dann bitte antworten.

lg
Arnulf
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 05:05 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz