github.com/gocuntian/go@v0.0.0-20160610041250-fee02d270bf8/src/debug/pe/string.go (about) 1 // Copyright 2016 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package pe 6 7 import ( 8 "encoding/binary" 9 "fmt" 10 "io" 11 ) 12 13 // cstring converts ASCII byte sequence b to string. 14 // It stops once it finds 0 or reaches end of b. 15 func cstring(b []byte) string { 16 var i int 17 for i = 0; i < len(b) && b[i] != 0; i++ { 18 } 19 return string(b[:i]) 20 } 21 22 // _StringTable is a COFF string table. 23 type _StringTable []byte 24 25 func readStringTable(fh *FileHeader, r io.ReadSeeker) (_StringTable, error) { 26 // COFF string table is located right after COFF symbol table. 27 offset := fh.PointerToSymbolTable + COFFSymbolSize*fh.NumberOfSymbols 28 _, err := r.Seek(int64(offset), io.SeekStart) 29 if err != nil { 30 return nil, fmt.Errorf("fail to seek to string table: %v", err) 31 } 32 var l uint32 33 err = binary.Read(r, binary.LittleEndian, &l) 34 if err != nil { 35 return nil, fmt.Errorf("fail to read string table length: %v", err) 36 } 37 // string table length includes itself 38 if l <= 4 { 39 return nil, nil 40 } 41 l -= 4 42 buf := make([]byte, l) 43 _, err = io.ReadFull(r, buf) 44 if err != nil { 45 return nil, fmt.Errorf("fail to read string table: %v", err) 46 } 47 return _StringTable(buf), nil 48 } 49 50 // TODO(brainman): decide if start parameter should be int instead of uint32 51 52 // String extracts string from COFF string table st at offset start. 53 func (st _StringTable) String(start uint32) (string, error) { 54 // start includes 4 bytes of string table length 55 if start < 4 { 56 return "", fmt.Errorf("offset %d is before the start of string table", start) 57 } 58 start -= 4 59 if int(start) > len(st) { 60 return "", fmt.Errorf("offset %d is beyond the end of string table", start) 61 } 62 return cstring(st[start:]), nil 63 }