Parent

Class/Module Index [+]

Quicksearch

Rex::PeParsey::PeBase

Constants

IMAGE_BASE_RELOCATION
IMAGE_BASE_RELOCATION_TYPE_OFFSET
IMAGE_DATA_DIRECTORY
IMAGE_DATA_DIRECTORY_SIZE
IMAGE_DIRECTORY_ENTRY_ARCHITECTURE
IMAGE_DIRECTORY_ENTRY_BASERELOC
IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT
IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR
IMAGE_DIRECTORY_ENTRY_COPYRIGHT
IMAGE_DIRECTORY_ENTRY_DEBUG
IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT
IMAGE_DIRECTORY_ENTRY_EXCEPTION
IMAGE_DIRECTORY_ENTRY_EXPORT
IMAGE_DIRECTORY_ENTRY_GLOBALPTR
IMAGE_DIRECTORY_ENTRY_IAT
IMAGE_DIRECTORY_ENTRY_IMPORT
IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG
IMAGE_DIRECTORY_ENTRY_RESOURCE
IMAGE_DIRECTORY_ENTRY_SECURITY
IMAGE_DIRECTORY_ENTRY_TLS
IMAGE_DOS_HEADER
IMAGE_DOS_HEADER_SIZE

typedef struct _IMAGE_DOS_HEADER { // DOS .EXE header

  WORD   e_magic;                     // Magic number
  WORD   e_cblp;                      // Bytes on last page of file
  WORD   e_cp;                        // Pages in file
  WORD   e_crlc;                      // Relocations
  WORD   e_cparhdr;                   // Size of header in paragraphs
  WORD   e_minalloc;                  // Minimum extra paragraphs needed
  WORD   e_maxalloc;                  // Maximum extra paragraphs needed
  WORD   e_ss;                        // Initial (relative) SS value
  WORD   e_sp;                        // Initial SP value
  WORD   e_csum;                      // Checksum
  WORD   e_ip;                        // Initial IP value
  WORD   e_cs;                        // Initial (relative) CS value
  WORD   e_lfarlc;                    // File address of relocation table
  WORD   e_ovno;                      // Overlay number
  WORD   e_res[4];                    // Reserved words
  WORD   e_oemid;                     // OEM identifier (for e_oeminfo)
  WORD   e_oeminfo;                   // OEM information; e_oemid specific
  WORD   e_res2[10];                  // Reserved words
  LONG   e_lfanew;                    // File address of new exe header
} IMAGE_DOS_HEADER, *PIMAGE_DOS_HEADER;
IMAGE_DOS_SIGNATURE

define IMAGE_DOS_SIGNATURE 0x5A4D // MZ

IMAGE_EXPORT_DESCRIPTOR
IMAGE_EXPORT_DESCRIPTOR_SIZE

typedef struct _IMAGE_EXPORT_DIRECTORY {

DWORD   Characteristics;
DWORD   TimeDateStamp;
WORD    MajorVersion;
WORD    MinorVersion;
DWORD   Name;
DWORD   Base;
DWORD   NumberOfFunctions;
DWORD   NumberOfNames;
DWORD   AddressOfFunctions;     // RVA from base of image
DWORD   AddressOfNames;         // RVA from base of image
DWORD   AddressOfNameOrdinals;  // RVA from base of image

} IMAGE_EXPORT_DIRECTORY, *PIMAGE_EXPORT_DIRECTORY;

IMAGE_FILE_HEADER
IMAGE_FILE_HEADER_SIZE
IMAGE_FILE_MACHINE_ALPHA64
IMAGE_FILE_MACHINE_AMD64
IMAGE_FILE_MACHINE_I386
IMAGE_FILE_MACHINE_IA64
IMAGE_IMPORT_DESCRIPTOR
IMAGE_IMPORT_DESCRIPTOR_SIZE
IMAGE_LOAD_CONFIG_DIRECTORY32

typedef struct {

DWORD   Size;
DWORD   TimeDateStamp;
WORD    MajorVersion;
WORD    MinorVersion;
DWORD   GlobalFlagsClear;
DWORD   GlobalFlagsSet;
DWORD   CriticalSectionDefaultTimeout;
DWORD   DeCommitFreeBlockThreshold;
DWORD   DeCommitTotalFreeThreshold;
DWORD   LockPrefixTable;            // VA
DWORD   MaximumAllocationSize;
DWORD   VirtualMemoryThreshold;
DWORD   ProcessHeapFlags;
DWORD   ProcessAffinityMask;
WORD    CSDVersion;
WORD    Reserved1;
DWORD   EditList;                   // VA
DWORD   SecurityCookie;             // VA
DWORD   SEHandlerTable;             // VA
DWORD   SEHandlerCount;

} IMAGE_LOAD_CONFIG_DIRECTORY32, *PIMAGE_LOAD_CONFIG_DIRECTORY32;

IMAGE_LOAD_CONFIG_DIRECTORY64

typedef struct {

ULONG      Size;
ULONG      TimeDateStamp;
USHORT     MajorVersion;
USHORT     MinorVersion;
ULONG      GlobalFlagsClear;
ULONG      GlobalFlagsSet;
ULONG      CriticalSectionDefaultTimeout;
ULONGLONG  DeCommitFreeBlockThreshold;
ULONGLONG  DeCommitTotalFreeThreshold;
ULONGLONG  LockPrefixTable;         // VA
ULONGLONG  MaximumAllocationSize;
ULONGLONG  VirtualMemoryThreshold;
ULONGLONG  ProcessAffinityMask;
ULONG      ProcessHeapFlags;
USHORT     CSDVersion;
USHORT     Reserved1;
ULONGLONG  EditList;                // VA
ULONGLONG  SecurityCookie;          // VA
ULONGLONG  SEHandlerTable;          // VA
ULONGLONG  SEHandlerCount;

} IMAGE_LOAD_CONFIG_DIRECTORY64, *PIMAGE_LOAD_CONFIG_DIRECTORY64;

IMAGE_LOAD_TLS_DIRECTORY32

typedef struct {

DWORD   Size;
DWORD   TimeDateStamp;
WORD    MajorVersion;
WORD    MinorVersion;
DWORD   GlobalFlagsClear;
DWORD   GlobalFlagsSet;
DWORD   CriticalSectionDefaultTimeout;
DWORD   DeCommitFreeBlockThreshold;
DWORD   DeCommitTotalFreeThreshold;
DWORD   LockPrefixTable;            // VA
DWORD   MaximumAllocationSize;
DWORD   VirtualMemoryThreshold;
DWORD   ProcessHeapFlags;
DWORD   ProcessAffinityMask;
WORD    CSDVersion;
WORD    Reserved1;
DWORD   EditList;                   // VA
DWORD   SecurityCookie;             // VA
DWORD   SEHandlerTable;             // VA
DWORD   SEHandlerCount;

} IMAGE_LOAD_CONFIG_DIRECTORY32, *PIMAGE_LOAD_CONFIG_DIRECTORY32;

IMAGE_LOAD_TLS_DIRECTORY64

typedef struct {

ULONG      Size;
ULONG      TimeDateStamp;
USHORT     MajorVersion;
USHORT     MinorVersion;
ULONG      GlobalFlagsClear;
ULONG      GlobalFlagsSet;
ULONG      CriticalSectionDefaultTimeout;
ULONGLONG  DeCommitFreeBlockThreshold;
ULONGLONG  DeCommitTotalFreeThreshold;
ULONGLONG  LockPrefixTable;         // VA
ULONGLONG  MaximumAllocationSize;
ULONGLONG  VirtualMemoryThreshold;
ULONGLONG  ProcessAffinityMask;
ULONG      ProcessHeapFlags;
USHORT     CSDVersion;
USHORT     Reserved1;
ULONGLONG  EditList;                // VA
ULONGLONG  SecurityCookie;          // VA
ULONGLONG  SEHandlerTable;          // VA
ULONGLONG  SEHandlerCount;

} IMAGE_LOAD_CONFIG_DIRECTORY64, *PIMAGE_LOAD_CONFIG_DIRECTORY64;

IMAGE_NT_OPTIONAL_HDR32_MAGIC

typedef struct _IMAGE_OPTIONAL_HEADER {

//
// Standard fields.
//

WORD    Magic;
BYTE    MajorLinkerVersion;
BYTE    MinorLinkerVersion;
DWORD   SizeOfCode;
DWORD   SizeOfInitializedData;
DWORD   SizeOfUninitializedData;
DWORD   AddressOfEntryPoint;
DWORD   BaseOfCode;
DWORD   BaseOfData;

//
// NT additional fields.
//

DWORD   ImageBase;
DWORD   SectionAlignment;
DWORD   FileAlignment;
WORD    MajorOperatingSystemVersion;
WORD    MinorOperatingSystemVersion;
WORD    MajorImageVersion;
WORD    MinorImageVersion;
WORD    MajorSubsystemVersion;
WORD    MinorSubsystemVersion;
DWORD   Win32VersionValue;
DWORD   SizeOfImage;
DWORD   SizeOfHeaders;
DWORD   CheckSum;
WORD    Subsystem;
WORD    DllCharacteristics;
DWORD   SizeOfStackReserve;
DWORD   SizeOfStackCommit;
DWORD   SizeOfHeapReserve;
DWORD   SizeOfHeapCommit;
DWORD   LoaderFlags;
DWORD   NumberOfRvaAndSizes;
IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES];

} IMAGE_OPTIONAL_HEADER32, *PIMAGE_OPTIONAL_HEADER32;

define IMAGE_NT_OPTIONAL_HDR32_MAGIC 0x10b define IMAGE_SIZEOF_NT_OPTIONAL32_HEADER 224

IMAGE_NT_OPTIONAL_HDR64_MAGIC

typedef struct _IMAGE_OPTIONAL_HEADER64 {

USHORT      Magic;
UCHAR       MajorLinkerVersion;
UCHAR       MinorLinkerVersion;
ULONG       SizeOfCode;
ULONG       SizeOfInitializedData;
ULONG       SizeOfUninitializedData;
ULONG       AddressOfEntryPoint;
ULONG       BaseOfCode;
ULONGLONG   ImageBase;
ULONG       SectionAlignment;
ULONG       FileAlignment;
USHORT      MajorOperatingSystemVersion;
USHORT      MinorOperatingSystemVersion;
USHORT      MajorImageVersion;
USHORT      MinorImageVersion;
USHORT      MajorSubsystemVersion;
USHORT      MinorSubsystemVersion;
ULONG       Win32VersionValue;
ULONG       SizeOfImage;
ULONG       SizeOfHeaders;
ULONG       CheckSum;
USHORT      Subsystem;
USHORT      DllCharacteristics;
ULONGLONG   SizeOfStackReserve;
ULONGLONG   SizeOfStackCommit;
ULONGLONG   SizeOfHeapReserve;
ULONGLONG   SizeOfHeapCommit;
ULONG       LoaderFlags;
ULONG       NumberOfRvaAndSizes;
IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES];

} IMAGE_OPTIONAL_HEADER64, *PIMAGE_OPTIONAL_HEADER64;

define IMAGE_NT_OPTIONAL_HDR64_MAGIC 0x20b define IMAGE_SIZEOF_NT_OPTIONAL64_HEADER 240

IMAGE_NT_SIGNATURE

typedef struct _IMAGE_FILE_HEADER {

WORD    Machine;
WORD    NumberOfSections;
DWORD   TimeDateStamp;
DWORD   PointerToSymbolTable;
DWORD   NumberOfSymbols;
WORD    SizeOfOptionalHeader;
WORD    Characteristics;

} IMAGE_FILE_HEADER, *PIMAGE_FILE_HEADER;

define IMAGE_NT_SIGNATURE 0x00004550 // PE00 define IMAGE_FILE_MACHINE_I386 0x014c // Intel 386. define IMAGE_FILE_MACHINE_IA64 0x0200 // Intel 64 define IMAGE_FILE_MACHINE_ALPHA64 0x0284 // ALPHA64 define IMAGE_FILE_MACHINE_AMD64 0x8664 // AMD64 (K8) define IMAGE_SIZEOF_FILE_HEADER 20

IMAGE_NUMBEROF_DIRECTORY_ENTRIES

typedef struct _IMAGE_DATA_DIRECTORY {

DWORD   VirtualAddress;
DWORD   Size;

} IMAGE_DATA_DIRECTORY, *PIMAGE_DATA_DIRECTORY;

IMAGE_OPTIONAL_HEADER32
IMAGE_OPTIONAL_HEADER64
IMAGE_ORDINAL_FLAG32

typedef struct _IMAGE_IMPORT_DESCRIPTOR {

union {
    DWORD   Characteristics;            // 0 for terminating null import descriptor
    DWORD   OriginalFirstThunk;         // RVA to original unbound IAT (PIMAGE_THUNK_DATA)
};
DWORD   TimeDateStamp;                  // 0 if not bound,
                                        // -1 if bound, and real date\time stamp
                                        //     in IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT (new BIND)
                                        // O.W. date/time stamp of DLL bound to (Old BIND)

DWORD   ForwarderChain;                 // -1 if no forwarders
DWORD   Name;
DWORD   FirstThunk;                     // RVA to IAT (if bound this IAT has actual addresses)

} IMAGE_IMPORT_DESCRIPTOR;

IMAGE_RUNTIME_FUNCTION_ENTRY
IMAGE_RUNTIME_FUNCTION_ENTRY_SZ

typedef struct _IMAGE_RUNTIME_FUNCTION_ENTRY {

DWORD BeginAddress;
DWORD EndAddress;
DWORD UnwindInfoAddress;

} _IMAGE_RUNTIME_FUNCTION_ENTRY, *_PIMAGE_RUNTIME_FUNCTION_ENTRY;

IMAGE_SECTION_HEADER
IMAGE_SIZEOF_BASE_RELOCATION

typedef struct _IMAGE_BASE_RELOCATION {

DWORD   VirtualAddress;
DWORD   SizeOfBlock;

// WORD TypeOffset; } IMAGE_BASE_RELOCATION; typedef IMAGE_BASE_RELOCATION UNALIGNED * PIMAGE_BASE_RELOCATION;

define IMAGE_SIZEOF_BASE_RELOCATION 8

IMAGE_SIZEOF_NT_OPTIONAL32_HEADER
IMAGE_SIZEOF_NT_OPTIONAL64_HEADER
IMAGE_SIZEOF_SECTION_HEADER

typedef struct _IMAGE_SECTION_HEADER {

BYTE    Name[IMAGE_SIZEOF_SHORT_NAME];
union {
        DWORD   PhysicalAddress;
        DWORD   VirtualSize;
} Misc;
DWORD   VirtualAddress;
DWORD   SizeOfRawData;
DWORD   PointerToRawData;
DWORD   PointerToRelocations;
DWORD   PointerToLinenumbers;
WORD    NumberOfRelocations;
WORD    NumberOfLinenumbers;
DWORD   Characteristics;

} IMAGE_SECTION_HEADER, *PIMAGE_SECTION_HEADER;

define IMAGE_SIZEOF_SECTION_HEADER 40

SUPPORTED_MACHINES
UNWIND_INFO_HEADER
UNWIND_INFO_HEADER_SZ
UNW_FLAG_CHAININFO
UNW_FLAG_EHANDLER
UNW_FLAG_UHANDLER
UWOP_ALLOC_LARGE
UWOP_ALLOC_SMALL
UWOP_PUSH_MACHFRAME
UWOP_PUSH_NONVOL
UWOP_SAVE_NONVOL
UWOP_SAVE_NONVOL_FAR
UWOP_SAVE_XMM128
UWOP_SAVE_XMM128_FAR
UWOP_SET_FPREG

Attributes

_config_header[RW]
_dos_header[RW]
_exception_header[RW]
_exports_cache[RW]
_exports_cached[RW]
_file_header[RW]
_imports_cache[RW]
_imports_cached[RW]
_isource[RW]

instance stuff

_optional_header[RW]
_relocations_cache[RW]
_relocations_cached[RW]
_resources_cache[RW]
_resources_cached[RW]
_section_headers[RW]
_tls_header[RW]
hdr[RW]
header_section[RW]
image_base[RW]
sections[RW]

Public Class Methods

_align_offset(offset, alignment) click to toggle source

Just a stupid routine to round an offset up to it's alignment.

For example, you're going to want this for FileAlignment and SectionAlignment, etc...

# File lib/rex/peparsey/pebase.rb, line 1151
def self._align_offset(offset, alignment)
        offset += alignment - 1
        offset -= offset % alignment
        return offset
end
_parse_dos_header(rawdata) click to toggle source
# File lib/rex/peparsey/pebase.rb, line 139
def self._parse_dos_header(rawdata)
        return DosHeader.new(rawdata)
end
_parse_file_header(rawdata) click to toggle source
# File lib/rex/peparsey/pebase.rb, line 219
def self._parse_file_header(rawdata)
        return FileHeader.new(rawdata)
end
_parse_optional_header(rawdata) click to toggle source
# File lib/rex/peparsey/pebase.rb, line 582
def self._parse_optional_header(rawdata)
        case rawdata.length
                # no optional header
                when 0
                        return nil

                # good, good
                when IMAGE_SIZEOF_NT_OPTIONAL32_HEADER
                        return OptionalHeader32.new(rawdata)

                when IMAGE_SIZEOF_NT_OPTIONAL64_HEADER
                        return OptionalHeader64.new(rawdata)

                # bad, bad
                else
                        raise OptionalHeaderError, "I don't know this header size, #{rawdata.length}", caller
        end

end
_parse_section_headers(rawdata) click to toggle source
# File lib/rex/peparsey/pebase.rb, line 657
def self._parse_section_headers(rawdata)
        section_headers = [ ]
        size = IMAGE_SIZEOF_SECTION_HEADER
        numsections = rawdata.length / size

        numsections.times do |i|
                data = rawdata[i * size, size]
                section_headers << SectionHeader.new(data)
        end

        return section_headers
end
new_from_file(filename, disk_backed = false) click to toggle source
# File lib/rex/peparsey/pebase.rb, line 1174
def self.new_from_file(filename, disk_backed = false)

        file = ::File.new(filename)
        file.binmode # windows... :\

        if disk_backed
                return self.new(ImageSource::Disk.new(file))
        else
                obj = new_from_string(file.read)
                file.close
                return obj
        end
end
new_from_string(data) click to toggle source
# File lib/rex/peparsey/pebase.rb, line 1188
def self.new_from_string(data)
        return self.new(ImageSource::Memory.new(data))
end

Public Instance Methods

_find_section_by_rva(rva) click to toggle source

Find a section by an RVA

# File lib/rex/peparsey/pebase.rb, line 1252
def _find_section_by_rva(rva)
        all_sections.each do |section|
                if section.contains_rva?(rva)
                        return section
                end
        end

        return nil
end
_load_exception_directory() click to toggle source
# File lib/rex/peparsey/pebase.rb, line 1114
def _load_exception_directory
        @exception   = []
        
        exception_entry = _optional_header['DataDirectory'][IMAGE_DIRECTORY_ENTRY_EXCEPTION]
        rva             = exception_entry.v['VirtualAddress']
        size            = exception_entry.v['Size']
        
        return if (rva == 0)
        
        data = _isource.read(rva_to_file_offset(rva), size)
        
        case hdr.file.Machine
                when IMAGE_FILE_MACHINE_AMD64
                        count = data.length / IMAGE_RUNTIME_FUNCTION_ENTRY_SZ
                        
                        count.times { |current|
                                @exception << RuntimeFunctionEntry.new(self,
                                        data.slice!(0, IMAGE_RUNTIME_FUNCTION_ENTRY_SZ))
                        }
                else
        end
        
        return @exception
end
_load_exports() click to toggle source
# File lib/rex/peparsey/pebase.rb, line 1396
def _load_exports

        #
        # Get the data directory entry, size, etc
        #
        exports_entry = _optional_header['DataDirectory'][0]
        rva           = exports_entry.v['VirtualAddress']
        size          = exports_entry.v['Size']

        return nil if size == 0

        #
        # Ok, so we have the data directory, now lets parse it
        #

        directory = IMAGE_EXPORT_DESCRIPTOR.make_struct
        directory.from_s(_isource.read(rva_to_file_offset(rva), IMAGE_EXPORT_DESCRIPTOR_SIZE))

        #
        # We can have nameless exports, so we need to do the whole
        # NumberOfFunctions NumberOfNames foo
        #
        num_functions = directory.v['NumberOfFunctions']
        num_names     = directory.v['NumberOfNames']

        dllname_rva   = directory.v['Name']
        dllname       = _isource.read_asciiz(rva_to_file_offset(dllname_rva))

        # FIXME Base, etc
        fun_off       = rva_to_file_offset(directory.v['AddressOfFunctions'])
        name_off      = rva_to_file_offset(directory.v['AddressOfNames'])
        ord_off       = rva_to_file_offset(directory.v['AddressOfNameOrdinals'])
        base          = directory.v['Base']

        # Allocate the list of names
        names = Array.new(num_functions)

        #
        # Iterate the names and name/ordinal list, getting the names
        # and storing them in the name list...
        #
        num_names.times do |i|
                name_rva = _isource.read(name_off + (i * 4), 4).unpack('V')[0]
                ordinal  = _isource.read(ord_off + (i * 2), 2).unpack('v')[0]
                name     = _isource.read_asciiz(rva_to_file_offset(name_rva))

                # store the exported name in the name list
                names[ordinal] = name
        end

        exports = ExportDirectory.new(dllname, [ ], base)

        #
        # Now just iterate the functions (rvas) list..
        #
        num_functions.times do |i|
                rva      = _isource.read(fun_off + (i * 4), 4).unpack('V')[0]

                # ExportEntry.new(name, ordinal, rva)
                exports.entries << ExportEntry.new(names[i], i + base, rva)
        end

        return exports
end
_load_imports() click to toggle source
# File lib/rex/peparsey/pebase.rb, line 1325
def _load_imports
        #
        # Get the data directory entry, size, etc
        #
        imports_entry = _optional_header['DataDirectory'][1]
        rva           = imports_entry.v['VirtualAddress']
        size          = imports_entry.v['Size']

        return nil if size == 0

        #
        # Ok, so we have the data directory, now lets parse it
        #

        imports = [ ]

        descriptors_data = _isource.read(rva_to_file_offset(rva), size)

        while descriptors_data.length >= IMAGE_IMPORT_DESCRIPTOR_SIZE
                descriptor = IMAGE_IMPORT_DESCRIPTOR.make_struct
                descriptor.from_s(descriptors_data)
                descriptors_data = descriptor.leftover

                othunk = descriptor.v['OriginalFirstThunk']
                fthunk = descriptor.v['FirstThunk']

                break if fthunk == 0

                dllname = _isource.read_asciiz(rva_to_file_offset(descriptor.v['Name']))

                import = ImportDescriptor.new(dllname, [ ])

                # we prefer the Characteristics/OriginalFirstThunk...
                thunk_off = rva_to_file_offset(othunk == 0 ? fthunk : othunk)

                while (orgrva = _isource.read(thunk_off, 4).unpack('V')[0]) != 0
                        hint = nil
                        name = nil

                        if (orgrva & IMAGE_ORDINAL_FLAG32) != 0
                                hint = orgrva & 0xffff
                        else
                                foff = rva_to_file_offset(orgrva)
                                hint = _isource.read(foff, 2).unpack('v')[0]
                                name = _isource.read_asciiz(foff + 2)
                        end

                        import.entries << ImportEntry.new(name, hint)

                        thunk_off += 4
                end

                imports << import
        end

        return imports
end
_load_relocations() click to toggle source
# File lib/rex/peparsey/pebase.rb, line 1472
def _load_relocations

        #
        # Get the data directory entry, size, etc
        #
        exports_entry = _optional_header['DataDirectory'][5]
        rva           = exports_entry.v['VirtualAddress']
        size          = exports_entry.v['Size']

        return nil if size == 0

        #
        # Ok, so we have the data directory, now lets parse it
        #

        dirdata = _isource.read(rva_to_file_offset(rva), size)

        relocdirs = [ ]

        while dirdata.length >= IMAGE_SIZEOF_BASE_RELOCATION
                header = IMAGE_BASE_RELOCATION.make_struct
                header.from_s(dirdata)
                dirdata = header.leftover

                numrelocs = (header.v['SizeOfBlock'] - IMAGE_SIZEOF_BASE_RELOCATION) / 2

                relocbase = header.v['VirtualAddress']

                relocdir = RelocationDirectory.new(relocbase, [ ])

                numrelocs.times do
                        reloc = IMAGE_BASE_RELOCATION_TYPE_OFFSET.make_struct
                        reloc.from_s(dirdata)
                        dirdata = reloc.leftover

                        typeoffset = reloc.v['TypeOffset']

                        relocrva  = relocbase + (typeoffset & 0xfff)
                        reloctype = (typeoffset >> 12) & 0xf

                        relocdir.entries << RelocationEntry.new(relocrva, reloctype)
                end

                relocdirs << relocdir
        end

        return relocdirs
end
_load_resources() click to toggle source
# File lib/rex/peparsey/pebase.rb, line 1534
def _load_resources
        #
        # Get the data directory entry, size, etc
        #
        rsrc_entry = _optional_header['DataDirectory'][IMAGE_DIRECTORY_ENTRY_RESOURCE]
        rva        = rsrc_entry.v['VirtualAddress']
        size       = rsrc_entry.v['Size']

        return nil if size == 0

        #
        # Ok, so we have the data directory, now lets parse it
        #
        data = _isource.read(rva_to_file_offset(rva), size)

        self._resources_cache = {}
        _parse_resource_directory(data)
end
_parse_config_header() click to toggle source
doesn't seem to be used -- not compatible with 64-bit

def self._parse_config_header(rawdata)

header = IMAGE_LOAD_CONFIG_DIRECTORY32.make_struct
header.from_s(rawdata)
ConfigHeader.new(header)

end

# File lib/rex/peparsey/pebase.rb, line 846
def _parse_config_header

        #
        # Get the data directory entry, size, etc
        #
        exports_entry = _optional_header['DataDirectory'][IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG]
        rva           = exports_entry.v['VirtualAddress']
        size          = exports_entry.v['Size']

        return nil if size == 0

        #
        # Ok, so we have the data directory, now lets parse it
        #

        dirdata = _isource.read(rva_to_file_offset(rva), size)
        klass   = (ptr_64?) ? IMAGE_LOAD_CONFIG_DIRECTORY64 : IMAGE_LOAD_CONFIG_DIRECTORY32
        header  = klass.make_struct

        header.from_s(dirdata)

        @config = ConfigHeader.new(header)
end
_parse_resource_directory(data, rname=0, rvalue=0x80000000, path='0', pname=nil) click to toggle source
# File lib/rex/peparsey/pebase.rb, line 1553
def _parse_resource_directory(data, rname=0, rvalue=0x80000000, path='0', pname=nil)

        pname = _parse_resource_name(data, rname)
        if (path.scan('/').length == 1)
                if (pname !~ /^\d+/)
                        path = "/" + pname
                else
                        path = "/" + _resource_lookup( (rname & ~0x80000000).to_s)
                end
        end


        rvalue &= ~0x80000000
        vals  = data[rvalue, 16].unpack('VVvvvv')

        chars = vals[0]
        tdate = vals[1]
        vers  = "#{vals[2]}#{vals[3]}"
        count = vals[4] + vals[5]

        0.upto(count-1) do |i|

                ename, evalue = data[rvalue + 16 + ( i * 8), 8].unpack('VV')
                epath = path + '/' + i.to_s

                if (ename & 0x80000000 != 0)
                        pname = _parse_resource_name(data, ename)
                end

                if (evalue & 0x80000000 != 0)
                        # This is a subdirectory
                        _parse_resource_directory(data, ename, evalue, epath, pname)
                else
                        # This is an entry
                        _parse_resource_entry(data, ename, evalue, epath, pname)
                end
        end

end
_parse_resource_entry(data, rname, rvalue, path, pname) click to toggle source
# File lib/rex/peparsey/pebase.rb, line 1625
def _parse_resource_entry(data, rname, rvalue, path, pname)

        rva, size, code = data[rvalue, 12].unpack('VVV')
        lang = _parse_resource_name(data, rname)

        ent = ResourceEntry.new(
                self,
                path,
                lang,
                code,
                rva,
                size,
                pname
        )
        self._resources_cache[path] = ent
end
_parse_resource_name(data, rname) click to toggle source
# File lib/rex/peparsey/pebase.rb, line 1642
def _parse_resource_name(data, rname)
        if (rname & 0x80000000 != 0)
                rname &= ~0x80000000
                unistr = data[rname+2, 2 * data[rname,2].unpack('v')[0] ]
                unistr, trash = unistr.split(/\x00\x00/, 2)
                return unistr ? unistr.gsub(/\x00/, '') : nil
        end

        rname.to_s
end
_parse_tls_header() click to toggle source
# File lib/rex/peparsey/pebase.rb, line 979
def _parse_tls_header

        #
        # Get the data directory entry, size, etc
        #
        exports_entry = _optional_header['DataDirectory'][IMAGE_DIRECTORY_ENTRY_TLS]
        rva           = exports_entry.v['VirtualAddress']
        size          = exports_entry.v['Size']

        return nil if size == 0

        #
        # Ok, so we have the data directory, now lets parse it
        #

        dirdata = _isource.read(rva_to_file_offset(rva), size)
        klass   = (ptr_64?) ? IMAGE_LOAD_TLS_DIRECTORY64 : IMAGE_LOAD_TLS_DIRECTORY32
        header  = klass.make_struct

        header.from_s(dirdata)

        @tls = TLSHeader.new(header)
end
_resource_lookup(i) click to toggle source
# File lib/rex/peparsey/pebase.rb, line 1593
def _resource_lookup(i)
        tbl = {
                '1'      => 'RT_CURSOR',
                '2'      => 'RT_BITMAP',
                '3'      => 'RT_ICON',
                '4'      => 'RT_MENU',
                '5'      => 'RT_DIALOG',
                '6'      => 'RT_STRING',
                '7'      => 'RT_FONTDIR',
                '8'      => 'RT_FONT',
                '9'      => 'RT_ACCELERATORS',
                '10'     => 'RT_RCDATA',
                '11'     => 'RT_MESSAGETABLE',
                '12'     => 'RT_GROUP_CURSOR',
                '14'     => 'RT_GROUP_ICON',
                '16'     => 'RT_VERSION',
                '17'     => 'RT_DLGINCLUDE',
                '19'     => 'RT_PLUGPLAY',
                '20'     => 'RT_VXD',
                '21'     => 'RT_ANICURSOR',
                '22'     => 'RT_ANIICON',
                '23'     => 'RT_HTML',
                '24'     => 'RT_MANIFEST',
                '32767'  => 'RT_ERROR',
                '8192'   => 'RT_NEWRESOURCE',
                '8194'   => 'RT_NEWBITMAP',
                '8196'   => 'RT_NEWMENU',
                '8197'   => 'RT_NEWDIALOG'
        }
        tbl[i] || i
end
close() click to toggle source
# File lib/rex/peparsey/pebase.rb, line 1192
def close
        _isource.close
end
config() click to toggle source
# File lib/rex/peparsey/pebase.rb, line 871
def config
        _parse_config_header if @config.nil?
        @config
end
exception() click to toggle source
# File lib/rex/peparsey/pebase.rb, line 1140
def exception
        _load_exception_directory if @exception.nil?
        @exception
end
exports() click to toggle source

We lazily parse the exports, and then cache it

# File lib/rex/peparsey/pebase.rb, line 1388
def exports
        if !_exports_cached
                self._exports_cache  = _load_exports
                self._exports_cached = true
        end
        return _exports_cache
end
file_offset_to_rva(foffset) click to toggle source
# File lib/rex/peparsey/pebase.rb, line 1223
def file_offset_to_rva(foffset)
        if foffset < 0
                raise WtfError, "lame", caller
        end

        all_sections.each do |section|
                if section.contains_file_offset?(foffset)
                        return section.file_offset_to_rva(foffset)
                end
        end

        raise WtfError, "wtf! #{foffset}", caller
end
file_offset_to_vma(foffset) click to toggle source
# File lib/rex/peparsey/pebase.rb, line 1237
def file_offset_to_vma(foffset)
        return rva_to_vma(file_offset_to_rva(foffset))
end
find_section_by_rva(rva) click to toggle source
# File lib/rex/peparsey/pebase.rb, line 1261
def find_section_by_rva(rva)
        section = _find_section_by_rva(rva)

        if !section
                raise WtfError, "Cannot find rva! #{rva}", caller
        end

        return section
end
find_section_by_vma(vma) click to toggle source

Find a section by a VMA

# File lib/rex/peparsey/pebase.rb, line 1274
def find_section_by_vma(vma)
        return find_section_by_rva(vma_to_rva(vma))
end
imports() click to toggle source

We lazily parse the imports, and then cache it

# File lib/rex/peparsey/pebase.rb, line 1317
def imports
        if !_imports_cached
                self._imports_cache  = _load_imports
                self._imports_cached = true
        end
        return _imports_cache
end
read_asciiz_rva(rva) click to toggle source
# File lib/rex/peparsey/pebase.rb, line 1300
def read_asciiz_rva(rva)
        return find_section_by_rva(rva).read_asciiz_rva(rva)
end
read_asciiz_vma(vma) click to toggle source
# File lib/rex/peparsey/pebase.rb, line 1304
def read_asciiz_vma(vma)
        return read_asciiz_rva(vma_to_rva(vma))
end
read_rva(rva, length) click to toggle source

Some convenient methods to read a vma/rva without having the section... (inefficent though I suppose...)

# File lib/rex/peparsey/pebase.rb, line 1292
def read_rva(rva, length)
        return find_section_by_rva(rva).read_rva(rva, length)
end
read_vma(vma, length) click to toggle source
# File lib/rex/peparsey/pebase.rb, line 1296
def read_vma(vma, length)
        return read_rva(vma_to_rva(vma), length)
end
relocations() click to toggle source

Base relocations in the hizzy

# File lib/rex/peparsey/pebase.rb, line 1464
def relocations
        if !_relocations_cached
                self._relocations_cache  = _load_relocations
                self._relocations_cached = true
        end
        return _relocations_cache
end
resources() click to toggle source

We lazily parse the resources, and then cache them

# File lib/rex/peparsey/pebase.rb, line 1525
def resources
        if !_resources_cached
                _load_resources
                self._resources_cached = true
        end

        return self._resources_cache
end
rva_to_file_offset(rva) click to toggle source
# File lib/rex/peparsey/pebase.rb, line 1210
def rva_to_file_offset(rva)
        all_sections.each do |section|
                if section.contains_rva?(rva)
                        return section.rva_to_file_offset(rva)
                end
        end
        raise WtfError, "wtf!", caller
end
rva_to_vma(rva) click to toggle source

Random rva, vma, file offset, section offset, etc conversion routines...

# File lib/rex/peparsey/pebase.rb, line 1202
def rva_to_vma(rva)
        return rva + image_base
end
tls() click to toggle source
# File lib/rex/peparsey/pebase.rb, line 1004
def tls
        _parse_config_header if @tls.nil?
        @tls
end
update_checksum() click to toggle source
# File lib/rex/peparsey/pebase.rb, line 1653
def update_checksum
        off = _dos_header.e_lfanew + IMAGE_FILE_HEADER_SIZE + 0x40
        _isource.rawdata[off, 4] = [0].pack('V')

        rem = _isource.size % 4
        sum_me = ''
        sum_me << _isource.rawdata
        sum_me << "\x00" * (4 - rem) if rem > 0

        cksum = 0
        sum_me.unpack('V*').each { |el|
                cksum = (cksum & 0xffffffff) + (cksum >> 32) + el
                if cksum > 2**32
                        cksum = (cksum & 0xffffffff) + (cksum >> 32)
                end
        }

        cksum = (cksum & 0xffff) + (cksum >> 16)
        cksum += (cksum >> 16)
        cksum &= 0xffff

        cksum += _isource.size

        _isource.rawdata[off, 4] = [cksum].pack('V')
end
valid_rva?(rva) click to toggle source
# File lib/rex/peparsey/pebase.rb, line 1278
def valid_rva?(rva)
        _find_section_by_rva(rva) != nil
end
valid_vma?(vma) click to toggle source
# File lib/rex/peparsey/pebase.rb, line 1281
def valid_vma?(vma)
        _find_section_by_rva(vma_to_rva(vma)) != nil
end
vma_to_file_offset(vma) click to toggle source
# File lib/rex/peparsey/pebase.rb, line 1219
def vma_to_file_offset(vma)
        return rva_to_file_offset(vma_to_rva(vma))
end
vma_to_rva(vma) click to toggle source
# File lib/rex/peparsey/pebase.rb, line 1206
def vma_to_rva(vma)
        return vma - image_base
end

[Validate]

Generated with the Darkfish Rdoc Generator 2.