diff --git a/de4dot.code/PE/FileHeader.cs b/de4dot.code/PE/FileHeader.cs
new file mode 100644
index 00000000..cbe5ea64
--- /dev/null
+++ b/de4dot.code/PE/FileHeader.cs
@@ -0,0 +1,48 @@
+/*
+ Copyright (C) 2011 de4dot@gmail.com
+
+ This file is part of de4dot.
+
+ de4dot is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ de4dot is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with de4dot. If not, see .
+*/
+
+using System.IO;
+
+namespace de4dot.PE {
+ enum Machine : ushort {
+ i386 = 0x14C,
+ ia64 = 0x200,
+ amd64 = 0x8664,
+ }
+
+ class FileHeader {
+ public Machine machine;
+ public ushort numberOfSections;
+ public uint timeDateStamp;
+ public uint pointerToSymbolTable;
+ public uint numberOfSymbols;
+ public ushort sizeOfOptionalHeader;
+ public ushort characteristics;
+
+ public FileHeader(BinaryReader reader) {
+ machine = (Machine)reader.ReadUInt16();
+ numberOfSections = reader.ReadUInt16();
+ timeDateStamp = reader.ReadUInt32();
+ pointerToSymbolTable = reader.ReadUInt32();
+ numberOfSymbols = reader.ReadUInt32();
+ sizeOfOptionalHeader = reader.ReadUInt16();
+ characteristics = reader.ReadUInt16();
+ }
+ }
+}
diff --git a/de4dot.code/PE/OptionalHeader.cs b/de4dot.code/PE/OptionalHeader.cs
new file mode 100644
index 00000000..b7f5ca1c
--- /dev/null
+++ b/de4dot.code/PE/OptionalHeader.cs
@@ -0,0 +1,115 @@
+/*
+ Copyright (C) 2011 de4dot@gmail.com
+
+ This file is part of de4dot.
+
+ de4dot is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ de4dot is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with de4dot. If not, see .
+*/
+
+using System.IO;
+
+namespace de4dot.PE {
+ struct DataDirectory {
+ public uint virtualAddress;
+ public uint size;
+
+ public override string ToString() {
+ return string.Format("{0:X8} {1:X8}", virtualAddress, size);
+ }
+ }
+
+ class OptionalHeader {
+ public ushort magic;
+ public byte majorLinkerVersion;
+ public byte minorLinkerVersion;
+ public uint sizeOfCode;
+ public uint sizeOfInitializedData;
+ public uint sizeOfUninitializedData;
+ public uint addressOfEntryPoint;
+ public uint baseOfCode;
+ public uint baseOfData; // 32-bit only
+ public ulong imageBase;
+ public uint sectionAlignment;
+ public uint fileAlignment;
+ public ushort majorOperatingSystemVersion;
+ public ushort minorOperatingSystemVersion;
+ public ushort majorImageVersion;
+ public ushort minorImageVersion;
+ public ushort majorSubsystemVersion;
+ public ushort minorSubsystemVersion;
+ public uint win32VersionValue;
+ public uint sizeOfImage;
+ public uint sizeOfHeaders;
+ public uint checkSum;
+ public ushort subsystem;
+ public ushort dllCharacteristics;
+ public ulong sizeOfStackReserve;
+ public ulong sizeOfStackCommit;
+ public ulong sizeOfHeapReserve;
+ public ulong sizeOfHeapCommit;
+ public uint loaderFlags;
+ public uint numberOfRvaAndSizes;
+ public DataDirectory[] dataDirectories;
+
+ public OptionalHeader(BinaryReader reader) {
+ magic = reader.ReadUInt16();
+ majorLinkerVersion = reader.ReadByte();
+ minorLinkerVersion = reader.ReadByte();
+ sizeOfCode = reader.ReadUInt32();
+ sizeOfInitializedData = reader.ReadUInt32();
+ sizeOfUninitializedData = reader.ReadUInt32();
+ addressOfEntryPoint = reader.ReadUInt32();
+ baseOfCode = reader.ReadUInt32();
+ if (is32bit())
+ baseOfData = reader.ReadUInt32();
+ imageBase = read4Or8(reader);
+ sectionAlignment = reader.ReadUInt32();
+ fileAlignment = reader.ReadUInt32();
+ majorOperatingSystemVersion = reader.ReadUInt16();
+ minorOperatingSystemVersion = reader.ReadUInt16();
+ majorImageVersion = reader.ReadUInt16();
+ minorImageVersion = reader.ReadUInt16();
+ majorSubsystemVersion = reader.ReadUInt16();
+ minorSubsystemVersion = reader.ReadUInt16();
+ win32VersionValue = reader.ReadUInt32();
+ sizeOfImage = reader.ReadUInt32();
+ sizeOfHeaders = reader.ReadUInt32();
+ checkSum = reader.ReadUInt32();
+ subsystem = reader.ReadUInt16();
+ dllCharacteristics = reader.ReadUInt16();
+ sizeOfStackReserve = read4Or8(reader);
+ sizeOfStackCommit = read4Or8(reader);
+ sizeOfHeapReserve = read4Or8(reader);
+ sizeOfHeapCommit = read4Or8(reader);
+ loaderFlags = reader.ReadUInt32();
+ numberOfRvaAndSizes = reader.ReadUInt32();
+
+ dataDirectories = new DataDirectory[16];
+ for (int i = 0; i < dataDirectories.Length; i++) {
+ dataDirectories[i].virtualAddress = reader.ReadUInt32();
+ dataDirectories[i].size = reader.ReadUInt32();
+ }
+ }
+
+ ulong read4Or8(BinaryReader reader) {
+ if (is32bit())
+ return reader.ReadUInt32();
+ return reader.ReadUInt64();
+ }
+
+ public bool is32bit() {
+ return magic != 0x20B;
+ }
+ }
+}
diff --git a/de4dot.code/PE/PeImage.cs b/de4dot.code/PE/PeImage.cs
new file mode 100644
index 00000000..97a7df41
--- /dev/null
+++ b/de4dot.code/PE/PeImage.cs
@@ -0,0 +1,88 @@
+/*
+ Copyright (C) 2011 de4dot@gmail.com
+
+ This file is part of de4dot.
+
+ de4dot is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ de4dot is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with de4dot. If not, see .
+*/
+
+using System;
+using System.IO;
+
+namespace de4dot.PE {
+ class PeImage {
+ BinaryReader reader;
+ BinaryWriter writer;
+ FileHeader fileHeader;
+ OptionalHeader optionalHeader;
+ SectionHeader[] sectionHeaders;
+
+ public PeImage(byte[] data)
+ : this(new MemoryStream(data)) {
+ }
+
+ public PeImage(Stream stream) {
+ reader = new BinaryReader(stream);
+ writer = new BinaryWriter(stream);
+
+ init();
+ }
+
+ void seek(uint position) {
+ reader.BaseStream.Position = position;
+ }
+
+ void skip(int bytes) {
+ reader.BaseStream.Position += bytes;
+ }
+
+ void init() {
+ seek(0);
+ if (reader.ReadUInt16() != 0x5A4D)
+ throw new BadImageFormatException("Not a PE file");
+ skip(29 * 2);
+ seek(reader.ReadUInt32());
+
+ if (reader.ReadUInt32() != 0x4550)
+ throw new BadImageFormatException("Not a PE file");
+ fileHeader = new FileHeader(reader);
+ optionalHeader = new OptionalHeader(reader);
+
+ sectionHeaders = new SectionHeader[fileHeader.numberOfSections];
+ for (int i = 0; i < sectionHeaders.Length; i++)
+ sectionHeaders[i] = new SectionHeader(reader);
+ }
+
+ SectionHeader getSectionHeader(uint rva) {
+ for (int i = 0; i < sectionHeaders.Length; i++) {
+ var section = sectionHeaders[i];
+ if (section.virtualAddress <= rva && rva < section.virtualAddress + section.virtualSize)
+ return section;
+ }
+ return null;
+ }
+
+ uint rvaToOffset(uint rva) {
+ var section = getSectionHeader(rva);
+ if (section == null)
+ throw new ApplicationException(string.Format("Invalid RVA {0:X8}", rva));
+ return rva - section.virtualAddress + section.pointerToRawData;
+ }
+
+ public void write(uint rva, byte[] data) {
+ seek(rvaToOffset(rva));
+ writer.Write(data);
+ }
+ }
+}
diff --git a/de4dot.code/PE/SectionHeader.cs b/de4dot.code/PE/SectionHeader.cs
new file mode 100644
index 00000000..bce7aa02
--- /dev/null
+++ b/de4dot.code/PE/SectionHeader.cs
@@ -0,0 +1,62 @@
+/*
+ Copyright (C) 2011 de4dot@gmail.com
+
+ This file is part of de4dot.
+
+ de4dot is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ de4dot is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with de4dot. If not, see .
+*/
+
+using System.IO;
+using System.Text;
+
+namespace de4dot.PE {
+ class SectionHeader {
+ public byte[] name;
+ public uint virtualSize;
+ public uint virtualAddress;
+ public uint sizeOfRawData;
+ public uint pointerToRawData;
+ public uint pointerToRelocations;
+ public uint pointerToLinenumbers;
+ public ushort numberOfRelocations;
+ public ushort numberOfLinenumbers;
+ public uint characteristics;
+ public string displayName;
+
+ public SectionHeader(BinaryReader reader) {
+ name = reader.ReadBytes(8);
+ virtualSize = reader.ReadUInt32();
+ virtualAddress = reader.ReadUInt32();
+ sizeOfRawData = reader.ReadUInt32();
+ pointerToRawData = reader.ReadUInt32();
+ pointerToRelocations = reader.ReadUInt32();
+ pointerToLinenumbers = reader.ReadUInt32();
+ numberOfRelocations = reader.ReadUInt16();
+ numberOfLinenumbers = reader.ReadUInt16();
+ characteristics = reader.ReadUInt32();
+
+ var sb = new StringBuilder(name.Length);
+ foreach (var c in name) {
+ if (c == 0)
+ break;
+ sb.Append((char)c);
+ }
+ displayName = sb.ToString();
+ }
+
+ public override string ToString() {
+ return string.Format("{0:X8} {1:X8} {2:X8} - {3}", virtualAddress, virtualSize, sizeOfRawData, displayName);
+ }
+ }
+}
diff --git a/de4dot.code/de4dot.code.csproj b/de4dot.code/de4dot.code.csproj
index 0213a9a4..5fb54e29 100644
--- a/de4dot.code/de4dot.code.csproj
+++ b/de4dot.code/de4dot.code.csproj
@@ -103,6 +103,10 @@
+
+
+
+