class Metasm::COFF::ImportDirectory

contains the name of dynamic libraries required by the program, and the function to import from them

Attributes

iat[RW]
imports[RW]
libname[RW]

Public Class Methods

decode_all(coff) click to toggle source

decodes all COFF import directories from coff.cursection

# File metasm/exe_format/coff_decode.rb, line 126
def self.decode_all(coff)
        ret = []
        loop do
                idata = decode(coff)
                break if [idata.ilt_p, idata.libname_p].uniq == [0]
                ret << idata
        end
        ret.each { |idata| idata.decode_inner(coff) }
        ret
end
encode(coff, ary) click to toggle source

encode all import directories + iat

# File metasm/exe_format/coff_encode.rb, line 143
def self.encode(coff, ary)
        edata = { 'iat' => [] }
        %w[idata ilt nametable].each { |name| edata[name] = EncodedData.new }

        ary.each { |i| i.encode(coff, edata) }

        it = edata['idata'] <<
        coff.encode_word(0) <<
        coff.encode_word(0) <<
        coff.encode_word(0) <<
        coff.encode_word(0) <<
        coff.encode_word(0) <<
        edata['ilt'] <<
        edata['nametable']

        iat = edata['iat']   # why not fragmented ?

        [it, iat]
end

Public Instance Methods

decode_inner(coff) click to toggle source

decode the tables referenced

# File metasm/exe_format/coff_decode.rb, line 138
def decode_inner(coff)
        if coff.sect_at_rva(@libname_p)
                @libname = coff.decode_strz
        end

        if coff.sect_at_rva(@ilt_p) || coff.sect_at_rva(@iat_p)
                addrs = []
                while (a_ = coff.decode_xword) != 0
                        addrs << a_
                end

                @imports = []

                ord_mask = 1 << (coff.bitsize-1)
                addrs.each { |a|
                        i = Import.new
                        if (a & ord_mask) != 0
                                i.ordinal = a & (~ord_mask)
                        else
                                i.hintname_p = a
                                if coff.sect_at_rva(a)
                                        i.hint = coff.decode_half
                                        i.name = coff.decode_strz
                                end
                        end
                        @imports << i
                }
        end

        if coff.sect_at_rva(@iat_p)
                @iat = []
                while (a = coff.decode_xword) != 0
                        @iat << a
                end
        end
end
encode(coff, edata) click to toggle source

encode one import directory + iat + names in the edata hash received as arg

Calls superclass method Metasm::SerialStruct#encode
# File metasm/exe_format/coff_encode.rb, line 164
def encode(coff, edata)
        edata['iat'] << EncodedData.new
        # edata['ilt'] = edata['iat']
        label = lambda { |n| coff.label_at(edata[n], 0, n) }
        rva_end = lambda { |n| Expression[[label[n], :-, coff.label_at(coff.encoded, 0)], :+, edata[n].virtsize] }

        @libname_p = rva_end['nametable']
        @ilt_p = rva_end['ilt']
        @iat_p ||= Expression[coff.label_at(edata['iat'].last, 0, 'iat'), :-, coff.label_at(coff.encoded, 0)]
        edata['idata'] << super(coff)

        edata['nametable'] << @libname << 0

        ord_mask = 1 << (coff.bitsize - 1)
        @imports.each { |i|
                edata['iat'].last.add_export i.target, edata['iat'].last.virtsize if i.target
                if i.ordinal
                        ptr = coff.encode_xword(Expression[i.ordinal, :|, ord_mask])
                else
                        edata['nametable'].align 2
                        ptr = coff.encode_xword(rva_end['nametable'])
                        edata['nametable'] << coff.encode_half(i.hint || 0) << i.name << 0
                end
                edata['ilt'] << ptr
                edata['iat'].last << ptr
        }
        edata['ilt'] << coff.encode_xword(0)
        edata['iat'].last << coff.encode_xword(0)
end