Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore: increase unit test coverage to 80% #74

Merged
merged 14 commits into from
Mar 25, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 36 additions & 9 deletions cmd/dump.go
Original file line number Diff line number Diff line change
Expand Up @@ -272,22 +272,23 @@ func parsePE(filename string, cfg config) {
if cfg.wantNTHeader {
ntHeader := pe.NtHeader.FileHeader
w := tabwriter.NewWriter(os.Stdout, 1, 1, 3, ' ', tabwriter.AlignRight)
characteristics := strings.Join(ntHeader.Characteristics.String(), " | ")

fmt.Print("\n\t------[ File Header ]------\n\n")
fmt.Fprintf(w, "Machine:\t 0x%x (%s)\n", ntHeader.Machine, pe.PrettyMachineType())
fmt.Fprintf(w, "Machine:\t 0x%x (%s)\n", int(ntHeader.Machine), ntHeader.Machine.String())
fmt.Fprintf(w, "Number Of Sections:\t 0x%x\n", ntHeader.NumberOfSections)
fmt.Fprintf(w, "TimeDateStamp:\t 0x%x (%s)\n", ntHeader.TimeDateStamp, humanizeTimestamp(ntHeader.TimeDateStamp))
fmt.Fprintf(w, "Pointer To Symbol Table:\t 0x%x\n", ntHeader.PointerToSymbolTable)
fmt.Fprintf(w, "Number Of Symbols:\t 0x%x\n", ntHeader.NumberOfSymbols)
fmt.Fprintf(w, "Number Of Symbols:\t 0x%x\n", ntHeader.NumberOfSymbols)
fmt.Fprintf(w, "Size Of Optional Header:\t 0x%x\n", ntHeader.SizeOfOptionalHeader)
fmt.Fprintf(w, "Characteristics:\t 0x%x\n", ntHeader.Characteristics)
fmt.Fprintf(w, "Characteristics:\t 0x%x (%s)\n", ntHeader.Characteristics, characteristics)
w.Flush()

fmt.Print("\n\t------[ Optional Header ]------\n\n")
if pe.Is64 {
oh := pe.NtHeader.OptionalHeader.(peparser.ImageOptionalHeader64)
dllCharacteristics := strings.Join(pe.PrettyDllCharacteristics(), " | ")
dllCharacteristics := strings.Join(oh.DllCharacteristics.String(), " | ")
fmt.Fprintf(w, "Magic:\t 0x%x (%s)\n", oh.Magic, pe.PrettyOptionalHeaderMagic())
fmt.Fprintf(w, "Major Linker Version:\t 0x%x\n", oh.MajorLinkerVersion)
fmt.Fprintf(w, "Minor Linker Version:\t 0x%x\n", oh.MinorLinkerVersion)
Expand All @@ -313,8 +314,8 @@ func parsePE(filename string, cfg config) {
fmt.Fprintf(w, "Size Of Image:\t 0x%x (%s)\n", oh.SizeOfImage, BytesSize(float64(oh.SizeOfImage)))
fmt.Fprintf(w, "Size Of Headers:\t 0x%x (%s)\n", oh.SizeOfHeaders, BytesSize(float64(oh.SizeOfHeaders)))
fmt.Fprintf(w, "Checksum:\t 0x%x\n", oh.CheckSum)
fmt.Fprintf(w, "Subsystem:\t 0x%x (%s)\n", oh.Subsystem, pe.PrettySubsystem())
fmt.Fprintf(w, "Dll Characteristics:\t 0x%x (%s)\n", oh.DllCharacteristics, dllCharacteristics)
fmt.Fprintf(w, "Subsystem:\t 0x%x (%s)\n", uint16(oh.Subsystem), oh.Subsystem.String())
fmt.Fprintf(w, "Dll Characteristics:\t 0x%x (%s)\n", uint16(oh.DllCharacteristics), dllCharacteristics)
fmt.Fprintf(w, "Size Of Stack Reserve:\t 0x%x (%s)\n", oh.SizeOfStackReserve, BytesSize(float64(oh.SizeOfStackReserve)))
fmt.Fprintf(w, "Size Of Stack Commit:\t 0x%x (%s)\n", oh.SizeOfStackCommit, BytesSize(float64(oh.SizeOfStackCommit)))
fmt.Fprintf(w, "Size Of Heap Reserve:\t 0x%x (%s)\n", oh.SizeOfHeapReserve, BytesSize(float64(oh.SizeOfHeapReserve)))
Expand All @@ -329,7 +330,7 @@ func parsePE(filename string, cfg config) {
}
} else {
oh := pe.NtHeader.OptionalHeader.(peparser.ImageOptionalHeader32)
dllCharacteristics := strings.Join(pe.PrettyDllCharacteristics(), " | ")
dllCharacteristics := strings.Join(oh.DllCharacteristics.String(), " | ")
fmt.Fprintf(w, "Magic:\t 0x%x (%s)\n", oh.Magic, pe.PrettyOptionalHeaderMagic())
fmt.Fprintf(w, "Major Linker Version:\t 0x%x\n", oh.MajorLinkerVersion)
fmt.Fprintf(w, "Minor Linker Version:\t 0x%x\n", oh.MinorLinkerVersion)
Expand All @@ -355,8 +356,8 @@ func parsePE(filename string, cfg config) {
fmt.Fprintf(w, "Size Of Image:\t 0x%x (%s)\n", oh.SizeOfImage, BytesSize(float64(oh.SizeOfImage)))
fmt.Fprintf(w, "Size Of Headers:\t 0x%x (%s)\n", oh.SizeOfHeaders, BytesSize(float64(oh.SizeOfHeaders)))
fmt.Fprintf(w, "Checksum:\t 0x%x\n", oh.CheckSum)
fmt.Fprintf(w, "Subsystem:\t 0x%x (%s)\n", oh.Subsystem, pe.PrettySubsystem())
fmt.Fprintf(w, "Dll Characteristics:\t 0x%x (%s)\n", oh.DllCharacteristics, dllCharacteristics)
fmt.Fprintf(w, "Subsystem:\t 0x%x (%s)\n", uint16(oh.Subsystem), oh.Subsystem.String())
fmt.Fprintf(w, "Dll Characteristics:\t 0x%x (%s)\n", uint16(oh.DllCharacteristics), dllCharacteristics)
fmt.Fprintf(w, "Size Of Stack Reserve:\t 0x%x (%s)\n", oh.SizeOfStackReserve, BytesSize(float64(oh.SizeOfStackReserve)))
fmt.Fprintf(w, "Size Of Stack Commit:\t 0x%x (%s)\n", oh.SizeOfStackCommit, BytesSize(float64(oh.SizeOfStackCommit)))
fmt.Fprintf(w, "Size Of Heap Reserve:\t 0x%x (%s)\n", oh.SizeOfHeapReserve, BytesSize(float64(oh.SizeOfHeapReserve)))
Expand All @@ -373,6 +374,19 @@ func parsePE(filename string, cfg config) {
w.Flush()
}

if cfg.wantCOFF && pe.FileInfo.HasCOFF {
fmt.Printf("\nCOFF\n****\n")
w := tabwriter.NewWriter(os.Stdout, 1, 1, 3, ' ', tabwriter.AlignRight)
fmt.Fprintln(w, "Name\tValue\tSectionNumber\tType\tStorageClass\tNumberOfAuxSymbols\t")
for _, sym := range pe.COFF.SymbolTable {
symName, _ := sym.String(pe)
fmt.Fprintf(w, "%s\t0x%x\t0x%x\t0x%x\t0x%x\t0x%x\t\n",
symName, sym.Value, sym.SectionNumber,
sym.Type, sym.StorageClass, sym.NumberOfAuxSymbols)
}
w.Flush()
}

if cfg.wantSections && pe.FileInfo.HasSections {
w := tabwriter.NewWriter(os.Stdout, 1, 1, 3, ' ', tabwriter.AlignRight)
for i, sec := range pe.Sections {
Expand Down Expand Up @@ -512,7 +526,7 @@ func parsePE(filename string, cfg config) {
fmt.Print("|- Unwind codes:\n")
for _, uc := range ui.UnwindCodes {
fmt.Printf("|- * %.2x: %s, %s\n", uc.CodeOffset,
peparser.PrettyUnwindOpcode(uc.UnwindOp), uc.Operand)
uc.UnwindOp.String(), uc.Operand)
}
}
}
Expand All @@ -538,6 +552,19 @@ func parsePE(filename string, cfg config) {
w.Flush()
}

if cfg.wantReloc && pe.FileInfo.HasReloc {
fmt.Printf("\nRELOCATIONS\n***********\n")
for _, reloc := range pe.Relocations {
fmt.Printf("\n\u27A1 Virtual Address: 0x%x | Size Of Block:0x%x | Entries Count:0x%x\t\n",
reloc.Data.VirtualAddress, reloc.Data.SizeOfBlock, len(reloc.Entries))
fmt.Print("|- Entries:\n")
for _, relocEntry := range reloc.Entries {
fmt.Printf("|- Data: 0x%x | Offset: 0x%x | Type:0x%x (%s)\n", relocEntry.Data,
relocEntry.Offset, relocEntry.Type, relocEntry.Type.String(pe))
}
}
}

if cfg.wantDebug && pe.FileInfo.HasDebug {
fmt.Printf("\nDEBUGS\n*******\n")
w := tabwriter.NewWriter(os.Stdout, 1, 1, 3, ' ', tabwriter.AlignRight)
Expand Down
29 changes: 29 additions & 0 deletions dosheader_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,3 +68,32 @@ func TestParseDOSHeader(t *testing.T) {
})
}
}

func TestParseDOSHeaderNonMZ(t *testing.T) {

tests := []struct {
in string
out error
}{
{
// This is an ELF file.
getAbsoluteFilePath("test/look"),
ErrDOSMagicNotFound,
},
}

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.ParseDOSHeader()
if err != tt.out {
t.Fatalf("parsing DOS header failed, got %v, want %v", err, tt.out)
}
})
}
}
45 changes: 23 additions & 22 deletions dotnet.go
Original file line number Diff line number Diff line change
Expand Up @@ -495,15 +495,15 @@ type ModuleTableRow struct {
// CLRData embeds the Common Language Runtime Header structure as well as the
// Metadata header structure.
type CLRData struct {
CLRHeader *ImageCOR20Header `json:"clr_header,omitempty"`
MetadataHeader *MetadataHeader `json:"metadata_header,omitempty"`
MetadataStreamHeaders []*MetadataStreamHeader `json:"metadata_stream_headers,omitempty"`
MetadataStreams map[string][]byte `json:"-"`
MetadataTablesStreamHeader *MetadataTableStreamHeader `json:"metadata_tables_stream_header,omitempty"`
MetadataTables map[int]*MetadataTable `json:"metadata_tables,omitempty"`
StringStreamIndexSize int `json:"-"`
GUIDStreamIndexSize int `json:"-"`
BlobStreamIndexSize int `json:"-"`
CLRHeader ImageCOR20Header `json:"clr_header"`
MetadataHeader MetadataHeader `json:"metadata_header"`
MetadataStreamHeaders []MetadataStreamHeader `json:"metadata_stream_headers"`
MetadataStreams map[string][]byte `json:"-"`
MetadataTablesStreamHeader MetadataTableStreamHeader `json:"metadata_tables_stream_header"`
MetadataTables map[int]*MetadataTable `json:"metadata_tables"`
StringStreamIndexSize int `json:"-"`
GUIDStreamIndexSize int `json:"-"`
BlobStreamIndexSize int `json:"-"`
}

func (pe *File) readFromMetadataSteam(Stream int, off uint32, out *uint32) (uint32, error) {
Expand Down Expand Up @@ -589,35 +589,35 @@ func (pe *File) parseMetadataHeader(offset, size uint32) (MetadataHeader, error)
return mh, err
}

func (pe *File) parseMetadataModuleTable(moduleTable *MetadataTable, off uint32) error {
func (pe *File) parseMetadataModuleTable(off uint32) (ModuleTableRow, error) {
var err error
var indexSize uint32
modTableRow := ModuleTableRow{}

if modTableRow.Generation, err = pe.ReadUint16(off); err != nil {
return err
return ModuleTableRow{}, err
}
off += 2

if indexSize, err = pe.readFromMetadataSteam(StringStream, off, &modTableRow.Name); err != nil {
return err
return ModuleTableRow{}, err
}
off += indexSize

if indexSize, err = pe.readFromMetadataSteam(GUIDStream, off, &modTableRow.Mvid); err != nil {
return err
return ModuleTableRow{}, err
}
off += indexSize
if indexSize, err = pe.readFromMetadataSteam(GUIDStream, off, &modTableRow.EncID); err != nil {
return err
return ModuleTableRow{}, err
}
off += indexSize

if _, err = pe.readFromMetadataSteam(GUIDStream, off, &modTableRow.EncBaseID); err != nil {
return err
return ModuleTableRow{}, err
}

moduleTable.Content = modTableRow
return nil
return modTableRow, nil
}

// The 15th directory entry of the PE header contains the RVA and size of the
Expand All @@ -634,7 +634,7 @@ func (pe *File) parseCLRHeaderDirectory(rva, size uint32) error {
return err
}

pe.CLR.CLRHeader = &clrHeader
pe.CLR.CLRHeader = clrHeader
if clrHeader.MetaData.VirtualAddress == 0 || clrHeader.MetaData.Size == 0 {
return nil
}
Expand All @@ -649,7 +649,7 @@ func (pe *File) parseCLRHeaderDirectory(rva, size uint32) error {
if err != nil {
return err
}
pe.CLR.MetadataHeader = &mh
pe.CLR.MetadataHeader = mh
pe.CLR.MetadataStreams = make(map[string][]byte)
offset += 16 + mh.VersionString + 4

Expand Down Expand Up @@ -696,7 +696,7 @@ func (pe *File) parseCLRHeaderDirectory(rva, size uint32) error {
rva = clrHeader.MetaData.VirtualAddress + sh.Offset
start := pe.GetOffsetFromRva(rva)
pe.CLR.MetadataStreams[sh.Name] = pe.data[start : start+sh.Size]
pe.CLR.MetadataStreamHeaders = append(pe.CLR.MetadataStreamHeaders, &sh)
pe.CLR.MetadataStreamHeaders = append(pe.CLR.MetadataStreamHeaders, sh)
}

// Get the Metadata Table Stream.
Expand All @@ -711,7 +711,7 @@ func (pe *File) parseCLRHeaderDirectory(rva, size uint32) error {
if err != nil {
return nil
}
pe.CLR.MetadataTablesStreamHeader = &mdTableStreamHdr
pe.CLR.MetadataTablesStreamHeader = mdTableStreamHdr

// Get the size of indexes of #String", "#GUID" and "#Blob" streams.
pe.CLR.StringStreamIndexSize = pe.GetMetadataStreamIndexSize(StringStream)
Expand Down Expand Up @@ -740,7 +740,8 @@ func (pe *File) parseCLRHeaderDirectory(rva, size uint32) error {
for tableIdx, table := range pe.CLR.MetadataTables {
switch tableIdx {
case Module:
if err = pe.parseMetadataModuleTable(table, offset); err != nil {
table.Content, err = pe.parseMetadataModuleTable(offset)
if err != nil {
return err
}
}
Expand Down
Loading