Skip to content

Commit 1c60391

Browse files
committed
WIP: pe: Add decoder
1 parent 94834c0 commit 1c60391

File tree

5 files changed

+133
-1
lines changed

5 files changed

+133
-1
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: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -114,14 +114,17 @@ var (
114114
OpusPacket = &decode.Group{Name: "opus_packet"}
115115
Pcap = &decode.Group{Name: "pcap"}
116116
Pcapng = &decode.Group{Name: "pcapng"}
117+
Pe = &decode.Group{Name: "pe"}
118+
PeCoff = &decode.Group{Name: "pe_coff"}
119+
PeMsdosStub = &decode.Group{Name: "pe_msdos_stub"}
117120
Png = &decode.Group{Name: "png"}
118121
ProresFrame = &decode.Group{Name: "prores_frame"}
119122
Protobuf = &decode.Group{Name: "protobuf"}
120123
ProtobufWidevine = &decode.Group{Name: "protobuf_widevine"}
121124
PsshPlayready = &decode.Group{Name: "pssh_playready"}
122125
Rtmp = &decode.Group{Name: "rtmp"}
123-
SllPacket = &decode.Group{Name: "sll_packet"}
124126
Sll2Packet = &decode.Group{Name: "sll2_packet"}
127+
SllPacket = &decode.Group{Name: "sll_packet"}
125128
Tar = &decode.Group{Name: "tar"}
126129
TcpSegment = &decode.Group{Name: "tcp_segment"}
127130
Tiff = &decode.Group{Name: "tiff"}

format/pe/pe.go

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
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+
// TODO: not pe_ prefix for format names?
13+
14+
var peMSDosStubGroup decode.Group
15+
var peCOFFGroup decode.Group
16+
17+
func init() {
18+
interp.RegisterFormat(
19+
format.Pe,
20+
&decode.Format{
21+
Description: "Portable Executable",
22+
Groups: []*decode.Group{format.Probe},
23+
Dependencies: []decode.Dependency{
24+
{Groups: []*decode.Group{format.PeMsdosStub}, Out: &peMSDosStubGroup},
25+
{Groups: []*decode.Group{format.PeCoff}, Out: &peCOFFGroup},
26+
},
27+
DecodeFn: peDecode,
28+
})
29+
}
30+
31+
func peDecode(d *decode.D) any {
32+
33+
d.FieldFormat("ms_dos_stub", &peMSDosStubGroup, nil)
34+
d.FieldFormat("coff", &peCOFFGroup, nil)
35+
36+
return nil
37+
}

format/pe/pe_coff.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+
"github.com/wader/fq/pkg/scalar"
10+
)
11+
12+
// TODO: probe?
13+
14+
func init() {
15+
interp.RegisterFormat(
16+
format.PeCoff,
17+
&decode.Format{
18+
Description: "Common Object File Format",
19+
DecodeFn: peCoffStubDecode,
20+
})
21+
}
22+
23+
func peCoffStubDecode(d *decode.D) any {
24+
25+
d.FieldU32("signature", scalar.UintHex, d.UintAssert(0x50450000))
26+
d.FieldU16("machine")
27+
d.FieldU16("number_of_sections")
28+
d.FieldU32("time_date_stamp")
29+
d.FieldU32("pointer_to_symbol_table")
30+
d.FieldU32("number_of_symbol_table")
31+
d.FieldU16("size_of_optional_header")
32+
d.FieldU16("characteristics")
33+
34+
return nil
35+
}

format/pe/pe_msdos_stub.go

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
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(
16+
format.PeMsdosStub,
17+
&decode.Format{
18+
Description: "MS-DOS Stub",
19+
DecodeFn: msDosStubDecode,
20+
})
21+
}
22+
23+
func msDosStubDecode(d *decode.D) any {
24+
d.Endian = decode.LittleEndian
25+
26+
d.FieldU16("e_magic", scalar.UintDescription("Magic number"), d.UintAssert(0x5a4d), scalar.UintHex)
27+
d.FieldU16("e_cblp", scalar.UintDescription("Bytes on last page of file"))
28+
d.FieldU16("e_cp", scalar.UintDescription("Pages in file"))
29+
d.FieldU16("e_crlc", scalar.UintDescription("Relocations"))
30+
d.FieldU16("e_cparhdr", scalar.UintDescription("Size of header in paragraphs"))
31+
d.FieldU16("e_minalloc", scalar.UintDescription("Minimum extra paragraphs needed"))
32+
d.FieldU16("e_maxalloc", scalar.UintDescription("Maximum extra paragraphs needed"))
33+
d.FieldU16("e_ss", scalar.UintDescription("Initial (relative) SS value"))
34+
d.FieldU16("e_sp", scalar.UintDescription("Initial SP value"))
35+
d.FieldU16("e_csum", scalar.UintDescription("Checksum"))
36+
d.FieldU16("e_ip", scalar.UintDescription("Initial IP value"))
37+
d.FieldU16("e_cs", scalar.UintDescription("Initial (relative) CS value"))
38+
d.FieldU16("e_lfarlc", scalar.UintDescription("File address of relocation table"))
39+
d.FieldU16("e_ovno", scalar.UintDescription("Overlay number"))
40+
d.FieldRawLen("e_res", 4*16, scalar.BitBufDescription("Reserved words"))
41+
d.FieldU16("e_oemid", scalar.UintDescription("OEM identifier (for e_oeminfo)"))
42+
d.FieldU16("e_oeminfo", scalar.UintDescription("OEM information; e_oemid specific"))
43+
d.FieldRawLen("e_res2", 10*16, scalar.BitBufDescription("Reserved words"))
44+
lfanew := d.FieldU32("e_lfanew", scalar.UintDescription("File address of new exe header"))
45+
46+
// TODO: x86 format in the future
47+
d.FieldRawLen("stub", 64*8, scalar.BitBufDescription("Sub program"))
48+
49+
subEndPos := d.Pos()
50+
51+
// TODO: is not padding i guess?
52+
padding := lfanew*8 - uint64(subEndPos)
53+
d.FieldRawLen("padding", int64(padding))
54+
55+
return nil
56+
}

0 commit comments

Comments
 (0)