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 May 17, 2023
1 parent a7d54ff commit 3da5530
Show file tree
Hide file tree
Showing 5 changed files with 132 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 @@ -39,6 +39,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/postgres"
_ "github.com/wader/fq/format/prores"
Expand Down
3 changes: 3 additions & 0 deletions format/format.go
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,9 @@ var (
Opus_Packet = &decode.Group{Name: "opus_packet"}
PCAP = &decode.Group{Name: "pcap"}
PCAPNG = &decode.Group{Name: "pcapng"}
PE = &decode.Group{Name: "pe"}
PE_COFF = &decode.Group{Name: "pe_coff"}
PE_MSDOS_Stub = &decode.Group{Name: "pe_msdos_stub"}
Pg_BTree = &decode.Group{Name: "pg_btree"}
Pg_Control = &decode.Group{Name: "pg_control"}
Pg_Heap = &decode.Group{Name: "pg_heap"}
Expand Down
37 changes: 37 additions & 0 deletions format/pe/pe.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
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?
// TODO: not pe_ prefix for format names?

var peMSDosStubGroup decode.Group
var peCOFFGroup decode.Group

func init() {
interp.RegisterFormat(
format.PE,
&decode.Format{
Description: "Portable Executable",
Groups: []*decode.Group{format.Probe},
Dependencies: []decode.Dependency{
{Groups: []*decode.Group{format.PE_MSDOS_Stub}, Out: &peMSDosStubGroup},
{Groups: []*decode.Group{format.PE_COFF}, Out: &peCOFFGroup},
},
DecodeFn: peDecode,
})
}

func peDecode(d *decode.D) any {

d.FieldFormat("ms_dos_stub", &peMSDosStubGroup, nil)
d.FieldFormat("coff", &peCOFFGroup, nil)

return nil
}
35 changes: 35 additions & 0 deletions format/pe/pe_coff.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"
"github.com/wader/fq/pkg/scalar"
)

// TODO: probe?

func init() {
interp.RegisterFormat(
format.PE_COFF,
&decode.Format{
Description: "Common Object File Format",
DecodeFn: peCoffStubDecode,
})
}

func peCoffStubDecode(d *decode.D) any {

d.FieldU32("signature", scalar.UintHex, d.UintAssert(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
}
56 changes: 56 additions & 0 deletions format/pe/pe_msdos_stub.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
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(
format.PE_MSDOS_Stub,
&decode.Format{
Description: "MS-DOS Stub",
DecodeFn: msDosStubDecode,
})
}

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

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

// TODO: x86 format in the future
d.FieldRawLen("stub", 64*8, scalar.BitBufDescription("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 3da5530

Please sign in to comment.