github.com/saferwall/pe@v1.5.2/ntheader.go (about) 1 // Copyright 2018 Saferwall. All rights reserved. 2 // Use of this source code is governed by Apache v2 license 3 // license that can be found in the LICENSE file. 4 5 package pe 6 7 import ( 8 "encoding/binary" 9 ) 10 11 // ImageFileHeaderMachineType represents the type of the image file header `Machine“ field. 12 type ImageFileHeaderMachineType uint16 13 14 // ImageFileHeaderCharacteristicsType represents the type of the image file header 15 // `Characteristics` field. 16 type ImageFileHeaderCharacteristicsType uint16 17 18 // ImageOptionalHeaderSubsystemType represents the type of the optional header `Subsystem field. 19 type ImageOptionalHeaderSubsystemType uint16 20 21 // ImageOptionalHeaderDllCharacteristicsType represents the type of the optional header `DllCharacteristics field. 22 type ImageOptionalHeaderDllCharacteristicsType uint16 23 24 // ImageNtHeader represents the PE header and is the general term for a structure 25 // named IMAGE_NT_HEADERS. 26 type ImageNtHeader struct { 27 // Signature is a DWORD containing the value 50h, 45h, 00h, 00h. 28 Signature uint32 `json:"signature"` 29 30 // IMAGE_NT_HEADERS provides a standard COFF header. It is located 31 // immediately after the PE signature. The COFF header provides the most 32 // general characteristics of a PE/COFF file, applicable to both object and 33 // executable files. It is represented with IMAGE_FILE_HEADER structure. 34 FileHeader ImageFileHeader `json:"file_header"` 35 36 // OptionalHeader is of type *OptionalHeader32 or *OptionalHeader64. 37 OptionalHeader interface{} `json:"optional_header"` 38 } 39 40 // ImageFileHeader contains infos about the physical layout and properties of the 41 // file. 42 type ImageFileHeader struct { 43 // The number that identifies the type of target machine. 44 Machine ImageFileHeaderMachineType `json:"machine"` 45 46 // The number of sections. This indicates the size of the section table, 47 // which immediately follows the headers. 48 NumberOfSections uint16 `json:"number_of_sections"` 49 50 // // The low 32 bits of the number of seconds since 00:00 January 1, 1970 51 // (a C run-time time_t value), that indicates when the file was created. 52 TimeDateStamp uint32 `json:"time_date_stamp"` 53 54 // // The file offset of the COFF symbol table, or zero if no COFF symbol 55 // table is present. This value should be zero for an image because COFF 56 // debugging information is deprecated. 57 PointerToSymbolTable uint32 `json:"pointer_to_symbol_table"` 58 59 // The number of entries in the symbol table. This data can be used to 60 // locate the string table, which immediately follows the symbol table. 61 // This value should be zero for an image because COFF debugging information 62 // is deprecated. 63 NumberOfSymbols uint32 `json:"number_of_symbols"` 64 65 // The size of the optional header, which is required for executable files 66 // but not for object files. This value should be zero for an object file. 67 SizeOfOptionalHeader uint16 `json:"size_of_optional_header"` 68 69 // The flags that indicate the attributes of the file. 70 Characteristics ImageFileHeaderCharacteristicsType `json:"characteristics"` 71 } 72 73 // ImageOptionalHeader32 represents the PE32 format structure of the optional header. 74 // PE32 contains this additional field, which is absent in PE32+. 75 type ImageOptionalHeader32 struct { 76 77 // The unsigned integer that identifies the state of the image file. 78 // The most common number is 0x10B, which identifies it as a normal 79 // executable file. 0x107 identifies it as a ROM image, and 0x20B identifies 80 // it as a PE32+ executable. 81 Magic uint16 `json:"magic"` 82 83 // Linker major version number. The VC++ linker sets this field to current 84 // version of Visual Studio. 85 MajorLinkerVersion uint8 `json:"major_linker_version"` 86 87 // The linker minor version number. 88 MinorLinkerVersion uint8 `json:"minor_linker_version"` 89 90 // The size of the code (text) section, or the sum of all code sections 91 // if there are multiple sections. 92 SizeOfCode uint32 `json:"size_of_code"` 93 94 // The size of the initialized data section (held in the field SizeOfRawData 95 // of the respective section header), or the sum of all such sections if 96 // there are multiple data sections. 97 SizeOfInitializedData uint32 `json:"size_of_initialized_data"` 98 99 // The size of the uninitialized data section (BSS), or the sum of all 100 // such sections if there are multiple BSS sections. This data is not part 101 // of the disk file and does not have specific values, but the OS loader 102 // commits memory space for this data when the file is loaded. 103 SizeOfUninitializedData uint32 `json:"size_of_uninitialized_data"` 104 105 // The address of the entry point relative to the image base when the 106 // executable file is loaded into memory. For program images, this is the 107 // starting address. For device drivers, this is the address of the 108 // initialization function. An entry point is optional for DLLs. When no 109 // entry point is present, this field must be zero. For managed PE files, 110 // this value always points to the common language runtime invocation stub. 111 AddressOfEntryPoint uint32 `json:"address_of_entrypoint"` 112 113 // The address that is relative to the image base of the beginning-of-code 114 // section when it is loaded into memory. 115 BaseOfCode uint32 `json:"base_of_code"` 116 117 // The address that is relative to the image base of the beginning-of-data 118 // section when it is loaded into memory. This entry doesn’t exist in the 119 // 64-bit Optional header. 120 BaseOfData uint32 `json:"base_of_data"` 121 122 // The preferred address of the first byte of image when loaded into memory; 123 // must be a multiple of 64 K. The default for DLLs is 0x10000000. The 124 // default for Windows CE EXEs is 0x00010000. The default for Windows NT, 125 // Windows 2000, Windows XP, Windows 95, Windows 98, and Windows Me is 126 // 0x00400000. 127 ImageBase uint32 `json:"image_base"` 128 129 // The alignment (in bytes) of sections when they are loaded into memory. 130 // It must be greater than or equal to FileAlignment. The default is the 131 // page size for the architecture. 132 SectionAlignment uint32 `json:"section_alignment"` 133 134 // The alignment factor (in bytes) that is used to align the raw data of 135 // sections in the image file. The value should be a power of 2 between 512 136 // and 64 K, inclusive. The default is 512. If the SectionAlignment is less 137 // than the architecture's page size, then FileAlignment must match 138 // SectionAlignment. 139 FileAlignment uint32 `json:"file_alignment"` 140 141 // The major version number of the required operating system. 142 MajorOperatingSystemVersion uint16 `json:"major_os_version"` 143 144 // The minor version number of the required operating system. 145 MinorOperatingSystemVersion uint16 `json:"minor_os_version"` 146 147 // The major version number of the image. 148 MajorImageVersion uint16 `json:"major_image_version"` 149 150 // The minor version number of the image. 151 MinorImageVersion uint16 `json:"minor_image_version"` 152 153 // The major version number of the subsystem. 154 MajorSubsystemVersion uint16 `json:"major_subsystem_version"` 155 156 // The minor version number of the subsystem. 157 MinorSubsystemVersion uint16 `json:"minor_subsystem_version"` 158 159 // Reserved, must be zero. 160 Win32VersionValue uint32 `json:"win32_version_value"` 161 162 // The size (in bytes) of the image, including all headers, as the image 163 // is loaded in memory. It must be a multiple of SectionAlignment. 164 SizeOfImage uint32 `json:"size_of_image"` 165 166 // The combined size of an MS-DOS stub, PE header, and section headers 167 // rounded up to a multiple of FileAlignment. 168 SizeOfHeaders uint32 `json:"size_of_headers"` 169 170 // The image file checksum. The algorithm for computing the checksum is 171 // incorporated into IMAGHELP.DLL. The following are checked for validation 172 // at load time: all drivers, any DLL loaded at boot time, and any DLL 173 // that is loaded into a critical Windows process. 174 CheckSum uint32 `json:"checksum"` 175 176 // The subsystem that is required to run this image. 177 Subsystem ImageOptionalHeaderSubsystemType `json:"subsystem"` 178 179 // For more information, see DLL Characteristics later in this specification. 180 DllCharacteristics ImageOptionalHeaderDllCharacteristicsType `json:"dll_characteristics"` 181 182 // Size of virtual memory to reserve for the initial thread’s stack. Only 183 // the SizeOfStackCommit field is committed; the rest is available in 184 // one-page increments. The default is 1MB for 32-bit images and 4MB for 185 // 64-bit images. 186 SizeOfStackReserve uint32 `json:"size_of_stack_reserve"` 187 188 // Size of virtual memory initially committed for the initial thread’s 189 // stack. The default is one page (4KB) for 32-bit images and 16KB for 190 // 64-bit images. 191 SizeOfStackCommit uint32 `json:"size_of_stack_commit"` 192 193 // size of the local heap space to reserve. Only SizeOfHeapCommit is 194 // committed; the rest is made available one page at a time until the 195 // reserve size is reached. The default is 1MB for both 32-bit and 64-bit 196 // images. 197 SizeOfHeapReserve uint32 `json:"size_of_heap_reserve"` 198 199 // Size of virtual memory initially committed for the process heap. The 200 // default is 4KB (one operating system memory page) for 32-bit images and 201 // 16KB for 64-bit images. 202 SizeOfHeapCommit uint32 `json:"size_of_heap_commit"` 203 204 // Reserved, must be zero. 205 LoaderFlags uint32 `json:"loader_flags"` 206 207 // Number of entries in the DataDirectory array; at least 16. Although it 208 // is theoretically possible to emit more than 16 data directories, all 209 // existing managed compilers emit exactly 16 data directories, with the 210 // 16th (last) data directory never used (reserved). 211 NumberOfRvaAndSizes uint32 `json:"number_of_rva_and_sizes"` 212 213 // An array of 16 IMAGE_DATA_DIRECTORY structures. 214 DataDirectory [16]DataDirectory `json:"data_directories"` 215 } 216 217 // ImageOptionalHeader64 represents the PE32+ format structure of the optional header. 218 type ImageOptionalHeader64 struct { 219 // The unsigned integer that identifies the state of the image file. 220 // The most common number is 0x10B, which identifies it as a normal 221 // executable file. 0x107 identifies it as a ROM image, and 0x20B identifies 222 // it as a PE32+ executable. 223 Magic uint16 `json:"magic"` 224 225 // Linker major version number. The VC++ linker sets this field to current 226 // version of Visual Studio. 227 MajorLinkerVersion uint8 `json:"major_linker_version"` 228 229 // The linker minor version number. 230 MinorLinkerVersion uint8 `json:"minor_linker_version"` 231 232 // The size of the code (text) section, or the sum of all code sections 233 // if there are multiple sections. 234 SizeOfCode uint32 `json:"size_of_code"` 235 236 // The size of the initialized data section (held in the field SizeOfRawData 237 // of the respective section header), or the sum of all such sections if 238 // there are multiple data sections. 239 SizeOfInitializedData uint32 `json:"size_of_initialized_data"` 240 241 // The size of the uninitialized data section (BSS), or the sum of all 242 // such sections if there are multiple BSS sections. This data is not part 243 // of the disk file and does not have specific values, but the OS loader 244 // commits memory space for this data when the file is loaded. 245 SizeOfUninitializedData uint32 `json:"size_of_uninitialized_data"` 246 247 // The address of the entry point relative to the image base when the 248 // executable file is loaded into memory. For program images, this is the 249 // starting address. For device drivers, this is the address of the 250 // initialization function. An entry point is optional for DLLs. When no 251 // entry point is present, this field must be zero. For managed PE files, 252 // this value always points to the common language runtime invocation stub. 253 AddressOfEntryPoint uint32 `json:"address_of_entrypoint"` 254 255 // The address that is relative to the image base of the beginning-of-code 256 // section when it is loaded into memory. 257 BaseOfCode uint32 `json:"base_of_code"` 258 259 // In PE+, ImageBase is 8 bytes size. 260 ImageBase uint64 `json:"image_base"` 261 262 // The alignment (in bytes) of sections when they are loaded into memory. 263 // It must be greater than or equal to FileAlignment. The default is the 264 // page size for the architecture. 265 SectionAlignment uint32 `json:"section_alignment"` 266 267 // The alignment factor (in bytes) that is used to align the raw data of 268 // sections in the image file. The value should be a power of 2 between 512 269 // and 64 K, inclusive. The default is 512. If the SectionAlignment is less 270 // than the architecture's page size, then FileAlignment must match SectionAlignment. 271 FileAlignment uint32 `json:"file_alignment"` 272 273 // The major version number of the required operating system. 274 MajorOperatingSystemVersion uint16 `json:"major_os_version"` 275 276 // The minor version number of the required operating system. 277 MinorOperatingSystemVersion uint16 `json:"minor_os_version"` 278 279 // The major version number of the image. 280 MajorImageVersion uint16 `json:"major_image_version"` 281 282 // The minor version number of the image. 283 MinorImageVersion uint16 `json:"minor_image_version"` 284 285 // The major version number of the subsystem. 286 MajorSubsystemVersion uint16 `json:"major_subsystem_version"` 287 288 // The minor version number of the subsystem. 289 MinorSubsystemVersion uint16 `json:"minor_subsystem_version"` 290 291 // Reserved, must be zero. 292 Win32VersionValue uint32 `json:"win32_version_value"` 293 294 // The size (in bytes) of the image, including all headers, as the image 295 // is loaded in memory. It must be a multiple of SectionAlignment. 296 SizeOfImage uint32 `json:"size_of_image"` 297 298 // The combined size of an MS-DOS stub, PE header, and section headers 299 // rounded up to a multiple of FileAlignment. 300 SizeOfHeaders uint32 `json:"size_of_headers"` 301 302 // The image file checksum. The algorithm for computing the checksum is 303 // incorporated into IMAGHELP.DLL. The following are checked for validation 304 // at load time: all drivers, any DLL loaded at boot time, and any DLL 305 // that is loaded into a critical Windows process. 306 CheckSum uint32 `json:"checksum"` 307 308 // The subsystem that is required to run this image. 309 Subsystem ImageOptionalHeaderSubsystemType `json:"subsystem"` 310 311 // For more information, see DLL Characteristics later in this specification. 312 DllCharacteristics ImageOptionalHeaderDllCharacteristicsType `json:"dll_characteristics"` 313 314 // Size of virtual memory to reserve for the initial thread’s stack. Only 315 // the SizeOfStackCommit field is committed; the rest is available in 316 // one-page increments. The default is 1MB for 32-bit images and 4MB for 317 // 64-bit images. 318 SizeOfStackReserve uint64 `json:"size_of_stack_reserve"` 319 320 // Size of virtual memory initially committed for the initial thread’s 321 // stack. The default is one page (4KB) for 32-bit images and 16KB for 322 // 64-bit images. 323 SizeOfStackCommit uint64 `json:"size_of_stack_commit"` 324 325 // size of the local heap space to reserve. Only SizeOfHeapCommit is 326 // committed; the rest is made available one page at a time until the 327 // reserve size is reached. The default is 1MB for both 32-bit and 64-bit 328 // images. 329 SizeOfHeapReserve uint64 `json:"size_of_heap_reserve"` 330 331 // Size of virtual memory initially committed for the process heap. The 332 // default is 4KB (one operating system memory page) for 32-bit images and 333 // 16KB for 64-bit images. 334 SizeOfHeapCommit uint64 `json:"size_of_heap_commit"` 335 336 // Reserved, must be zero. 337 LoaderFlags uint32 `json:"loader_flags"` 338 339 // Number of entries in the DataDirectory array; at least 16. Although it 340 // is theoretically possible to emit more than 16 data directories, all 341 // existing managed compilers emit exactly 16 data directories, with the 342 // 16th (last) data directory never used (reserved). 343 NumberOfRvaAndSizes uint32 `json:"number_of_rva_and_sizes"` 344 345 // An array of 16 IMAGE_DATA_DIRECTORY structures. 346 DataDirectory [16]DataDirectory `json:"data_directories"` 347 } 348 349 // DataDirectory represents an array of 16 IMAGE_DATA_DIRECTORY structures, 350 // 8 bytes apiece, each relating to an important data structure in the PE file. 351 // The data directory table starts at offset 96 in a 32-bit PE header and at 352 // offset 112 in a 64-bit PE header. Each entry in the data directory table 353 // contains the RVA and size of a table or a string that this particular 354 // directory entry describes;this information is used by the operating system. 355 type DataDirectory struct { 356 // The RVA of the data structure. 357 VirtualAddress uint32 `json:"virtual_address"` 358 // The size in bytes of the data structure referred to. 359 Size uint32 `json:"size"` 360 } 361 362 // ParseNTHeader parse the PE NT header structure referred as IMAGE_NT_HEADERS. 363 // Its offset is given by the e_lfanew field in the IMAGE_DOS_HEADER at the 364 // beginning of the file. 365 func (pe *File) ParseNTHeader() (err error) { 366 ntHeaderOffset := pe.DOSHeader.AddressOfNewEXEHeader 367 signature, err := pe.ReadUint32(ntHeaderOffset) 368 if err != nil { 369 return ErrInvalidNtHeaderOffset 370 } 371 372 // Probe for PE signature. 373 if signature&0xFFFF == ImageOS2Signature { 374 return ErrImageOS2SignatureFound 375 } 376 if signature&0xFFFF == ImageOS2LESignature { 377 return ErrImageOS2LESignatureFound 378 } 379 if signature&0xFFFF == ImageVXDSignature { 380 return ErrImageVXDSignatureFound 381 } 382 if signature&0xFFFF == ImageTESignature { 383 return ErrImageTESignatureFound 384 } 385 386 // This is the smallest requirement for a valid PE. 387 if signature != ImageNTSignature { 388 return ErrImageNtSignatureNotFound 389 } 390 pe.NtHeader.Signature = signature 391 392 // The file header structure contains some basic information about the file; 393 // most importantly, a field describing the size of the optional data that 394 // follows it. 395 fileHeaderSize := uint32(binary.Size(pe.NtHeader.FileHeader)) 396 fileHeaderOffset := ntHeaderOffset + 4 397 err = pe.structUnpack(&pe.NtHeader.FileHeader, fileHeaderOffset, fileHeaderSize) 398 if err != nil { 399 return err 400 } 401 402 // The PE header which immediately follows the COFF header, provides 403 // information for the OS loader. Although this header is referred to as 404 // the optional header, it is optional only in the sense that object files 405 // usually don’t contain it. For PE files, this header is mandatory. 406 // The size of the PE header is not fixed. It depends on the number of data 407 // directories defined in the header and is specified in the 408 // SizeOfOptionalHeader field of the COFF header. 409 // The optional header could be either for a PE or PE+ file. 410 oh32 := ImageOptionalHeader32{} 411 oh64 := ImageOptionalHeader64{} 412 413 optHeaderOffset := ntHeaderOffset + (fileHeaderSize + 4) 414 magic, err := pe.ReadUint16(optHeaderOffset) 415 if err != nil { 416 return err 417 } 418 419 // Probes for PE32/PE32+ optional header magic. 420 if magic != ImageNtOptionalHeader32Magic && 421 magic != ImageNtOptionalHeader64Magic { 422 return ErrImageNtOptionalHeaderMagicNotFound 423 } 424 425 // Are we dealing with a PE64 optional header. 426 switch magic { 427 case ImageNtOptionalHeader64Magic: 428 size := uint32(binary.Size(oh64)) 429 err = pe.structUnpack(&oh64, optHeaderOffset, size) 430 if err != nil { 431 return err 432 } 433 pe.Is64 = true 434 pe.NtHeader.OptionalHeader = oh64 435 case ImageNtOptionalHeader32Magic: 436 size := uint32(binary.Size(oh32)) 437 err = pe.structUnpack(&oh32, optHeaderOffset, size) 438 if err != nil { 439 return err 440 } 441 pe.Is32 = true 442 pe.NtHeader.OptionalHeader = oh32 443 } 444 445 // ImageBase should be multiple of 10000h. 446 if (pe.Is64 && oh64.ImageBase%0x10000 != 0) || (pe.Is32 && oh32.ImageBase%0x10000 != 0) { 447 return ErrImageBaseNotAligned 448 } 449 450 // ImageBase can be any value as long as: 451 // ImageBase + SizeOfImage < 80000000h for PE32. 452 // ImageBase + SizeOfImage < 0xffff080000000000 for PE32+. 453 if (pe.Is32 && oh32.ImageBase+oh32.SizeOfImage >= 0x80000000) || (pe.Is64 && oh64.ImageBase+uint64(oh64.SizeOfImage) >= 0xffff080000000000) { 454 pe.Anomalies = append(pe.Anomalies, AnoImageBaseOverflow) 455 } 456 457 pe.HasNTHdr = true 458 return nil 459 } 460 461 // String returns the string representations of the `Machine` field of the IMAGE_FILE_HEADER. 462 func (t ImageFileHeaderMachineType) String() string { 463 machineType := map[ImageFileHeaderMachineType]string{ 464 ImageFileMachineUnknown: "Unknown", 465 ImageFileMachineAM33: "Matsushita AM33", 466 ImageFileMachineAMD64: "x64", 467 ImageFileMachineARM: "ARM little endian", 468 ImageFileMachineARM64: "ARM64 little endian", 469 ImageFileMachineARMNT: "ARM Thumb-2 little endian", 470 ImageFileMachineEBC: "EFI byte code", 471 ImageFileMachineI386: "Intel 386 or later / compatible processors", 472 ImageFileMachineIA64: "Intel Itanium processor family", 473 ImageFileMachineM32R: "Mitsubishi M32R little endian", 474 ImageFileMachineMIPS16: "MIPS16", 475 ImageFileMachineMIPSFPU: "MIPS with FPU", 476 ImageFileMachineMIPSFPU16: "MIPS16 with FPU", 477 ImageFileMachinePowerPC: "Power PC little endian", 478 ImageFileMachinePowerPCFP: "Power PC with floating point support", 479 ImageFileMachineR4000: "MIPS little endian", 480 ImageFileMachineRISCV32: "RISC-V 32-bit address space", 481 ImageFileMachineRISCV64: "RISC-V 64-bit address space", 482 ImageFileMachineRISCV128: "RISC-V 128-bit address space", 483 ImageFileMachineSH3: "Hitachi SH3", 484 ImageFileMachineSH3DSP: "Hitachi SH3 DSP", 485 ImageFileMachineSH4: "Hitachi SH4", 486 ImageFileMachineSH5: "Hitachi SH5", 487 ImageFileMachineTHUMB: "Thumb", 488 ImageFileMachineWCEMIPSv2: "MIPS little-endian WCE v2", 489 } 490 491 if val, ok := machineType[t]; ok { 492 return val 493 } 494 return "?" 495 } 496 497 // String returns the string representations of the `Characteristics` field of the IMAGE_FILE_HEADER. 498 func (t ImageFileHeaderCharacteristicsType) String() []string { 499 var values []string 500 fileHeaderCharacteristics := map[ImageFileHeaderCharacteristicsType]string{ 501 ImageFileRelocsStripped: "RelocsStripped", 502 ImageFileExecutableImage: "ExecutableImage", 503 ImageFileLineNumsStripped: "LineNumsStripped", 504 ImageFileLocalSymsStripped: "LocalSymsStripped", 505 ImageFileAggressiveWSTrim: "AgressibeWsTrim", 506 ImageFileLargeAddressAware: "LargeAddressAware", 507 ImageFileBytesReservedLow: "BytesReservedLow", 508 ImageFile32BitMachine: "32BitMachine", 509 ImageFileDebugStripped: "DebugStripped", 510 ImageFileRemovableRunFromSwap: "RemovableRunFromSwap", 511 ImageFileSystem: "FileSystem", 512 ImageFileDLL: "DLL", 513 ImageFileUpSystemOnly: "UpSystemOnly", 514 ImageFileBytesReservedHigh: "BytesReservedHigh", 515 } 516 517 for k, s := range fileHeaderCharacteristics { 518 if k&t != 0 { 519 values = append(values, s) 520 } 521 } 522 523 return values 524 } 525 526 // String returns the string representations of the `DllCharacteristics` field of ImageOptionalHeader. 527 func (t ImageOptionalHeaderDllCharacteristicsType) String() []string { 528 var values []string 529 530 imgDllCharacteristics := map[ImageOptionalHeaderDllCharacteristicsType]string{ 531 ImageDllCharacteristicsHighEntropyVA: "HighEntropyVA", 532 ImageDllCharacteristicsDynamicBase: "DynamicBase", 533 ImageDllCharacteristicsForceIntegrity: "ForceIntegrity", 534 ImageDllCharacteristicsNXCompact: "NXCompact", 535 ImageDllCharacteristicsNoIsolation: "NoIsolation", 536 ImageDllCharacteristicsNoSEH: "NoSEH", 537 ImageDllCharacteristicsNoBind: "NoBind", 538 ImageDllCharacteristicsAppContainer: "AppContainer", 539 ImageDllCharacteristicsWdmDriver: "WdmDriver", 540 ImageDllCharacteristicsGuardCF: "GuardCF", 541 ImageDllCharacteristicsTerminalServiceAware: "TerminalServiceAware", 542 } 543 544 for k, s := range imgDllCharacteristics { 545 if k&t != 0 { 546 values = append(values, s) 547 } 548 } 549 550 return values 551 } 552 553 // String returns the string representations of the `Subsystem` field 554 // of ImageOptionalHeader. 555 func (subsystem ImageOptionalHeaderSubsystemType) String() string { 556 subsystemMap := map[ImageOptionalHeaderSubsystemType]string{ 557 ImageSubsystemUnknown: "Unknown", 558 ImageSubsystemNative: "Native", 559 ImageSubsystemWindowsGUI: "Windows GUI", 560 ImageSubsystemWindowsCUI: "Windows CUI", 561 ImageSubsystemOS2CUI: "OS/2 character", 562 ImageSubsystemPosixCUI: "POSIX character", 563 ImageSubsystemNativeWindows: "Native Win9x driver", 564 ImageSubsystemWindowsCEGUI: "Windows CE GUI", 565 ImageSubsystemEFIApplication: "EFI Application", 566 ImageSubsystemEFIBootServiceDriver: "EFI Boot Service Driver", 567 ImageSubsystemEFIRuntimeDriver: "EFI ROM image", 568 ImageSubsystemEFIRom: "EFI ROM image", 569 ImageSubsystemXBOX: "XBOX", 570 ImageSubsystemWindowsBootApplication: "Windows boot application", 571 } 572 573 if val, ok := subsystemMap[subsystem]; ok { 574 return val 575 } 576 577 return "?" 578 } 579 580 // PrettyOptionalHeaderMagic returns the string representations of the 581 // `Magic` field of ImageOptionalHeader. 582 func (pe *File) PrettyOptionalHeaderMagic() string { 583 584 var magic uint16 585 586 if pe.Is64 { 587 magic = 588 pe.NtHeader.OptionalHeader.(ImageOptionalHeader64).Magic 589 } else { 590 magic = 591 pe.NtHeader.OptionalHeader.(ImageOptionalHeader32).Magic 592 } 593 594 switch magic { 595 case ImageNtOptionalHeader32Magic: 596 return "PE32" 597 case ImageNtOptionalHeader64Magic: 598 return "PE64" 599 case ImageROMOptionalHeaderMagic: 600 return "ROM" 601 default: 602 return "?" 603 } 604 }