github.com/saferwall/pe@v1.5.2/iat.go (about) 1 // Copyright 2022 Saferwall. All rights reserved. 2 // Use of this source code is governed by Apache v2 license 3 // license that can be found in the LICENSE file. 4 5 package pe 6 7 // IATEntry represents an entry inside the IAT. 8 type IATEntry struct { 9 Index uint32 `json:"index"` 10 Rva uint32 `json:"rva"` 11 Value interface{} `json:"value,omitempty"` 12 Meaning string `json:"meaning"` 13 } 14 15 // The structure and content of the import address table are identical to those 16 // of the import lookup table, until the file is bound. During binding, the 17 // entries in the import address table are overwritten with the 32-bit (for 18 // PE32) or 64-bit (for PE32+) addresses of the symbols that are being imported. 19 // These addresses are the actual memory addresses of the symbols, although 20 // technically they are still called “virtual addresses.” The loader typically 21 // processes the binding. 22 // 23 // The Import Address Table is there to to only trigger Copy On Write for as 24 // few pages as possible (those being the actual Import Address Table pages 25 // themselves). 26 // This is, partially the reason there's that extra level of indirection in the 27 // PE to begin with. 28 func (pe *File) parseIATDirectory(rva, size uint32) error { 29 30 var entries []IATEntry 31 var index uint32 32 var err error 33 34 startRva := rva 35 36 for startRva+size > rva { 37 ie := IATEntry{} 38 offset := pe.GetOffsetFromRva(rva) 39 if pe.Is64 { 40 ie.Value, err = pe.ReadUint64(offset) 41 if err != nil { 42 break 43 } 44 ie.Rva = rva 45 rva += 8 46 } else { 47 ie.Value, err = pe.ReadUint32(offset) 48 if err != nil { 49 break 50 } 51 ie.Rva = rva 52 53 rva += 4 54 } 55 ie.Index = index 56 imp, i := pe.GetImportEntryInfoByRVA(rva) 57 if len(imp.Functions) != 0 { 58 ie.Meaning = imp.Name + "!" + imp.Functions[i].Name 59 } 60 entries = append(entries, ie) 61 index++ 62 } 63 64 pe.IAT = entries 65 pe.HasIAT = true 66 return nil 67 }