AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren

.text section dumpen

Ein Thema von Lyan · begonnen am 21. Okt 2015 · letzter Beitrag vom 22. Okt 2015
Antwort Antwort
Lyan

Registriert seit: 5. Aug 2011
187 Beiträge
 
#1

.text section dumpen

  Alt 21. Okt 2015, 20:11
Hallo,

Ich würde gerne (so schön wie möglich) die .text oder CODE section aus meinem eigenen Prozess dumpen.

Mein momentaner Plan ist mittels ReadProcessMemory() ab der Imagebase den gesamten (eigenen) Prozess zu kopieren (aus dem Speicher) und dann mittels PE-Offsets die Stelle der .text-Section zu ermitteln.

Da ich wirklich faul bin und überhaupt keine Lust mehr habe ein PE-Tutorial auszupacken und mich durch die ganzen Offsets, Alignments und was weiß ich durchzuwühlen, hoffe ich hier um ehrlich zusein auf eine Codelösung.
a
Vieleicht hat ja jemand ein früheres Projekt in dem er eine Section des eigenen (oder fremden) Prozesses kopiert/gedumpt hat und wäre so freundlich das Snippet hier zu posten.

Ansonsten hoffe ich auf alternative Lösungen.

Alternative Lösungen sollten aber nur das von mir genannte Problem lösen, also keine Workarounds. Ich möchte aus dem Speicher heraus, eine Section kopieren - nicht anders.

Danke
  Mit Zitat antworten Zitat
Benutzerbild von Zacherl
Zacherl

Registriert seit: 3. Sep 2004
4.629 Beiträge
 
Delphi 10.2 Tokyo Starter
 
#2

AW: .text section dumpen

  Alt 21. Okt 2015, 23:07
Mit der PE Dokumentation hast du das in einer Stunde locker geschafft. Dauert deutlich weniger lange, als hier auf eine fertige Lösung zu warten (die aller Wahrscheinlichkeit nach bei dieser spezifischen Fragestellung nicht kommen wird).

ReadProcessMemory im eigenen Prozess zu verwenden ist btw. relativ unsinnig. Du kannst den Speicher auch einfach direkt ansprechen.
Projekte:
- GitHub (Profil, zyantific)
- zYan Disassembler Engine ( Zydis Online, Zydis GitHub)
  Mit Zitat antworten Zitat
Lyan

Registriert seit: 5. Aug 2011
187 Beiträge
 
#3

AW: .text section dumpen

  Alt 22. Okt 2015, 03:35
Mit der PE Dokumentation hast du das in einer Stunde locker geschafft. Dauert deutlich weniger lange, als hier auf eine fertige Lösung zu warten (die aller Wahrscheinlichkeit nach bei dieser spezifischen Fragestellung nicht kommen wird).

ReadProcessMemory im eigenen Prozess zu verwenden ist btw. relativ unsinnig. Du kannst den Speicher auch einfach direkt ansprechen.
Ja - mein "Plan" war nicht ganz durchdacht..

Vermutlich hast du recht.

Ich muss auch gestehen, dass ich die letzte Zeile in diesem Thread gelöscht habe. In der stand: "Ich warte dann mal auf die Antwort von Zacherl, mit viel Glück hat er noch was übrig".

Wenn - dann hätte ich ein Snippet von dir erwartet hier als native Windows Experte


Naja dann pack ich mal die alten ARTeam Tut's aus ^^

Danke trotzdem
  Mit Zitat antworten Zitat
Benutzerbild von Zacherl
Zacherl

Registriert seit: 3. Sep 2004
4.629 Beiträge
 
Delphi 10.2 Tokyo Starter
 
#4

AW: .text section dumpen

  Alt 22. Okt 2015, 12:59
Ich muss auch gestehen, dass ich die letzte Zeile in diesem Thread gelöscht habe. In der stand: "Ich warte dann mal auf die Antwort von Zacherl, mit viel Glück hat er noch was übrig".


Habe leider nichts fertiges hier, aber zum iterieren der Sections schnell aus dem Kopf:
Delphi-Quellcode:
var
  ImageBase: Pointer;
  ImageDosHeader: PImageDosHeader;
  ImageNtHeaders: PImageNtHeaders;
  ImageSectionHeader: PImageSectionHeader;
  I: Integer;
begin
  ImageBase := Pointer(hInstance);
  ImageDosHeader := PImageDosHeader(ImageBase);
  if (ImageDosHeader^.e_magic <> IMAGE_DOS_SIGNATURE) then
  begin
    Exit;
  end;
  ImageNtHeaders := PImageNtHeaders(PByte(ImageDosHeader) + ImageDosHeader^._lfanew);
  if (ImageNtHeaders^.Signature <> IMAGE_NT_SIGNATURE) then
  begin
    Exit;
  end;
  ImageSectionHeader := PImageSectionHeader(PByte(ImageNtHeaders) + SizeOf(TImageNtHeaders) -
    SizeOf(TImageOptionalHeader) + ImageNtHeaders^.FileHeader.SizeOfOptionalHeader);
  I := 1;
  while (I < ImageNtHeaders^.FileHeader.NumberOfSections) do
  begin
    WriteLn('Section Name:');
    WriteLn(PAnsiChar(@ImageSectionHeader^.Name[0]));
    WriteLn('Virtual Address:');
    WriteLn(IntToHex(NativeUInt(ImageBase) + ImageSectionHeader^.VirtualAddress,
      SizeOf(Pointer) * 2));
    WriteLn('Size:');
    WriteLn(IntToHex(ImageSectionHeader^.SizeOfRawData, 1));
    Inc(ImageSectionHeader);
    Inc(I);
  end;
end;
Statt hInstance kannst du auch die ImageBase einer beliebigen Dll nehmen, falls du das brauchst. Die Section dumpst du dir dann einfach mit CreateFile/WriteFile über die Virtual Address.

Würde mich allerdings nicht drauf verlassen, dass sich alle Binaries an die .text bzw. .code Konvention bezüglich des Section Names halten.
Projekte:
- GitHub (Profil, zyantific)
- zYan Disassembler Engine ( Zydis Online, Zydis GitHub)
  Mit Zitat antworten Zitat
Lyan

Registriert seit: 5. Aug 2011
187 Beiträge
 
#5

AW: .text section dumpen

  Alt 22. Okt 2015, 16:05
Ich muss auch gestehen, dass ich die letzte Zeile in diesem Thread gelöscht habe. In der stand: "Ich warte dann mal auf die Antwort von Zacherl, mit viel Glück hat er noch was übrig".


Habe leider nichts fertiges hier, aber zum iterieren der Sections schnell aus dem Kopf:
Delphi-Quellcode:
var
  ImageBase: Pointer;
  ImageDosHeader: PImageDosHeader;
  ImageNtHeaders: PImageNtHeaders;
  ImageSectionHeader: PImageSectionHeader;
  I: Integer;
begin
  ImageBase := Pointer(hInstance);
  ImageDosHeader := PImageDosHeader(ImageBase);
  if (ImageDosHeader^.e_magic <> IMAGE_DOS_SIGNATURE) then
  begin
    Exit;
  end;
  ImageNtHeaders := PImageNtHeaders(PByte(ImageDosHeader) + ImageDosHeader^._lfanew);
  if (ImageNtHeaders^.Signature <> IMAGE_NT_SIGNATURE) then
  begin
    Exit;
  end;
  ImageSectionHeader := PImageSectionHeader(PByte(ImageNtHeaders) + SizeOf(TImageNtHeaders) -
    SizeOf(TImageOptionalHeader) + ImageNtHeaders^.FileHeader.SizeOfOptionalHeader);
  I := 1;
  while (I < ImageNtHeaders^.FileHeader.NumberOfSections) do
  begin
    WriteLn('Section Name:');
    WriteLn(PAnsiChar(@ImageSectionHeader^.Name[0]));
    WriteLn('Virtual Address:');
    WriteLn(IntToHex(NativeUInt(ImageBase) + ImageSectionHeader^.VirtualAddress,
      SizeOf(Pointer) * 2));
    WriteLn('Size:');
    WriteLn(IntToHex(ImageSectionHeader^.SizeOfRawData, 1));
    Inc(ImageSectionHeader);
    Inc(I);
  end;
end;
Statt hInstance kannst du auch die ImageBase einer beliebigen Dll nehmen, falls du das brauchst. Die Section dumpst du dir dann einfach mit CreateFile/WriteFile über die Virtual Address.

Würde mich allerdings nicht drauf verlassen, dass sich alle Binaries an die .text bzw. .code Konvention bezüglich des Section Names halten.
Wow vielen Dank

Ja für .UPX etc. brauche ich ja keinen Support, schließlich dumpe ich ja die eigene Section und den Namen kann ich ja (wenn er wirklich != .text/.code sein sollte anpassen

Anonsten hast du mir das Leben erleichtert, ist schon eine ganze Weile her seitdem ich was mit w32 PE zeug gemacht habe, und ich vergesse leider schnell.

Ich schreibs später fertig, dann poste ich es mal


Bis dann & nochmals danke
  Mit Zitat antworten Zitat
SMO

Registriert seit: 20. Jul 2005
178 Beiträge
 
Delphi XE6 Professional
 
#6

AW: .text section dumpen

  Alt 22. Okt 2015, 17:39
Habe leider nichts fertiges hier, aber zum iterieren der Sections schnell aus dem Kopf:
Delphi-Quellcode:
    WriteLn('Section Name:');
    WriteLn(PAnsiChar(@ImageSectionHeader^.Name[0]));
Das ist strenggenommen falsch, denn TImageSectionHeader.Name ist nicht notwendigerweise nullterminiert!
Wenn der Name genau 8 Zeichen lang ist, wird ein einfacher PAnsiChar-Cast wie oben möglicherweise zusätzlichen Müll ausgeben.

TImageSectionHeader.Name ist dummerweise als Array of Byte deklariert, nicht als Array of Char.
Für letzteres hat Delphi nämlich ein paar Compiler-Magic-Funktionen, die aus einem Array of (Ansi)Char einen (Ansi)String machen und dabei nicht stur nach der Nullterminierung suchen, sondern auch die Maximallänge des Arrays berücksichtigen (_LStrFromArray, _LStrFromWArray, _UStrFromArray, _UStrFromWArray).

Um es besser zu machen, muss man entweder eigenen Code schreiben, der das Name-Bytearray in einen String kovertiert, oder man benutzt einfach einen Cast auf ein passendes Char-Array, damit die Compiler-Magic benutzt wird:
Delphi-Quellcode:
type
  TImageSectionHeaderName = array [0..IMAGE_SIZEOF_SHORT_NAME-1] of AnsiChar; // genaugenommen UTF-8 Bytes, argh
// ..
    WriteLn('Section Name:');
    WriteLn(TImageSectionHeaderName(ImageSectionHeader^.Name));
Um es ganz korrekt zu machen, sollte man den String als UTF-8 kodiert ansehen und dekodieren lassen...


Hier mal Code von mir:
Delphi-Quellcode:
// GetModuleSectionHeaders: get an array of all TImageSectionHeader structures of a given Module
function GetModuleSectionHeaders(const Module: HMODULE): TArray<TImageSectionHeader>;
var
  DosHeader: PImageDosHeader;
  NtHeaders: PImageNtHeaders;
  SectionHeader: PImageSectionHeader;
  i: Integer;
begin
begin
  Result := nil;
  DosHeader := PImageDosHeader(Module); // a HMODULE is a memory address
  // navigate the various headers and check their signatures
  if DosHeader.e_magic <> IMAGE_DOS_SIGNATURE then Exit;
  NtHeaders := Pointer(PByte(Module) + DosHeader._lfanew);
  if (NtHeaders.Signature <> IMAGE_NT_SIGNATURE) or
    (NtHeaders.OptionalHeader.Magic <> IMAGE_NT_OPTIONAL_HDR32_MAGIC) then Exit;
  // corrected, thanks to Zacherl
  SectionHeader := PImageSectionHeader(PByte(NtHeaders) + SizeOf(TImageNtHeaders) -
    SizeOf(TImageOptionalHeader) + NtHeaders^.FileHeader.SizeOfOptionalHeader);
  SetLength(Result, NtHeaders.FileHeader.NumberOfSections);
  for i := Low(Result) to High(Result) do
  begin
    Result[i] := SectionHeader^;
    // add Module's current base address to VirtualAddress
    Inc(Result[i].VirtualAddress, UIntPtr(Module));
    Inc(SectionHeader);
  end;
end;

// GetSectionHeaderName: convert SH.Name from UTF-8 byte array to string
function GetSectionHeaderName(const SH: TImageSectionHeader): string;
type
  TSectionHeaderName = array [0..IMAGE_SIZEOF_SHORT_NAME-1] of AnsiChar;
var
  Raw: RawByteString;
begin
  Raw := TSectionHeaderName(SH.Name); // _LStrFromArray
  Result := UTF8ToString(Raw);
end;

var
  SH: TImageSectionHeader;
begin
  for SH in GetModuleSectionHeaders(HInstance) do
    Writeln(Format('%-8s : VirtualAddress=%.8x, VirtualSize=%.8x, Characteristics=%.8x',
      [GetSectionHeaderName(SH), SH.VirtualAddress, SH.Misc.VirtualSize, SH.Characteristics]));
end;

Geändert von SMO (22. Okt 2015 um 19:01 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von Zacherl
Zacherl

Registriert seit: 3. Sep 2004
4.629 Beiträge
 
Delphi 10.2 Tokyo Starter
 
#7

AW: .text section dumpen

  Alt 22. Okt 2015, 18:35
Das ist strenggenommen falsch, denn TImageSectionHeader.Name ist nicht notwendigerweise nullterminiert!
Wenn der Name genau 8 Zeichen lang ist, wird ein einfacher PAnsiChar-Cast wie oben möglicherweise zusätzlichen Müll ausgeben.
Da hast du recht!

Deine Funktion berechnet allerdings den Zeiger auf die erste ImageSection nicht korrekt. SectionHeader := PImageSectionHeader(NativeInt(NtHeaders) + SizeOf(NtHeaders^)) funktioniert nicht immer. Ist zwar ein ziemlich synthetischer Fall, aber das PE Format sieht vor, dass der OptionalHeader eine variable Länge haben kann. Deshalb muss die korrekte Berechnung über
Delphi-Quellcode:
ImageSectionHeader := PImageSectionHeader(PByte(ImageNtHeaders) + SizeOf(TImageNtHeaders) -
    SizeOf(TImageOptionalHeader) + ImageNtHeaders^.FileHeader.SizeOfOptionalHeader)
erfolgen.
Projekte:
- GitHub (Profil, zyantific)
- zYan Disassembler Engine ( Zydis Online, Zydis GitHub)
  Mit Zitat antworten Zitat
SMO

Registriert seit: 20. Jul 2005
178 Beiträge
 
Delphi XE6 Professional
 
#8

AW: .text section dumpen

  Alt 22. Okt 2015, 18:53
Danke! Wieder was gelernt.
Der Code von mir war auch schon etwas älter, sehe ich gerade an der Benutzung von NativeInt. Heute caste ich Pointer nur noch auf vorzeichenlose Typen (NativeUInt oder UIntPtr), oder gleich auf PByte wie in deinem Beispiel.
  Mit Zitat antworten Zitat
Themen-Optionen Thema durchsuchen
Thema durchsuchen:

Erweiterte Suche
Ansicht

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 08:10 Uhr.
Powered by vBulletin® Copyright ©2000 - 2022, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2021 by Daniel R. Wolf