-
Notifications
You must be signed in to change notification settings - Fork 2
/
overlay.go
71 lines (60 loc) · 1.68 KB
/
overlay.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
package pe
import (
"io"
)
type LargestOffsetAndSize struct {
offset, size uint32
}
func (f *File) getOverlayDataStartOffset() uint32 {
if f.OptionalHeader == nil {
return 0
}
largest := &LargestOffsetAndSize{offset: 0, size: 0}
updateIfSumIsLargerAndWithinFile := func(offsetAndSize *LargestOffsetAndSize) *LargestOffsetAndSize {
sum := offsetAndSize.offset + offsetAndSize.size
if sum <= f.size && sum > largest.offset+largest.size {
return offsetAndSize
}
return largest
}
offsetAndSize := &LargestOffsetAndSize{
offset: f.DOSHeader.AddressOfNewEXEHeader + 24,
size: uint32(f.FileHeader.SizeOfOptionalHeader),
}
largest = updateIfSumIsLargerAndWithinFile(offsetAndSize)
for _, section := range f.Sections {
offsetAndSize := &LargestOffsetAndSize{
offset: section.Offset,
size: section.Size,
}
largest = updateIfSumIsLargerAndWithinFile(offsetAndSize)
}
var dds [16]DataDirectory
switch f.Is64 {
case true:
dds = f.OptionalHeader.(*OptionalHeader64).DataDirectory
case false:
dds = f.OptionalHeader.(*OptionalHeader32).DataDirectory
}
for idx, directory := range dds {
if idx == ImageDirectoryEntrySecurity {
continue
}
offsetAndSize := &LargestOffsetAndSize{
offset: f.getOffsetFromRva(directory.VirtualAddress),
size: directory.Size,
}
largest = updateIfSumIsLargerAndWithinFile(offsetAndSize)
}
if f.size-largest.size > largest.offset {
return largest.offset + largest.size
}
return 0
}
func (f *File) GetOverlay() *io.SectionReader {
f.OverlayOffset = int64(f.getOverlayDataStartOffset())
if f.OverlayOffset != 0 {
return io.NewSectionReader(f.sr, f.OverlayOffset, int64(f.size)-f.OverlayOffset)
}
return nil
}