Table of Contents

Sometimes, you want to parse well-formed binary data and bring it into your objects to do some dirty stuff with it.

In the Windows world most data structures are stored in special binary format. Either we call a WinApi function or we want to read from special files like images, spool files, executables or may be the previously announced Outlook Personal Folders File.

Before we start we need to know how this file is formatted. The following figure shows an overview of the Microsoft PE executable format. Source: Microsoft

Our goal is to get the PE header. As we can see, the image starts with a MS-DOS 2.0 header with is not important for us. From the documentation we can read "...After the MS DOS stub, at the file offset specified at offset 0x3c, is a 4-byte...".

With this information we know our reader has to jump to location 0x3c and read the offset to the signature. The signature is always 4 bytes that ensures that the image is a PE file. The signature is: PE\0\0.

To prove this we first seek to the offset 0x3c, read if the file consist the signature.

So we need to declare some constants, because we do not want magic numbers.

Then a method for moving the reader to the correct location to read the offset of signature. With this method we always move the underlining Stream of the BinaryReader to the start location of the PE signature.

Now, we can check if it is a valid PE image by reading of the next 4 byte contains the content PE.

private bool IsValidPeSignature(BinaryReader br) {
// read 4 bytes to get the PE signature
byte[] peSigBytes = br.ReadBytes(PeSignatureSize);
// convert it to a string and trim \0 at the end of the content
string peContent = Encoding.Default.GetString(peSigBytes).TrimEnd('\0');
// check if PE is in the content
return peContent.Equals(PeSignatureContent);
}

With this basic functionality we have a good base reader class to try the different methods of parsing the COFF file header.

The first solution is using the BinaryReader. It is the general way to get the data. We only need to know which order, which data-type and its size. If we read byte for byte we could comment out the first line in the CoffHeader structure, because we have control about the order of the member assignment.

If the structure is as short as the COFF header here and the specification will never changed, there is probably no reason to change the strategy. But if a data-type will be changed, a new member will be added or ordering of member will be changed the maintenance costs of this method are very high.

Another way to bring the data into this structure is using a "magically" unsafe trick. As above, we know the layout and order of the data structure. Now, we need the StructLayout attribute, because we have to ensure that the .NET Runtime allocates the structure in the same order as it is specified in the source code. We also need to enable "Allow unsafe code (/unsafe)" in the project's build properties.

Then we need to add the following constructor to the CoffHeader structure.

The "magic" trick is in the statement: this = *(CoffHeader*)packet;. What happens here? We have a fixed size of data somewhere in the memory and because a struct in C# is a value-type, the assignment operator = copies the whole data of the structure and not only the reference.

To fill the structure with data, we need to pass the data as bytes into the CoffHeader structure. This can be achieved by reading the exact size of the structure from the PE file.

We saw that we can parse well-formed binary data to our data structures using different approaches. The first is probably the clearest way, because we know each member and its size and ordering and we have control about the reading the data for each member. But if add member or the structure is going change by some reason, we need to change the reader.

The two other solutions use the approach of the structure assignment. In the unsafe implementation we need to compile the project with the /unsafe option. We increase the performance, but we get some security risks.

Comments

Once the chronograph is triggered, another central hands begins sweeping across the dial and also the contrast between both of these hands advancing at different jumping times is aesthetically breathtaking patek philippe replika .Within the version presented here, the Chronograph True Beat is located inside a 44 mm stainless situation installed on black alligator strap with a stainless-steel pin buckle but I wouldn't be too surprised to determine a rose or red-colored gold version at Baselworld too.

I must admit that I have always been impressed by the programming activities, but when I got in the position to make contact with this environment, I realized that I will not succeed to reach that level of professionalism that I really want.progress

this article usefull.newtopwatch rolex replicaDiamond and crystal combination developing an incredibly personal visual impact, definitely attract a large number of modern women and luxury lovers. When talking about high-end watches, however, rolex <a the gold standard is a Rolex. The style has been a little bit more than us.