poke-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Interesting example of internal padding


From: Jose E. Marchesi
Subject: Interesting example of internal padding
Date: Mon, 03 Oct 2022 00:59:37 +0200
User-agent: Gnus/5.13 (Gnus v5.13) Emacs/28.0.50 (gnu/linux)

Implementing the PE/COFF pickle is fun.  I just made use of internal
padding to implement this excerpt of the spec:

  "The virtual address value from the Certificate Table entry in the
   Optional Header Data Directory is a file offset to the first
   attribute certificate entry. Subsequent entries are accessed by
   advancing that entry's dwLength bytes, rounded up to an 8-byte
   multiple, from the start of the current attribute certificate
   entry. This continues until the sum of the rounded dwLength values
   equals the Size value from the Certificates Table entry in the
   Optional Header Data Directory. If the sum of the rounded dwLength
   values does not equal the Size value, then either the attribute
   certificate table or the Size field is corrupted."

Each attribute certificate looks like this:

  type PE_Attribute_Certificate =
    struct
    {
      offset<uint<32>,B> length;
      uint<16> revision;
      uint<16> cert_type;

      /* Note: we use internal padding here so we can map arrays of
         attribute certificates by total size.  */
      byte[0] certificate_begin;
      byte[0] certificate_end @ length + alignto (length, 8#B);
    };

Note how I am avoiding mapping the contents of the certificate itself,
as I think these things can be big (convenience zero sized fields
certificate_begin and certificate_end can then be used to poke at them
if that's what the user wants.)

Anyhow, the table of certificates, if present, is at the end of the PE
file.  Checking the data integrity described in the spec paragraph above
can be implemented very naturally by mapping the table as an array of
variable-length values with internal padding (the
PE_Attribute_Certificate struct above) itself size-bounded by total
size:

type PE_File =
  struct
  {
    [...]
    var certs_datadir = opt_hdr.data_directories.certificate_table;

    PE_Attribute_Certificate[certs_datadir.size] certificates
      @ certs_datadir.rva
      if certs_datadir.size > 0#B;
  };

poke will thus detect file corruption as expected in the spec by raising
an exception if it cannot fill an exact number of variable-length
certificates in exactly certs_datadir.size bytes.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]