![]() |
code section lesen bzw. ram editor
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 |
Re: code section lesen bzw. ram editor
Ich habe für ein Spiel einen Trainer-Prototypen mit entsprechenden Basisklassen entworfen, welche dir als Vorlage oder Inspiration dienen könnten.
![]() Der entsprechende Thread ist hier zu finden: ![]() (rein informativ und hat nichts mit deiner Fragestellung zu tun) Gruß Nico |
Re: code section lesen bzw. ram editor
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:
bzw. war auch die eigentliche Frage welche sections muss ich durchsuchen um nur die code section eines programms zu durchsuchen.
if (Section.Size >= NameSize) and Section.IsReadable and
not Section.IsWriteable and not Section.IsExecutable then 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??? |
Re: code section lesen bzw. ram editor
Zitat:
Zitat:
Grundsätzlich alle, die "ausführbar" sind. Zitat:
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:
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:
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. |
Re: code section lesen bzw. ram editor
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:
Arnulf
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; |
Re: code section lesen bzw. ram editor
Zitat:
Unter Windows ist der Wert eines Modul-Handles identisch mit seiner Basisadresse im jeweiligen Adressraum (falls es nicht als Datendatei geladen wurde). Zitat:
Siehe: ![]() |
Re: code section lesen bzw. ram editor
Ich hab es noch nicht ganz da ich nie sicher bin, dass es so stimmt.
kurzfassung:
Delphi-Quellcode:
ich dachte eigentlich ich müsste nur den image_nt_header überspringen und wäre dirrekt bei den section header...
// pointer to nt header
INH := Pointer(Cardinal(IDH) + Cardinal(IDH^._lfanew)); // pointer to sectionheader SHD := pointer(cardinal(@(INH^.OptionalHeader)) + INH^.FileHeader.SizeOfOptionalHeader);
Delphi-Quellcode:
sollte ich jedenfalls endgültig an den richtigen section header sein
SHD := Pointer (Cardinal(INH) + Cardinal(SizeOf(IMAGE_NT_HEADERS)));
wollte ich noch wissen wie ich jetzt wirklich an die daten komme
Delphi-Quellcode:
liefert die virtuelle adresse vom image base - aber welche image base?
SHD^.VirtualAddress
die im optional header als image base angegeben wird oder der ursprüngliche .exe basis?
Delphi-Quellcode:
ich versuch wirklich schlau zu werden aus den pcoff trotzdem bin ich absolut unsicher was ich da mache.
INH^.OptionalHeader.ImageBase
lg Arnulf |
Re: code section lesen bzw. ram editor
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:
Hoffe es kann mir noch jemand helfen
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; lg Arnulf |
Re: code section lesen bzw. ram editor
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:
wobei sich der startpointer dann so berechnet:
rawCodePosition := SHD^.PointerToRawData;
virtualCodeSize := SHD^.Misc.VirtualSize;
Delphi-Quellcode:
offset ist in dem fall einfach der begin des dos header wie man ihn von moduleentry32 bekommt.
startpos := offset + rawCodePosition;
lesen kann man also einfach so:
Delphi-Quellcode:
wobei ich diesmal als puffer
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;
Delphi-Quellcode:
genommen habe.
puffer : Array [0..4095] of Byte;
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 |
Alle Zeitangaben in WEZ +1. Es ist jetzt 13:36 Uhr. |
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