Skip to content

Commit

Permalink
WIP: pe: Add decoder
Browse files Browse the repository at this point in the history
  • Loading branch information
wader committed Oct 4, 2022
1 parent 56474a6 commit 4a50b62
Show file tree
Hide file tree
Showing 5 changed files with 128 additions and 0 deletions.
1 change: 1 addition & 0 deletions format/all/all.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ import (
_ "github.com/wader/fq/format/ogg"
_ "github.com/wader/fq/format/opus"
_ "github.com/wader/fq/format/pcap"
_ "github.com/wader/fq/format/pe"
_ "github.com/wader/fq/format/png"
_ "github.com/wader/fq/format/prores"
_ "github.com/wader/fq/format/protobuf"
Expand Down
3 changes: 3 additions & 0 deletions format/format.go
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,9 @@ const (
OPUS_PACKET = "opus_packet"
PCAP = "pcap"
PCAPNG = "pcapng"
PE = "pe"
PE_COFF = "pe_coff"
PE_MSDOS_STUB = "pe_msdos_stub"
PNG = "png"
PRORES_FRAME = "prores_frame"
PROTOBUF = "protobuf"
Expand Down
35 changes: 35 additions & 0 deletions format/pe/pe.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package pe

// https://osandamalith.com/2020/07/19/exploring-the-ms-dos-stub/

import (
"github.com/wader/fq/format"
"github.com/wader/fq/pkg/decode"
"github.com/wader/fq/pkg/interp"
)

// TODO: probe?

var peMSDosStubFormat decode.Group
var peCOFFFormat decode.Group

func init() {
interp.RegisterFormat(decode.Format{
Name: format.PE, // TODO: not PE_ prefix?
Description: "Portable Executable",
Groups: []string{format.PROBE},
Dependencies: []decode.Dependency{
{Names: []string{format.PE_MSDOS_STUB}, Group: &peMSDosStubFormat},
{Names: []string{format.PE_COFF}, Group: &peCOFFFormat},
},
DecodeFn: peDecode,
})
}

func peDecode(d *decode.D, _ any) any {

d.FieldFormat("ms_dos_stub", peMSDosStubFormat, nil)
d.FieldFormat("coff", peCOFFFormat, nil)

return nil
}
34 changes: 34 additions & 0 deletions format/pe/pe_coff.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package pe

// https://osandamalith.com/2020/07/19/exploring-the-ms-dos-stub/

import (
"github.com/wader/fq/format"
"github.com/wader/fq/pkg/decode"
"github.com/wader/fq/pkg/interp"
"github.com/wader/fq/pkg/scalar"
)

// TODO: probe?

func init() {
interp.RegisterFormat(decode.Format{
Name: format.PE_COFF, // TODO: not PE_ prefix?
Description: "Common Object File Format",
DecodeFn: peCoffStubDecode,
})
}

func peCoffStubDecode(d *decode.D, _ any) any {

d.FieldU32("signature", scalar.ActualHex, d.AssertU(0x50450000))
d.FieldU16("machine")
d.FieldU16("number_of_sections")
d.FieldU32("time_date_stamp")
d.FieldU32("pointer_to_symbol_table")
d.FieldU32("number_of_symbol_table")
d.FieldU16("size_of_optional_header")
d.FieldU16("characteristics")

return nil
}
55 changes: 55 additions & 0 deletions format/pe/pe_msdos_stub.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
package pe

// https://osandamalith.com/2020/07/19/exploring-the-ms-dos-stub/

import (
"github.com/wader/fq/format"
"github.com/wader/fq/pkg/decode"
"github.com/wader/fq/pkg/interp"
"github.com/wader/fq/pkg/scalar"
)

// TODO: probe?

func init() {
interp.RegisterFormat(decode.Format{
Name: format.PE_MSDOS_STUB, // TODO: not PE_ prefix?
Description: "MS-DOS Stub",
DecodeFn: msDosStubDecode,
})
}

func msDosStubDecode(d *decode.D, _ any) any {
d.Endian = decode.LittleEndian

d.FieldU16("e_magic", scalar.Description("Magic number"), d.AssertU(0x5a4d), scalar.ActualHex)
d.FieldU16("e_cblp", scalar.Description("Bytes on last page of file"))
d.FieldU16("e_cp", scalar.Description("Pages in file"))
d.FieldU16("e_crlc", scalar.Description("Relocations"))
d.FieldU16("e_cparhdr", scalar.Description("Size of header in paragraphs"))
d.FieldU16("e_minalloc", scalar.Description("Minimum extra paragraphs needed"))
d.FieldU16("e_maxalloc", scalar.Description("Maximum extra paragraphs needed"))
d.FieldU16("e_ss", scalar.Description("Initial (relative) SS value"))
d.FieldU16("e_sp", scalar.Description("Initial SP value"))
d.FieldU16("e_csum", scalar.Description("Checksum"))
d.FieldU16("e_ip", scalar.Description("Initial IP value"))
d.FieldU16("e_cs", scalar.Description("Initial (relative) CS value"))
d.FieldU16("e_lfarlc", scalar.Description("File address of relocation table"))
d.FieldU16("e_ovno", scalar.Description("Overlay number"))
d.FieldRawLen("e_res", 4*16, scalar.Description("Reserved words"))
d.FieldU16("e_oemid", scalar.Description("OEM identifier (for e_oeminfo)"))
d.FieldU16("e_oeminfo", scalar.Description("OEM information; e_oemid specific"))
d.FieldRawLen("e_res2", 10*16, scalar.Description("Reserved words"))
lfanew := d.FieldU32("e_lfanew", scalar.Description("File address of new exe header"))

// TODO: x86 format in the future
d.FieldRawLen("stub", 64*8, scalar.Description("Sub program"))

subEndPos := d.Pos()

// TODO: is not padding i guess?
padding := lfanew*8 - uint64(subEndPos)
d.FieldRawLen("padding", int64(padding))

return nil
}

0 comments on commit 4a50b62

Please sign in to comment.