
PE es un paquete GO para analizar el formato de archivo ejecutable portátil. Este paquete fue diseñado teniendo en cuenta el análisis de malware y ser resistente a las malformaciones de PE.
Usar este paquete Go es fácil. Primero, use go get a instalar la última versión de la biblioteca. Este comando instalará el ejecutable pedumper junto con la biblioteca y sus dependencias:
go get -u github.com/saferwall/pe
A continuación, incluya el paquete pe en su aplicación:
import "github.com/saferwall/pe" package main
import (
peparser "github.com/saferwall/pe"
)
func main () {
filename := "C: \ Binaries \ notepad.exe"
pe , err := peparser . New ( filename , & peparser. Options {})
if err != nil {
log . Fatalf ( "Error while opening file: %s, reason: %v" , filename , err )
}
err = pe . Parse ()
if err != nil {
log . Fatalf ( "Error while parsing file: %s, reason: %v" , filename , err )
}
} Comience instanciando un objeto PE llamado el método New() , que toma la ruta del archivo al archivo para analizar y algunas opciones opcionales.
Posteriormente, una llamada al método Parse() le dará acceso a todas las diferentes partes del formato PE, directamente accesible para ser utilizada. Aquí está la definición de la estructura:
type File struct {
DOSHeader ImageDOSHeader `json:"dos_header,omitempty"`
RichHeader RichHeader `json:"rich_header,omitempty"`
NtHeader ImageNtHeader `json:"nt_header,omitempty"`
COFF COFF `json:"coff,omitempty"`
Sections [] Section `json:"sections,omitempty"`
Imports [] Import `json:"imports,omitempty"`
Export Export `json:"export,omitempty"`
Debugs [] DebugEntry `json:"debugs,omitempty"`
Relocations [] Relocation `json:"relocations,omitempty"`
Resources ResourceDirectory `json:"resources,omitempty"`
TLS TLSDirectory `json:"tls,omitempty"`
LoadConfig LoadConfig `json:"load_config,omitempty"`
Exceptions [] Exception `json:"exceptions,omitempty"`
Certificates CertificateSection `json:"certificates,omitempty"`
DelayImports [] DelayImport `json:"delay_imports,omitempty"`
BoundImports [] BoundImportDescriptorData `json:"bound_imports,omitempty"`
GlobalPtr uint32 `json:"global_ptr,omitempty"`
CLR CLRData `json:"clr,omitempty"`
IAT [] IATEntry `json:"iat,omitempty"`
Anomalies [] string `json:"anomalies,omitempty"`
Header [] byte
data mmap. MMap
FileInfo
size uint32
OverlayOffset int64
f * os. File
opts * Options
logger * log. Helper
} Como se mencionó anteriormente, todos los miembros de la estructura son directamente accesibles (sin Getters), además, los tipos de campos se han preservado como la especificación los define, eso significa que si necesita mostrar la versión pretificada de un tipo int , debe llamar a la función de ayuda correspondiente.
fmt . Printf ( "Magic is: 0x%x n " , pe . DOSHeader . Magic )
fmt . Printf ( "Signature is: 0x%x n " , pe . NtHeader . Signature )
fmt . Printf ( "Machine is: 0x%x, Meaning: %s n " , pe . NtHeader . FileHeader . Machine , pe . NtHeader . FileHeader . Machine . String ())Producción:
Magic is: 0x5a4d
Signature is: 0x4550
Machine is: 0x8664, Meaning: x64
Ejemplo:
richHeader , _ := json . Marshal ( pe . RichHeader )
fmt . Print ( prettyPrint ( richHeader ))Producción:
{
"XorKey" : 2796214951 ,
"CompIDs" : [
{
"MinorCV" : 27412 ,
"ProdID" : 257 ,
"Count" : 4 ,
"Unmasked" : 16870164
},
{
"MinorCV" : 30729 ,
"ProdID" : 147 ,
"Count" : 193 ,
"Unmasked" : 9664521
},
{
"MinorCV" : 0 ,
"ProdID" : 1 ,
"Count" : 1325 ,
"Unmasked" : 65536
},
{
"MinorCV" : 27412 ,
"ProdID" : 260 ,
"Count" : 9 ,
"Unmasked" : 17066772
},
{
"MinorCV" : 27412 ,
"ProdID" : 259 ,
"Count" : 3 ,
"Unmasked" : 17001236
},
{
"MinorCV" : 27412 ,
"ProdID" : 256 ,
"Count" : 1 ,
"Unmasked" : 16804628
},
{
"MinorCV" : 27412 ,
"ProdID" : 269 ,
"Count" : 209 ,
"Unmasked" : 17656596
},
{
"MinorCV" : 27412 ,
"ProdID" : 255 ,
"Count" : 1 ,
"Unmasked" : 16739092
},
{
"MinorCV" : 27412 ,
"ProdID" : 258 ,
"Count" : 1 ,
"Unmasked" : 16935700
}
],
"DansOffset" : 128 ,
"Raw" : " 47vE9afaqqan2qqmp9qqprOxq6ej2qqmrqI5pmbaqqan2qumit+qprOxrqeu2qqms7Gpp6TaqqazsaqnptqqprOxp6d22qqms7FVpqbaqqazsainptqqplJpY2in2qqm "
}
for _ , sec := range pe . Sections {
fmt . Printf ( "Section Name : %s n " , sec . NameString ())
fmt . Printf ( "Section VirtualSize : %x n " , sec . Header . VirtualSize )
fmt . Printf ( "Section Flags : %x, Meaning: %v n n " ,
sec . Header . Characteristics , sec . PrettySectionFlags ())
}Producción:
Section Name : .text
Section VirtualSize : 2ea58
Section Flags : 60500060, Meaning: [Align8Bytes Readable Align16Bytes Executable Contains Code Initialized Data Align1Bytes]
Section Name : .data
Section VirtualSize : 58
Section Flags : c0500040, Meaning: [Readable Initialized Data Writable Align1Bytes Align16Bytes Align8Bytes]
Section Name : .rdata
Section VirtualSize : 18d0
Section Flags : 40600040, Meaning: [Align2Bytes Align8Bytes Readable Initialized Data Align32Bytes]
...
Para validar el analizador, usamos el Fuzz Go y un corpus de archivos PE malformados y complicados de Corkami.

Fibratus Una herramienta moderna para la exploración y el rastreo del núcleo de Windows con un enfoque en la seguridad.