Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Variante Records? (https://www.delphipraxis.net/131210-variante-records.html)

Zacherl 20. Mär 2009 15:58


Variante Records?
 
Hey,

ich schreibe grade an einer Unit, mit der man PE Dateien bearbeiten kann. Nun muss ich zwischen 32 und 64 Bit Header differenzieren. Es ändert sich nur die Größe von 4 Feldern. Bei 32 Bit sind diese vom Typ DWord und bei 64 Bit vom Typ Int64.

Möchte jetzt innerhalb meiner Methoden nicht immer zwischen 32 und 64 Bit unterscheiden müssen. Gibt es eine Methode, mit der ich den Typ des Records zur Laufzeit festlegen kann?

Gruß Zacherl

Apollonius 20. Mär 2009 16:00

Re: Variante Records?
 
Nein. Das einfachste ist wohl, eine Klasse mit Eigenschaften zu erstellen, deren Getter abstrakt sind. Diese leitest du dann zweimal ab.

Reinhard Kern 21. Mär 2009 14:46

Re: Variante Records?
 
Zitat:

Zitat von Zacherl
Hey,

ich schreibe grade an einer Unit, mit der man PE Dateien bearbeiten kann. Nun muss ich zwischen 32 und 64 Bit Header differenzieren. Es ändert sich nur die Größe von 4 Feldern. Bei 32 Bit sind diese vom Typ DWord und bei 64 Bit vom Typ Int64.

Möchte jetzt innerhalb meiner Methoden nicht immer zwischen 32 und 64 Bit unterscheiden müssen. Gibt es eine Methode, mit der ich den Typ des Records zur Laufzeit festlegen kann?

Gruß Zacherl

Hallo,

der Compiler verwendet die Offsets innerhalb des Records wie Konstanten, sie werden fest in das Compilat eingebaut. Das gilt auch für variante Teile des Records, die stehen am gleichen Offset, und es wird der Platz der grössten Variante reserviert, d.h. der Record und alle Offsets sind immer gleich - genau das ist ja bei deinen Records nicht der Fall.

Eine Möglichkeit: du arbeitest intern ausschliesslich mit der 64bit-Variante und wandelst 32bit-Records schon beim Lesen um.

Gruss Reinhard

Dax 21. Mär 2009 14:51

Re: Variante Records?
 
Sehe ich das richtig, dass die PE-Header erst gemeinsame Felder haben (32/64bit shared), dann ein Flag für die Wortgröße und danach erst den Rest? Dann könntest du das nämlich aufteilen: je einen Record für die wortgrößenspezifischen Sachen, der in den varianten Teil eines Records kommt, der den Rest selbst hält. Nicht schön, aber es wären variante Records ;)

Zacherl 21. Mär 2009 16:03

Re: Variante Records?
 
Alles ziemlich unschön. Das mit dem Varianten Record kann ich mir glaube ich abschminken, da doch nicht ganz alle Felder gleich sind:

Code:
typedef struct _IMAGE_OPTIONAL_HEADER {
  WORD                Magic;
  BYTE                MajorLinkerVersion;
  BYTE                MinorLinkerVersion;
  DWORD               SizeOfCode;
  DWORD               SizeOfInitializedData;
  DWORD               SizeOfUninitializedData;
  DWORD               AddressOfEntryPoint;
  DWORD               BaseOfCode;
  DWORD               BaseOfData;
  DWORD               ImageBase;
  DWORD               SectionAlignment;
  DWORD               FileAlignment;
  WORD                MajorOperatingSystemVersion;
  WORD                MinorOperatingSystemVersion;
  WORD                MajorImageVersion;
  WORD                MinorImageVersion;
  WORD                MajorSubsystemVersion;
  WORD                MinorSubsystemVersion;
  DWORD               Win32VersionValue;
  DWORD               SizeOfImage;
  DWORD               SizeOfHeaders;
  DWORD               CheckSum;
  WORD                Subsystem;
  WORD                DllCharacteristics;
  DWORD               SizeOfStackReserve;
  DWORD               SizeOfStackCommit;
  DWORD               SizeOfHeapReserve;
  DWORD               SizeOfHeapCommit;
  DWORD               LoaderFlags;
  DWORD               NumberOfRvaAndSizes;
  IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES];
} IMAGE_OPTIONAL_HEADER, *PIMAGE_OPTIONAL_HEADER;

typedef struct _IMAGE_OPTIONAL_HEADER64 {
 WORD       Magic;
 BYTE       MajorLinkerVersion;
 BYTE       MinorLinkerVersion;
 DWORD      SizeOfCode;
 DWORD      SizeOfInitializedData;
 DWORD      SizeOfUninitializedData;
 DWORD      AddressOfEntryPoint;
 DWORD      BaseOfCode;
 ULONGLONG  ImageBase;
 DWORD      SectionAlignment;
 DWORD      FileAlignment;
 WORD       MajorOperatingSystemVersion;
 WORD       MinorOperatingSystemVersion;
 WORD       MajorImageVersion;
 WORD       MinorImageVersion;
 WORD       MajorSubsystemVersion;
 WORD       MinorSubsystemVersion;
 DWORD      Win32VersionValue;
 DWORD      SizeOfImage;
 DWORD      SizeOfHeaders;
 DWORD      CheckSum;
 WORD       Subsystem;
 WORD       DllCharacteristics;
 ULONGLONG  SizeOfStackReserve;
 ULONGLONG  SizeOfStackCommit;
 ULONGLONG  SizeOfHeapReserve;
 ULONGLONG  SizeOfHeapCommit;
 DWORD      LoaderFlags;
 DWORD      NumberOfRvaAndSizes;
 IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES];
} IMAGE_OPTIONAL_HEADER64, *PIMAGE_OPTIONAL_HEADER64;
BaseOfData wurde im 64 Bit Header entfernt und dafür die ImageBase Kapazität vergrößert.

Mit OOP zu arbeiten bringt mir auch keine Vorteile, soweit ich das sehe, da ich alle Codes 2x schreiben muss. Ich lade die komplette PE Datei in einen Buffer und lese / schreibe Daten, indem ich mit PImageNtHeaders, etc arbeite. Und grade den Case auf PImageNtHeaders kann ich ja nicht irgendwie variabel gestalten. Ansonsten wäre das alles ja kein Problem. Dann würde ich mir einen Getter schreiben, der entweder einen Pointer auf den 32 oder den 64 Bit Header zurückgibt.

Apollonius 21. Mär 2009 16:12

Re: Variante Records?
 
Ich meinte eigentlich, dass du eine Klasse schreibst, die das selbe Interface wie IMAGE_OPTIONAL_HEADER hat, nur mit Eigenschaften statt Feldern. Damit kannst du vermeiden, den gesamten Code doppelt zu schreiben.

Zacherl 21. Mär 2009 16:28

Re: Variante Records?
 
Ah okay dann hatte ich dich erst falsch verstanden. Bin grade selbst auf die Idee gekommen so eine Klasse zu schreiben. Muss halt jetzt den ImageOptionalHeader von den anderen Feldern des ImageNtHeaders trennen, aber geht wohl nicht anders.

Gruß Zacherl


Alle Zeitangaben in WEZ +1. Es ist jetzt 14:58 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