class Rex::PeScan::Analyze::Information
Attributes
pe[RW]
Public Class Methods
new(pe)
click to toggle source
# File lib/rex/pescan/analyze.rb, line 74 def initialize(pe) self.pe = pe end
Public Instance Methods
add_fields(tbl, obj, fields)
click to toggle source
# File lib/rex/pescan/analyze.rb, line 78 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
scan(param)
click to toggle source
# File lib/rex/pescan/analyze.rb, line 88 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" # Get DllCharacteristics (in Integer) dllcharacteristics = pe.hdr.opt.struct[23].value if (dllcharacteristics > 0) tbl = table("DllCharacteristics", ['Flag', 'Value']) # http://msdn.microsoft.com/en-us/library/ms680339(v=vs.85).aspx traits = { :ASLR => 'False', #IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE :Integrity => 'False', #IMAGE_DLLCHARACTERISTICS_FORCE_INTEGRITY :NX => 'False', #IMAGE_DLLCHARACTERISTICS_NX_COMPAT :Isolation => 'False', #IMAGE_DLLCHARACTERISTICS_NO_ISOLATION :SEH => 'False', #IMAGE_DLLCHARACTERISTICS_NO_SEH :Bind => 'False', #IMAGE_DLLCHARACTERISTICS_NO_BIND :WDM => 'False', #IMAGE_DLLCHARACTERISTICS_WDM_DRIVER :Terminal => 'False' #IMAGE_DLLCHARACTERISTICS_TERMINAL_SERVER_AWARE } # Convert integer to an bit array c_bits = ("%32d" %dllcharacteristics.to_s(2)).split('').map { |e| e.to_i }.reverse # Check characteristics traits[:ASLR] = 'True' if c_bits[6] == 1 #0x0040 traits[:Integrity] = 'True' if c_bits[7] == 1 #0x0080 traits[:NX] = 'True' if c_bits[8] == 1 #0x0100 traits[:Isolation] = 'True' if c_bits[9] == 1 #0x0200 traits[:SEH] = 'True' if c_bits[10] == 1 #0x0400 traits[:Bind] = 'True' if c_bits[11] == 1 #0x0800 traits[:WDM] = 'True' if c_bits[13] == 1 #2000 traits[:Terminal] = 'True' if c_bits[15] == 1 #0x8000 # Putting results to table traits.each do |trait_name, trait_value| tbl << [trait_name, trait_value] end $stdout.puts tbl.to_s $stdout.puts "\n\n" end 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 # Rex::PeParsey::Pe doesn't seem to give us any offset information for each function, # which makes it difficult to calculate the actual addresses for them. So instead we # are using Metasm::COFF::ImportDirectory to do this task. The ability to see # addresses is mainly for ROP. if (pe.imports) tbl = table("Imported Functions", ['Library', 'Address', 'Ordinal', 'Name']) exefmt = Metasm::AutoExe.orshellcode{ Metasm.const_get('x86_64').new } exe = exefmt.decode_file(pe._isource.file.path) ibase = pe.image_base exe_imports = exe.imports exe_imports.each do |lib| lib_name = lib.libname ini_offset = lib.iat_p func_table = lib.imports offset = 0 func_table.each do |func| func_addr = "0x%08x" %(ibase + ini_offset + offset) tbl << [lib_name, func_addr, func.hint, func.name] offset += 4 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 if(pe.resources) 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 tbl = table("Section Header", ["Name", "VirtualAddress", "SizeOfRawData", "Characteristics"]) pe.sections.each do |sec| tbl << [ sec.name, *[sec.vma, sec.raw_size, sec.flags].map{|x| "0x%.8x" % x} ] end $stdout.puts tbl.to_s $stdout.puts "\n\n" end
table(name, cols)
click to toggle source
# File lib/rex/pescan/analyze.rb, line 264 def table(name, cols) Rex::Ui::Text::Table.new( 'Header' => name, 'Columns' => cols ) end