Skip to content

Commit 60bb378

Browse files
committed
WIP: pe: Add decoder
1 parent 23d980d commit 60bb378

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
@@ -39,6 +39,7 @@ import (
3939
_ "github.com/wader/fq/format/ogg"
4040
_ "github.com/wader/fq/format/opus"
4141
_ "github.com/wader/fq/format/pcap"
42+
_ "github.com/wader/fq/format/pe"
4243
_ "github.com/wader/fq/format/png"
4344
_ "github.com/wader/fq/format/prores"
4445
_ "github.com/wader/fq/format/protobuf"

format/format.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,9 @@ const (
111111
OPUS_PACKET = "opus_packet"
112112
PCAP = "pcap"
113113
PCAPNG = "pcapng"
114+
PE = "pe"
115+
PE_COFF = "pe_coff"
116+
PE_MSDOS_STUB = "pe_msdos_stub"
114117
PNG = "png"
115118
PRORES_FRAME = "prores_frame"
116119
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 {
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 {
23+
24+
d.FieldU32("signature", scalar.UintHex, d.UintAssert(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 {
23+
d.Endian = decode.LittleEndian
24+
25+
d.FieldU16("e_magic", scalar.UintDescription("Magic number"), d.UintAssert(0x5a4d), scalar.UintHex)
26+
d.FieldU16("e_cblp", scalar.UintDescription("Bytes on last page of file"))
27+
d.FieldU16("e_cp", scalar.UintDescription("Pages in file"))
28+
d.FieldU16("e_crlc", scalar.UintDescription("Relocations"))
29+
d.FieldU16("e_cparhdr", scalar.UintDescription("Size of header in paragraphs"))
30+
d.FieldU16("e_minalloc", scalar.UintDescription("Minimum extra paragraphs needed"))
31+
d.FieldU16("e_maxalloc", scalar.UintDescription("Maximum extra paragraphs needed"))
32+
d.FieldU16("e_ss", scalar.UintDescription("Initial (relative) SS value"))
33+
d.FieldU16("e_sp", scalar.UintDescription("Initial SP value"))
34+
d.FieldU16("e_csum", scalar.UintDescription("Checksum"))
35+
d.FieldU16("e_ip", scalar.UintDescription("Initial IP value"))
36+
d.FieldU16("e_cs", scalar.UintDescription("Initial (relative) CS value"))
37+
d.FieldU16("e_lfarlc", scalar.UintDescription("File address of relocation table"))
38+
d.FieldU16("e_ovno", scalar.UintDescription("Overlay number"))
39+
d.FieldRawLen("e_res", 4*16, scalar.BitBufDescription("Reserved words"))
40+
d.FieldU16("e_oemid", scalar.UintDescription("OEM identifier (for e_oeminfo)"))
41+
d.FieldU16("e_oeminfo", scalar.UintDescription("OEM information; e_oemid specific"))
42+
d.FieldRawLen("e_res2", 10*16, scalar.BitBufDescription("Reserved words"))
43+
lfanew := d.FieldU32("e_lfanew", scalar.UintDescription("File address of new exe header"))
44+
45+
// TODO: x86 format in the future
46+
d.FieldRawLen("stub", 64*8, scalar.BitBufDescription("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)