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 1, 2023
1 parent 94834c0 commit 1c60391
Show file tree
Hide file tree
Showing 5 changed files with 133 additions and 1 deletion.
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/prores"
_ "github.com/wader/fq/format/protobuf"
Expand Down
5 changes: 4 additions & 1 deletion format/format.go
Original file line number Diff line number Diff line change
Expand Up @@ -114,14 +114,17 @@ var (
OpusPacket = &decode.Group{Name: "opus_packet"}
Pcap = &decode.Group{Name: "pcap"}
Pcapng = &decode.Group{Name: "pcapng"}
Pe = &decode.Group{Name: "pe"}
PeCoff = &decode.Group{Name: "pe_coff"}
PeMsdosStub = &decode.Group{Name: "pe_msdos_stub"}
Png = &decode.Group{Name: "png"}
ProresFrame = &decode.Group{Name: "prores_frame"}
Protobuf = &decode.Group{Name: "protobuf"}
ProtobufWidevine = &decode.Group{Name: "protobuf_widevine"}
PsshPlayready = &decode.Group{Name: "pssh_playready"}
Rtmp = &decode.Group{Name: "rtmp"}
SllPacket = &decode.Group{Name: "sll_packet"}
Sll2Packet = &decode.Group{Name: "sll2_packet"}
SllPacket = &decode.Group{Name: "sll_packet"}
Tar = &decode.Group{Name: "tar"}
TcpSegment = &decode.Group{Name: "tcp_segment"}
Tiff = &decode.Group{Name: "tiff"}
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.PeMsdosStub}, Out: &peMSDosStubGroup},
{Groups: []*decode.Group{format.PeCoff}, 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.PeCoff,
&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.PeMsdosStub,
&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 1c60391

Please sign in to comment.