diff --git a/CHANGELOG.md b/CHANGELOG.md index d9b3291..f74f369 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,7 +15,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Parse .net metadata Module table. - Parse .net metadata stream headers and metadata tables stream header. - Add cmd/pedumper to illustrate how to use the library. -- Add unit test for relocation, exception, security, symbol, file, section and helper files. +- Add unit test for relocation, exception, security, symbol, file, nt header, section and helper files. - Add an option `New()` to customize max of relocations entries and COFF symbols to parse. ### Changed diff --git a/cmd/pedumper.go b/cmd/pedumper.go index 5bfee74..98a967d 100644 --- a/cmd/pedumper.go +++ b/cmd/pedumper.go @@ -54,7 +54,6 @@ func parsePE(filename string, cmd *cobra.Command) { data, _ := ioutil.ReadFile(filename) pe, err := peparser.NewBytes(data, &peparser.Options{}) - // pe, err := peparser.New(filename, &peparser.Options{}) if err != nil { log.Printf("Error while opening file: %s, reason: %s", filename, err) return @@ -67,6 +66,12 @@ func parsePE(filename string, cmd *cobra.Command) { return } + // Calculate the PE authentihash. + //pe.Authentihash() + + // Calculate the PE checksum. + pe.Checksum() + wantDosHeader, _ := cmd.Flags().GetBool("dosheader") if wantDosHeader { dosHeader, _ := json.Marshal(pe.DosHeader) @@ -81,6 +86,12 @@ func parsePE(filename string, cmd *cobra.Command) { wantSections, _ := cmd.Flags().GetBool("sections") if wantSections { + 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()) + } sectionsHeaders, _ := json.Marshal(pe.Sections) fmt.Println(prettyPrint(sectionsHeaders)) } diff --git a/ntheader_test.go b/ntheader_test.go new file mode 100644 index 0000000..c49b6ae --- /dev/null +++ b/ntheader_test.go @@ -0,0 +1,104 @@ +// Copyright 2021 Saferwall. All rights reserved. +// Use of this source code is governed by Apache v2 license +// license that can be found in the LICENSE file. + +package pe + +import ( + "reflect" + "sort" + "testing" +) + +func TestPrettyMachineType(t *testing.T) { + + tests := []struct { + in string + out string + }{ + {getAbsoluteFilePath("test/putty.exe"), "x64"}, + } + + for _, tt := range tests { + t.Run(tt.in, func(t *testing.T) { + ops := Options{Fast: true} + file, err := New(tt.in, &ops) + if err != nil { + t.Fatalf("New(%s) failed, reason: %v", tt.in, err) + } + err = file.Parse() + if err != nil { + t.Fatalf("Parse(%s) failed, reason: %v", tt.in, err) + } + + prettyMachineType := file.PrettyMachineType() + if prettyMachineType != tt.out { + t.Errorf("pretty machine type assertion failed, got %v, want %v", + prettyMachineType, tt.out) + } + }) + } +} + +func TestSubsystem(t *testing.T) { + + tests := []struct { + in string + out string + }{ + {getAbsoluteFilePath("test/putty.exe"), "Windows GUI"}, + } + + for _, tt := range tests { + t.Run(tt.in, func(t *testing.T) { + ops := Options{Fast: true} + file, err := New(tt.in, &ops) + if err != nil { + t.Fatalf("New(%s) failed, reason: %v", tt.in, err) + } + err = file.Parse() + if err != nil { + t.Fatalf("Parse(%s) failed, reason: %v", tt.in, err) + } + + prettySubsystem := file.PrettySubsystem() + if prettySubsystem != tt.out { + t.Errorf("pretty subsystem type assertion failed, got %v, want %v", + prettySubsystem, tt.out) + } + }) + } +} + +func TestPrettyDllCharacteristics(t *testing.T) { + + tests := []struct { + in string + out []string + }{ + {getAbsoluteFilePath("test/putty.exe"), []string{ + "DynamicBase", "HighEntropyVA", "NXCompact", "TerminalServiceAware"}}, + } + + for _, tt := range tests { + t.Run(tt.in, func(t *testing.T) { + ops := Options{Fast: true} + file, err := New(tt.in, &ops) + if err != nil { + t.Fatalf("New(%s) failed, reason: %v", tt.in, err) + } + err = file.Parse() + if err != nil { + t.Fatalf("Parse(%s) failed, reason: %v", tt.in, err) + } + + dllCharacteristics := file.PrettyDllCharacteristics() + sort.Strings(dllCharacteristics) + if !reflect.DeepEqual(dllCharacteristics, tt.out) { + t.Errorf("pretty dll characteristics type assertion failed, got %v, want %v", + dllCharacteristics, tt.out) + } + + }) + } +} diff --git a/section_test.go b/section_test.go index 1f9eb37..597d564 100644 --- a/section_test.go +++ b/section_test.go @@ -6,6 +6,7 @@ package pe import ( "reflect" + "sort" "testing" ) @@ -72,6 +73,7 @@ func TestParseSectionHeaders(t *testing.T) { } prettySectionFlags := section.PrettySectionFlags() + sort.Strings(prettySectionFlags) if !reflect.DeepEqual(prettySectionFlags, tt.out.sectionFlags) { t.Errorf("pretty section flags assertion failed, got %v, want %v", prettySectionFlags, tt.out.sectionFlags)