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  }