class PEdump::IMAGE_RESOURCE_DIRECTORY

Attributes

base[RW]

Public Class Methods

read(f, root=true) click to toggle source
# File lib/pedump/resources.rb, line 304
def read f, root=true
  if root
    @@loopchk1 = Hash.new(0)
    @@loopchk2 = Hash.new(0)
    @@loopchk3 = Hash.new(0)
    @@nErrors1 = 0
    @@nErrors2 = 0
  elsif (@@loopchk1[f.tell] += 1) > 1
    PEdump.logger.error "[!] #{self}: loop1 detected at file pos #{f.tell}" if @@loopchk1[f.tell] < 2
    return nil
  end
  read_without_children(f).tap do |r|
    nToRead = r.NumberOfNamedEntries.to_i + r.NumberOfIdEntries.to_i
    r.entries = []
    nToRead.times do |i|
      if f.eof?
        PEdump.logger.error "[!] #{self}: #{nToRead} entries in directory, but got EOF on #{i}-th."
        break
      end
      if (@@loopchk2[f.tell] += 1) > 1
        PEdump.logger.error "[!] #{self}: loop2 detected at file pos #{f.tell}" if @@loopchk2[f.tell] < 2
        next
      end
      r.entries << IMAGE_RESOURCE_DIRECTORY_ENTRY.read(f)
    end
    #r.entries.uniq!
    r.entries.each_with_index do |entry,idx|
      entry.name =
        if (entry.Name.to_i & 0x8000_0000 > 0) && f.checked_seek(base + entry.Name & 0x7fff_ffff)
          # Name is an address of unicode string
          nChars = f.read(2).to_s.unpack("v").first.to_i
          begin
            f.read(nChars*2).force_encoding('UTF-16LE').encode!('UTF-8')
          rescue
            PEdump.logger.error "[!] #{self} failed to read entry name: #{$!}"
            if (@@nErrors1+=1) > MAX_ERRORS
              PEdump.logger.warn "[?] too many errors getting resource names, stopped on #{idx} of #{r.entries.size}"
              r.entries = r.entries[0,idx]
              break

            end
            "???"
          end
        else
          # Name is a numeric id
          "##{entry.Name}"
        end
      if entry.OffsetToData
        if (@@loopchk3[entry.OffsetToData] += 1) > 1
          PEdump.logger.error "[!] #{self}: loop3 detected at file pos #{f.tell}" if @@loopchk3[f.tell] < 2
          if (@@nErrors2+=1) > MAX_ERRORS
            PEdump.logger.warn "[?] too many errors getting resource data, stopped on #{idx} of #{r.entries.size}"
            r.entries = r.entries[0,idx]
            break

          end
          next
        end
        next unless f.checked_seek(base + entry.OffsetToData & 0x7fff_ffff)
        entry.data =
          if entry.OffsetToData & 0x8000_0000 > 0
            # child is a directory
            IMAGE_RESOURCE_DIRECTORY.read(f,false)
          else
            # child is a resource
            IMAGE_RESOURCE_DATA_ENTRY.read(f)
          end
      end
    end
    @@loopchk1 = @@loopchk2 = @@loopchk3 = nil if root # save some memory
  end
end
Also aliased as: read_without_children
read_without_children(f, root=true)
Alias for: read