Commit e9f0fc88 authored by Robin Eklind's avatar Robin Eklind Committed by Alex Brainman

debug/pe: support PE files which contain no symbol table (if NumberOfSymbols is…

debug/pe: support PE files which contain no symbol table (if NumberOfSymbols is equal to 0 in the IMAGE_FILE_HEADER structure).

No longer assume that e_lfanew (in the IMAGE_DOS_HEADER strcuture) is always one byte. It is now regarded as a 4 byte uint32.

Fixes #4177.

R=golang-dev, alex.brainman, dave, minux.ma
CC=golang-dev
https://golang.org/cl/6587048
parent 6f7b66db
...@@ -131,12 +131,13 @@ func NewFile(r io.ReaderAt) (*File, error) { ...@@ -131,12 +131,13 @@ func NewFile(r io.ReaderAt) (*File, error) {
} }
var base int64 var base int64
if dosheader[0] == 'M' && dosheader[1] == 'Z' { if dosheader[0] == 'M' && dosheader[1] == 'Z' {
signoff := int64(binary.LittleEndian.Uint32(dosheader[0x3c:]))
var sign [4]byte var sign [4]byte
r.ReadAt(sign[0:], int64(dosheader[0x3c])) r.ReadAt(sign[:], signoff)
if !(sign[0] == 'P' && sign[1] == 'E' && sign[2] == 0 && sign[3] == 0) { if !(sign[0] == 'P' && sign[1] == 'E' && sign[2] == 0 && sign[3] == 0) {
return nil, errors.New("Invalid PE File Format.") return nil, errors.New("Invalid PE File Format.")
} }
base = int64(dosheader[0x3c]) + 4 base = signoff + 4
} else { } else {
base = int64(0) base = int64(0)
} }
...@@ -148,45 +149,48 @@ func NewFile(r io.ReaderAt) (*File, error) { ...@@ -148,45 +149,48 @@ func NewFile(r io.ReaderAt) (*File, error) {
return nil, errors.New("Invalid PE File Format.") return nil, errors.New("Invalid PE File Format.")
} }
// Get COFF string table, which is located at the end of the COFF symbol table. var ss []byte
sr.Seek(int64(f.FileHeader.PointerToSymbolTable+COFFSymbolSize*f.FileHeader.NumberOfSymbols), os.SEEK_SET) if f.FileHeader.NumberOfSymbols > 0 {
var l uint32 // Get COFF string table, which is located at the end of the COFF symbol table.
if err := binary.Read(sr, binary.LittleEndian, &l); err != nil { sr.Seek(int64(f.FileHeader.PointerToSymbolTable+COFFSymbolSize*f.FileHeader.NumberOfSymbols), os.SEEK_SET)
return nil, err var l uint32
} if err := binary.Read(sr, binary.LittleEndian, &l); err != nil {
ss := make([]byte, l)
if _, err := r.ReadAt(ss, int64(f.FileHeader.PointerToSymbolTable+COFFSymbolSize*f.FileHeader.NumberOfSymbols)); err != nil {
return nil, err
}
// Process COFF symbol table.
sr.Seek(int64(f.FileHeader.PointerToSymbolTable), os.SEEK_SET)
aux := uint8(0)
for i := 0; i < int(f.FileHeader.NumberOfSymbols); i++ {
cs := new(COFFSymbol)
if err := binary.Read(sr, binary.LittleEndian, cs); err != nil {
return nil, err return nil, err
} }
if aux > 0 { ss = make([]byte, l)
aux-- if _, err := r.ReadAt(ss, int64(f.FileHeader.PointerToSymbolTable+COFFSymbolSize*f.FileHeader.NumberOfSymbols)); err != nil {
continue return nil, err
}
var name string
if cs.Name[0] == 0 && cs.Name[1] == 0 && cs.Name[2] == 0 && cs.Name[3] == 0 {
si := int(binary.LittleEndian.Uint32(cs.Name[4:]))
name, _ = getString(ss, si)
} else {
name = cstring(cs.Name[:])
} }
aux = cs.NumberOfAuxSymbols
s := &Symbol{ // Process COFF symbol table.
Name: name, sr.Seek(int64(f.FileHeader.PointerToSymbolTable), os.SEEK_SET)
Value: cs.Value, aux := uint8(0)
SectionNumber: cs.SectionNumber, for i := 0; i < int(f.FileHeader.NumberOfSymbols); i++ {
Type: cs.Type, cs := new(COFFSymbol)
StorageClass: cs.StorageClass, if err := binary.Read(sr, binary.LittleEndian, cs); err != nil {
return nil, err
}
if aux > 0 {
aux--
continue
}
var name string
if cs.Name[0] == 0 && cs.Name[1] == 0 && cs.Name[2] == 0 && cs.Name[3] == 0 {
si := int(binary.LittleEndian.Uint32(cs.Name[4:]))
name, _ = getString(ss, si)
} else {
name = cstring(cs.Name[:])
}
aux = cs.NumberOfAuxSymbols
s := &Symbol{
Name: name,
Value: cs.Value,
SectionNumber: cs.SectionNumber,
Type: cs.Type,
StorageClass: cs.StorageClass,
}
f.Symbols = append(f.Symbols, s)
} }
f.Symbols = append(f.Symbols, s)
} }
// Process sections. // Process sections.
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment