module Data.PE.Structures where
import Data.Word
import Data.PE.Utils
import Data.ByteString.Lazy
import Numeric
import Data.Binary
import Data.Binary.Get
import Data.Char
--import System.Time

-- |The over-arching container.  Holds the headers and a list of binary sections
data PEFile = PEFile {
    PEFile -> PEHeader
peHeader :: PEHeader
} deriving Int -> PEFile -> ShowS
[PEFile] -> ShowS
PEFile -> String
(Int -> PEFile -> ShowS)
-> (PEFile -> String) -> ([PEFile] -> ShowS) -> Show PEFile
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [PEFile] -> ShowS
$cshowList :: [PEFile] -> ShowS
show :: PEFile -> String
$cshow :: PEFile -> String
showsPrec :: Int -> PEFile -> ShowS
$cshowsPrec :: Int -> PEFile -> ShowS
Show

data PEObject = PEObj {
    PEObject -> PEObjectHeader
peObjHeader :: PEObjectHeader
} deriving Int -> PEObject -> ShowS
[PEObject] -> ShowS
PEObject -> String
(Int -> PEObject -> ShowS)
-> (PEObject -> String) -> ([PEObject] -> ShowS) -> Show PEObject
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [PEObject] -> ShowS
$cshowList :: [PEObject] -> ShowS
show :: PEObject -> String
$cshow :: PEObject -> String
showsPrec :: Int -> PEObject -> ShowS
$cshowsPrec :: Int -> PEObject -> ShowS
Show

-- |The Binary Section container.  Holds names and containers.
data BinSection = BinSection {
    BinSection -> String
secname :: String,
    BinSection -> ByteString
binSection :: ByteString
} deriving Int -> BinSection -> ShowS
[BinSection] -> ShowS
BinSection -> String
(Int -> BinSection -> ShowS)
-> (BinSection -> String)
-> ([BinSection] -> ShowS)
-> Show BinSection
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [BinSection] -> ShowS
$cshowList :: [BinSection] -> ShowS
show :: BinSection -> String
$cshow :: BinSection -> String
showsPrec :: Int -> BinSection -> ShowS
$cshowsPrec :: Int -> BinSection -> ShowS
Show

data PEObjectHeader = PEObjHdr {
  PEObjectHeader -> COFFHeader
objcoffhdr :: COFFHeader,
  PEObjectHeader -> [(SectionTable, ByteString)]
objsectionTables :: [(SectionTable,ByteString)]
} deriving Int -> PEObjectHeader -> ShowS
[PEObjectHeader] -> ShowS
PEObjectHeader -> String
(Int -> PEObjectHeader -> ShowS)
-> (PEObjectHeader -> String)
-> ([PEObjectHeader] -> ShowS)
-> Show PEObjectHeader
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [PEObjectHeader] -> ShowS
$cshowList :: [PEObjectHeader] -> ShowS
show :: PEObjectHeader -> String
$cshow :: PEObjectHeader -> String
showsPrec :: Int -> PEObjectHeader -> ShowS
$cshowsPrec :: Int -> PEObjectHeader -> ShowS
Show

-- |The Header section, holds entries for each header in the PE File
data PEHeader = PEHeader {
	PEHeader -> MSDOSHeader
msdosHeader :: MSDOSHeader,
	PEHeader -> PESignature
peSignature :: PESignature,
	PEHeader -> COFFHeader
coffHeader :: COFFHeader,
	PEHeader -> StandardFields
standardFields :: StandardFields,
	PEHeader -> WindowsSpecFields
windowsSpecFields :: WindowsSpecFields,
	PEHeader -> [DirectoryEntry]
dataDirectories :: [DirectoryEntry],
	PEHeader -> [(SectionTable, ByteString)]
sectionTables :: [(SectionTable,ByteString)]
--	sectionbytes :: [ByteString]
} deriving Int -> PEHeader -> ShowS
[PEHeader] -> ShowS
PEHeader -> String
(Int -> PEHeader -> ShowS)
-> (PEHeader -> String) -> ([PEHeader] -> ShowS) -> Show PEHeader
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [PEHeader] -> ShowS
$cshowList :: [PEHeader] -> ShowS
show :: PEHeader -> String
$cshow :: PEHeader -> String
showsPrec :: Int -> PEHeader -> ShowS
$cshowsPrec :: Int -> PEHeader -> ShowS
Show

data MSDOSHeader = MSDOSHeader {
	MSDOSHeader -> Word16
signature :: Word16,
	MSDOSHeader -> Word16
lastsize :: Word16,
	MSDOSHeader -> Word16
pagesInFile :: Word16,
	MSDOSHeader -> Word16
relocations :: Word16,
	MSDOSHeader -> Word16
headerSizeInParagraph :: Word16,
	MSDOSHeader -> Word16
minExtraParagraphs :: Word16,
	MSDOSHeader -> Word16
maxExtraParagraphs :: Word16,
	MSDOSHeader -> Word16
ss :: Word16,
	MSDOSHeader -> Word16
sp :: Word16,
	MSDOSHeader -> Word16
checksum :: Word16,
	MSDOSHeader -> Word16
ip :: Word16,
	MSDOSHeader -> Word16
cs :: Word16,
	MSDOSHeader -> Word16
relocTableOffset :: Word16,
	MSDOSHeader -> Word16
overlayNumber :: Word16,
	--4 * short reserved spaces
	MSDOSHeader -> Word16
oemIdentifier :: Word16,
	MSDOSHeader -> Word16
oemInformation :: Word16,
	--10 * short reserved spaces
	MSDOSHeader -> Word32
offset :: Word32
} 
instance Show MSDOSHeader where
	show :: MSDOSHeader -> String
show MSDOSHeader
header = String
"Signature: " String -> ShowS
forall a. [a] -> [a] -> [a]
++ (ByteString -> String
forall a. Show a => a -> String
show(ByteString -> String)
-> (Word16 -> ByteString) -> Word16 -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
.Word16 -> ByteString
forall a. Binary a => a -> ByteString
encode (Word16 -> String) -> Word16 -> String
forall a b. (a -> b) -> a -> b
$ MSDOSHeader -> Word16
signature MSDOSHeader
header) String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
"\n"
		String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
"Last Page Size: " String -> ShowS
forall a. [a] -> [a] -> [a]
++ (Word16 -> String
forall a. Show a => a -> String
show (Word16 -> String) -> Word16 -> String
forall a b. (a -> b) -> a -> b
$ MSDOSHeader -> Word16
lastsize MSDOSHeader
header) String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
"\n"
		String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
"Number of Pages: " String -> ShowS
forall a. [a] -> [a] -> [a]
++ (Word16 -> String
forall a. Show a => a -> String
show (Word16 -> String) -> Word16 -> String
forall a b. (a -> b) -> a -> b
$ MSDOSHeader -> Word16
pagesInFile MSDOSHeader
header) String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
"\n"
		String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
"Relocations: " String -> ShowS
forall a. [a] -> [a] -> [a]
++ (Word16 -> String
forall a. Show a => a -> String
show (Word16 -> String) -> Word16 -> String
forall a b. (a -> b) -> a -> b
$ MSDOSHeader -> Word16
relocations MSDOSHeader
header) String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
"\n"
		String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
"Header Size in Paragraphs: " String -> ShowS
forall a. [a] -> [a] -> [a]
++ (Word16 -> String
forall a. Show a => a -> String
show (Word16 -> String) -> Word16 -> String
forall a b. (a -> b) -> a -> b
$ MSDOSHeader -> Word16
headerSizeInParagraph MSDOSHeader
header) String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
"\n"
		String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
"Min Extra Paragraphs: " String -> ShowS
forall a. [a] -> [a] -> [a]
++ (Word16 -> String
forall a. Show a => a -> String
show (Word16 -> String) -> Word16 -> String
forall a b. (a -> b) -> a -> b
$ MSDOSHeader -> Word16
minExtraParagraphs MSDOSHeader
header) String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
"\n"
		String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
"Max Extra Paragraphs: " String -> ShowS
forall a. [a] -> [a] -> [a]
++ (Word16 -> String
forall a. Show a => a -> String
show (Word16 -> String) -> Word16 -> String
forall a b. (a -> b) -> a -> b
$ MSDOSHeader -> Word16
maxExtraParagraphs MSDOSHeader
header) String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
"\n"
		String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
"Stack Segment: 0x" String -> ShowS
forall a. [a] -> [a] -> [a]
++ (Word16 -> ShowS
forall a. (Integral a, Show a) => a -> ShowS
showHex (MSDOSHeader -> Word16
ss MSDOSHeader
header) String
"") String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
"\n"
		String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
"Stack Pointer: 0x" String -> ShowS
forall a. [a] -> [a] -> [a]
++ (Word16 -> ShowS
forall a. (Integral a, Show a) => a -> ShowS
showHex (MSDOSHeader -> Word16
sp MSDOSHeader
header) String
"") String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
"\n"
		String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
"File checksum: " String -> ShowS
forall a. [a] -> [a] -> [a]
++ (Word16 -> String
forall a. Show a => a -> String
show (Word16 -> String) -> Word16 -> String
forall a b. (a -> b) -> a -> b
$ MSDOSHeader -> Word16
checksum MSDOSHeader
header) String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
"\n"
		String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
"Code Segment: " String -> ShowS
forall a. [a] -> [a] -> [a]
++ (Word16 -> String
forall a. Show a => a -> String
show (Word16 -> String) -> Word16 -> String
forall a b. (a -> b) -> a -> b
$ MSDOSHeader -> Word16
cs MSDOSHeader
header) String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
"\n"
		String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
"Instruction Pointer: " String -> ShowS
forall a. [a] -> [a] -> [a]
++ (Word16 -> String
forall a. Show a => a -> String
show (Word16 -> String) -> Word16 -> String
forall a b. (a -> b) -> a -> b
$ MSDOSHeader -> Word16
ip MSDOSHeader
header) String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
"\n"
		String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
"Relocation Offset: " String -> ShowS
forall a. [a] -> [a] -> [a]
++ (Word16 -> String
forall a. Show a => a -> String
show (Word16 -> String) -> Word16 -> String
forall a b. (a -> b) -> a -> b
$ MSDOSHeader -> Word16
relocTableOffset MSDOSHeader
header) String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
"\n"
		String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
"Overlay Number: " String -> ShowS
forall a. [a] -> [a] -> [a]
++ (Word16 -> String
forall a. Show a => a -> String
show (Word16 -> String) -> Word16 -> String
forall a b. (a -> b) -> a -> b
$ MSDOSHeader -> Word16
overlayNumber MSDOSHeader
header) String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
"\n"
		String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
"OEM Identifier: 0x" String -> ShowS
forall a. [a] -> [a] -> [a]
++ (Word16 -> ShowS
forall a. (Integral a, Show a) => a -> ShowS
showHex (MSDOSHeader -> Word16
oemIdentifier MSDOSHeader
header) String
"") String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
"\n"
		String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
"OEM Information: 0x" String -> ShowS
forall a. [a] -> [a] -> [a]
++(Word16 -> ShowS
forall a. (Integral a, Show a) => a -> ShowS
showHex (MSDOSHeader -> Word16
oemInformation MSDOSHeader
header) String
"") String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
"\n"
		String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
"PE Header Offset: " String -> ShowS
forall a. [a] -> [a] -> [a]
++ (Word32 -> String
forall a. Show a => a -> String
show (Word32 -> String) -> Word32 -> String
forall a b. (a -> b) -> a -> b
$ MSDOSHeader -> Word32
offset MSDOSHeader
header) String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
"\n"
		

data PESignature = PESignature {
	PESignature -> Word32
pesignature :: Word32 --0x00004550
} 
instance Show PESignature where
	show :: PESignature -> String
show (PESignature Word32
sig) = String
"PE-Signature: 0x" String -> ShowS
forall a. [a] -> [a] -> [a]
++ (Word32 -> ShowS
forall a. (Integral a, Show a) => a -> ShowS
showHex Word32
sig String
"") String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
"\n"

data COFFHeader = COFFHeader {
	COFFHeader -> MachineType
targetMachine :: MachineType,
	COFFHeader -> Word16
numberOfSections :: Word16,  --IMPORTANT
	COFFHeader -> Word32
timeDateStamp :: Word32,
	COFFHeader -> Word32
pointerToSymbolTable :: Word32, --0 for image
	COFFHeader -> Word32
numberOfSymbols :: Word32, --0 for image
	COFFHeader -> Word16
sizeofOptionalHeaders :: Word16,
	COFFHeader -> Word16
coffCharacteristics :: Word16
}
instance Show COFFHeader where
	show :: COFFHeader -> String
show COFFHeader
hdr = String
"Target Machine: " String -> ShowS
forall a. [a] -> [a] -> [a]
++ (MachineType -> String
forall a. Show a => a -> String
show (MachineType -> String) -> MachineType -> String
forall a b. (a -> b) -> a -> b
$ COFFHeader -> MachineType
targetMachine COFFHeader
hdr) String -> ShowS
forall a. [a] -> [a] -> [a]
++String
"\n"
		String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
"Number of Sections: " String -> ShowS
forall a. [a] -> [a] -> [a]
++ (Word16 -> String
forall a. Show a => a -> String
show (COFFHeader -> Word16
numberOfSections COFFHeader
hdr)) String -> ShowS
forall a. [a] -> [a] -> [a]
++String
"\n"
		String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
"Timestamp: " String -> ShowS
forall a. [a] -> [a] -> [a]
++ (Word32 -> String
forall a. Show a => a -> String
show (Word32 -> String) -> Word32 -> String
forall a b. (a -> b) -> a -> b
$ COFFHeader -> Word32
timeDateStamp (COFFHeader -> Word32) -> COFFHeader -> Word32
forall a b. (a -> b) -> a -> b
$ COFFHeader
hdr) String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
"\n"
		String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
"Symbol Table Pointer: 0x" String -> ShowS
forall a. [a] -> [a] -> [a]
++ (Word32 -> ShowS
forall a. (Integral a, Show a) => a -> ShowS
showHex (COFFHeader -> Word32
pointerToSymbolTable COFFHeader
hdr) String
"") String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
"\n"
		String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
"Number of Symbols: " String -> ShowS
forall a. [a] -> [a] -> [a]
++ (Word32 -> String
forall a. Show a => a -> String
show (Word32 -> String) -> Word32 -> String
forall a b. (a -> b) -> a -> b
$ COFFHeader -> Word32
numberOfSymbols COFFHeader
hdr) String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
"\n"
		String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
"Size of Optional Headers: " String -> ShowS
forall a. [a] -> [a] -> [a]
++ (Word16 -> String
forall a. Show a => a -> String
show (Word16 -> String) -> Word16 -> String
forall a b. (a -> b) -> a -> b
$ COFFHeader -> Word16
sizeofOptionalHeaders COFFHeader
hdr) String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
"\n"
		String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
"COFF Characteristics: 0x" String -> ShowS
forall a. [a] -> [a] -> [a]
++ (Word16 -> ShowS
forall a. (Integral a, Show a) => a -> ShowS
showHex (COFFHeader -> Word16
coffCharacteristics COFFHeader
hdr) String
"") String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
"\n"

data StandardFields = StandardFields {
	StandardFields -> Word16
standardSig :: Word16, -- Should be 0x10B or 0x20B if PE32+
	StandardFields -> Word8
lnMajorVersion :: Word8,
	StandardFields -> Word8
lnMinorVersion :: Word8,
	StandardFields -> Word32
sizeOfCode :: Word32,
	StandardFields -> Word32
sizeOfInitializedData :: Word32,
	StandardFields -> Word32
sizeOfUninitData :: Word32,
	StandardFields -> Word32
addressOfEntryPoint :: Word32,
	StandardFields -> Word32
baseOfCode :: Word32,
	StandardFields -> Word32
baseOfData :: Word32
} | SFPlus { standardSig :: Word16, 
              lnMajorVersion :: Word8,
              lnMinorVersion :: Word8,
              sizeOfCode :: Word32,
              sizeOfInitializedData :: Word32,
              sizeOfUninitData :: Word32,
              addressOfEntryPoint :: Word32, 
	            baseOfCode :: Word32 }

instance Show StandardFields where
	show :: StandardFields -> String
show StandardFields
sf = String
"Signature: 0x" String -> ShowS
forall a. [a] -> [a] -> [a]
++ (Word16 -> ShowS
forall a. (Integral a, Show a) => a -> ShowS
showHex (StandardFields -> Word16
standardSig StandardFields
sf) String
"") String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
"\n"
		String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
"Linker Major Version: " String -> ShowS
forall a. [a] -> [a] -> [a]
++ (Word8 -> String
forall a. Show a => a -> String
show (Word8 -> String) -> Word8 -> String
forall a b. (a -> b) -> a -> b
$ StandardFields -> Word8
lnMajorVersion StandardFields
sf) String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
"\n"
		String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
"Linker Minor Version: " String -> ShowS
forall a. [a] -> [a] -> [a]
++ (Word8 -> String
forall a. Show a => a -> String
show (Word8 -> String) -> Word8 -> String
forall a b. (a -> b) -> a -> b
$ StandardFields -> Word8
lnMinorVersion StandardFields
sf) String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
"\n"
		String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
"Size of Code: " String -> ShowS
forall a. [a] -> [a] -> [a]
++ (Word32 -> String
forall a. Show a => a -> String
show (Word32 -> String) -> Word32 -> String
forall a b. (a -> b) -> a -> b
$ StandardFields -> Word32
sizeOfCode StandardFields
sf) String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
"\n"
		String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
"Size of Initialized Data: " String -> ShowS
forall a. [a] -> [a] -> [a]
++ (Word32 -> String
forall a. Show a => a -> String
show (Word32 -> String) -> Word32 -> String
forall a b. (a -> b) -> a -> b
$ StandardFields -> Word32
sizeOfInitializedData StandardFields
sf) String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
"\n"
		String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
"Size of Un-initialized Data: " String -> ShowS
forall a. [a] -> [a] -> [a]
++ (Word32 -> String
forall a. Show a => a -> String
show (Word32 -> String) -> Word32 -> String
forall a b. (a -> b) -> a -> b
$ StandardFields -> Word32
sizeOfUninitData StandardFields
sf) String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
"\n"
		String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
"Entry Point Address: 0x" String -> ShowS
forall a. [a] -> [a] -> [a]
++ (Word32 -> ShowS
forall a. (Integral a, Show a) => a -> ShowS
showHex (StandardFields -> Word32
addressOfEntryPoint StandardFields
sf) String
"") String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
"\n"
		String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
"Code base Address: 0x" String -> ShowS
forall a. [a] -> [a] -> [a]
++ (Word32 -> ShowS
forall a. (Integral a, Show a) => a -> ShowS
showHex (StandardFields -> Word32
baseOfCode StandardFields
sf) String
"") String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
"\n"
		-- ++"Data base Address: 0x"++(showHex (baseOfData sf) "")++"\n"

data WindowsSpecFields = WindowsSpecFields {
	WindowsSpecFields -> Word32
imageBase :: Word32,
	WindowsSpecFields -> Word32
sectionAlignment :: Word32,
	WindowsSpecFields -> Word32
fileAlignment :: Word32,
	WindowsSpecFields -> Word16
majorOSVersion :: Word16,
	WindowsSpecFields -> Word16
minorOSVersion :: Word16,
	WindowsSpecFields -> Word16
majorImageVersion :: Word16,
	WindowsSpecFields -> Word16
minorImageVersion :: Word16,
	WindowsSpecFields -> Word16
majorSubSystemVersion :: Word16,
	WindowsSpecFields -> Word16
minorSubSystemVersion :: Word16,
	WindowsSpecFields -> Word32
win32VersionValue :: Word32,
	WindowsSpecFields -> Word32
sizeOfImage :: Word32,
	WindowsSpecFields -> Word32
sizeOfHeaders :: Word32,
	WindowsSpecFields -> Word32
checkSum32 :: Word32,
	WindowsSpecFields -> Word16
checkSum16 :: Word16,
	WindowsSpecFields -> Word16
dllCharacteristics :: Word16,
	WindowsSpecFields -> Word32
sizeOfStackReserve :: Word32,
	WindowsSpecFields -> Word32
sizeOfStackCommit :: Word32,
	WindowsSpecFields -> Word32
sizeOfHeapReserve :: Word32,
	WindowsSpecFields -> Word32
sizeOfHeapCommit :: Word32,
	WindowsSpecFields -> Word32
loaderFlags :: Word32,
	WindowsSpecFields -> Word32
numberOfRVAandSizes :: Word32
} | WSFPlus { WindowsSpecFields -> Word64
imgBase :: Word64,
            sectionAlignment :: Word32,
            fileAlignment :: Word32,
            majorOSVersion :: Word16,
            minorOSVersion :: Word16,
            majorImageVersion :: Word16,
            minorImageVersion :: Word16,
            majorSubSystemVersion :: Word16,
            minorSubSystemVersion :: Word16,
            win32VersionValue :: Word32,
            sizeOfImage :: Word32,
            sizeOfHeaders :: Word32,
            checkSum32 :: Word32,
            checkSum16 :: Word16,
            dllCharacteristics :: Word16,
            WindowsSpecFields -> Word64
szOfStackReserve :: Word64,
            WindowsSpecFields -> Word64
szOfStackCommit :: Word64,
            WindowsSpecFields -> Word64
szOfHeapReserve :: Word64,
            WindowsSpecFields -> Word64
szOfHeapCommit :: Word64,
            loaderFlags :: Word32,
            numberOfRVAandSizes :: Word32 }

--instance Binary WindowsSpecFields where
--  get = 

instance Show WindowsSpecFields where
	show :: WindowsSpecFields -> String
show WindowsSpecFields
hdr = String
"Image Base: 0x" String -> ShowS
forall a. [a] -> [a] -> [a]
++ (Word32 -> ShowS
forall a. (Integral a, Show a) => a -> ShowS
showHex (WindowsSpecFields -> Word32
imageBase WindowsSpecFields
hdr) String
"") String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
"\n"
		String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
"Section Alignment: 0x" String -> ShowS
forall a. [a] -> [a] -> [a]
++ (Word32 -> ShowS
forall a. (Integral a, Show a) => a -> ShowS
showHex (WindowsSpecFields -> Word32
sectionAlignment WindowsSpecFields
hdr) String
"") String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
"\n"
		String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
"File Alignment: 0x" String -> ShowS
forall a. [a] -> [a] -> [a]
++ (Word32 -> ShowS
forall a. (Integral a, Show a) => a -> ShowS
showHex (WindowsSpecFields -> Word32
fileAlignment WindowsSpecFields
hdr) String
"") String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
"\n"
		String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
"Major OS Version: " String -> ShowS
forall a. [a] -> [a] -> [a]
++ (Word16 -> String
forall a. Show a => a -> String
show (Word16 -> String) -> Word16 -> String
forall a b. (a -> b) -> a -> b
$ WindowsSpecFields -> Word16
majorOSVersion WindowsSpecFields
hdr) String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
"\n"
		String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
"Minor OS Version: " String -> ShowS
forall a. [a] -> [a] -> [a]
++ (Word16 -> String
forall a. Show a => a -> String
show (Word16 -> String) -> Word16 -> String
forall a b. (a -> b) -> a -> b
$ WindowsSpecFields -> Word16
minorOSVersion WindowsSpecFields
hdr) String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
"\n"
		String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
"Major Subsystem Version: " String -> ShowS
forall a. [a] -> [a] -> [a]
++ (Word16 -> String
forall a. Show a => a -> String
show (Word16 -> String) -> Word16 -> String
forall a b. (a -> b) -> a -> b
$ WindowsSpecFields -> Word16
majorSubSystemVersion WindowsSpecFields
hdr) String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
"\n"
		String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
"Minor Subsystem Version: " String -> ShowS
forall a. [a] -> [a] -> [a]
++ (Word16 -> String
forall a. Show a => a -> String
show (Word16 -> String) -> Word16 -> String
forall a b. (a -> b) -> a -> b
$ WindowsSpecFields -> Word16
minorSubSystemVersion WindowsSpecFields
hdr) String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
"\n"
		String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
"Win 32 Version Value: " String -> ShowS
forall a. [a] -> [a] -> [a]
++ (Word32 -> String
forall a. Show a => a -> String
show (Word32 -> String) -> Word32 -> String
forall a b. (a -> b) -> a -> b
$ WindowsSpecFields -> Word32
win32VersionValue WindowsSpecFields
hdr) String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
"\n"
		String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
"Size of Image: " String -> ShowS
forall a. [a] -> [a] -> [a]
++ (Word32 -> String
forall a. Show a => a -> String
show (Word32 -> String) -> Word32 -> String
forall a b. (a -> b) -> a -> b
$ WindowsSpecFields -> Word32
sizeOfImage WindowsSpecFields
hdr) String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
"\n"
		String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
"Size of Headers: " String -> ShowS
forall a. [a] -> [a] -> [a]
++ (Word32 -> String
forall a. Show a => a -> String
show (Word32 -> String) -> Word32 -> String
forall a b. (a -> b) -> a -> b
$ WindowsSpecFields -> Word32
sizeOfHeaders WindowsSpecFields
hdr) String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
"\n"
		String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
"Checksum 32: " String -> ShowS
forall a. [a] -> [a] -> [a]
++ (Word32 -> String
forall a. Show a => a -> String
show (Word32 -> String) -> Word32 -> String
forall a b. (a -> b) -> a -> b
$ WindowsSpecFields -> Word32
checkSum32 WindowsSpecFields
hdr) String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
"\n"
		String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
"Checksum 15: " String -> ShowS
forall a. [a] -> [a] -> [a]
++ (Word16 -> String
forall a. Show a => a -> String
show (Word16 -> String) -> Word16 -> String
forall a b. (a -> b) -> a -> b
$ WindowsSpecFields -> Word16
checkSum16 WindowsSpecFields
hdr) String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
"\n"
		String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
"DLL Characteristics: 0x" String -> ShowS
forall a. [a] -> [a] -> [a]
++ (Word16 -> ShowS
forall a. (Integral a, Show a) => a -> ShowS
showHex (WindowsSpecFields -> Word16
dllCharacteristics WindowsSpecFields
hdr) String
"") String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
"\n"
		String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
"Size of Stack Reserved: " String -> ShowS
forall a. [a] -> [a] -> [a]
++ (Word32 -> String
forall a. Show a => a -> String
show (Word32 -> String) -> Word32 -> String
forall a b. (a -> b) -> a -> b
$ WindowsSpecFields -> Word32
sizeOfStackReserve WindowsSpecFields
hdr) String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
"\n"
		String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
"Size of Stack Commit: " String -> ShowS
forall a. [a] -> [a] -> [a]
++ (Word32 -> String
forall a. Show a => a -> String
show (Word32 -> String) -> Word32 -> String
forall a b. (a -> b) -> a -> b
$ WindowsSpecFields -> Word32
sizeOfStackCommit WindowsSpecFields
hdr) String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
"\n"
		String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
"Size of Heap Reserved: " String -> ShowS
forall a. [a] -> [a] -> [a]
++ (Word32 -> String
forall a. Show a => a -> String
show (Word32 -> String) -> Word32 -> String
forall a b. (a -> b) -> a -> b
$ WindowsSpecFields -> Word32
sizeOfHeapReserve WindowsSpecFields
hdr) String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
"\n"
		String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
"Size of Heap Commit: " String -> ShowS
forall a. [a] -> [a] -> [a]
++ (Word32 -> String
forall a. Show a => a -> String
show (Word32 -> String) -> Word32 -> String
forall a b. (a -> b) -> a -> b
$ WindowsSpecFields -> Word32
sizeOfHeapCommit WindowsSpecFields
hdr) String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
"\n"
		String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
"Loader Flags: 0x" String -> ShowS
forall a. [a] -> [a] -> [a]
++ (Word32 -> ShowS
forall a. (Integral a, Show a) => a -> ShowS
showHex (WindowsSpecFields -> Word32
loaderFlags WindowsSpecFields
hdr) String
"") String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
"\n"
		String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
"RVA: " String -> ShowS
forall a. [a] -> [a] -> [a]
++ (Word32 -> String
forall a. Show a => a -> String
show (Word32 -> String) -> Word32 -> String
forall a b. (a -> b) -> a -> b
$ WindowsSpecFields -> Word32
numberOfRVAandSizes WindowsSpecFields
hdr) String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
"\n"


data DirectoryEntry = DirEntry {
  DirectoryEntry -> Word32
virtualAddr :: Word32,
  DirectoryEntry -> Word32
entrySize :: Word32
} deriving Int -> DirectoryEntry -> ShowS
[DirectoryEntry] -> ShowS
DirectoryEntry -> String
(Int -> DirectoryEntry -> ShowS)
-> (DirectoryEntry -> String)
-> ([DirectoryEntry] -> ShowS)
-> Show DirectoryEntry
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [DirectoryEntry] -> ShowS
$cshowList :: [DirectoryEntry] -> ShowS
show :: DirectoryEntry -> String
$cshow :: DirectoryEntry -> String
showsPrec :: Int -> DirectoryEntry -> ShowS
$cshowsPrec :: Int -> DirectoryEntry -> ShowS
Show

instance Binary DirectoryEntry where
  get :: Get DirectoryEntry
get = do
          Word32
addr <- Get Word32
getWord32le
          Word32
size <- Get Word32
getWord32le
          let entry :: DirectoryEntry
entry = DirEntry :: Word32 -> Word32 -> DirectoryEntry
DirEntry {virtualAddr :: Word32
virtualAddr=Word32
addr, entrySize :: Word32
entrySize=Word32
size}
          DirectoryEntry -> Get DirectoryEntry
forall (m :: * -> *) a. Monad m => a -> m a
return (DirectoryEntry -> Get DirectoryEntry)
-> DirectoryEntry -> Get DirectoryEntry
forall a b. (a -> b) -> a -> b
$ DirectoryEntry
entry 
  put :: DirectoryEntry -> Put
put DirectoryEntry
_ = String -> Put
forall a. HasCallStack => String -> a
error String
"Serialization of DirectoryEntry not supported."

data SectionTable = SectionTable {
	SectionTable -> String
sectionHeaderName :: String,
	SectionTable -> Word32
virtualSize :: Word32,
	SectionTable -> Word32
virtualAddress :: Word32,
	SectionTable -> Word32
sizeOfRawData :: Word32,
	SectionTable -> Word32
pointerToRawData :: Word32,
	SectionTable -> Word32
pointerToRelocations :: Word32,
	SectionTable -> Word32
pointerToLineNumbers :: Word32,
	SectionTable -> Word16
numberOfRelocations :: Word16,
	SectionTable -> Word16
numberOfLineNumbers :: Word16,
	SectionTable -> Word32
secCharacteristics :: Word32
} deriving Int -> SectionTable -> ShowS
[SectionTable] -> ShowS
SectionTable -> String
(Int -> SectionTable -> ShowS)
-> (SectionTable -> String)
-> ([SectionTable] -> ShowS)
-> Show SectionTable
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [SectionTable] -> ShowS
$cshowList :: [SectionTable] -> ShowS
show :: SectionTable -> String
$cshow :: SectionTable -> String
showsPrec :: Int -> SectionTable -> ShowS
$cshowsPrec :: Int -> SectionTable -> ShowS
Show

instance Binary SectionTable where
  get :: Get SectionTable
get = do 
           Word64
sectionHeaderName' <- Get Word64
getWord64le
           Word32
virtualSize' <- Get Word32
getWord32le
           Word32
virtualAddress' <- Get Word32
getWord32le
           Word32
sizeOfRawData' <- Get Word32
getWord32le
           Word32
pointerToRawData' <- Get Word32
getWord32le
           Word32
pointerToRelocations' <- Get Word32
getWord32le
           Word32
pointerToLineNumbers' <- Get Word32
getWord32le
           Word16
numberOfRelocations' <- Get Word16
getWord16le
           Word16
numberOfLineNumbers' <- Get Word16
getWord16le
           Word32
secCharacteristics' <- Get Word32
getWord32le
           let header :: SectionTable
header = SectionTable :: String
-> Word32
-> Word32
-> Word32
-> Word32
-> Word32
-> Word32
-> Word16
-> Word16
-> Word32
-> SectionTable
SectionTable { sectionHeaderName :: String
sectionHeaderName=(Word64 -> String
byte64String Word64
sectionHeaderName'), virtualSize :: Word32
virtualSize=Word32
virtualSize',
                                       virtualAddress :: Word32
virtualAddress=Word32
virtualAddress', sizeOfRawData :: Word32
sizeOfRawData=Word32
sizeOfRawData',
                                       pointerToRawData :: Word32
pointerToRawData=Word32
pointerToRawData', pointerToRelocations :: Word32
pointerToRelocations=Word32
pointerToRelocations',
                                       pointerToLineNumbers :: Word32
pointerToLineNumbers=Word32
pointerToLineNumbers', numberOfRelocations :: Word16
numberOfRelocations=Word16
numberOfRelocations',
                                       numberOfLineNumbers :: Word16
numberOfLineNumbers=Word16
numberOfLineNumbers', secCharacteristics :: Word32
secCharacteristics=Word32
secCharacteristics'}
           SectionTable -> Get SectionTable
forall (m :: * -> *) a. Monad m => a -> m a
return SectionTable
header
       
  put :: SectionTable -> Put
put SectionTable
_ = String -> Put
forall a. HasCallStack => String -> a
error String
"SectionTable serialization not supported"

         


data MachineType = UNKNOWN | AM33 | AMD64 | ARM | ARMV7 | EBC | I386 | IA64 | M32R | MIPS16 | MIPSFPU | MIPSFPU16 |
                    PPC | PPCFP | R4000 | SH3 | SH3DSP | SH4 | SH5 | THUMB | WCE | INVALID deriving (Int -> MachineType -> ShowS
[MachineType] -> ShowS
MachineType -> String
(Int -> MachineType -> ShowS)
-> (MachineType -> String)
-> ([MachineType] -> ShowS)
-> Show MachineType
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [MachineType] -> ShowS
$cshowList :: [MachineType] -> ShowS
show :: MachineType -> String
$cshow :: MachineType -> String
showsPrec :: Int -> MachineType -> ShowS
$cshowsPrec :: Int -> MachineType -> ShowS
Show)


instance Binary MachineType where
  get :: Get MachineType
get = do
          Word16
x <- Get Word16
getWord16le
          MachineType -> Get MachineType
forall (m :: * -> *) a. Monad m => a -> m a
return (MachineType -> Get MachineType) -> MachineType -> Get MachineType
forall a b. (a -> b) -> a -> b
$ Word16 -> MachineType
mapMachine Word16
x
  put :: MachineType -> Put
put MachineType
_ = String -> Put
forall a. HasCallStack => String -> a
error String
"Serialization of MachineType not supported"



mapMachine :: Word16 -> MachineType
mapMachine :: Word16 -> MachineType
mapMachine Word16
w = case Word16
w of
                   Word16
0x00 -> MachineType
UNKNOWN
                   Word16
0x1d3 -> MachineType
AM33
                   Word16
0x8664 -> MachineType
AMD64
                   Word16
0x1c0 -> MachineType
ARM
                   Word16
0x1c4 -> MachineType
ARMV7
                   Word16
0xebc -> MachineType
EBC
                   Word16
0x14c -> MachineType
I386
                   Word16
0x200 -> MachineType
IA64
                   Word16
0x9041 -> MachineType
M32R
                   Word16
0x266 -> MachineType
MIPS16
                   Word16
0x366 -> MachineType
MIPSFPU
                   Word16
0x466 -> MachineType
MIPSFPU16
                   Word16
0x1f0 -> MachineType
PPC
                   Word16
0x1f1 -> MachineType
PPCFP
                   Word16
0x166 -> MachineType
R4000
                   Word16
0x1a2 -> MachineType
SH3
                   Word16
0x1a3 -> MachineType
SH3DSP
                   Word16
0x1a6 -> MachineType
SH4
                   Word16
0x1a8 -> MachineType
SH5
                   Word16
0x1c2 -> MachineType
THUMB
                   Word16
0x169 -> MachineType
WCE
                   Word16
_ -> String -> MachineType
forall a. HasCallStack => String -> a
error String
"Bad machine type."

getAStr :: Get String
getAStr :: Get String
getAStr = do
            Word8
x <- Get Word8
getWord8
            case (Word8
x Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== Word8
0x0) of
                  Bool
True  -> String -> Get String
forall (m :: * -> *) a. Monad m => a -> m a
return []
                  Bool
False -> Get String
getAStr Get String -> (String -> Get String) -> Get String
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \String
xs -> String -> Get String
forall (m :: * -> *) a. Monad m => a -> m a
return ((Int -> Char
chr (Int -> Char) -> Int -> Char
forall a b. (a -> b) -> a -> b
$ Word8 -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word8
x) Char -> ShowS
forall a. a -> [a] -> [a]
: String
xs)