Skip to content

Commit 4a50b62

Browse files
committed
WIP: pe: Add decoder
1 parent 56474a6 commit 4a50b62

File tree

5 files changed

+128
-0
lines changed

5 files changed

+128
-0
lines changed

format/all/all.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ import (
3838
_ "github.com/wader/fq/format/ogg"
3939
_ "github.com/wader/fq/format/opus"
4040
_ "github.com/wader/fq/format/pcap"
41+
_ "github.com/wader/fq/format/pe"
4142
_ "github.com/wader/fq/format/png"
4243
_ "github.com/wader/fq/format/prores"
4344
_ "github.com/wader/fq/format/protobuf"

format/format.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,9 @@ const (
103103
OPUS_PACKET = "opus_packet"
104104
PCAP = "pcap"
105105
PCAPNG = "pcapng"
106+
PE = "pe"
107+
PE_COFF = "pe_coff"
108+
PE_MSDOS_STUB = "pe_msdos_stub"
106109
PNG = "png"
107110
PRORES_FRAME = "prores_frame"
108111
PROTOBUF = "protobuf"

format/pe/pe.go

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
package pe
2+
3+
// https://osandamalith.com/2020/07/19/exploring-the-ms-dos-stub/
4+
5+
import (
6+
"github.com/wader/fq/format"
7+
"github.com/wader/fq/pkg/decode"
8+
"github.com/wader/fq/pkg/interp"
9+
)
10+
11+
// TODO: probe?
12+
13+
var peMSDosStubFormat decode.Group
14+
var peCOFFFormat decode.Group
15+
16+
func init() {
17+
interp.RegisterFormat(decode.Format{
18+
Name: format.PE, // TODO: not PE_ prefix?
19+
Description: "Portable Executable",
20+
Groups: []string{format.PROBE},
21+
Dependencies: []decode.Dependency{
22+
{Names: []string{format.PE_MSDOS_STUB}, Group: &peMSDosStubFormat},
23+
{Names: []string{format.PE_COFF}, Group: &peCOFFFormat},
24+
},
25+
DecodeFn: peDecode,
26+
})
27+
}
28+
29+
func peDecode(d *decode.D, _ any) any {
30+
31+
d.FieldFormat("ms_dos_stub", peMSDosStubFormat, nil)
32+
d.FieldFormat("coff", peCOFFFormat, nil)
33+
34+
return nil
35+
}

format/pe/pe_coff.go

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
package pe
2+
3+
// https://osandamalith.com/2020/07/19/exploring-the-ms-dos-stub/
4+
5+
import (
6+
"github.com/wader/fq/format"
7+
"github.com/wader/fq/pkg/decode"
8+
"github.com/wader/fq/pkg/interp"
9+
"github.com/wader/fq/pkg/scalar"
10+
)
11+
12+
// TODO: probe?
13+
14+
func init() {
15+
interp.RegisterFormat(decode.Format{
16+
Name: format.PE_COFF, // TODO: not PE_ prefix?
17+
Description: "Common Object File Format",
18+
DecodeFn: peCoffStubDecode,
19+
})
20+
}
21+
22+
func peCoffStubDecode(d *decode.D, _ any) any {
23+
24+
d.FieldU32("signature", scalar.ActualHex, d.AssertU(0x50450000))
25+
d.FieldU16("machine")
26+
d.FieldU16("number_of_sections")
27+
d.FieldU32("time_date_stamp")
28+
d.FieldU32("pointer_to_symbol_table")
29+
d.FieldU32("number_of_symbol_table")
30+
d.FieldU16("size_of_optional_header")
31+
d.FieldU16("characteristics")
32+
33+
return nil
34+
}

format/pe/pe_msdos_stub.go

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
package pe
2+
3+
// https://osandamalith.com/2020/07/19/exploring-the-ms-dos-stub/
4+
5+
import (
6+
"github.com/wader/fq/format"
7+
"github.com/wader/fq/pkg/decode"
8+
"github.com/wader/fq/pkg/interp"
9+
"github.com/wader/fq/pkg/scalar"
10+
)
11+
12+
// TODO: probe?
13+
14+
func init() {
15+
interp.RegisterFormat(decode.Format{
16+
Name: format.PE_MSDOS_STUB, // TODO: not PE_ prefix?
17+
Description: "MS-DOS Stub",
18+
DecodeFn: msDosStubDecode,
19+
})
20+
}
21+
22+
func msDosStubDecode(d *decode.D, _ any) any {
23+
d.Endian = decode.LittleEndian
24+
25+
d.FieldU16("e_magic", scalar.Description("Magic number"), d.AssertU(0x5a4d), scalar.ActualHex)
26+
d.FieldU16("e_cblp", scalar.Description("Bytes on last page of file"))
27+
d.FieldU16("e_cp", scalar.Description("Pages in file"))
28+
d.FieldU16("e_crlc", scalar.Description("Relocations"))
29+
d.FieldU16("e_cparhdr", scalar.Description("Size of header in paragraphs"))
30+
d.FieldU16("e_minalloc", scalar.Description("Minimum extra paragraphs needed"))
31+
d.FieldU16("e_maxalloc", scalar.Description("Maximum extra paragraphs needed"))
32+
d.FieldU16("e_ss", scalar.Description("Initial (relative) SS value"))
33+
d.FieldU16("e_sp", scalar.Description("Initial SP value"))
34+
d.FieldU16("e_csum", scalar.Description("Checksum"))
35+
d.FieldU16("e_ip", scalar.Description("Initial IP value"))
36+
d.FieldU16("e_cs", scalar.Description("Initial (relative) CS value"))
37+
d.FieldU16("e_lfarlc", scalar.Description("File address of relocation table"))
38+
d.FieldU16("e_ovno", scalar.Description("Overlay number"))
39+
d.FieldRawLen("e_res", 4*16, scalar.Description("Reserved words"))
40+
d.FieldU16("e_oemid", scalar.Description("OEM identifier (for e_oeminfo)"))
41+
d.FieldU16("e_oeminfo", scalar.Description("OEM information; e_oemid specific"))
42+
d.FieldRawLen("e_res2", 10*16, scalar.Description("Reserved words"))
43+
lfanew := d.FieldU32("e_lfanew", scalar.Description("File address of new exe header"))
44+
45+
// TODO: x86 format in the future
46+
d.FieldRawLen("stub", 64*8, scalar.Description("Sub program"))
47+
48+
subEndPos := d.Pos()
49+
50+
// TODO: is not padding i guess?
51+
padding := lfanew*8 - uint64(subEndPos)
52+
d.FieldRawLen("padding", int64(padding))
53+
54+
return nil
55+
}

0 commit comments

Comments
 (0)