As I sit down to write this, I get to the one, two, many stage and will write some code to help. We will eventually want to parse out all of the different HelloWorld.exe files, all 14 of them. Well, 14 for now. And this is just the first program, it isn't even doing anything real or interesting! Automation is key. Performance is a feature, but I am going to optimize on readability for now. That means that I will build structs and Marshall byte arrays into them. A quick StackOverflow search yields C#, read structures from a binary file which has the following method:
public static T? ReadStructure<T>(this Stream stream) where T : struct { if (stream == null) return null; int size = Marshal.SizeOf(typeof(T)); byte[] bytes = new byte[size]; if (stream.Read(bytes, 0, size) != size) // can't build this structure! return null; GCHandle handle = GCHandle.Alloc(bytes, GCHandleType.Pinned); try { return (T)Marshal.PtrToStructure(handle.AddrOfPinnedObject(), typeof(T)); } finally { handle.Free(); } }
I have written similar code in the past, but not as well. In Part 3 we started the actual dissection by delving into the COFF header, so let's start by writing some code to read it and print out the useful parts for analysis. I am going to build another console application and (of course) use the Command Line Parser Library mentioned earlier to take in arguments.
This is going to be a different kind of fun, but it should be educational.