From 598568e079993a5369115a26e7ac6d444c637cfa Mon Sep 17 00:00:00 2001 From: HD Moore Date: Thu, 18 Oct 2007 20:42:00 +0000 Subject: [PATCH] New update from dustin git-svn-id: file:///home/svn/framework3/trunk@5157 4d416f70-5f16-0410-b530-b9f4589650da --- lib/rex/pescan/analyze.rb | 334 +++++--------------------------------- 1 file changed, 37 insertions(+), 297 deletions(-) diff --git a/lib/rex/pescan/analyze.rb b/lib/rex/pescan/analyze.rb index d4981038a7..fe80e01f01 100644 --- a/lib/rex/pescan/analyze.rb +++ b/lib/rex/pescan/analyze.rb @@ -1,297 +1,37 @@ -module Rex -module PeScan -module Analyze - - require "rex/ui/text/table" - - class Fingerprint - attr_accessor :pe - - def initialize(pe) - self.pe = pe - end - - def config(param) - @sigs = {} - - name = nil - regx = '' - epon = 0 - sidx = 0 - - fd = File.open(param['database'], 'rb') - fd.each_line do |line| - case line - when /^\s*#/ - next - when /\[\s*(.*)\s*\]/ - if (name) - @sigs[ name ] = [regx, epon] - end - name = $1 + " [#{ sidx+=1 }]" - epon = 0 - next - when /signature\s*=\s*(.*)/ - pat = $1.strip - regx = '' - pat.split(/\s+/).each do |c| - next if c.length != 2 - regx << (c.index('?') ? '.' : "\\x#{c}") - end - when /ep_only\s*=\s*(.*)/ - epon = ($1 =~ /^T/i) ? 1 : 0 - end - end - - if (name and ! @sigs[name]) - @sigs[ name ] = [regx, epon] - end - - fd.close - end - - def scan(param) - config(param) - - epa = pe.hdr.opt.AddressOfEntryPoint - buf = pe.read_rva(epa, 256) - - @sigs.each_pair do |name, data| - begin - if (buf.match(Regexp.new('^' + data[0]))) - $stdout.puts param['file'] + ": " + name - end - rescue RegexpError - $stderr.puts "Invalid signature: #{name} #{data[0]}" - end - end - end - end - - class Information - attr_accessor :pe - - def initialize(pe) - self.pe = pe - end - - def add_fields(tbl, obj, fields) - fields.each do |name| - begin - tbl << [name, "0x%.8x" % obj.send(name)] - rescue ::NoMethodError => e - $stderr.puts "Invalid field #{name}" - end - end - end - - def scan(param) - - $stdout.puts "\n\n" - - tbl = table("Image Headers", ['Name', 'Value']) - add_fields(tbl, pe.hdr.file, %W{ - Characteristics - SizeOfOptionalHeader - PointerToSymbolTable - TimeDateStamp - NumberOfSections - Machine - }) - $stdout.puts tbl.to_s - $stdout.puts "\n\n" - - tbl = table("Optional Image Headers", ['Name', 'Value']) - add_fields(tbl, pe.hdr.opt, %W{ - ImageBase - Magic - MajorLinkerVersion - MinorLinkerVersion - SizeOfCode - SizeOfInitializeData - SizeOfUninitializeData - AddressOfEntryPoint - BaseOfCode - BaseOfData - SectionAlignment - FileAlignment - MajorOperatingSystemVersion - MinorOperatingSystemVersion - MajorImageVersion - MinorImageVersion - MajorSubsystemVersion - MinorSubsystemVersion - Win32VersionValue - SizeOfImage - SizeOfHeaders - CheckSum - Subsystem - DllCharacteristics - SizeOfStackReserve - SizeOfStackCommit - SizeOfHeapReserve - SizeOfHeapCommit - LoaderFlags - NumberOfRvaAndSizes - }) - $stdout.puts tbl.to_s - $stdout.puts "\n\n" - - if (pe.exports) - tbl = table("Exported Functions", ['Ordinal', 'Name', 'Address']) - pe.exports.entries.each do |ent| - tbl << [ent.ordinal, ent.name, "0x%.8x" % pe.rva_to_vma(ent.rva)] - end - $stdout.puts tbl.to_s - $stdout.puts "\n\n" - end - - if (pe.imports) - tbl = table("Imported Functions", ['Library', 'Ordinal', 'Name']) - pe.imports.each do |lib| - lib.entries.each do |ent| - tbl << [lib.name, ent.ordinal, ent.name] - end - end - $stdout.puts tbl.to_s - $stdout.puts "\n\n" - end - - if(pe.config) - tbl = table("Configuration Header", ['Name', 'Value']) - add_fields(tbl, pe.config, %W{ - Size - TimeDateStamp - MajorVersion - MinorVersion - GlobalFlagsClear - GlobalFlagsSet - CriticalSectionDefaultTimeout - DeCommitFreeBlockThreshold - DeCommitTotalFreeThreshold - LockPrefixTable - MaximumAllocationSize - VirtualMemoryThreshold - ProcessAffinityMask - ProcessHeapFlags - CSDVersion - Reserved1 - EditList - SecurityCookie - SEHandlerTable - SEHandlerCount - }) - $stdout.puts tbl.to_s - $stdout.puts "\n\n" - end - - - tbl = table("Resources", ['ID', 'Language', 'Code Page', 'Size', 'Name']) - pe.resources.keys.sort.each do |rkey| - res = pe.resources[rkey] - tbl << [rkey, res.lang, res.code, res.size, res.file] - end - $stdout.puts tbl.to_s - $stdout.puts "\n\n" - - end - - def table(name, cols) - Rex::Ui::Text::Table.new( - 'Header' => name, - 'Columns' => cols - ) - end - end - - - class Ripper - - require "fileutils" - - attr_accessor :pe - - def initialize(pe) - self.pe = pe - end - - def scan(param) - dest = param['dir'] - - if (param['file']) - dest = File.join(dest, File.basename(param['file'])) - end - - FileUtils.mkdir_p(dest) - - pe.resources.keys.sort.each do |rkey| - res = pe.resources[rkey] - path = File.join(dest, rkey.split('/')[1] + '_' + res.file) - - fd = File.new(path, 'w') - fd.write(res.data) - fd.close - end - end - end - - class ContextMapDumper - - attr_accessor :pe - - def initialize(pe) - self.pe = pe - end - - def scan(param) - dest = param['dir'] - path = '' - - FileUtils.mkdir_p(dest) - - if(not (param['dir'] and param['file'])) - $stderr.puts "No directory or file specified" - return - end - - if (param['file']) - path = File.join(dest, File.basename(param['file']) + ".map") - end - - fd = File.new(path, "w") - pe.all_sections.each do |section| - - # Skip over known bad sections - next if section.name == ".data" - next if section.name == ".reloc" - - for offset in 0...section.size - byte = section.read(offset, 1)[0] - if byte != 0 - chunkbase = pe.rva_to_vma( section.base_rva) + offset - data = '' - while byte != 0 - data << byte - offset += 1 - byte = 0 - byte = section.read(offset, 1)[0] if offset < section.size - end - buff = nil - buff = [ 0x01, chunkbase, data.length, data].pack("CNNA*") if data.length > 0 - - fd.write(buff) if buff - end - end - - end - - - fd.close - end - end - -# EOC - -end -end -end +Index: lib/rex/pescan/analyze.rb +=================================================================== +--- lib/rex/pescan/analyze.rb (revision 5155) ++++ lib/rex/pescan/analyze.rb (working copy) +@@ -265,12 +265,28 @@ + next if section.name == ".data" + next if section.name == ".reloc" + +- data = section.read(0, section.size) +- buff = [ 0x01, pe.rva_to_vma( section.base_rva ), data.length, data].pack("CNNA*") ++ offset = 0 ++ while offset < section.size ++ byte = section.read(offset, 1)[0] ++ if byte != 0 ++ chunkbase = pe.rva_to_vma( section.base_rva) + offset ++ data = '' ++ while byte != 0 ++ data << byte ++ offset += 1 ++ byte = 0 ++ byte = section.read(offset, 1)[0] if offset < section.size ++ end ++ buff = nil ++ buff = [ 0x01, chunkbase, data.length, data].pack("CNNA*") if data.length > 0 + +- fd.write(buff) ++ fd.write(buff) if buff ++ end ++ offset += 1 ++ end ++ ++ end + +- end + + fd.close + end