github.com/saferwall/pe@v1.5.2/README.md (about) 1 <a href="https://saferwall.com" target="_blank" rel="noopener noreferrer"><img align="right" width="300" src=".github/assets/logo.png" alt="Saferwall logo"></a> 2 3 # Portable Executable Parser 4 5 [](https://pkg.go.dev/github.com/saferwall/pe)  [](https://goreportcard.com/report/github.com/saferwall/pe) [](https://codecov.io/gh/saferwall/pe)  6 7 8 **pe** is a go package for parsing the [portable executable](https://docs.microsoft.com/en-us/windows/win32/debug/pe-format) file format. This package was designed with malware analysis in mind, and being resistent to PE malformations. 9 10 ## Table of content 11 12 - [Portable Executable Parser](#portable-executable-parser) 13 - [Table of content](#table-of-content) 14 - [Features](#features) 15 - [Installing](#installing) 16 - [Using the library](#using-the-library) 17 - [PE Header](#pe-header) 18 - [Rich Header](#rich-header) 19 - [Iterating over sections](#iterating-over-sections) 20 - [Roadmap](#roadmap) 21 - [Fuzz Testing](#fuzz-testing) 22 - [References](#references) 23 24 ## Features 25 26 - Works with PE32/PE32+ file format. 27 - Supports Intel x86/AMD64/ARM7ARM7 Thumb/ARM8-64/IA64/CHPE architectures. 28 - MS DOS header. 29 - Rich Header (calculate checksum and hash). 30 - NT Header (file header + optional header). 31 - COFF symbol table and string table. 32 - Sections headers + entropy calculation. 33 - Data directories 34 - Import Table + ImpHash calculation. 35 - Export Table 36 - Resource Table 37 - Exceptions Table 38 - Security Table + Authentihash calculation. 39 - Relocations Table 40 - Debug Table (CODEVIEW, POGO, VC FEATURE, REPRO, FPO, EXDLL CHARACTERISTICS debug types). 41 - TLS Table 42 - Load Config Directory (SEH, GFID, GIAT, Guard LongJumps, CHPE, Dynamic Value Reloc Table, Enclave Configuration, Volatile Metadata tables). 43 - Bound Import Table 44 - Delay Import Table 45 - COM Table (CLR Metadata Header, Metadata Table Streams) 46 - Report several anomalies 47 48 ## Installing 49 50 Using this go package is easy. First, use `go get` to install the latest version of the library. This command will install the `pedumper` executable along with the library and its dependencies: 51 52 go get -u github.com/saferwall/pe 53 54 Next, include `pe` package in your application: 55 56 ```go 57 import "github.com/saferwall/pe" 58 ``` 59 60 ## Using the library 61 62 ```go 63 package main 64 65 import ( 66 peparser "github.com/saferwall/pe" 67 ) 68 69 func main() { 70 filename := "C:\\Binaries\\notepad.exe" 71 pe, err := peparser.New(filename, &peparser.Options{}) 72 if err != nil { 73 log.Fatalf("Error while opening file: %s, reason: %v", filename, err) 74 } 75 76 err = pe.Parse() 77 if err != nil { 78 log.Fatalf("Error while parsing file: %s, reason: %v", filename, err) 79 } 80 } 81 ``` 82 83 Start by instantiating a pe object by called the `New()` method, which takes the file path to the file to be parsed and some optional options. 84 85 Afterwards, a call to the `Parse()` method will give you access to all the different part of the PE format, directly accessible to be used. Here is the definition of the struct: 86 87 ```go 88 type File struct { 89 DOSHeader ImageDOSHeader 90 RichHeader RichHeader 91 NtHeader ImageNtHeader 92 COFF COFF 93 Sections []Section 94 Imports []Import 95 Export Export 96 Debugs []DebugEntry 97 Relocations []Relocation 98 Resources ResourceDirectory 99 TLS TLSDirectory 100 LoadConfig LoadConfig 101 Exceptions []Exception 102 Certificates Certificate 103 DelayImports []DelayImport 104 BoundImports []BoundImportDescriptorData 105 GlobalPtr uint32 106 CLR CLRData 107 IAT []IATEntry 108 Header []byte 109 data mmap.MMap 110 closer io.Closer 111 Is64 bool 112 Is32 bool 113 Anomalies []string 114 size uint32 115 f *os.File 116 opts *Options 117 } 118 ``` 119 120 ### PE Header 121 122 As mentionned before, all members of the struct are directly (no getters) accessible, additionally, the fields types has been preserved as the spec defines them, that means if you need to show the prettified version of an `int` type, you have to call the corresponding helper function. 123 124 ```go 125 fmt.Printf("Magic is: 0x%x\n", pe.DosHeader.Magic) 126 fmt.Printf("Signature is: 0x%x\n", pe.NtHeader.Signature) 127 fmt.Printf("Machine is: 0x%x, Meaning: %s\n", pe.NtHeader.FileHeader.Machine, pe.PrettyMachineType()) 128 ``` 129 130 Output: 131 ``` 132 Magic is: 0x5a4d 133 Signature is: 0x4550 134 Machine is: 0x8664, Meaning: x64 135 ``` 136 137 ### Rich Header 138 139 Example: 140 ```go 141 richHeader, _ := json.Marshal(pe.RichHeader) 142 fmt.Print(prettyPrint(richHeader)) 143 ``` 144 145 Output: 146 ```json 147 { 148 "XorKey": 2796214951, 149 "CompIDs": [ 150 { 151 "MinorCV": 27412, 152 "ProdID": 257, 153 "Count": 4, 154 "Unmasked": 16870164 155 }, 156 { 157 "MinorCV": 30729, 158 "ProdID": 147, 159 "Count": 193, 160 "Unmasked": 9664521 161 }, 162 { 163 "MinorCV": 0, 164 "ProdID": 1, 165 "Count": 1325, 166 "Unmasked": 65536 167 }, 168 { 169 "MinorCV": 27412, 170 "ProdID": 260, 171 "Count": 9, 172 "Unmasked": 17066772 173 }, 174 { 175 "MinorCV": 27412, 176 "ProdID": 259, 177 "Count": 3, 178 "Unmasked": 17001236 179 }, 180 { 181 "MinorCV": 27412, 182 "ProdID": 256, 183 "Count": 1, 184 "Unmasked": 16804628 185 }, 186 { 187 "MinorCV": 27412, 188 "ProdID": 269, 189 "Count": 209, 190 "Unmasked": 17656596 191 }, 192 { 193 "MinorCV": 27412, 194 "ProdID": 255, 195 "Count": 1, 196 "Unmasked": 16739092 197 }, 198 { 199 "MinorCV": 27412, 200 "ProdID": 258, 201 "Count": 1, 202 "Unmasked": 16935700 203 } 204 ], 205 "DansOffset": 128, 206 "Raw": "47vE9afaqqan2qqmp9qqprOxq6ej2qqmrqI5pmbaqqan2qumit+qprOxrqeu2qqms7Gpp6TaqqazsaqnptqqprOxp6d22qqms7FVpqbaqqazsainptqqplJpY2in2qqm" 207 } 208 209 ``` 210 211 ### Iterating over sections 212 213 ```go 214 for _, sec := range pe.Sections { 215 fmt.Printf("Section Name : %s\n", sec.NameString()) 216 fmt.Printf("Section VirtualSize : %x\n", sec.Header.VirtualSize) 217 fmt.Printf("Section Flags : %x, Meaning: %v\n\n", 218 sec.Header.Characteristics, sec.PrettySectionFlags()) 219 } 220 ``` 221 222 Output: 223 224 ``` 225 Section Name : .text 226 Section VirtualSize : 2ea58 227 Section Flags : 60500060, Meaning: [Align8Bytes Readable Align16Bytes Executable Contains Code Initialized Data Align1Bytes] 228 229 Section Name : .data 230 Section VirtualSize : 58 231 Section Flags : c0500040, Meaning: [Readable Initialized Data Writable Align1Bytes Align16Bytes Align8Bytes] 232 233 Section Name : .rdata 234 Section VirtualSize : 18d0 235 Section Flags : 40600040, Meaning: [Align2Bytes Align8Bytes Readable Initialized Data Align32Bytes] 236 237 ... 238 ``` 239 240 ## Roadmap 241 242 - imports MS-styled names demangling 243 - PE: VB5 and VB6 typical structures: project info, DLLCall-imports, referenced modules, object table 244 245 ## Fuzz Testing 246 247 To validate the parser we use the [go-fuzz](https://github.com/dvyukov/go-fuzz) and a corpus of known malformed and tricky PE files from [corkami](https://github.com/corkami/pocs/tree/master/PE). 248 249 ## Projects Using This Library 250 251 <a href="https://www.fibratus.io" > 252 <img src="https://github.com/rabbitstack/fibratus/raw/master/logo.png" alt="Fibratus" width="50px"> 253 </a> 254 255 [Fibratus](https://github.com/rabbitstack/fibratus) A modern tool for Windows kernel exploration and tracing with a focus on security. 256 257 ## References 258 259 - [Peering Inside the PE: A Tour of the Win32 Portable Executable File Format by Matt Pietrek](http://bytepointer.com/resources/pietrek_peering_inside_pe.htm) 260 - [An In-Depth Look into the Win32 Portable Executable File Format - Part 1 by Matt Pietrek](http://www.delphibasics.info/home/delphibasicsarticles/anin-depthlookintothewin32portableexecutablefileformat-part1) 261 - [An In-Depth Look into the Win32 Portable Executable File Format - Part 2 by Matt Pietrek](http://www.delphibasics.info/home/delphibasicsarticles/anin-depthlookintothewin32portableexecutablefileformat-part2) 262 - [Portable Executable File Format](https://blog.kowalczyk.info/articles/pefileformat.html) 263 - [PE Format MSDN spec](https://docs.microsoft.com/en-us/windows/win32/debug/pe-format) 264 - [DotNET format](https://www.ntcore.com/files/dotnetformat.htm) 265 - [BlackHat 2011 - CONSTANT INSECURITY: (PECOFF) Portable Executable FIle Format](https://www.youtube.com/watch?v=uoQL3CE24ls)