Created
February 1, 2015 10:28
-
-
Save josephspurrier/120d6f1c87fde4d9769e to your computer and use it in GitHub Desktop.
Golang - Output PE Info
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Copyright 2015 Joseph Spurrier | |
// Author: Joseph Spurrier (http://josephspurrier.com) | |
// License: http://www.apache.org/licenses/LICENSE-2.0.html | |
package main | |
import ( | |
"debug/pe" | |
"flag" | |
"fmt" | |
"os" | |
"time" | |
) | |
var ( | |
Version string | |
BuildDate string | |
) | |
func init() { | |
flag.Usage = func() { | |
fmt.Fprintf(os.Stderr, "Version: %s\n", Version) | |
fmt.Fprintf(os.Stderr, "Build Date: %s\n", BuildDate) | |
fmt.Fprintf(os.Stderr, "Usage of %s:\n", os.Args[0]) | |
flag.PrintDefaults() | |
} | |
flag.Parse() | |
} | |
func printExtra(extra ...interface{}) { | |
if extra != nil { | |
for _, v := range extra { | |
fmt.Print(" | ", v) | |
} | |
} | |
fmt.Println() | |
} | |
func printHexAndDec(name string, value interface{}, extra ...interface{}) { | |
fmt.Printf(name+" %0#8x | %d", value, value) | |
printExtra(extra...) | |
} | |
func printHexAndString(name string, value interface{}, extra ...interface{}) { | |
fmt.Printf(name+" %0#8x | %v", value, value) | |
printExtra(extra...) | |
} | |
func printHexAndTime(name string, value interface{}, extra ...interface{}) { | |
fmt.Printf(name+" %0#8x | %s", value, time.Unix(int64(value.(uint32)), 0)) | |
printExtra(extra...) | |
} | |
func getMachine(i uint16) string { | |
// http://msdn.microsoft.com/en-us/library/windows/desktop/ms680313%28v=vs.85%29.aspx | |
switch i { | |
case 0x8664: | |
return "x64" | |
case 0x0200: | |
return "Intel Itanium" | |
case 0x014c: | |
return "x86" | |
default: | |
return "unknown: " + fmt.Sprintf("%0#8x", i) | |
} | |
} | |
type Bitmask uint16 | |
// BitValue is a value and a description | |
type BitValue struct { | |
value Bitmask | |
description string | |
} | |
// Bitwise returns a string array of all set bits | |
func (value Bitmask) ListDescriptions(values []BitValue) []string { | |
list := make([]string, 0) | |
currentValue := value | |
for currentValue > 0 { | |
for _, bv := range values { | |
if currentValue&bv.value != 0 { | |
currentValue ^= bv.value | |
list = append(list, bv.description) | |
} | |
} | |
} | |
return list | |
} | |
// Bitwise returns a string array of all set bits | |
func (value Bitmask) ListValues(values []BitValue) []Bitmask { | |
list := make([]Bitmask, 0) | |
currentValue := value | |
for currentValue > 0 { | |
for _, bv := range values { | |
if currentValue&bv.value != 0 { | |
currentValue ^= bv.value | |
list = append(list, bv.value) | |
} | |
} | |
} | |
return list | |
} | |
// IsSet returns true if a bit is set | |
func (value Bitmask) IsSet(test Bitmask) bool { | |
if value&test != 0 { | |
return true | |
} | |
return false | |
} | |
func main() { | |
fmt.Println("Microsoft Windows Portable Executable") | |
fmt.Println("File: starttest.exe\n") | |
f, _ := pe.Open("starttest.exe") | |
defer f.Close() | |
charValues := []BitValue{ | |
{0x8000, "IMAGE_FILE_BYTES_REVERSED_HI"}, | |
{0x4000, "IMAGE_FILE_UP_SYSTEM_ONLY"}, | |
{0x2000, "IMAGE_FILE_DLL"}, | |
{0x800, "IMAGE_FILE_NET_RUN_FROM_SWAP"}, | |
{0x400, "IMAGE_FILE_REMOVABLE_RUN_FROM_SWAP"}, | |
{0x200, "IMAGE_FILE_DEBUG_STRIPPED"}, | |
{0x100, "IMAGE_FILE_32BIT_MACHINE"}, | |
{0x80, "IMAGE_FILE_BYTES_REVERSED_LO"}, | |
{0x20, "IMAGE_FILE_LARGE_ADDRESS_AWARE"}, | |
{0x10, "IMAGE_FILE_AGGRESIVE_WS_TRIM"}, | |
{0x8, "IMAGE_FILE_LOCAL_SYMS_STRIPPED"}, | |
{0x4, "IMAGE_FILE_LINE_NUMS_STRIPPED"}, | |
{0x2, "IMAGE_FILE_EXECUTABLE_IMAGE"}, | |
{0x1, "IMAGE_FILE_RELOCS_STRIPPED"}, | |
} | |
// Use this table for Characteristics | |
// http://msdn.microsoft.com/en-us/library/windows/desktop/ms680313%28v=vs.85%29.aspx | |
printHexAndDec("Header Characteristics: ", f.FileHeader.Characteristics, Bitmask(f.FileHeader.Characteristics).ListDescriptions(charValues)) | |
printHexAndDec("Header Machine: ", f.FileHeader.Machine, getMachine(f.FileHeader.Machine)) | |
printHexAndDec("Header Number of Sections: ", f.FileHeader.NumberOfSections) | |
printHexAndDec("Header Number of Symbols: ", f.FileHeader.NumberOfSymbols) | |
printHexAndDec("Header Pointer to Symbol Table:", f.FileHeader.PointerToSymbolTable) | |
printHexAndDec("Header Size of Optional Header:", f.FileHeader.SizeOfOptionalHeader) | |
printHexAndTime("Header Timestamp: ", f.FileHeader.TimeDateStamp) | |
fmt.Println() | |
fmt.Println("Sections:\n") | |
for _, s := range f.Sections { | |
fmt.Printf("%s\n", s.Name) | |
fmt.Printf("%0#8x %s\n", s.VirtualSize, "Virtual Size") | |
fmt.Printf("%0#8x %s\n", s.VirtualAddress, "Virtual Address") | |
fmt.Printf("%0#8x %s\n", s.Size, "Size") | |
fmt.Printf("%0#8x %s\n", s.Offset, "Offset") | |
fmt.Printf("%0#8x %s\n", s.PointerToRelocations, "Pointer To Relocations") | |
fmt.Printf("%0#8x %s\n", s.PointerToLineNumbers, "Pointer to Line Numbers") | |
fmt.Printf("%0#8x %s\n", s.NumberOfRelocations, "Number of Relocations") | |
fmt.Printf("%0#8x %s\n", s.NumberOfLineNumbers, "Number of Line Numbers") | |
fmt.Printf("%0#8x %s\n", s.Characteristics, "Characteristics") | |
fmt.Println() | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment