Skip to content

Commit 613d957

Browse files
committed
pe: parse overlay at end of PE file
1 parent 6f7e3f7 commit 613d957

File tree

2 files changed

+56
-2
lines changed

2 files changed

+56
-2
lines changed

Diff for: overlay.go

+46
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
package pe
2+
3+
import (
4+
"io"
5+
6+
"github.com/pkg/errors"
7+
)
8+
9+
// Overlay returns the overlay of the PE fil (i.e. any optional bytes directly
10+
// succeeding the image).
11+
func (file *File) Overlay() ([]byte, error) {
12+
if file.overlay == nil {
13+
if err := file.parseOverlay(); err != nil {
14+
return nil, err
15+
}
16+
}
17+
return file.overlay, nil
18+
}
19+
20+
// parseOverlay parses the overlay of the PE file.
21+
func (file *File) parseOverlay() error {
22+
// Locate start of overlay (i.e. end of image).
23+
overlayStart := int64(0)
24+
sectHdrs, err := file.SectHeaders()
25+
if err != nil {
26+
return errors.WithStack(err)
27+
}
28+
for _, sectHdr := range sectHdrs {
29+
sectStart := int64(sectHdr.Offset + sectHdr.Size)
30+
if sectStart > overlayStart {
31+
overlayStart = sectStart
32+
}
33+
}
34+
// Locate end of overlay (i.e. end of file).
35+
overlayEnd, err := file.r.Seek(0, io.SeekEnd)
36+
if err != nil {
37+
return errors.WithStack(err)
38+
}
39+
overlaySize := overlayEnd - overlayStart
40+
overlay := make([]byte, overlaySize)
41+
if _, err := file.r.ReadAt(overlay, overlayStart); err != nil {
42+
return errors.WithStack(err)
43+
}
44+
file.overlay = overlay
45+
return nil
46+
}

Diff for: pe.go

+10-2
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,10 @@ type File struct {
1818
opthdr *OptHeader
1919
// Section headers.
2020
sectHdrs []*SectHeader
21+
// Overlay.
22+
overlay []byte
2123
// Underlying reader.
22-
r io.ReaderAt
24+
r ReadAtSeeker
2325
io.Closer
2426
}
2527

@@ -40,8 +42,14 @@ func Open(path string) (file *File, err error) {
4042
return file, nil
4143
}
4244

45+
// ReadAtSeeker is the interface that wraps the basic ReadAt and Seek methods.
46+
type ReadAtSeeker interface {
47+
io.ReaderAt
48+
io.Seeker
49+
}
50+
4351
// New returns a new File for accessing the PE binary of r.
44-
func New(r io.ReaderAt) (file *File, err error) {
52+
func New(r ReadAtSeeker) (file *File, err error) {
4553
// TODO(u): Figure out which headers that should always be parsed.
4654
// * DOS header
4755
// - Contains no relevant information, but is required to locate the

0 commit comments

Comments
 (0)