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  [![GoDoc](http://godoc.org/github.com/saferwall/pe?status.svg)](https://pkg.go.dev/github.com/saferwall/pe) ![Go Version](https://img.shields.io/badge/go%20version-%3E=1.15-61CFDD.svg) [![Report Card](https://goreportcard.com/badge/github.com/saferwall/pe)](https://goreportcard.com/report/github.com/saferwall/pe) [![codecov](https://codecov.io/gh/saferwall/pe/branch/main/graph/badge.svg?token=W7WTOUZLRY)](https://codecov.io/gh/saferwall/pe) ![GitHub Workflow Status](https://img.shields.io/github/actions/workflow/status/saferwall/pe/ci.yaml?branch=main)
     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)