Thema: Delphi .text section dumpen

Einzelnen Beitrag anzeigen

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