1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143
| package main
import ( "debug/pe" "encoding/binary" "fmt" "io" "log" "os" )
func main() { f, err := os.Open("G:\\Windows\\WinSxS\\amd64_microsoft-windows-calc_31bf3856ad364e35_10.0.18362.1_none_7c1b713697f466dd\\calc.exe") check(err) pefile, err := pe.NewFile(f) check(err) defer f.Close() defer pefile.Close()
dosHeader := make([]byte, 96) sizeOffset := make([]byte, 4)
_, err = f.Read(dosHeader) check(err) fmt.Println("[-----DOS Header / Stub----- header和stub解析]") fmt.Printf("[+] Magic Value: %s%s\n", string(dosHeader[0]), string(dosHeader[1]))
pe_sig_offset := int64(binary.LittleEndian.Uint32(dosHeader[0x3c:])) f.ReadAt(sizeOffset, pe_sig_offset)
fmt.Println("[-----Signature Header-----]") fmt.Printf("[+] LFANEW Value: %s\n", string(sizeOffset))
sr := io.NewSectionReader(f, 0, 1<<63-1) _, err = sr.Seek(pe_sig_offset+4, os.SEEK_SET) check(err) binary.Read(sr, binary.LittleEndian, &pefile.FileHeader)
var sizeofOptionalHeader32 = uint16(binary.Size(pe.OptionalHeader32{})) var sizeofOptionalHeader64 = uint16(binary.Size(pe.OptionalHeader64{})) var oh32 pe.OptionalHeader32 var oh64 pe.OptionalHeader64
switch pefile.FileHeader.SizeOfOptionalHeader { case sizeofOptionalHeader32: binary.Read(sr, binary.LittleEndian, &oh32) case sizeofOptionalHeader64: binary.Read(sr, binary.LittleEndian, &oh64) } fmt.Println("[-----COFF File Header-----]") fmt.Printf("[+] Machine Architecture: %#x\n", pefile.FileHeader.Machine) fmt.Printf("[+] Number of Sections: %#x\n", pefile.FileHeader.NumberOfSections) fmt.Printf("[+] Size of Optional Header: %#x\n", pefile.FileHeader.SizeOfOptionalHeader) fmt.Println("[-----Section Offsets-----]") fmt.Printf("[+] Number of Sections Field Offset: %#x\n", pe_sig_offset+6) fmt.Printf("[+] Section Table Offset: %#x\n", pe_sig_offset+0xF8) fmt.Println("[-----Optional Header-----]")
fmt.Printf("[+] Entry Point: %#x\n", oh32.AddressOfEntryPoint) fmt.Printf("[+] ImageBase: %#x\n", oh32.ImageBase)
fmt.Printf("[+] Size of Image: %#x\n", oh32.SizeOfImage) fmt.Printf("[+] Sections Alignment: %#x\n", oh32.SectionAlignment) fmt.Printf("[+] File Alignment: %#x\n", oh32.FileAlignment) fmt.Printf("[+] Characteristics: %#x\n", pefile.FileHeader.Characteristics) fmt.Printf("[+] Size of Headers: %#x\n", oh32.SizeOfHeaders) fmt.Printf("[+] Checksum: %#x\n", oh32.CheckSum) fmt.Printf("[+] Machine: %#x\n", pefile.FileHeader.Machine) fmt.Printf("[+] Subsystem: %#x\n", oh32.Subsystem) fmt.Printf("[+] DLLCharacteristics: %#x\n", oh32.DllCharacteristics)
fmt.Println("[-----Data Directory----- 数据目录解析,可选头的最后128字节]") var winnt_datadirs = []string{ "IMAGE_DIRECTORY_ENTRY_EXPORT", "IMAGE_DIRECTORY_ENTRY_IMPORT", "IMAGE_DIRECTORY_ENTRY_RESOURCE", "IMAGE_DIRECTORY_ENTRY_EXCEPTION", "IMAGE_DIRECTORY_ENTRY_SECURITY", "IMAGE_DIRECTORY_ENTRY_BASERELOC", "IMAGE_DIRECTORY_ENTRY_DEBUG", "IMAGE_DIRECTORY_ENTRY_COPYRIGHT", "IMAGE_DIRECTORY_ENTRY_GLOBALPTR", "IMAGE_DIRECTORY_ENTRY_TLS", "IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG", "IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT", "IMAGE_DIRECTORY_ENTRY_IAT", "IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT", "IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR", "IMAGE_NUMBEROF_DIRECTORY_ENTRIES", } for idx, directory := range oh32.DataDirectory { fmt.Printf("[!] Data Directory: %s\n", winnt_datadirs[idx]) fmt.Printf("[+] Image Virtual Address: %#x\n", directory.VirtualAddress) fmt.Printf("[+] Image Size: %#x\n", directory.Size) }
fmt.Println("[-----Section Table----- 解析分区表]") for _, section := range pefile.Sections { fmt.Println("[+] --------------------") fmt.Printf("[+] Section Name: %s\n", section.Name) fmt.Printf("[+] Section Characteristics: %#x\n", section.Characteristics) fmt.Printf("[+] Section Virtual Size: %#x\n", section.VirtualSize) fmt.Printf("[+] Section Virtual Offset: %#x\n", section.VirtualAddress) fmt.Printf("[+] Section Raw Size: %#x\n", section.Size) fmt.Printf("[+] Section Raw Offset to Data: %#x\n", section.Offset) fmt.Printf("[+] Section Append Offset (Next Section): %#x\n", section.Offset+section.Size) }
}
func check(e error) { if e != nil { log.Fatal(e) } }
|