class PEdump::NE
from wine’s winnt.h
Constants
- DEFAULT_CP
Attributes
io[RW]
offset[RW]
Public Class Methods
cp()
click to toggle source
# File lib/pedump/ne.rb, line 39 def self.cp @@cp || DEFAULT_CP end
cp=(cp)
click to toggle source
# File lib/pedump/ne.rb, line 43 def self.cp= cp @@cp = cp end
read(io, *args)
click to toggle source
Calls superclass method
# File lib/pedump/ne.rb, line 47 def self.read io, *args self.cp = DEFAULT_CP offset = io.tell super.tap do |x| x.io, x.offset = io, offset end end
Public Instance Methods
_detect_codepage(a, io=@io)
click to toggle source
# File lib/pedump/ne.rb, line 228 def _detect_codepage a, io=@io a.find_all{ |res| res.type == 'VERSION' }.each do |res| res.parse(io) res.data.each do |vi| if vi.respond_to?(:Children) && vi.Children.respond_to?(:each) # vi is PEdump::NE::VS_VERSIONINFO vi.Children.each do |vfi| if vfi.is_a?(PEdump::NE::VarFileInfo) && vfi.Children.is_a?(PEdump::NE::Var) var = vfi.Children # var is PEdump::NE::Var if var.respond_to?(:Value) && var.Value.is_a?(Array) && var.Value.size == 2 return var.Value.last end end end end end end nil end
_id2string(id, io, res_base)
click to toggle source
# File lib/pedump/ne.rb, line 186 def _id2string id, io, res_base if id & 0x8000 == 0 # offset to name io.seek id + res_base namesize = (io.getc || 0.chr).ord io.read(namesize) else # numerical id "##{id & 0x7fff}" end end
bundles(io=@io)
click to toggle source
# File lib/pedump/ne.rb, line 369 def bundles io=@io io.seek @offset+ne_enttab bundles = [] while bundle = Bundle.read(io) bundles << bundle end bundles end
entrypoints(io=@io)
click to toggle source
# File lib/pedump/ne.rb, line 378 def entrypoints io=@io @entrypoints ||= begin r = [0] # entrypoint indexes are 1-based bundles(io).each do |b| if b.entries.empty? b.num_entries.times{ r<<0 } else b.entries.each do |e| if e.is_a?(Bundle::MovableEntry) r << (e.seg_idx<<16) + e.offset elsif e.is_a?(Bundle::FixedEntry) r << (b.seg_idx<<16) + e.offset else raise "invalid ep #{e.inspect}" end end end end r end end
exports(io=@io)
click to toggle source
first string with ordinal 0 is a module name
# File lib/pedump/ne.rb, line 309 def exports io=@io exp_dir = IMAGE_EXPORT_DIRECTORY.new exp_dir.functions = [] io.seek @offset+ne_restab while !io.eof && (namelen = io.getc.ord) > 0 exp_dir.functions << ExportedFunction.new( io.read(namelen), io.read(2).unpack('v').first, 0 ) end exp_dir.name = exp_dir.functions.shift.name if exp_dir.functions.any? a = [] io.seek ne_nrestab while !io.eof && (namelen = io.getc.ord) > 0 a << ExportedFunction.new( io.read(namelen), io.read(2).unpack('v').first, 0 ) end exp_dir.description = a.shift.name if a.any? exp_dir.functions += a exp_dir.functions.each do |f| f.va = entrypoints[f.ord] end exp_dir end
imports(io=@io)
click to toggle source
# File lib/pedump/ne.rb, line 277 def imports io=@io @imports ||= begin io.seek @offset+ne_modtab modules = io.read(2*ne_cmod).unpack('v*') modules.map! do |ofs| io.seek @offset+ne_imptab+ofs namelen = io.getc.ord io.read(namelen) end r = [] segments(io).each do |seg| seg.relocs.each do |rel| if rel.type == Reloc::TYPE_IMPORTORDINAL r << (f = PEdump::ImportedFunction.new) f.module_name = modules[rel.module_idx-1] f.ordinal = rel.func_idx elsif rel.type == Reloc::TYPE_IMPORTNAME r << (f = PEdump::ImportedFunction.new) f.module_name = modules[rel.module_idx-1] io.seek @offset+ne_imptab+rel.func_idx namelen = io.getc.ord f.name = io.read(namelen) end end end r end end
resource_directory(io=@io)
click to toggle source
# File lib/pedump/ne.rb, line 198 def resource_directory io=@io @resource_directory ||= begin res_base = ne_rsrctab+@offset io.seek res_base res_shift = io.read(2).unpack('v').first unless (0..16).include?(res_shift) PEdump.logger.error "[!] invalid res_shift = %d" % res_shift return [] end PEdump.logger.info "[.] res_shift = %d" % res_shift r = [] while !io.eof? && (g = ResourceGroup.read(io)) r << g end r.each do |g| g.type = (g.type_id & 0x8000 != 0) && PEdump::ROOT_RES_NAMES[g.type_id & 0x7fff] g.type ||= _id2string( g.type_id, io, res_base) g.children.each do |res| res.name = _id2string(res.name_offset, io, res_base) res.offset ||= 0 res.offset <<= res_shift res.size ||= 0 res.size <<= res_shift end end r end end
resources(io=@io)
click to toggle source
# File lib/pedump/ne.rb, line 249 def resources io=@io a = [] resource_directory(io).each do |grp| grp.children.each do |res| a << (r = Resource.new) r.id = (res.name_offset & 0x7fff) if (res.name_offset & 0x8000) != 0 r.type = grp.type r.size = res.size r.name = res.name r.file_offset = res.offset r.reserved = res.reserved end end # try to detect codepage cp = _detect_codepage(a, io) if cp PEdump::NE.cp = cp # XXX HACK PEdump.logger.info "[.] detect_codepage: #{cp.inspect}" else cp = DEFAULT_CP PEdump.logger.info "[.] detect_codepage failed, using default #{cp}" end a.each{ |r| r.parse(io, :cp => cp) } a end
segments(io=@io)
click to toggle source
# File lib/pedump/ne.rb, line 108 def segments io=@io @segments ||= io && begin io.seek ne_segtab+@offset ne_cseg.times.map{ Segment.read(io) }.each do |seg| seg.file_offset = seg.offset << ne_align seg.relocs = [] if (seg.flags & Segment::FLAG_RELOCINFO) != 0 io.seek seg.file_offset + seg.size nRelocs = io.read(2).unpack('v').first seg.relocs = nRelocs.times.map{ Reloc.read(io) } end end end end