...
Source file
src/debug/pe/string.go
1
2
3
4
5 package pe
6
7 import (
8 "bytes"
9 "encoding/binary"
10 "fmt"
11 "io"
12 )
13
14
15
16 func cstring(b []byte) string {
17 i := bytes.IndexByte(b, 0)
18 if i == -1 {
19 i = len(b)
20 }
21 return string(b[:i])
22 }
23
24
25 type StringTable []byte
26
27 func readStringTable(fh *FileHeader, r io.ReadSeeker) (StringTable, error) {
28
29 if fh.PointerToSymbolTable <= 0 {
30 return nil, nil
31 }
32 offset := fh.PointerToSymbolTable + COFFSymbolSize*fh.NumberOfSymbols
33 _, err := r.Seek(int64(offset), seekStart)
34 if err != nil {
35 return nil, fmt.Errorf("fail to seek to string table: %v", err)
36 }
37 var l uint32
38 err = binary.Read(r, binary.LittleEndian, &l)
39 if err != nil {
40 return nil, fmt.Errorf("fail to read string table length: %v", err)
41 }
42
43 if l <= 4 {
44 return nil, nil
45 }
46 l -= 4
47
48
49
50 const chunk = 10 << 20
51 var buf []byte
52 if l < chunk {
53 buf = make([]byte, l)
54 _, err = io.ReadFull(r, buf)
55 } else {
56 for l > 0 {
57 n := l
58 if n > chunk {
59 n = chunk
60 }
61 buf1 := make([]byte, n)
62 _, err = io.ReadFull(r, buf1)
63 if err != nil {
64 break
65 }
66 buf = append(buf, buf1...)
67 l -= n
68 }
69 }
70 if err != nil {
71 return nil, fmt.Errorf("fail to read string table: %v", err)
72 }
73 return StringTable(buf), nil
74 }
75
76
77
78
79 func (st StringTable) String(start uint32) (string, error) {
80
81 if start < 4 {
82 return "", fmt.Errorf("offset %d is before the start of string table", start)
83 }
84 start -= 4
85 if int(start) > len(st) {
86 return "", fmt.Errorf("offset %d is beyond the end of string table", start)
87 }
88 return cstring(st[start:]), nil
89 }
90
View as plain text