diff options
Diffstat (limited to 'miasm/loader')
| -rw-r--r-- | miasm/loader/__init__.py | 3 | ||||
| -rw-r--r-- | miasm/loader/cstruct.py | 154 | ||||
| -rw-r--r-- | miasm/loader/elf.py | 1538 | ||||
| -rw-r--r-- | miasm/loader/elf_init.py | 882 | ||||
| -rw-r--r-- | miasm/loader/minidump.py | 545 | ||||
| -rw-r--r-- | miasm/loader/minidump_init.py | 194 | ||||
| -rw-r--r-- | miasm/loader/new_cstruct.py | 267 | ||||
| -rw-r--r-- | miasm/loader/pe.py | 1693 | ||||
| -rw-r--r-- | miasm/loader/pe_init.py | 631 | ||||
| -rw-r--r-- | miasm/loader/strpatchwork.py | 106 |
10 files changed, 0 insertions, 6013 deletions
diff --git a/miasm/loader/__init__.py b/miasm/loader/__init__.py deleted file mode 100644 index 1a602f38..00000000 --- a/miasm/loader/__init__.py +++ /dev/null @@ -1,3 +0,0 @@ -#!/usr/bin/env python - -__all__ = ['pe_init', 'elf_init', 'strpatchwork'] diff --git a/miasm/loader/cstruct.py b/miasm/loader/cstruct.py deleted file mode 100644 index 06d2e002..00000000 --- a/miasm/loader/cstruct.py +++ /dev/null @@ -1,154 +0,0 @@ -#! /usr/bin/env python - -from __future__ import print_function -from builtins import zip -from functools import reduce -import struct - -from future.utils import PY3 - -type_size = {} -size2type = {} -for t in 'B', 'H', 'I', 'Q': - s = struct.calcsize(t) - type_size[t] = s * 8 - size2type[s * 8] = t - -type_size['u08'] = size2type[8] -type_size['u16'] = size2type[16] -type_size['u32'] = size2type[32] -type_size['u64'] = size2type[64] - - -def fix_size(fields, wsize): - out = [] - for name, v in fields: - if v.endswith("s"): - pass - elif v == "ptr": - v = size2type[wsize] - elif not v in type_size: - raise ValueError("unknown Cstruct type", v) - else: - v = type_size[v] - out.append((name, v)) - fields = out - return fields - - -class Cstruct_Metaclass(type): - - def __new__(cls, name, bases, dct): - o = super(Cstruct_Metaclass, cls).__new__(cls, name, bases, dct) - o._packstring = o._packformat + \ - "".join(x[1] for x in o._fields) - o._size = struct.calcsize(o._packstring) - return o - - -class CStruct(object): - #__metaclass__ = Cstruct_Metaclass - _packformat = "" - _fields = [] - - @classmethod - def _from_file(cls, f): - return cls(f.read(cls._size)) - - def __init__(self, sex, wsize, *args, **kargs): - if sex == 1: - sex = '<' - else: - sex = '>' - # packformat enforce sex - if self._packformat: - sex = "" - pstr = fix_size(self._fields, wsize) - self._packstring = sex + self._packformat + \ - "".join(x[1] for x in pstr) - self._size = struct.calcsize(self._packstring) - - self._names = [x[0] for x in self._fields] - if kargs: - self.__dict__.update(kargs) - else: - if args: - s = args[0] - else: - s = b"" - s += b"\x00" * self._size - s = s[:self._size] - self._unpack(s) - - def _unpack(self, s): - disas = struct.unpack(self._packstring, s) - for n, v in zip(self._names, disas): - setattr(self, n, v) - - def _pack(self): - return struct.pack(self._packstring, - *(getattr(self, x) for x in self._names)) - - def _spack(self, superstruct, shift=0): - attr = [] - for name in self._names: - s = getattr(self, name) - if isinstance(s, CStruct): - if s in superstruct: - s = reduce(lambda x, y: x + len(y), - superstruct[:superstruct.index(s)], - 0) - s += shift - else: - raise Exception("%r is not a superstructure" % s) - attr.append(s) - return struct.pack(self._packstring, *attr) - - def _copy(self): - return self.__class__(**self.__dict__) - - def __len__(self): - return self._size - - def __str__(self): - if PY3: - return repr(self) - return self.__bytes__() - - def __bytes__(self): - return self._pack() - - def __repr__(self): - return "<%s=%s>" % (self.__class__.__name__, "/".join(repr( - getattr(self, x[0])) for x in self._fields - )) - - def __getitem__(self, item): # to work with format strings - return getattr(self, item) - - def _show(self): - print("##%s:" % self.__class__.__name__) - fmt = "%%-%is = %%r" % max(len(x[0]) for x in self._fields) - for fn, ft in self._fields: - print(fmt % (fn, getattr(self, fn))) - - -class CStructStruct(object): - - def __init__(self, lst, shift=0): - self._lst = lst - self._shift = shift - - def __getattr__(self, attr): - return getattr(self._lst, attr) - - def __str__(self): - if PY3: - return repr(self) - return self.__bytes__() - - def __bytes__(self): - return b"".join( - a if isinstance(a, bytes) else a._spack(self._lst, self._shift) - for a in self._lst - ) diff --git a/miasm/loader/elf.py b/miasm/loader/elf.py deleted file mode 100644 index 74258782..00000000 --- a/miasm/loader/elf.py +++ /dev/null @@ -1,1538 +0,0 @@ -#! /usr/bin/env python - -from miasm.loader.cstruct import CStruct - -class Ehdr(CStruct): - _fields = [ ("ident","16s"), - ("type","u16"), - ("machine","u16"), - ("version","u32"), - ("entry","ptr"), - ("phoff","ptr"), - ("shoff","ptr"), - ("flags","u32"), - ("ehsize","u16"), - ("phentsize","u16"), - ("phnum","u16"), - ("shentsize","u16"), - ("shnum","u16"), - ("shstrndx","u16") ] - - -class Shdr(CStruct): - _fields = [ ("name","u32"), - ("type","u32"), - ("flags","ptr"), - ("addr","ptr"), - ("offset","ptr"), - ("size","ptr"), - ("link","u32"), - ("info","u32"), - ("addralign","ptr"), - ("entsize","ptr") ] - -class Phdr(CStruct): - _fields = [ ("type","u32"), - ("offset","u32"), - ("vaddr","u32"), - ("paddr","u32"), - ("filesz","u32"), - ("memsz","u32"), - ("flags","u32"), - ("align","u32") ] - -class Phdr64(CStruct): - _fields = [ ("type","u32"), - ("flags","u32"), - ("offset","ptr"), - ("vaddr","ptr"), - ("paddr","ptr"), - ("filesz","ptr"), - ("memsz","ptr"), - ("align","ptr") ] - -class Nhdr(CStruct): - _fields = [ ("namesz","u32"), - ("descsz","u32"), - ("type", "u32") ] - - -class Sym32(CStruct): - _fields = [ ("name","u32"), - ("value","u32"), - ("size","u32"), - ("info","u08"), - ("other","u08"), - ("shndx","u16") ] - -class Sym64(CStruct): - _fields = [ ("name","u32"), - ("info","u08"), - ("other","u08"), - ("shndx","u16"), - ("value","u64"), - ("size","u64") ] - -class Dym(CStruct): - _fields = [ ("tag","u32"), - ("val","u32") ] - -class Rel32(CStruct): - _fields = [ ("offset","ptr"), - ("info","u32") ] - -class Rel64(CStruct): - _fields = [ ("offset","ptr"), - ("info","u64") ] - -class Rela32(CStruct): - _fields = [ ("offset","ptr"), - ("info","u32"), - ("addend","ptr") ] - -class Rela64(CStruct): - _fields = [ ("offset","ptr"), - ("info","u64"), - ("addend","ptr") ] - -class Dynamic(CStruct): - _fields = [ ("type","ptr"), - ("name","ptr") ] - - -# Legal values for e_ident (identification indexes) - -EI_MAG0 = 0 # File identification -EI_MAG1 = 1 # File identification -EI_MAG2 = 2 # File identification -EI_MAG3 = 3 # File identification -EI_CLASS = 4 # File class -EI_DATA = 5 # Data encoding -EI_VERSION = 6 # File version -EI_OSABI = 7 # Operating system/ABI identification -EI_ABIVERSION = 8 # ABI version -EI_PAD = 9 # Start of padding bytes -EI_NIDENT = 16 # Size of e_ident[] - -# Legal values for e_ident[EI_CLASS] - -ELFCLASSNONE = 0 # Invalid class -ELFCLASS32 = 1 # 32-bit objects -ELFCLASS64 = 2 # 64-bit objects - -# Legal values for e_ident[EI_DATA] - -ELFDATANONE = 0 # Invalid data encoding -ELFDATA2LSB = 1 # Least significant byte at lowest address -ELFDATA2MSB = 2 # Most significant byte at lowest address - -# Legal values for e_type (object file type). - -ET_NONE = 0 # No file type -ET_REL = 1 # Relocatable file -ET_EXEC = 2 # Executable file -ET_DYN = 3 # Shared object file -ET_CORE = 4 # Core file -ET_NUM = 5 # Number of defined types -ET_LOOS = 0xfe00 # OS-specific range start -ET_HIOS = 0xfeff # OS-specific range end -ET_LOPROC = 0xff00 # Processor-specific range start -ET_HIPROC = 0xffff # Processor-specific range end - -# Legal values for e_machine (architecture). - -EM_NONE = 0 # No machine -EM_M32 = 1 # AT&T WE 32100 -EM_SPARC = 2 # SUN SPARC -EM_386 = 3 # Intel 80386 -EM_68K = 4 # Motorola m68k family -EM_88K = 5 # Motorola m88k family -EM_486 = 6 # Intel 80486 -EM_860 = 7 # Intel 80860 -EM_MIPS = 8 # MIPS R3000 big-endian -EM_S370 = 9 # IBM System/370 -EM_MIPS_RS3_LE = 10 # MIPS R3000 little-endian - -EM_PARISC = 15 # HPPA -EM_VPP500 = 17 # Fujitsu VPP500 -EM_SPARC32PLUS = 18 # Sun's "v8plus" -EM_960 = 19 # Intel 80960 -EM_PPC = 20 # PowerPC -EM_PPC64 = 21 # PowerPC 64-bit -EM_S390 = 22 # IBM S390 - -EM_V800 = 36 # NEC V800 series -EM_FR20 = 37 # Fujitsu FR20 -EM_RH32 = 38 # TRW RH-32 -EM_RCE = 39 # Motorola RCE -EM_ARM = 40 # ARM -EM_FAKE_ALPHA = 41 # Digital Alpha -EM_SH = 42 # Hitachi SH -EM_SPARCV9 = 43 # SPARC v9 64-bit -EM_TRICORE = 44 # Siemens Tricore -EM_ARC = 45 # Argonaut RISC Core -EM_H8_300 = 46 # Hitachi H8/300 -EM_H8_300H = 47 # Hitachi H8/300H -EM_H8S = 48 # Hitachi H8S -EM_H8_500 = 49 # Hitachi H8/500 -EM_IA_64 = 50 # Intel Merced -EM_MIPS_X = 51 # Stanford MIPS-X -EM_COLDFIRE = 52 # Motorola Coldfire -EM_68HC12 = 53 # Motorola M68HC12 -EM_MMA = 54 # Fujitsu MMA Multimedia Accelerator*/ -EM_PCP = 55 # Siemens PCP -EM_NCPU = 56 # Sony nCPU embeeded RISC -EM_NDR1 = 57 # Denso NDR1 microprocessor -EM_STARCORE = 58 # Motorola Start*Core processor -EM_ME16 = 59 # Toyota ME16 processor -EM_ST100 = 60 # STMicroelectronic ST100 processor -EM_TINYJ = 61 # Advanced Logic Corp. Tinyj emb.fam*/ -EM_X86_64 = 62 # AMD x86-64 architecture -EM_AARCH64 = 183 # Aarch64 architecture -EM_PDSP = 63 # Sony DSP Processor - -EM_FX66 = 66 # Siemens FX66 microcontroller -EM_ST9PLUS = 67 # STMicroelectronics ST9+ 8/16 mc -EM_ST7 = 68 # STmicroelectronics ST7 8 bit mc -EM_68HC16 = 69 # Motorola MC68HC16 microcontroller -EM_68HC11 = 70 # Motorola MC68HC11 microcontroller -EM_68HC08 = 71 # Motorola MC68HC08 microcontroller -EM_68HC05 = 72 # Motorola MC68HC05 microcontroller -EM_SVX = 73 # Silicon Graphics SVx -EM_ST19 = 74 # STMicroelectronics ST19 8 bit mc -EM_VAX = 75 # Digital VAX -EM_CRIS = 76 # Axis Communications 32-bit embedded processor -EM_JAVELIN = 77 # Infineon Technologies 32-bit embedded processor -EM_FIREPATH = 78 # Element 14 64-bit DSP Processor -EM_ZSP = 79 # LSI Logic 16-bit DSP Processor -EM_MMIX = 80 # Donald Knuth's educational 64-bit processor -EM_HUANY = 81 # Harvard University machine-independent object files -EM_PRISM = 82 # SiTera Prism -EM_AVR = 83 # Atmel AVR 8-bit microcontroller -EM_FR30 = 84 # Fujitsu FR30 -EM_D10V = 85 # Mitsubishi D10V -EM_D30V = 86 # Mitsubishi D30V -EM_V850 = 87 # NEC v850 -EM_M32R = 88 # Mitsubishi M32R -EM_MN10300 = 89 # Matsushita MN10300 -EM_MN10200 = 90 # Matsushita MN10200 -EM_PJ = 91 # picoJava -EM_OPENRISC = 92 # OpenRISC 32-bit embedded processor -EM_ARC_A5 = 93 # ARC Cores Tangent-A5 -EM_XTENSA = 94 # Tensilica Xtensa Architecture - -EM_ALPHA = 0x9026 - -# Legal values for sh_type (section type). - -SHT_NULL = 0 # Section header table entry unused -SHT_PROGBITS = 1 # Program data -SHT_SYMTAB = 2 # Symbol table -SHT_STRTAB = 3 # String table -SHT_RELA = 4 # Relocation entries with addends -SHT_HASH = 5 # Symbol hash table -SHT_DYNAMIC = 6 # Dynamic linking information -SHT_NOTE = 7 # Notes -SHT_NOBITS = 8 # Program space with no data (bss) -SHT_REL = 9 # Relocation entries, no addends -SHT_SHLIB = 10 # Reserved -SHT_DYNSYM = 11 # Dynamic linker symbol table -SHT_INIT_ARRAY = 14 # Array of constructors -SHT_FINI_ARRAY = 15 # Array of destructors -SHT_PREINIT_ARRAY = 16 # Array of pre-constructors -SHT_GROUP = 17 # Section group -SHT_SYMTAB_SHNDX = 18 # Extended section indices -SHT_NUM = 19 # Number of defined types. -SHT_LOOS = 0x60000000 # Start OS-specific -SHT_GNU_LIBLIST = 0x6ffffff7 # Prelink library list -SHT_CHECKSUM = 0x6ffffff8 # Checksum for DSO content. -SHT_LOSUNW = 0x6ffffffa # Sun-specific low bound. -SHT_SUNW_move = 0x6ffffffa -SHT_SUNW_COMDAT = 0x6ffffffb -SHT_SUNW_syminfo = 0x6ffffffc -SHT_GNU_verdef = 0x6ffffffd # Version definition section. -SHT_GNU_verneed = 0x6ffffffe # Version needs section. -SHT_GNU_versym = 0x6fffffff # Version symbol table. -SHT_HISUNW = 0x6fffffff # Sun-specific high bound. -SHT_HIOS = 0x6fffffff # End OS-specific type -SHT_LOPROC = 0x70000000 # Start of processor-specific -SHT_HIPROC = 0x7fffffff # End of processor-specific -SHT_LOUSER = 0x80000000 # Start of application-specific -SHT_HIUSER = 0x8fffffff # End of application-specific - -# Legal values for sh_flags (section flags). - -SHF_WRITE = (1 << 0) # Writable -SHF_ALLOC = (1 << 1) # Occupies memory during execution -SHF_EXECINSTR = (1 << 2) # Executable -SHF_MERGE = (1 << 4) # Might be merged -SHF_STRINGS = (1 << 5) # Contains nul-terminated strings -SHF_INFO_LINK = (1 << 6) # `sh_info' contains SHT index -SHF_LINK_ORDER = (1 << 7) # Preserve order after combining -SHF_OS_NONCONFORMING = (1 << 8) # Non-standard OS specific handling required -SHF_GROUP = (1 << 9) # Section is member of a group. -SHF_TLS = (1 << 10) # Section hold thread-local data. -SHF_MASKOS = 0x0ff00000 # OS-specific. -SHF_MASKPROC = 0xf0000000 # Processor-specific - -# Section group handling. - -GRP_COMDAT = 0x1 # Mark group as COMDAT. - -# Legal values for p_type (segment type). - -PT_NULL = 0 # Program header table entry unused -PT_LOAD = 1 # Loadable program segment -PT_DYNAMIC = 2 # Dynamic linking information -PT_INTERP = 3 # Program interpreter -PT_NOTE = 4 # Auxiliary information -PT_SHLIB = 5 # Reserved -PT_PHDR = 6 # Entry for header table itself -PT_TLS = 7 # Thread-local storage segment -PT_NUM = 8 # Number of defined types -PT_LOOS = 0x60000000 # Start of OS-specific -PT_GNU_EH_FRAME = 0x6474e550 # GCC .eh_frame_hdr segment -PT_GNU_STACK = 0x6474e551 # Indicates stack executability -PT_LOSUNW = 0x6ffffffa -PT_SUNWBSS = 0x6ffffffa # Sun Specific segment -PT_SUNWSTACK = 0x6ffffffb # Stack segment -PT_HISUNW = 0x6fffffff -PT_HIOS = 0x6fffffff # End of OS-specific -PT_LOPROC = 0x70000000 # Start of processor-specific -PT_HIPROC = 0x7fffffff # End of processor-specific - -# Legal values for p_flags (segment flags). - -PF_X = (1 << 0) # Segment is executable -PF_W = (1 << 1) # Segment is writable -PF_R = (1 << 2) # Segment is readable -PF_MASKOS = 0x0ff00000 # OS-specific -PF_MASKPROC = 0xf0000000 # Processor-specific - -# Legal values for note segment descriptor types for core files. - -NT_PRSTATUS = 1 # Contains copy of prstatus struct -NT_FPREGSET = 2 # Contains copy of fpregset struct -NT_PRPSINFO = 3 # Contains copy of prpsinfo struct -NT_PRXREG = 4 # Contains copy of prxregset struct -NT_TASKSTRUCT = 4 # Contains copy of task structure -NT_PLATFORM = 5 # String from sysinfo(SI_PLATFORM) -NT_AUXV = 6 # Contains copy of auxv array -NT_GWINDOWS = 7 # Contains copy of gwindows struct -NT_ASRS = 8 # Contains copy of asrset struct -NT_PSTATUS = 10 # Contains copy of pstatus struct -NT_PSINFO = 13 # Contains copy of psinfo struct -NT_PRCRED = 14 # Contains copy of prcred struct -NT_UTSNAME = 15 # Contains copy of utsname struct -NT_LWPSTATUS = 16 # Contains copy of lwpstatus struct -NT_LWPSINFO = 17 # Contains copy of lwpinfo struct -NT_PRFPXREG = 20 # Contains copy of fprxregset struct - -# Legal values for the note segment descriptor types for object files. - -NT_VERSION = 1 # Contains a version string. - -# Legal values for ST_BIND subfield of st_info (symbol binding). -# bind = Sym.info >> 4 -# val = Sym.info 0xf - -STB_LOCAL = 0 # Local symbol -STB_GLOBAL = 1 # Global symbol -STB_WEAK = 2 # Weak symbol -STB_NUM = 3 # Number of defined types. -STB_LOOS = 10 # Start of OS-specific -STB_HIOS = 12 # End of OS-specific -STB_LOPROC = 13 # Start of processor-specific -STB_HIPROC = 15 # End of processor-specific - -#Legal values for ST_TYPE subfield of st_info (symbol type). - -STT_NOTYPE = 0 # Symbol type is unspecified -STT_OBJECT = 1 # Symbol is a data object -STT_FUNC = 2 # Symbol is a code object -STT_SECTION = 3 # Symbol associated with a section -STT_FILE = 4 # Symbol's name is file name -STT_COMMON = 5 # Symbol is a common data object -STT_TLS = 6 # Symbol is thread-local data object*/ -STT_NUM = 7 # Number of defined types. -STT_LOOS = 10 # Start of OS-specific -STT_GNU_IFUNC = 10 # Symbol is indirect code object -STT_HIOS = 12 # End of OS-specific -STT_LOPROC = 13 # Start of processor-specific -STT_HIPROC = 15 # End of processor-specific - -# Legal values for d_tag (dynamic entry type). - -DT_NULL = 0 # Marks end of dynamic section -DT_NEEDED = 1 # Name of needed library -DT_PLTRELSZ = 2 # Size in bytes of PLT relocs -DT_PLTGOT = 3 # Processor defined value -DT_HASH = 4 # Address of symbol hash table -DT_STRTAB = 5 # Address of string table -DT_SYMTAB = 6 # Address of symbol table -DT_RELA = 7 # Address of Rela relocs -DT_RELASZ = 8 # Total size of Rela relocs -DT_RELAENT = 9 # Size of one Rela reloc -DT_STRSZ = 10 # Size of string table -DT_SYMENT = 11 # Size of one symbol table entry -DT_INIT = 12 # Address of init function -DT_FINI = 13 # Address of termination function -DT_SONAME = 14 # Name of shared object -DT_RPATH = 15 # Library search path (deprecated) -DT_SYMBOLIC = 16 # Start symbol search here -DT_REL = 17 # Address of Rel relocs -DT_RELSZ = 18 # Total size of Rel relocs -DT_RELENT = 19 # Size of one Rel reloc -DT_PLTREL = 20 # Type of reloc in PLT -DT_DEBUG = 21 # For debugging; unspecified -DT_TEXTREL = 22 # Reloc might modify .text -DT_JMPREL = 23 # Address of PLT relocs -DT_BIND_NOW = 24 # Process relocations of object -DT_INIT_ARRAY = 25 # Array with addresses of init fct -DT_FINI_ARRAY = 26 # Array with addresses of fini fct -DT_INIT_ARRAYSZ = 27 # Size in bytes of DT_INIT_ARRAY -DT_FINI_ARRAYSZ = 28 # Size in bytes of DT_FINI_ARRAY -DT_RUNPATH = 29 # Library search path -DT_FLAGS = 30 # Flags for the object being loaded -DT_ENCODING = 32 # Start of encoded range -DT_PREINIT_ARRAY = 32 # Array with addresses of preinit fct -DT_PREINIT_ARRAYSZ = 33 # size in bytes of DT_PREINIT_ARRAY -DT_NUM = 34 # Number used -DT_LOOS = 0x6000000d # Start of OS-specific -DT_HIOS = 0x6ffff000 # End of OS-specific -DT_LOPROC = 0x70000000 # Start of processor-specific -DT_HIPROC = 0x7fffffff # End of processor-specific -#DT_PROCNUM = DT_MIPS_NUM # Most used by any processor - -# DT_* entries which fall between DT_VALRNGHI & DT_VALRNGLO use the -# Dyn.d_un.d_val field of the Elf*_Dyn structure. This follows Sun's -# approach. -DT_VALRNGLO = 0x6ffffd00 -DT_GNU_PRELINKED = 0x6ffffdf5 # Prelinking timestamp -DT_GNU_CONFLICTSZ = 0x6ffffdf6 # Size of conflict section -DT_GNU_LIBLISTSZ = 0x6ffffdf7 # Size of library list -DT_CHECKSUM = 0x6ffffdf8 -DT_PLTPADSZ = 0x6ffffdf9 -DT_MOVEENT = 0x6ffffdfa -DT_MOVESZ = 0x6ffffdfb -DT_FEATURE_1 = 0x6ffffdfc # Feature selection (DTF_*). -DT_POSFLAG_1 = 0x6ffffdfd # Flags for DT_* entries, effecting the following DT_* entry. -DT_SYMINSZ = 0x6ffffdfe # Size of syminfo table (in bytes) -DT_SYMINENT = 0x6ffffdff # Entry size of syminfo -DT_VALRNGHI = 0x6ffffdff -DT_VALNUM = 12 - -# DT_* entries which fall between DT_ADDRRNGHI & DT_ADDRRNGLO use the -# Dyn.d_un.d_ptr field of the Elf*_Dyn structure. -# -# If any adjustment is made to the ELF object after it has been -# built these entries will need to be adjusted. -DT_ADDRRNGLO = 0x6ffffe00 -DT_GNU_CONFLICT = 0x6ffffef8 # Start of conflict section -DT_GNU_LIBLIST = 0x6ffffef9 # Library list -DT_CONFIG = 0x6ffffefa # Configuration information. -DT_DEPAUDIT = 0x6ffffefb # Dependency auditing. -DT_AUDIT = 0x6ffffefc # Object auditing. -DT_PLTPAD = 0x6ffffefd # PLT padding. -DT_MOVETAB = 0x6ffffefe # Move table. -DT_SYMINFO = 0x6ffffeff # Syminfo table. -DT_ADDRRNGHI = 0x6ffffeff -DT_ADDRNUM = 10 - -# The versioning entry types. The next are defined as part of the -# GNU extension. -DT_VERSYM = 0x6ffffff0 - -DT_RELACOUNT = 0x6ffffff9 -DT_RELCOUNT = 0x6ffffffa - -# These were chosen by Sun. -DT_FLAGS_1 = 0x6ffffffb # State flags, see DF_1_* below. -DT_VERDEF = 0x6ffffffc # Address of version definition table -DT_VERDEFNUM = 0x6ffffffd # Number of version definitions -DT_VERNEED = 0x6ffffffe # Address of table with needed versions -DT_VERNEEDNUM = 0x6fffffff # Number of needed versions -DT_VERSIONTAGNUM = 16 - -# Sun added these machine-independent extensions in the "processor-specific" -# range. Be compatible. -DT_AUXILIARY = 0x7ffffffd # Shared object to load before self -DT_FILTER = 0x7fffffff # Shared object to get values from -DT_EXTRANUM = 3 - -# Values of `d_un.d_val' in the DT_FLAGS entry. -DF_ORIGIN = 0x00000001 # Object may use DF_ORIGIN -DF_SYMBOLIC = 0x00000002 # Symbol resolutions starts here -DF_TEXTREL = 0x00000004 # Object contains text relocations -DF_BIND_NOW = 0x00000008 # No lazy binding for this object -DF_STATIC_TLS = 0x00000010 # Module uses the static TLS model - -# State flags selectable in the `d_un.d_val' element of the DT_FLAGS_1 -# entry in the dynamic section. -DF_1_NOW = 0x00000001 # Set RTLD_NOW for this object. -DF_1_GLOBAL = 0x00000002 # Set RTLD_GLOBAL for this object. -DF_1_GROUP = 0x00000004 # Set RTLD_GROUP for this object. -DF_1_NODELETE = 0x00000008 # Set RTLD_NODELETE for this object. -DF_1_LOADFLTR = 0x00000010 # Trigger filtee loading at runtime. -DF_1_INITFIRST = 0x00000020 # Set RTLD_INITFIRST for this object -DF_1_NOOPEN = 0x00000040 # Set RTLD_NOOPEN for this object. -DF_1_ORIGIN = 0x00000080 # $ORIGIN must be handled. -DF_1_DIRECT = 0x00000100 # Direct binding enabled. -DF_1_TRANS = 0x00000200 -DF_1_INTERPOSE = 0x00000400 # Object is used to interpose. -DF_1_NODEFLIB = 0x00000800 # Ignore default lib search path. -DF_1_NODUMP = 0x00001000 # Object can't be dldump'ed. -DF_1_CONFALT = 0x00002000 # Configuration alternative created. -DF_1_ENDFILTEE = 0x00004000 # Filtee terminates filters search. -DF_1_DISPRELDNE = 0x00008000 # Disp reloc applied at build time. -DF_1_DISPRELPND = 0x00010000 # Disp reloc applied at run-time. - -# Flags for the feature selection in DT_FEATURE_1. -DTF_1_PARINIT = 0x00000001 -DTF_1_CONFEXP = 0x00000002 - -# Flags in the DT_POSFLAG_1 entry effecting only the next DT_* entry. -DF_P1_LAZYLOAD = 0x00000001 # Lazyload following object. -DF_P1_GROUPPERM = 0x00000002 # Symbols from next object are not generally available. - -# GNU Versioning -VER_FLG_BASE = 1 # Version of the file itself, must not be used to match symbols -VER_FLG_WEAK = 2 # Reference to this version is weak -VER_NEED_CURRENT = 1 # Versioning implementation number - -# Relocs - -# Motorola 68k relocations - -R_68K_NONE = 0 # No reloc -R_68K_32 = 1 # Direct 32 bit -R_68K_16 = 2 # Direct 16 bit -R_68K_8 = 3 # Direct 8 bit -R_68K_PC32 = 4 # PC relative 32 bit -R_68K_PC16 = 5 # PC relative 16 bit -R_68K_PC8 = 6 # PC relative 8 bit -R_68K_GOT32 = 7 # 32 bit PC relative GOT entry -R_68K_GOT16 = 8 # 16 bit PC relative GOT entry -R_68K_GOT8 = 9 # 8 bit PC relative GOT entry -R_68K_GOT32O = 10 # 32 bit GOT offset -R_68K_GOT16O = 11 # 16 bit GOT offset -R_68K_GOT8O = 12 # 8 bit GOT offset -R_68K_PLT32 = 13 # 32 bit PC relative PLT address -R_68K_PLT16 = 14 # 16 bit PC relative PLT address -R_68K_PLT8 = 15 # 8 bit PC relative PLT address -R_68K_PLT32O = 16 # 32 bit PLT offset -R_68K_PLT16O = 17 # 16 bit PLT offset -R_68K_PLT8O = 18 # 8 bit PLT offset -R_68K_COPY = 19 # Copy symbol at runtime -R_68K_GLOB_DAT = 20 # Create GOT entry -R_68K_JMP_SLOT = 21 # Create PLT entry -R_68K_RELATIVE = 22 # Adjust by program base -R_68K_TLS_GD32 = 25 # 32 bit GOT offset for GD -R_68K_TLS_GD16 = 26 # 16 bit GOT offset for GD -R_68K_TLS_GD8 = 27 # 8 bit GOT offset for GD -R_68K_TLS_LDM32 = 28 # 32 bit GOT offset for LDM -R_68K_TLS_LDM16 = 29 # 16 bit GOT offset for LDM -R_68K_TLS_LDM8 = 30 # 8 bit GOT offset for LDM -R_68K_TLS_LDO32 = 31 # 32 bit module-relative offset -R_68K_TLS_LDO16 = 32 # 16 bit module-relative offset -R_68K_TLS_LDO8 = 33 # 8 bit module-relative offset -R_68K_TLS_IE32 = 34 # 32 bit GOT offset for IE -R_68K_TLS_IE16 = 35 # 16 bit GOT offset for IE -R_68K_TLS_IE8 = 36 # 8 bit GOT offset for IE -R_68K_TLS_LE32 = 37 # 32 bit offset relative to static TLS block -R_68K_TLS_LE16 = 38 # 16 bit offset relative to static TLS block -R_68K_TLS_LE8 = 39 # 8 bit offset relative to static TLS block -R_68K_TLS_DTPMOD32 = 40 # 32 bit module number -R_68K_TLS_DTPREL32 = 41 # 32 bit module-relative offset -R_68K_TLS_TPREL32 = 42 # 32 bit TP-relative offset -# Keep this the last entry. -R_68K_NUM = 43 - -# Intel 80386 relocations - -R_386_NONE = 0 # No reloc -R_386_32 = 1 # Direct 32 bit -R_386_PC32 = 2 # PC relative 32 bit -R_386_GOT32 = 3 # 32 bit GOT entry -R_386_PLT32 = 4 # 32 bit PLT address -R_386_COPY = 5 # Copy symbol at runtime -R_386_GLOB_DAT = 6 # Create GOT entry -R_386_JMP_SLOT = 7 # Create PLT entry -R_386_RELATIVE = 8 # Adjust by program base -R_386_GOTOFF = 9 # 32 bit offset to GOT -R_386_GOTPC = 10 # 32 bit PC relative offset to GOT -R_386_32PLT = 11 -R_386_TLS_TPOFF = 14 # Offset in static TLS block -R_386_TLS_IE = 15 # Address of GOT entry for static TLS block offset -R_386_TLS_GOTIE = 16 # GOT entry for static TLS block offset -R_386_TLS_LE = 17 # Offset relative to static TLS block -R_386_TLS_GD = 18 # Direct 32 bit for GNU version of general dynamic thread local data -R_386_TLS_LDM = 19 # Direct 32 bit for GNU version of local dynamic thread local data in LE code -R_386_16 = 20 -R_386_PC16 = 21 -R_386_8 = 22 -R_386_PC8 = 23 -R_386_TLS_GD_32 = 24 # Direct 32 bit for general dynamic thread local data -R_386_TLS_GD_PUSH = 25 # Tag for pushl in GD TLS code -R_386_TLS_GD_CALL = 26 # Relocation for call to __tls_get_addr() -R_386_TLS_GD_POP = 27 # Tag for popl in GD TLS code -R_386_TLS_LDM_32 = 28 # Direct 32 bit for local dynamic thread local data in LE code -R_386_TLS_LDM_PUSH = 29 # Tag for pushl in LDM TLS code -R_386_TLS_LDM_CALL = 30 # Relocation for call to __tls_get_addr() in LDM code -R_386_TLS_LDM_POP = 31 # Tag for popl in LDM TLS code -R_386_TLS_LDO_32 = 32 # Offset relative to TLS block -R_386_TLS_IE_32 = 33 # GOT entry for negated static TLS block offset -R_386_TLS_LE_32 = 34 # Negated offset relative to static TLS block -R_386_TLS_DTPMOD32 = 35 # ID of module containing symbol -R_386_TLS_DTPOFF32 = 36 # Offset in TLS block -R_386_TLS_TPOFF32 = 37 # Negated offset in static TLS block -# 38? -R_386_TLS_GOTDESC = 39 # GOT offset for TLS descriptor. -R_386_TLS_DESC_CALL = 40 # Marker of call through TLS descriptor for relaxation. -R_386_TLS_DESC = 41 # TLS descriptor containing pointer to code and to argument, returning the TLS offset for the symbol. -R_386_IRELATIVE = 42 # Adjust indirectly by program base -# Keep this the last entry. -R_386_NUM = 43 - -# SUN SPARC relocations - -R_SPARC_NONE = 0 # No reloc -R_SPARC_8 = 1 # Direct 8 bit -R_SPARC_16 = 2 # Direct 16 bit -R_SPARC_32 = 3 # Direct 32 bit -R_SPARC_DISP8 = 4 # PC relative 8 bit -R_SPARC_DISP16 = 5 # PC relative 16 bit -R_SPARC_DISP32 = 6 # PC relative 32 bit -R_SPARC_WDISP30 = 7 # PC relative 30 bit shifted -R_SPARC_WDISP22 = 8 # PC relative 22 bit shifted -R_SPARC_HI22 = 9 # High 22 bit -R_SPARC_22 = 10 # Direct 22 bit -R_SPARC_13 = 11 # Direct 13 bit -R_SPARC_LO10 = 12 # Truncated 10 bit -R_SPARC_GOT10 = 13 # Truncated 10 bit GOT entry -R_SPARC_GOT13 = 14 # 13 bit GOT entry -R_SPARC_GOT22 = 15 # 22 bit GOT entry shifted -R_SPARC_PC10 = 16 # PC relative 10 bit truncated -R_SPARC_PC22 = 17 # PC relative 22 bit shifted -R_SPARC_WPLT30 = 18 # 30 bit PC relative PLT address -R_SPARC_COPY = 19 # Copy symbol at runtime -R_SPARC_GLOB_DAT = 20 # Create GOT entry -R_SPARC_JMP_SLOT = 21 # Create PLT entry -R_SPARC_RELATIVE = 22 # Adjust by program base -R_SPARC_UA32 = 23 # Direct 32 bit unaligned - -# Additional Sparc64 relocs. - -R_SPARC_PLT32 = 24 # Direct 32 bit ref to PLT entry -R_SPARC_HIPLT22 = 25 # High 22 bit PLT entry -R_SPARC_LOPLT10 = 26 # Truncated 10 bit PLT entry -R_SPARC_PCPLT32 = 27 # PC rel 32 bit ref to PLT entry -R_SPARC_PCPLT22 = 28 # PC rel high 22 bit PLT entry -R_SPARC_PCPLT10 = 29 # PC rel trunc 10 bit PLT entry -R_SPARC_10 = 30 # Direct 10 bit -R_SPARC_11 = 31 # Direct 11 bit -R_SPARC_64 = 32 # Direct 64 bit -R_SPARC_OLO10 = 33 # 10bit with secondary 13bit addend -R_SPARC_HH22 = 34 # Top 22 bits of direct 64 bit -R_SPARC_HM10 = 35 # High middle 10 bits of ... -R_SPARC_LM22 = 36 # Low middle 22 bits of ... -R_SPARC_PC_HH22 = 37 # Top 22 bits of pc rel 64 bit -R_SPARC_PC_HM10 = 38 # High middle 10 bit of ... -R_SPARC_PC_LM22 = 39 # Low miggle 22 bits of ... -R_SPARC_WDISP16 = 40 # PC relative 16 bit shifted -R_SPARC_WDISP19 = 41 # PC relative 19 bit shifted -R_SPARC_GLOB_JMP = 42 # was part of v9 ABI but was removed -R_SPARC_7 = 43 # Direct 7 bit -R_SPARC_5 = 44 # Direct 5 bit -R_SPARC_6 = 45 # Direct 6 bit -R_SPARC_DISP64 = 46 # PC relative 64 bit -R_SPARC_PLT64 = 47 # Direct 64 bit ref to PLT entry -R_SPARC_HIX22 = 48 # High 22 bit complemented -R_SPARC_LOX10 = 49 # Truncated 11 bit complemented -R_SPARC_H44 = 50 # Direct high 12 of 44 bit -R_SPARC_M44 = 51 # Direct mid 22 of 44 bit -R_SPARC_L44 = 52 # Direct low 10 of 44 bit -R_SPARC_REGISTER = 53 # Global register usage -R_SPARC_UA64 = 54 # Direct 64 bit unaligned -R_SPARC_UA16 = 55 # Direct 16 bit unaligned -R_SPARC_TLS_GD_HI22 = 56 -R_SPARC_TLS_GD_LO10 = 57 -R_SPARC_TLS_GD_ADD = 58 -R_SPARC_TLS_GD_CALL = 59 -R_SPARC_TLS_LDM_HI22 = 60 -R_SPARC_TLS_LDM_LO10 = 61 -R_SPARC_TLS_LDM_ADD = 62 -R_SPARC_TLS_LDM_CALL = 63 -R_SPARC_TLS_LDO_HIX22 = 64 -R_SPARC_TLS_LDO_LOX10 = 65 -R_SPARC_TLS_LDO_ADD = 66 -R_SPARC_TLS_IE_HI22 = 67 -R_SPARC_TLS_IE_LO10 = 68 -R_SPARC_TLS_IE_LD = 69 -R_SPARC_TLS_IE_LDX = 70 -R_SPARC_TLS_IE_ADD = 71 -R_SPARC_TLS_LE_HIX22 = 72 -R_SPARC_TLS_LE_LOX10 = 73 -R_SPARC_TLS_DTPMOD32 = 74 -R_SPARC_TLS_DTPMOD64 = 75 -R_SPARC_TLS_DTPOFF32 = 76 -R_SPARC_TLS_DTPOFF64 = 77 -R_SPARC_TLS_TPOFF32 = 78 -R_SPARC_TLS_TPOFF64 = 79 -R_SPARC_GOTDATA_HIX22 = 80 -R_SPARC_GOTDATA_LOX10 = 81 -R_SPARC_GOTDATA_OP_HIX22 = 82 -R_SPARC_GOTDATA_OP_LOX10 = 83 -R_SPARC_GOTDATA_OP = 84 -R_SPARC_H34 = 85 -R_SPARC_SIZE32 = 86 -R_SPARC_SIZE64 = 87 -R_SPARC_JMP_IREL = 248 -R_SPARC_IRELATIVE = 249 -R_SPARC_GNU_VTINHERIT = 250 -R_SPARC_GNU_VTENTRY = 251 -R_SPARC_REV32 = 252 -# Keep this the last entry. -R_SPARC_NUM = 253 - -# MIPS R3000 relocations - -R_MIPS_NONE = 0 # No reloc -R_MIPS_16 = 1 # Direct 16 bit -R_MIPS_32 = 2 # Direct 32 bit -R_MIPS_REL32 = 3 # PC relative 32 bit -R_MIPS_26 = 4 # Direct 26 bit shifted -R_MIPS_HI16 = 5 # High 16 bit -R_MIPS_LO16 = 6 # Low 16 bit -R_MIPS_GPREL16 = 7 # GP relative 16 bit -R_MIPS_LITERAL = 8 # 16 bit literal entry -R_MIPS_GOT16 = 9 # 16 bit GOT entry -R_MIPS_PC16 = 10 # PC relative 16 bit -R_MIPS_CALL16 = 11 # 16 bit GOT entry for function -R_MIPS_GPREL32 = 12 # GP relative 32 bit - -R_MIPS_SHIFT5 = 16 -R_MIPS_SHIFT6 = 17 -R_MIPS_64 = 18 -R_MIPS_GOT_DISP = 19 -R_MIPS_GOT_PAGE = 20 -R_MIPS_GOT_OFST = 21 -R_MIPS_GOT_HI16 = 22 -R_MIPS_GOT_LO16 = 23 -R_MIPS_SUB = 24 -R_MIPS_INSERT_A = 25 -R_MIPS_INSERT_B = 26 -R_MIPS_DELETE = 27 -R_MIPS_HIGHER = 28 -R_MIPS_HIGHEST = 29 -R_MIPS_CALL_HI16 = 30 -R_MIPS_CALL_LO16 = 31 -R_MIPS_SCN_DISP = 32 -R_MIPS_REL16 = 33 -R_MIPS_ADD_IMMEDIATE = 34 -R_MIPS_PJUMP = 35 -R_MIPS_RELGOT = 36 -R_MIPS_JALR = 37 -R_MIPS_TLS_DTPMOD32 = 38 # Module number 32 bit -R_MIPS_TLS_DTPREL32 = 39 # Module-relative offset 32 bit -R_MIPS_TLS_DTPMOD64 = 40 # Module number 64 bit -R_MIPS_TLS_DTPREL64 = 41 # Module-relative offset 64 bit -R_MIPS_TLS_GD = 42 # 16 bit GOT offset for GD -R_MIPS_TLS_LDM = 43 # 16 bit GOT offset for LDM -R_MIPS_TLS_DTPREL_HI16 = 44 # Module-relative offset, high 16 bits -R_MIPS_TLS_DTPREL_LO16 = 45 # Module-relative offset, low 16 bits -R_MIPS_TLS_GOTTPREL = 46 # 16 bit GOT offset for IE -R_MIPS_TLS_TPREL32 = 47 # TP-relative offset, 32 bit -R_MIPS_TLS_TPREL64 = 48 # TP-relative offset, 64 bit -R_MIPS_TLS_TPREL_HI16 = 49 # TP-relative offset, high 16 bits -R_MIPS_TLS_TPREL_LO16 = 50 # TP-relative offset, low 16 bits -R_MIPS_GLOB_DAT = 51 -R_MIPS_COPY = 126 -R_MIPS_JUMP_SLOT = 127 -# Keep this the last entry. -R_MIPS_NUM = 128 - -# HPPA relocations - -R_PARISC_NONE = 0 # No reloc. -R_PARISC_DIR32 = 1 # Direct 32-bit reference. -R_PARISC_DIR21L = 2 # Left 21 bits of eff. address. -R_PARISC_DIR17R = 3 # Right 17 bits of eff. address. -R_PARISC_DIR17F = 4 # 17 bits of eff. address. -R_PARISC_DIR14R = 6 # Right 14 bits of eff. address. -R_PARISC_PCREL32 = 9 # 32-bit rel. address. -R_PARISC_PCREL21L = 10 # Left 21 bits of rel. address. -R_PARISC_PCREL17R = 11 # Right 17 bits of rel. address. -R_PARISC_PCREL17F = 12 # 17 bits of rel. address. -R_PARISC_PCREL14R = 14 # Right 14 bits of rel. address. -R_PARISC_DPREL21L = 18 # Left 21 bits of rel. address. -R_PARISC_DPREL14R = 22 # Right 14 bits of rel. address. -R_PARISC_GPREL21L = 26 # GP-relative, left 21 bits. -R_PARISC_GPREL14R = 30 # GP-relative, right 14 bits. -R_PARISC_LTOFF21L = 34 # LT-relative, left 21 bits. -R_PARISC_LTOFF14R = 38 # LT-relative, right 14 bits. -R_PARISC_SECREL32 = 41 # 32 bits section rel. address. -R_PARISC_SEGBASE = 48 # No relocation, set segment base. -R_PARISC_SEGREL32 = 49 # 32 bits segment rel. address. -R_PARISC_PLTOFF21L = 50 # PLT rel. address, left 21 bits. -R_PARISC_PLTOFF14R = 54 # PLT rel. address, right 14 bits. -R_PARISC_LTOFF_FPTR32 = 57 # 32 bits LT-rel. function pointer. -R_PARISC_LTOFF_FPTR21L = 58 # LT-rel. fct ptr, left 21 bits. -R_PARISC_LTOFF_FPTR14R = 62 # LT-rel. fct ptr, right 14 bits. -R_PARISC_FPTR64 = 64 # 64 bits function address. -R_PARISC_PLABEL32 = 65 # 32 bits function address. -R_PARISC_PLABEL21L = 66 # Left 21 bits of fdesc address. -R_PARISC_PLABEL14R = 70 # Right 14 bits of fdesc address. -R_PARISC_PCREL64 = 72 # 64 bits PC-rel. address. -R_PARISC_PCREL22F = 74 # 22 bits PC-rel. address. -R_PARISC_PCREL14WR = 75 # PC-rel. address, right 14 bits. -R_PARISC_PCREL14DR = 76 # PC rel. address, right 14 bits. -R_PARISC_PCREL16F = 77 # 16 bits PC-rel. address. -R_PARISC_PCREL16WF = 78 # 16 bits PC-rel. address. -R_PARISC_PCREL16DF = 79 # 16 bits PC-rel. address. -R_PARISC_DIR64 = 80 # 64 bits of eff. address. -R_PARISC_DIR14WR = 83 # 14 bits of eff. address. -R_PARISC_DIR14DR = 84 # 14 bits of eff. address. -R_PARISC_DIR16F = 85 # 16 bits of eff. address. -R_PARISC_DIR16WF = 86 # 16 bits of eff. address. -R_PARISC_DIR16DF = 87 # 16 bits of eff. address. -R_PARISC_GPREL64 = 88 # 64 bits of GP-rel. address. -R_PARISC_GPREL14WR = 91 # GP-rel. address, right 14 bits. -R_PARISC_GPREL14DR = 92 # GP-rel. address, right 14 bits. -R_PARISC_GPREL16F = 93 # 16 bits GP-rel. address. -R_PARISC_GPREL16WF = 94 # 16 bits GP-rel. address. -R_PARISC_GPREL16DF = 95 # 16 bits GP-rel. address. -R_PARISC_LTOFF64 = 96 # 64 bits LT-rel. address. -R_PARISC_LTOFF14WR = 99 # LT-rel. address, right 14 bits. -R_PARISC_LTOFF14DR = 100 # LT-rel. address, right 14 bits. -R_PARISC_LTOFF16F = 101 # 16 bits LT-rel. address. -R_PARISC_LTOFF16WF = 102 # 16 bits LT-rel. address. -R_PARISC_LTOFF16DF = 103 # 16 bits LT-rel. address. -R_PARISC_SECREL64 = 104 # 64 bits section rel. address. -R_PARISC_SEGREL64 = 112 # 64 bits segment rel. address. -R_PARISC_PLTOFF14WR = 115 # PLT-rel. address, right 14 bits. -R_PARISC_PLTOFF14DR = 116 # PLT-rel. address, right 14 bits. -R_PARISC_PLTOFF16F = 117 # 16 bits LT-rel. address. -R_PARISC_PLTOFF16WF = 118 # 16 bits PLT-rel. address. -R_PARISC_PLTOFF16DF = 119 # 16 bits PLT-rel. address. -R_PARISC_LTOFF_FPTR64 = 120 # 64 bits LT-rel. function ptr. -R_PARISC_LTOFF_FPTR14WR = 123 # LT-rel. fct. ptr., right 14 bits. -R_PARISC_LTOFF_FPTR14DR = 124 # LT-rel. fct. ptr., right 14 bits. -R_PARISC_LTOFF_FPTR16F = 125 # 16 bits LT-rel. function ptr. -R_PARISC_LTOFF_FPTR16WF = 126 # 16 bits LT-rel. function ptr. -R_PARISC_LTOFF_FPTR16DF = 127 # 16 bits LT-rel. function ptr. -R_PARISC_LORESERVE = 128 -R_PARISC_COPY = 128 # Copy relocation. -R_PARISC_IPLT = 129 # Dynamic reloc, imported PLT -R_PARISC_EPLT = 130 # Dynamic reloc, exported PLT -R_PARISC_TPREL32 = 153 # 32 bits TP-rel. address. -R_PARISC_TPREL21L = 154 # TP-rel. address, left 21 bits. -R_PARISC_TPREL14R = 158 # TP-rel. address, right 14 bits. -R_PARISC_LTOFF_TP21L = 162 # LT-TP-rel. address, left 21 bits. -R_PARISC_LTOFF_TP14R = 166 # LT-TP-rel. address, right 14 bits.*/ -R_PARISC_LTOFF_TP14F = 167 # 14 bits LT-TP-rel. address. -R_PARISC_TPREL64 = 216 # 64 bits TP-rel. address. -R_PARISC_TPREL14WR = 219 # TP-rel. address, right 14 bits. -R_PARISC_TPREL14DR = 220 # TP-rel. address, right 14 bits. -R_PARISC_TPREL16F = 221 # 16 bits TP-rel. address. -R_PARISC_TPREL16WF = 222 # 16 bits TP-rel. address. -R_PARISC_TPREL16DF = 223 # 16 bits TP-rel. address. -R_PARISC_LTOFF_TP64 = 224 # 64 bits LT-TP-rel. address. -R_PARISC_LTOFF_TP14WR = 227 # LT-TP-rel. address, right 14 bits.*/ -R_PARISC_LTOFF_TP14DR = 228 # LT-TP-rel. address, right 14 bits.*/ -R_PARISC_LTOFF_TP16F = 229 # 16 bits LT-TP-rel. address. -R_PARISC_LTOFF_TP16WF = 230 # 16 bits LT-TP-rel. address. -R_PARISC_LTOFF_TP16DF = 231 # 16 bits LT-TP-rel. address. -R_PARISC_GNU_VTENTRY = 232 -R_PARISC_GNU_VTINHERIT = 233 -R_PARISC_TLS_GD21L = 234 # GD 21-bit left. -R_PARISC_TLS_GD14R = 235 # GD 14-bit right. -R_PARISC_TLS_GDCALL = 236 # GD call to __t_g_a. -R_PARISC_TLS_LDM21L = 237 # LD module 21-bit left. -R_PARISC_TLS_LDM14R = 238 # LD module 14-bit right. -R_PARISC_TLS_LDMCALL = 239 # LD module call to __t_g_a. -R_PARISC_TLS_LDO21L = 240 # LD offset 21-bit left. -R_PARISC_TLS_LDO14R = 241 # LD offset 14-bit right. -R_PARISC_TLS_DTPMOD32 = 242 # DTP module 32-bit. -R_PARISC_TLS_DTPMOD64 = 243 # DTP module 64-bit. -R_PARISC_TLS_DTPOFF32 = 244 # DTP offset 32-bit. -R_PARISC_TLS_DTPOFF64 = 245 # DTP offset 32-bit. -R_PARISC_TLS_LE21L = R_PARISC_TPREL21L -R_PARISC_TLS_LE14R = R_PARISC_TPREL14R -R_PARISC_TLS_IE21L = R_PARISC_LTOFF_TP21L -R_PARISC_TLS_IE14R = R_PARISC_LTOFF_TP14R -R_PARISC_TLS_TPREL32 = R_PARISC_TPREL32 -R_PARISC_TLS_TPREL64 = R_PARISC_TPREL64 -R_PARISC_HIRESERVE = 255 - -# Alpha relocations - -R_ALPHA_NONE = 0 # No reloc -R_ALPHA_REFLONG = 1 # Direct 32 bit -R_ALPHA_REFQUAD = 2 # Direct 64 bit -R_ALPHA_GPREL32 = 3 # GP relative 32 bit -R_ALPHA_LITERAL = 4 # GP relative 16 bit w/optimization -R_ALPHA_LITUSE = 5 # Optimization hint for LITERAL -R_ALPHA_GPDISP = 6 # Add displacement to GP -R_ALPHA_BRADDR = 7 # PC+4 relative 23 bit shifted -R_ALPHA_HINT = 8 # PC+4 relative 16 bit shifted -R_ALPHA_SREL16 = 9 # PC relative 16 bit -R_ALPHA_SREL32 = 10 # PC relative 32 bit -R_ALPHA_SREL64 = 11 # PC relative 64 bit -R_ALPHA_GPRELHIGH = 17 # GP relative 32 bit, high 16 bits -R_ALPHA_GPRELLOW = 18 # GP relative 32 bit, low 16 bits -R_ALPHA_GPREL16 = 19 # GP relative 16 bit -R_ALPHA_COPY = 24 # Copy symbol at runtime -R_ALPHA_GLOB_DAT = 25 # Create GOT entry -R_ALPHA_JMP_SLOT = 26 # Create PLT entry -R_ALPHA_RELATIVE = 27 # Adjust by program base -R_ALPHA_TLS_GD_HI = 28 -R_ALPHA_TLSGD = 29 -R_ALPHA_TLS_LDM = 30 -R_ALPHA_DTPMOD64 = 31 -R_ALPHA_GOTDTPREL = 32 -R_ALPHA_DTPREL64 = 33 -R_ALPHA_DTPRELHI = 34 -R_ALPHA_DTPRELLO = 35 -R_ALPHA_DTPREL16 = 36 -R_ALPHA_GOTTPREL = 37 -R_ALPHA_TPREL64 = 38 -R_ALPHA_TPRELHI = 39 -R_ALPHA_TPRELLO = 40 -R_ALPHA_TPREL16 = 41 -# Keep this the last entry. -R_ALPHA_NUM = 46 - -# PowerPC relocations - -R_PPC_NONE = 0 -R_PPC_ADDR32 = 1 # 32bit absolute address -R_PPC_ADDR24 = 2 # 26bit address, 2 bits ignored. -R_PPC_ADDR16 = 3 # 16bit absolute address -R_PPC_ADDR16_LO = 4 # lower 16bit of absolute address -R_PPC_ADDR16_HI = 5 # high 16bit of absolute address -R_PPC_ADDR16_HA = 6 # adjusted high 16bit -R_PPC_ADDR14 = 7 # 16bit address, 2 bits ignored -R_PPC_ADDR14_BRTAKEN = 8 -R_PPC_ADDR14_BRNTAKEN = 9 -R_PPC_REL24 = 10 # PC relative 26 bit -R_PPC_REL14 = 11 # PC relative 16 bit -R_PPC_REL14_BRTAKEN = 12 -R_PPC_REL14_BRNTAKEN = 13 -R_PPC_GOT16 = 14 -R_PPC_GOT16_LO = 15 -R_PPC_GOT16_HI = 16 -R_PPC_GOT16_HA = 17 -R_PPC_PLTREL24 = 18 -R_PPC_COPY = 19 -R_PPC_GLOB_DAT = 20 -R_PPC_JMP_SLOT = 21 -R_PPC_RELATIVE = 22 -R_PPC_LOCAL24PC = 23 -R_PPC_UADDR32 = 24 -R_PPC_UADDR16 = 25 -R_PPC_REL32 = 26 -R_PPC_PLT32 = 27 -R_PPC_PLTREL32 = 28 -R_PPC_PLT16_LO = 29 -R_PPC_PLT16_HI = 30 -R_PPC_PLT16_HA = 31 -R_PPC_SDAREL16 = 32 -R_PPC_SECTOFF = 33 -R_PPC_SECTOFF_LO = 34 -R_PPC_SECTOFF_HI = 35 -R_PPC_SECTOFF_HA = 36 - -# PowerPC relocations defined for the TLS access ABI. -R_PPC_TLS = 67 # none (sym+add)@tls -R_PPC_DTPMOD32 = 68 # word32 (sym+add)@dtpmod -R_PPC_TPREL16 = 69 # half16* (sym+add)@tprel -R_PPC_TPREL16_LO = 70 # half16 (sym+add)@tprel@l -R_PPC_TPREL16_HI = 71 # half16 (sym+add)@tprel@h -R_PPC_TPREL16_HA = 72 # half16 (sym+add)@tprel@ha -R_PPC_TPREL32 = 73 # word32 (sym+add)@tprel -R_PPC_DTPREL16 = 74 # half16* (sym+add)@dtprel -R_PPC_DTPREL16_LO = 75 # half16 (sym+add)@dtprel@l -R_PPC_DTPREL16_HI = 76 # half16 (sym+add)@dtprel@h -R_PPC_DTPREL16_HA = 77 # half16 (sym+add)@dtprel@ha -R_PPC_DTPREL32 = 78 # word32 (sym+add)@dtprel -R_PPC_GOT_TLSGD16 = 79 # half16* (sym+add)@got@tlsgd -R_PPC_GOT_TLSGD16_LO = 80 # half16 (sym+add)@got@tlsgd@l -R_PPC_GOT_TLSGD16_HI = 81 # half16 (sym+add)@got@tlsgd@h -R_PPC_GOT_TLSGD16_HA = 82 # half16 (sym+add)@got@tlsgd@ha -R_PPC_GOT_TLSLD16 = 83 # half16* (sym+add)@got@tlsld -R_PPC_GOT_TLSLD16_LO = 84 # half16 (sym+add)@got@tlsld@l -R_PPC_GOT_TLSLD16_HI = 85 # half16 (sym+add)@got@tlsld@h -R_PPC_GOT_TLSLD16_HA = 86 # half16 (sym+add)@got@tlsld@ha -R_PPC_GOT_TPREL16 = 87 # half16* (sym+add)@got@tprel -R_PPC_GOT_TPREL16_LO = 88 # half16 (sym+add)@got@tprel@l -R_PPC_GOT_TPREL16_HI = 89 # half16 (sym+add)@got@tprel@h -R_PPC_GOT_TPREL16_HA = 90 # half16 (sym+add)@got@tprel@ha -R_PPC_GOT_DTPREL16 = 91 # half16* (sym+add)@got@dtprel -R_PPC_GOT_DTPREL16_LO = 92 # half16* (sym+add)@got@dtprel@l -R_PPC_GOT_DTPREL16_HI = 93 # half16* (sym+add)@got@dtprel@h -R_PPC_GOT_DTPREL16_HA = 94 # half16* (sym+add)@got@dtprel@ha - -# The remaining relocs are from the Embedded ELF ABI, and are not in the SVR4 ELF ABI. -R_PPC_EMB_NADDR32 = 101 -R_PPC_EMB_NADDR16 = 102 -R_PPC_EMB_NADDR16_LO = 103 -R_PPC_EMB_NADDR16_HI = 104 -R_PPC_EMB_NADDR16_HA = 105 -R_PPC_EMB_SDAI16 = 106 -R_PPC_EMB_SDA2I16 = 107 -R_PPC_EMB_SDA2REL = 108 -R_PPC_EMB_SDA21 = 109 # 16 bit offset in SDA -R_PPC_EMB_MRKREF = 110 -R_PPC_EMB_RELSEC16 = 111 -R_PPC_EMB_RELST_LO = 112 -R_PPC_EMB_RELST_HI = 113 -R_PPC_EMB_RELST_HA = 114 -R_PPC_EMB_BIT_FLD = 115 -R_PPC_EMB_RELSDA = 116 # 16 bit relative offset in SDA - -# Diab tool relocations. -R_PPC_DIAB_SDA21_LO = 180 # like EMB_SDA21, but lower 16 bit -R_PPC_DIAB_SDA21_HI = 181 # like EMB_SDA21, but high 16 bit -R_PPC_DIAB_SDA21_HA = 182 # like EMB_SDA21, adjusted high 16 -R_PPC_DIAB_RELSDA_LO = 183 # like EMB_RELSDA, but lower 16 bit -R_PPC_DIAB_RELSDA_HI = 184 # like EMB_RELSDA, but high 16 bit -R_PPC_DIAB_RELSDA_HA = 185 # like EMB_RELSDA, adjusted high 16 - -# GNU extension to support local ifunc. -R_PPC_IRELATIVE = 248 - -# GNU relocs used in PIC code sequences. -R_PPC_REL16 = 249 # half16 (sym+add-.) -R_PPC_REL16_LO = 250 # half16 (sym+add-.)@l -R_PPC_REL16_HI = 251 # half16 (sym+add-.)@h -R_PPC_REL16_HA = 252 # half16 (sym+add-.)@ha - -# This is a phony reloc to handle any old fashioned TOC16 references that may still be in object files. -R_PPC_TOC16 = 255 - -# PowerPC64 relocations defined by the ABIs -R_PPC64_NONE = R_PPC_NONE -R_PPC64_ADDR32 = R_PPC_ADDR32 # 32bit absolute address -R_PPC64_ADDR24 = R_PPC_ADDR24 # 26bit address, word aligned -R_PPC64_ADDR16 = R_PPC_ADDR16 # 16bit absolute address -R_PPC64_ADDR16_LO = R_PPC_ADDR16_LO # lower 16bits of address -R_PPC64_ADDR16_HI = R_PPC_ADDR16_HI # high 16bits of address. -R_PPC64_ADDR16_HA = R_PPC_ADDR16_HA # adjusted high 16bits. -R_PPC64_ADDR14 = R_PPC_ADDR14 # 16bit address, word aligned -R_PPC64_ADDR14_BRTAKEN = R_PPC_ADDR14_BRTAKEN -R_PPC64_ADDR14_BRNTAKEN = R_PPC_ADDR14_BRNTAKEN -R_PPC64_REL24 = R_PPC_REL24 # PC-rel. 26 bit, word aligned -R_PPC64_REL14 = R_PPC_REL14 # PC relative 16 bit -R_PPC64_REL14_BRTAKEN = R_PPC_REL14_BRTAKEN -R_PPC64_REL14_BRNTAKEN = R_PPC_REL14_BRNTAKEN -R_PPC64_GOT16 = R_PPC_GOT16 -R_PPC64_GOT16_LO = R_PPC_GOT16_LO -R_PPC64_GOT16_HI = R_PPC_GOT16_HI -R_PPC64_GOT16_HA = R_PPC_GOT16_HA - -R_PPC64_COPY = R_PPC_COPY -R_PPC64_GLOB_DAT = R_PPC_GLOB_DAT -R_PPC64_JMP_SLOT = R_PPC_JMP_SLOT -R_PPC64_RELATIVE = R_PPC_RELATIVE - -R_PPC64_UADDR32 = R_PPC_UADDR32 -R_PPC64_UADDR16 = R_PPC_UADDR16 -R_PPC64_REL32 = R_PPC_REL32 -R_PPC64_PLT32 = R_PPC_PLT32 -R_PPC64_PLTREL32 = R_PPC_PLTREL32 -R_PPC64_PLT16_LO = R_PPC_PLT16_LO -R_PPC64_PLT16_HI = R_PPC_PLT16_HI -R_PPC64_PLT16_HA = R_PPC_PLT16_HA - -R_PPC64_SECTOFF = R_PPC_SECTOFF -R_PPC64_SECTOFF_LO = R_PPC_SECTOFF_LO -R_PPC64_SECTOFF_HI = R_PPC_SECTOFF_HI -R_PPC64_SECTOFF_HA = R_PPC_SECTOFF_HA -R_PPC64_ADDR30 = 37 # word30 (S + A - P) >> 2 -R_PPC64_ADDR64 = 38 # doubleword64 S + A -R_PPC64_ADDR16_HIGHER = 39 # half16 #higher(S + A) -R_PPC64_ADDR16_HIGHERA = 40 # half16 #highera(S + A) -R_PPC64_ADDR16_HIGHEST = 41 # half16 #highest(S + A) -R_PPC64_ADDR16_HIGHESTA = 42 # half16 #highesta(S + A) -R_PPC64_UADDR64 = 43 # doubleword64 S + A -R_PPC64_REL64 = 44 # doubleword64 S + A - P -R_PPC64_PLT64 = 45 # doubleword64 L + A -R_PPC64_PLTREL64 = 46 # doubleword64 L + A - P -R_PPC64_TOC16 = 47 # half16* S + A - .TOC -R_PPC64_TOC16_LO = 48 # half16 #lo(S + A - .TOC.) -R_PPC64_TOC16_HI = 49 # half16 #hi(S + A - .TOC.) -R_PPC64_TOC16_HA = 50 # half16 #ha(S + A - .TOC.) -R_PPC64_TOC = 51 # doubleword64 .TOC -R_PPC64_PLTGOT16 = 52 # half16* M + A -R_PPC64_PLTGOT16_LO = 53 # half16 #lo(M + A) -R_PPC64_PLTGOT16_HI = 54 # half16 #hi(M + A) -R_PPC64_PLTGOT16_HA = 55 # half16 #ha(M + A) - -R_PPC64_ADDR16_DS = 56 # half16ds* (S + A) >> 2 -R_PPC64_ADDR16_LO_DS = 57 # half16ds #lo(S + A) >> 2 -R_PPC64_GOT16_DS = 58 # half16ds* (G + A) >> 2 -R_PPC64_GOT16_LO_DS = 59 # half16ds #lo(G + A) >> 2 -R_PPC64_PLT16_LO_DS = 60 # half16ds #lo(L + A) >> 2 -R_PPC64_SECTOFF_DS = 61 # half16ds* (R + A) >> 2 -R_PPC64_SECTOFF_LO_DS = 62 # half16ds #lo(R + A) >> 2 -R_PPC64_TOC16_DS = 63 # half16ds* (S + A - .TOC.) >> 2 -R_PPC64_TOC16_LO_DS = 64 # half16ds #lo(S + A - .TOC.) >> 2 -R_PPC64_PLTGOT16_DS = 65 # half16ds* (M + A) >> 2 -R_PPC64_PLTGOT16_LO_DS = 66 # half16ds #lo(M + A) >> 2 - -# PowerPC64 relocations defined for the TLS access ABI. -R_PPC64_TLS = 67 # none (sym+add)@tls -R_PPC64_DTPMOD64 = 68 # doubleword64 (sym+add)@dtpmod -R_PPC64_TPREL16 = 69 # half16* (sym+add)@tprel -R_PPC64_TPREL16_LO = 70 # half16 (sym+add)@tprel@l -R_PPC64_TPREL16_HI = 71 # half16 (sym+add)@tprel@h -R_PPC64_TPREL16_HA = 72 # half16 (sym+add)@tprel@ha -R_PPC64_TPREL64 = 73 # doubleword64 (sym+add)@tprel -R_PPC64_DTPREL16 = 74 # half16* (sym+add)@dtprel -R_PPC64_DTPREL16_LO = 75 # half16 (sym+add)@dtprel@l -R_PPC64_DTPREL16_HI = 76 # half16 (sym+add)@dtprel@h -R_PPC64_DTPREL16_HA = 77 # half16 (sym+add)@dtprel@ha -R_PPC64_DTPREL64 = 78 # doubleword64 (sym+add)@dtprel -R_PPC64_GOT_TLSGD16 = 79 # half16* (sym+add)@got@tlsgd -R_PPC64_GOT_TLSGD16_LO = 80 # half16 (sym+add)@got@tlsgd@l -R_PPC64_GOT_TLSGD16_HI = 81 # half16 (sym+add)@got@tlsgd@h -R_PPC64_GOT_TLSGD16_HA = 82 # half16 (sym+add)@got@tlsgd@ha -R_PPC64_GOT_TLSLD16 = 83 # half16* (sym+add)@got@tlsld -R_PPC64_GOT_TLSLD16_LO = 84 # half16 (sym+add)@got@tlsld@l -R_PPC64_GOT_TLSLD16_HI = 85 # half16 (sym+add)@got@tlsld@h -R_PPC64_GOT_TLSLD16_HA = 86 # half16 (sym+add)@got@tlsld@ha -R_PPC64_GOT_TPREL16_DS = 87 # half16ds* (sym+add)@got@tprel -R_PPC64_GOT_TPREL16_LO_DS = 88 # half16ds (sym+add)@got@tprel@l -R_PPC64_GOT_TPREL16_HI = 89 # half16 (sym+add)@got@tprel@h -R_PPC64_GOT_TPREL16_HA = 90 # half16 (sym+add)@got@tprel@ha -R_PPC64_GOT_DTPREL16_DS = 91 # half16ds* (sym+add)@got@dtprel -R_PPC64_GOT_DTPREL16_LO_DS = 92 # half16ds (sym+add)@got@dtprel@l -R_PPC64_GOT_DTPREL16_HI = 93 # half16 (sym+add)@got@dtprel@h -R_PPC64_GOT_DTPREL16_HA = 94 # half16 (sym+add)@got@dtprel@ha -R_PPC64_TPREL16_DS = 95 # half16ds* (sym+add)@tprel -R_PPC64_TPREL16_LO_DS = 96 # half16ds (sym+add)@tprel@l -R_PPC64_TPREL16_HIGHER = 97 # half16 (sym+add)@tprel@higher -R_PPC64_TPREL16_HIGHERA = 98 # half16 (sym+add)@tprel@highera -R_PPC64_TPREL16_HIGHEST = 99 # half16 (sym+add)@tprel@highest -R_PPC64_TPREL16_HIGHESTA = 100 # half16 (sym+add)@tprel@highesta -R_PPC64_DTPREL16_DS = 101 # half16ds* (sym+add)@dtprel -R_PPC64_DTPREL16_LO_DS = 102 # half16ds (sym+add)@dtprel@l -R_PPC64_DTPREL16_HIGHER = 103 # half16 (sym+add)@dtprel@higher -R_PPC64_DTPREL16_HIGHERA = 104 # half16 (sym+add)@dtprel@highera -R_PPC64_DTPREL16_HIGHEST = 105 # half16 (sym+add)@dtprel@highest -R_PPC64_DTPREL16_HIGHESTA = 106 # half16 (sym+add)@dtprel@highesta - -# GNU extension to support local ifunc. -R_PPC64_JMP_IREL = 247 -R_PPC64_IRELATIVE = 248 -R_PPC64_REL16 = 249 # half16 (sym+add-.) -R_PPC64_REL16_LO = 250 # half16 (sym+add-.)@l -R_PPC64_REL16_HI = 251 # half16 (sym+add-.)@h -R_PPC64_REL16_HA = 252 # half16 (sym+add-.)@ha - -# PowerPC64 specific values for the Dyn d_tag field. -DT_PPC64_GLINK = (DT_LOPROC + 0) -DT_PPC64_OPD = (DT_LOPROC + 1) -DT_PPC64_OPDSZ = (DT_LOPROC + 2) -DT_PPC64_NUM = 3 - -# ARM relocations - -R_ARM_NONE = 0 # No reloc -R_ARM_PC24 = 1 # PC relative 26 bit branch -R_ARM_ABS32 = 2 # Direct 32 bit -R_ARM_REL32 = 3 # PC relative 32 bit -R_ARM_PC13 = 4 -R_ARM_ABS16 = 5 # Direct 16 bit -R_ARM_ABS12 = 6 # Direct 12 bit -R_ARM_THM_ABS5 = 7 -R_ARM_ABS8 = 8 # Direct 8 bit -R_ARM_SBREL32 = 9 -R_ARM_THM_PC22 = 10 -R_ARM_THM_PC8 = 11 -R_ARM_AMP_VCALL9 = 12 -R_ARM_SWI24 = 13 # Obsolete static relocation. -R_ARM_TLS_DESC = 13 # Dynamic relocation. -R_ARM_THM_SWI8 = 14 -R_ARM_XPC25 = 15 -R_ARM_THM_XPC22 = 16 -R_ARM_TLS_DTPMOD32 = 17 # ID of module containing symbol -R_ARM_TLS_DTPOFF32 = 18 # Offset in TLS block -R_ARM_TLS_TPOFF32 = 19 # Offset in static TLS block -R_ARM_COPY = 20 # Copy symbol at runtime -R_ARM_GLOB_DAT = 21 # Create GOT entry -R_ARM_JUMP_SLOT = 22 # Create PLT entry -R_ARM_RELATIVE = 23 # Adjust by program base -R_ARM_GOTOFF = 24 # 32 bit offset to GOT -R_ARM_GOTPC = 25 # 32 bit PC relative offset to GOT -R_ARM_GOT32 = 26 # 32 bit GOT entry -R_ARM_PLT32 = 27 # 32 bit PLT address -R_ARM_ALU_PCREL_7_0 = 32 -R_ARM_ALU_PCREL_15_8 = 33 -R_ARM_ALU_PCREL_23_15 = 34 -R_ARM_LDR_SBREL_11_0 = 35 -R_ARM_ALU_SBREL_19_12 = 36 -R_ARM_ALU_SBREL_27_20 = 37 -R_ARM_TLS_GOTDESC = 90 -R_ARM_TLS_CALL = 91 -R_ARM_TLS_DESCSEQ = 92 -R_ARM_THM_TLS_CALL = 93 -R_ARM_GNU_VTENTRY = 100 -R_ARM_GNU_VTINHERIT = 101 -R_ARM_THM_PC11 = 102 # thumb unconditional branch -R_ARM_THM_PC9 = 103 # thumb conditional branch -R_ARM_TLS_GD32 = 104 # PC-rel 32 bit for global dynamic thread local data -R_ARM_TLS_LDM32 = 105 # PC-rel 32 bit for local dynamic thread local data -R_ARM_TLS_LDO32 = 106 # 32 bit offset relative to TLS block -R_ARM_TLS_IE32 = 107 # PC-rel 32 bit for GOT entry of static TLS block offset -R_ARM_TLS_LE32 = 108 # 32 bit offset relative to static TLS block -R_ARM_THM_TLS_DESCSEQ = 129 -R_ARM_IRELATIVE = 160 -R_ARM_RXPC25 = 249 -R_ARM_RSBREL32 = 250 -R_ARM_THM_RPC22 = 251 -R_ARM_RREL32 = 252 -R_ARM_RABS22 = 253 -R_ARM_RPC24 = 254 -R_ARM_RBASE = 255 -# Keep this the last entry. -R_ARM_NUM = 256 - -# IA-64 relocations - -R_IA64_NONE = 0x00 # none -R_IA64_IMM14 = 0x21 # symbol + addend, add imm14 -R_IA64_IMM22 = 0x22 # symbol + addend, add imm22 -R_IA64_IMM64 = 0x23 # symbol + addend, mov imm64 -R_IA64_DIR32MSB = 0x24 # symbol + addend, data4 MSB -R_IA64_DIR32LSB = 0x25 # symbol + addend, data4 LSB -R_IA64_DIR64MSB = 0x26 # symbol + addend, data8 MSB -R_IA64_DIR64LSB = 0x27 # symbol + addend, data8 LSB -R_IA64_GPREL22 = 0x2a # @gprel(sym + add), add imm22 -R_IA64_GPREL64I = 0x2b # @gprel(sym + add), mov imm64 -R_IA64_GPREL32MSB = 0x2c # @gprel(sym + add), data4 MSB -R_IA64_GPREL32LSB = 0x2d # @gprel(sym + add), data4 LSB -R_IA64_GPREL64MSB = 0x2e # @gprel(sym + add), data8 MSB -R_IA64_GPREL64LSB = 0x2f # @gprel(sym + add), data8 LSB -R_IA64_LTOFF22 = 0x32 # @ltoff(sym + add), add imm22 -R_IA64_LTOFF64I = 0x33 # @ltoff(sym + add), mov imm64 -R_IA64_PLTOFF22 = 0x3a # @pltoff(sym + add), add imm22 -R_IA64_PLTOFF64I = 0x3b # @pltoff(sym + add), mov imm64 -R_IA64_PLTOFF64MSB = 0x3e # @pltoff(sym + add), data8 MSB -R_IA64_PLTOFF64LSB = 0x3f # @pltoff(sym + add), data8 LSB -R_IA64_FPTR64I = 0x43 # @fptr(sym + add), mov imm64 -R_IA64_FPTR32MSB = 0x44 # @fptr(sym + add), data4 MSB -R_IA64_FPTR32LSB = 0x45 # @fptr(sym + add), data4 LSB -R_IA64_FPTR64MSB = 0x46 # @fptr(sym + add), data8 MSB -R_IA64_FPTR64LSB = 0x47 # @fptr(sym + add), data8 LSB -R_IA64_PCREL60B = 0x48 # @pcrel(sym + add), brl -R_IA64_PCREL21B = 0x49 # @pcrel(sym + add), ptb, call -R_IA64_PCREL21M = 0x4a # @pcrel(sym + add), chk.s -R_IA64_PCREL21F = 0x4b # @pcrel(sym + add), fchkf -R_IA64_PCREL32MSB = 0x4c # @pcrel(sym + add), data4 MSB -R_IA64_PCREL32LSB = 0x4d # @pcrel(sym + add), data4 LSB -R_IA64_PCREL64MSB = 0x4e # @pcrel(sym + add), data8 MSB -R_IA64_PCREL64LSB = 0x4f # @pcrel(sym + add), data8 LSB -R_IA64_LTOFF_FPTR22 = 0x52 # @ltoff(@fptr(s+a)), imm22 -R_IA64_LTOFF_FPTR64I = 0x53 # @ltoff(@fptr(s+a)), imm64 -R_IA64_LTOFF_FPTR32MSB = 0x54 # @ltoff(@fptr(s+a)), data4 MSB -R_IA64_LTOFF_FPTR32LSB = 0x55 # @ltoff(@fptr(s+a)), data4 LSB -R_IA64_LTOFF_FPTR64MSB = 0x56 # @ltoff(@fptr(s+a)), data8 MSB -R_IA64_LTOFF_FPTR64LSB = 0x57 # @ltoff(@fptr(s+a)), data8 LSB -R_IA64_SEGREL32MSB = 0x5c # @segrel(sym + add), data4 MSB -R_IA64_SEGREL32LSB = 0x5d # @segrel(sym + add), data4 LSB -R_IA64_SEGREL64MSB = 0x5e # @segrel(sym + add), data8 MSB -R_IA64_SEGREL64LSB = 0x5f # @segrel(sym + add), data8 LSB -R_IA64_SECREL32MSB = 0x64 # @secrel(sym + add), data4 MSB -R_IA64_SECREL32LSB = 0x65 # @secrel(sym + add), data4 LSB -R_IA64_SECREL64MSB = 0x66 # @secrel(sym + add), data8 MSB -R_IA64_SECREL64LSB = 0x67 # @secrel(sym + add), data8 LSB -R_IA64_REL32MSB = 0x6c # data 4 + REL -R_IA64_REL32LSB = 0x6d # data 4 + REL -R_IA64_REL64MSB = 0x6e # data 8 + REL -R_IA64_REL64LSB = 0x6f # data 8 + REL -R_IA64_LTV32MSB = 0x74 # symbol + addend, data4 MSB -R_IA64_LTV32LSB = 0x75 # symbol + addend, data4 LSB -R_IA64_LTV64MSB = 0x76 # symbol + addend, data8 MSB -R_IA64_LTV64LSB = 0x77 # symbol + addend, data8 LSB -R_IA64_PCREL21BI = 0x79 # @pcrel(sym + add), 21bit inst -R_IA64_PCREL22 = 0x7a # @pcrel(sym + add), 22bit inst -R_IA64_PCREL64I = 0x7b # @pcrel(sym + add), 64bit inst -R_IA64_IPLTMSB = 0x80 # dynamic reloc, imported PLT, MSB -R_IA64_IPLTLSB = 0x81 # dynamic reloc, imported PLT, LSB -R_IA64_COPY = 0x84 # copy relocation -R_IA64_SUB = 0x85 # Addend and symbol difference -R_IA64_LTOFF22X = 0x86 # LTOFF22, relaxable. -R_IA64_LDXMOV = 0x87 # Use of LTOFF22X. -R_IA64_TPREL14 = 0x91 # @tprel(sym + add), imm14 -R_IA64_TPREL22 = 0x92 # @tprel(sym + add), imm22 -R_IA64_TPREL64I = 0x93 # @tprel(sym + add), imm64 -R_IA64_TPREL64MSB = 0x96 # @tprel(sym + add), data8 MSB -R_IA64_TPREL64LSB = 0x97 # @tprel(sym + add), data8 LSB -R_IA64_LTOFF_TPREL22 = 0x9a # @ltoff(@tprel(s+a)), imm2 -R_IA64_DTPMOD64MSB = 0xa6 # @dtpmod(sym + add), data8 MSB -R_IA64_DTPMOD64LSB = 0xa7 # @dtpmod(sym + add), data8 LSB -R_IA64_LTOFF_DTPMOD22 = 0xaa # @ltoff(@dtpmod(sym + add)), imm22 -R_IA64_DTPREL14 = 0xb1 # @dtprel(sym + add), imm14 -R_IA64_DTPREL22 = 0xb2 # @dtprel(sym + add), imm22 -R_IA64_DTPREL64I = 0xb3 # @dtprel(sym + add), imm64 -R_IA64_DTPREL32MSB = 0xb4 # @dtprel(sym + add), data4 MSB -R_IA64_DTPREL32LSB = 0xb5 # @dtprel(sym + add), data4 LSB -R_IA64_DTPREL64MSB = 0xb6 # @dtprel(sym + add), data8 MSB -R_IA64_DTPREL64LSB = 0xb7 # @dtprel(sym + add), data8 LSB -R_IA64_LTOFF_DTPREL22 = 0xba # @ltoff(@dtprel(s+a)), imm22 - -# SH relocations - -R_SH_NONE = 0 -R_SH_DIR32 = 1 -R_SH_REL32 = 2 -R_SH_DIR8WPN = 3 -R_SH_IND12W = 4 -R_SH_DIR8WPL = 5 -R_SH_DIR8WPZ = 6 -R_SH_DIR8BP = 7 -R_SH_DIR8W = 8 -R_SH_DIR8L = 9 -R_SH_SWITCH16 = 25 -R_SH_SWITCH32 = 26 -R_SH_USES = 27 -R_SH_COUNT = 28 -R_SH_ALIGN = 29 -R_SH_CODE = 30 -R_SH_DATA = 31 -R_SH_LABEL = 32 -R_SH_SWITCH8 = 33 -R_SH_GNU_VTINHERIT = 34 -R_SH_GNU_VTENTRY = 35 -R_SH_TLS_GD_32 = 144 -R_SH_TLS_LD_32 = 145 -R_SH_TLS_LDO_32 = 146 -R_SH_TLS_IE_32 = 147 -R_SH_TLS_LE_32 = 148 -R_SH_TLS_DTPMOD32 = 149 -R_SH_TLS_DTPOFF32 = 150 -R_SH_TLS_TPOFF32 = 151 -R_SH_GOT32 = 160 -R_SH_PLT32 = 161 -R_SH_COPY = 162 -R_SH_GLOB_DAT = 163 -R_SH_JMP_SLOT = 164 -R_SH_RELATIVE = 165 -R_SH_GOTOFF = 166 -R_SH_GOTPC = 167 -# Keep this the last entry. -R_SH_NUM = 256 - -# S/390 relocations - -R_390_NONE = 0 # No reloc. -R_390_8 = 1 # Direct 8 bit. -R_390_12 = 2 # Direct 12 bit. -R_390_16 = 3 # Direct 16 bit. -R_390_32 = 4 # Direct 32 bit. -R_390_PC32 = 5 # PC relative 32 bit. -R_390_GOT12 = 6 # 12 bit GOT offset. -R_390_GOT32 = 7 # 32 bit GOT offset. -R_390_PLT32 = 8 # 32 bit PC relative PLT address. -R_390_COPY = 9 # Copy symbol at runtime. -R_390_GLOB_DAT = 10 # Create GOT entry. -R_390_JMP_SLOT = 11 # Create PLT entry. -R_390_RELATIVE = 12 # Adjust by program base. -R_390_GOTOFF32 = 13 # 32 bit offset to GOT. -R_390_GOTPC = 14 # 32 bit PC relative offset to GOT. -R_390_GOT16 = 15 # 16 bit GOT offset. -R_390_PC16 = 16 # PC relative 16 bit. -R_390_PC16DBL = 17 # PC relative 16 bit shifted by 1. -R_390_PLT16DBL = 18 # 16 bit PC rel. PLT shifted by 1. -R_390_PC32DBL = 19 # PC relative 32 bit shifted by 1. -R_390_PLT32DBL = 20 # 32 bit PC rel. PLT shifted by 1. -R_390_GOTPCDBL = 21 # 32 bit PC rel. GOT shifted by 1. -R_390_64 = 22 # Direct 64 bit. -R_390_PC64 = 23 # PC relative 64 bit. -R_390_GOT64 = 24 # 64 bit GOT offset. -R_390_PLT64 = 25 # 64 bit PC relative PLT address. -R_390_GOTENT = 26 # 32 bit PC rel. to GOT entry >> 1. -R_390_GOTOFF16 = 27 # 16 bit offset to GOT. -R_390_GOTOFF64 = 28 # 64 bit offset to GOT. -R_390_GOTPLT12 = 29 # 12 bit offset to jump slot. -R_390_GOTPLT16 = 30 # 16 bit offset to jump slot. -R_390_GOTPLT32 = 31 # 32 bit offset to jump slot. -R_390_GOTPLT64 = 32 # 64 bit offset to jump slot. -R_390_GOTPLTENT = 33 # 32 bit rel. offset to jump slot. -R_390_PLTOFF16 = 34 # 16 bit offset from GOT to PLT. -R_390_PLTOFF32 = 35 # 32 bit offset from GOT to PLT. -R_390_PLTOFF64 = 36 # 16 bit offset from GOT to PLT. -R_390_TLS_LOAD = 37 # Tag for load insn in TLS code. -R_390_TLS_GDCALL = 38 # Tag for function call in general dynamic TLS code. -R_390_TLS_LDCALL = 39 # Tag for function call in local dynamic TLS code. -R_390_TLS_GD32 = 40 # Direct 32 bit for general dynamic thread local data. -R_390_TLS_GD64 = 41 # Direct 64 bit for general dynamic thread local data. -R_390_TLS_GOTIE12 = 42 # 12 bit GOT offset for static TLS block offset. -R_390_TLS_GOTIE32 = 43 # 32 bit GOT offset for static TLS block offset. -R_390_TLS_GOTIE64 = 44 # 64 bit GOT offset for static TLS block offset. -R_390_TLS_LDM32 = 45 # Direct 32 bit for local dynamic thread local data in LE code. -R_390_TLS_LDM64 = 46 # Direct 64 bit for local dynamic thread local data in LE code. -R_390_TLS_IE32 = 47 # 32 bit address of GOT entry for negated static TLS block offset. -R_390_TLS_IE64 = 48 # 64 bit address of GOT entry for negated static TLS block offset. -R_390_TLS_IEENT = 49 # 32 bit rel. offset to GOT entry for negated static TLS block offset. -R_390_TLS_LE32 = 50 # 32 bit negated offset relative to static TLS block. -R_390_TLS_LE64 = 51 # 64 bit negated offset relative to static TLS block. -R_390_TLS_LDO32 = 52 # 32 bit offset relative to TLS block. -R_390_TLS_LDO64 = 53 # 64 bit offset relative to TLS block. -R_390_TLS_DTPMOD = 54 # ID of module containing symbol. -R_390_TLS_DTPOFF = 55 # Offset in TLS block. -R_390_TLS_TPOFF = 56 # Negated offset in static TLS block. -R_390_20 = 57 # Direct 20 bit. -R_390_GOT20 = 58 # 20 bit GOT offset. -R_390_GOTPLT20 = 59 # 20 bit offset to jump slot. -R_390_TLS_GOTIE20 = 60 # 20 bit GOT offset for static TLS block offset. -# Keep this the last entry. -R_390_NUM = 61 - - -# CRIS relocations. -R_CRIS_NONE = 0 -R_CRIS_8 = 1 -R_CRIS_16 = 2 -R_CRIS_32 = 3 -R_CRIS_8_PCREL = 4 -R_CRIS_16_PCREL = 5 -R_CRIS_32_PCREL = 6 -R_CRIS_GNU_VTINHERIT = 7 -R_CRIS_GNU_VTENTRY = 8 -R_CRIS_COPY = 9 -R_CRIS_GLOB_DAT = 10 -R_CRIS_JUMP_SLOT = 11 -R_CRIS_RELATIVE = 12 -R_CRIS_16_GOT = 13 -R_CRIS_32_GOT = 14 -R_CRIS_16_GOTPLT = 15 -R_CRIS_32_GOTPLT = 16 -R_CRIS_32_GOTREL = 17 -R_CRIS_32_PLT_GOTREL = 18 -R_CRIS_32_PLT_PCREL = 19 - -R_CRIS_NUM = 20 - - -# AMD x86-64 relocations. -R_X86_64_NONE = 0 # No reloc -R_X86_64_64 = 1 # Direct 64 bit -R_X86_64_PC32 = 2 # PC relative 32 bit signed -R_X86_64_GOT32 = 3 # 32 bit GOT entry -R_X86_64_PLT32 = 4 # 32 bit PLT address -R_X86_64_COPY = 5 # Copy symbol at runtime -R_X86_64_GLOB_DAT = 6 # Create GOT entry -R_X86_64_JUMP_SLOT = 7 # Create PLT entry -R_X86_64_RELATIVE = 8 # Adjust by program base -R_X86_64_GOTPCREL = 9 # 32 bit signed PC relative offset to GOT -R_X86_64_32 = 10 # Direct 32 bit zero extended -R_X86_64_32S = 11 # Direct 32 bit sign extended -R_X86_64_16 = 12 # Direct 16 bit zero extended -R_X86_64_PC16 = 13 # 16 bit sign extended pc relative -R_X86_64_8 = 14 # Direct 8 bit sign extended -R_X86_64_PC8 = 15 # 8 bit sign extended pc relative -R_X86_64_DTPMOD64 = 16 # ID of module containing symbol -R_X86_64_DTPOFF64 = 17 # Offset in module's TLS block -R_X86_64_TPOFF64 = 18 # Offset in initial TLS block -R_X86_64_TLSGD = 19 # 32 bit signed PC relative offset to two GOT entries for GD symbol -R_X86_64_TLSLD = 20 # 32 bit signed PC relative offset to two GOT entries for LD symbol -R_X86_64_DTPOFF32 = 21 # Offset in TLS block -R_X86_64_GOTTPOFF = 22 # 32 bit signed PC relative offset to GOT entry for IE symbol -R_X86_64_TPOFF32 = 23 # Offset in initial TLS block -R_X86_64_PC64 = 24 # PC relative 64 bit -R_X86_64_GOTOFF64 = 25 # 64 bit offset to GOT -R_X86_64_GOTPC32 = 26 # 32 bit signed pc relative offset to GOT -R_X86_64_GOT64 = 27 # 64-bit GOT entry offset -R_X86_64_GOTPCREL64 = 28 # 64-bit PC relative offset to GOT entry -R_X86_64_GOTPC64 = 29 # 64-bit PC relative offset to GOT -R_X86_64_GOTPLT64 = 30 # like GOT64, says PLT entry needed -R_X86_64_PLTOFF64 = 31 # 64-bit GOT relative offset to PLT entry -R_X86_64_SIZE32 = 32 # Size of symbol plus 32-bit addend -R_X86_64_SIZE64 = 33 # Size of symbol plus 64-bit addend -R_X86_64_GOTPC32_TLSDESC = 34 # GOT offset for TLS descriptor. -R_X86_64_TLSDESC_CALL = 35 # Marker for call through TLS descriptor. -R_X86_64_TLSDESC = 36 # TLS descriptor. -R_X86_64_IRELATIVE = 37 # Adjust indirectly by program base - -R_X86_64_NUM = 38 - - -# AM33 relocations. -R_MN10300_NONE = 0 # No reloc. -R_MN10300_32 = 1 # Direct 32 bit. -R_MN10300_16 = 2 # Direct 16 bit. -R_MN10300_8 = 3 # Direct 8 bit. -R_MN10300_PCREL32 = 4 # PC-relative 32-bit. -R_MN10300_PCREL16 = 5 # PC-relative 16-bit signed. -R_MN10300_PCREL8 = 6 # PC-relative 8-bit signed. -R_MN10300_GNU_VTINHERIT = 7 # Ancient C++ vtable garbage... -R_MN10300_GNU_VTENTRY = 8 # ... collection annotation. -R_MN10300_24 = 9 # Direct 24 bit. -R_MN10300_GOTPC32 = 10 # 32-bit PCrel offset to GOT. -R_MN10300_GOTPC16 = 11 # 16-bit PCrel offset to GOT. -R_MN10300_GOTOFF32 = 12 # 32-bit offset from GOT. -R_MN10300_GOTOFF24 = 13 # 24-bit offset from GOT. -R_MN10300_GOTOFF16 = 14 # 16-bit offset from GOT. -R_MN10300_PLT32 = 15 # 32-bit PCrel to PLT entry. -R_MN10300_PLT16 = 16 # 16-bit PCrel to PLT entry. -R_MN10300_GOT32 = 17 # 32-bit offset to GOT entry. -R_MN10300_GOT24 = 18 # 24-bit offset to GOT entry. -R_MN10300_GOT16 = 19 # 16-bit offset to GOT entry. -R_MN10300_COPY = 20 # Copy symbol at runtime. -R_MN10300_GLOB_DAT = 21 # Create GOT entry. -R_MN10300_JMP_SLOT = 22 # Create PLT entry. -R_MN10300_RELATIVE = 23 # Adjust by program base. - -R_MN10300_NUM = 24 - - -# M32R relocs. -R_M32R_NONE = 0 # No reloc. -R_M32R_16 = 1 # Direct 16 bit. -R_M32R_32 = 2 # Direct 32 bit. -R_M32R_24 = 3 # Direct 24 bit. -R_M32R_10_PCREL = 4 # PC relative 10 bit shifted. -R_M32R_18_PCREL = 5 # PC relative 18 bit shifted. -R_M32R_26_PCREL = 6 # PC relative 26 bit shifted. -R_M32R_HI16_ULO = 7 # High 16 bit with unsigned low. -R_M32R_HI16_SLO = 8 # High 16 bit with signed low. -R_M32R_LO16 = 9 # Low 16 bit. -R_M32R_SDA16 = 10 # 16 bit offset in SDA. -R_M32R_GNU_VTINHERIT = 11 -R_M32R_GNU_VTENTRY = 12 -# M32R relocs use SHT_RELA. -R_M32R_16_RELA = 33 # Direct 16 bit. -R_M32R_32_RELA = 34 # Direct 32 bit. -R_M32R_24_RELA = 35 # Direct 24 bit. -R_M32R_10_PCREL_RELA = 36 # PC relative 10 bit shifted. -R_M32R_18_PCREL_RELA = 37 # PC relative 18 bit shifted. -R_M32R_26_PCREL_RELA = 38 # PC relative 26 bit shifted. -R_M32R_HI16_ULO_RELA = 39 # High 16 bit with unsigned low -R_M32R_HI16_SLO_RELA = 40 # High 16 bit with signed low -R_M32R_LO16_RELA = 41 # Low 16 bit -R_M32R_SDA16_RELA = 42 # 16 bit offset in SDA -R_M32R_RELA_GNU_VTINHERIT = 43 -R_M32R_RELA_GNU_VTENTRY = 44 -R_M32R_REL32 = 45 # PC relative 32 bit. - -R_M32R_GOT24 = 48 # 24 bit GOT entry -R_M32R_26_PLTREL = 49 # 26 bit PC relative to PLT shifted -R_M32R_COPY = 50 # Copy symbol at runtime -R_M32R_GLOB_DAT = 51 # Create GOT entry -R_M32R_JMP_SLOT = 52 # Create PLT entry -R_M32R_RELATIVE = 53 # Adjust by program base -R_M32R_GOTOFF = 54 # 24 bit offset to GOT -R_M32R_GOTPC24 = 55 # 24 bit PC relative offset to GOT -R_M32R_GOT16_HI_ULO = 56 # High 16 bit GOT entry with unsigned low -R_M32R_GOT16_HI_SLO = 57 # High 16 bit GOT entry with signed low -R_M32R_GOT16_LO = 58 # Low 16 bit GOT entry -R_M32R_GOTPC_HI_ULO = 59 # High 16 bit PC relative offset to GOT with unsigned low -R_M32R_GOTPC_HI_SLO = 60 # High 16 bit PC relative offset to GOT with signed low -R_M32R_GOTPC_LO = 61 # Low 16 bit PC relative offset to GOT -R_M32R_GOTOFF_HI_ULO = 62 # High 16 bit offset to GOT with unsigned low -R_M32R_GOTOFF_HI_SLO = 63 # High 16 bit offset to GOT with signed low -R_M32R_GOTOFF_LO = 64 # Low 16 bit offset to GOT -R_M32R_NUM = 256 # Keep this the last entry. diff --git a/miasm/loader/elf_init.py b/miasm/loader/elf_init.py deleted file mode 100644 index cffb3575..00000000 --- a/miasm/loader/elf_init.py +++ /dev/null @@ -1,882 +0,0 @@ -#! /usr/bin/env python - -from __future__ import print_function -from builtins import range -import logging -import struct - -from future.utils import PY3, with_metaclass - -from miasm.core.utils import force_bytes, force_str -from miasm.loader import cstruct -from miasm.loader import elf -from miasm.loader.strpatchwork import StrPatchwork - -log = logging.getLogger("elfparse") -console_handler = logging.StreamHandler() -console_handler.setFormatter(logging.Formatter("[%(levelname)-8s]: %(message)s")) -log.addHandler(console_handler) -log.setLevel(logging.WARN) - - -def printable(string): - if isinstance(string, bytes): - return "".join( - c.decode() if b" " <= c < b"~" else "." - for c in (string[i:i+1] for i in range(len(string))) - ) - return string - - -class StructWrapper_metaclass(type): - - def __new__(cls, name, bases, dct): - wrapped = dct["wrapped"] - if wrapped is not None: # XXX: make dct lookup look into base classes - for fname, v in wrapped._fields: - dct[fname] = property(dct.pop("get_" + fname, - lambda self, fname=fname: getattr( - self.cstr, fname)), - dct.pop("set_" + fname, - lambda self, v, fname=fname: setattr( - self.cstr, fname, v)), - dct.pop("del_" + fname, None)) - return type.__new__(cls, name, bases, dct) - - -class StructWrapper(with_metaclass(StructWrapper_metaclass, object)): - - wrapped = None - - def __init__(self, parent, sex, size, *args, **kargs): - self.cstr = self.wrapped(sex, size, *args, **kargs) - self.parent = parent - - def __getitem__(self, item): - return getattr(self, item) - - def __repr__(self): - return "<W-" + repr(self.cstr)[1:] - - def __str__(self): - return str(self.cstr) - - def __bytes__(self): - return bytes(self.cstr) - - -class WEhdr(StructWrapper): - wrapped = elf.Ehdr - - def set_shstrndx(self, val): - self.cstr.shstrndx = val - - -class WSym32(StructWrapper): - wrapped = elf.Sym32 - - def get_name(self): - return self.parent.linksection.get_name(self.cstr.name) - - -class WSym64(StructWrapper): - wrapped = elf.Sym64 - - def get_name(self): - return self.parent.linksection.get_name(self.cstr.name) - - -class WRel32(StructWrapper): - wrapped = elf.Rel32 - wrapped._fields.append(("sym", "u32")) - wrapped._fields.append(("type", "u08")) - - def get_sym(self): - if isinstance(self.parent.linksection, NullSection): - return None - return self.parent.linksection.symtab[self.cstr.info >> 8].name - - def get_type(self): - return self.cstr.info & 0xff - - -class WRel64(StructWrapper): - wrapped = elf.Rel64 - wrapped._fields.append(("sym", "u32")) - wrapped._fields.append(("type", "u32")) - - def get_sym(self): - if not hasattr(self.parent.linksection, 'symtab'): - return None - return self.parent.linksection.symtab[self.cstr.info >> 32].name - - def get_type(self): - return self.cstr.info & 0xffffffff - - -class WRela32(WRel32): - wrapped = elf.Rela32 - wrapped._fields.append(("sym", "u32")) - wrapped._fields.append(("type", "u08")) - - def get_sym(self): - return self.parent.linksection.symtab[self.cstr.info >> 8].name - - def get_type(self): - return self.cstr.info & 0xff - - -class WRela64(WRel64): - wrapped = elf.Rela64 - wrapped._fields.append(("sym", "u32")) - wrapped._fields.append(("type", "u32")) - - def get_sym(self): - return self.parent.linksection.symtab[self.cstr.info >> 32].name - - def get_type(self): - return self.cstr.info & 0xffffffff - - -class WShdr(StructWrapper): - wrapped = elf.Shdr - - def get_name(self): - return self.parent.parent._shstr.get_name(self.cstr.name) - - -class WDynamic(StructWrapper): - wrapped = elf.Dynamic - - def get_name(self): - if self.type == elf.DT_NEEDED: - return self.parent.linksection.get_name(self.cstr.name) - return self.cstr.name - - -class WPhdr(StructWrapper): - wrapped = elf.Phdr - - -class WPhdr64(StructWrapper): - wrapped = elf.Phdr64 - - -class WNhdr(StructWrapper): - wrapped = elf.Nhdr - - -class ContentManager(object): - - def __get__(self, owner, x): - if hasattr(owner, '_content'): - return owner._content - - def __set__(self, owner, new_content): - owner.resize(len(owner._content), len(new_content)) - owner._content = StrPatchwork(new_content) - owner.parse_content(owner.sex, owner.size) - - def __delete__(self, owner): - self.__set__(owner, None) - - -# Sections - -class Section_metaclass(type): - - def __new__(cls, name, bases, dct): - o = type.__new__(cls, name, bases, dct) - if name != "Section": - Section.register(o) - return o - - def register(cls, o): - if o.sht is not None: - cls.sectypes[o.sht] = o - - def __call__(cls, parent, sex, size, shstr=None): - sh = None - if shstr is not None: - sh = WShdr(None, sex, size, shstr) - if sh.type in Section.sectypes: - cls = Section.sectypes[sh.type] - i = cls.__new__(cls, cls.__name__, cls.__bases__, cls.__dict__) - if sh is not None: - sh.parent = i - i.__init__(parent, sh) - return i - - -class Section(with_metaclass(Section_metaclass, object)): - - sectypes = {} - content = ContentManager() - - def resize(self, old, new): - self.sh.size += new - old - self.parent.resize(self, new - old) - if self.phparent: - self.phparent.resize(self, new - old) - - def parse_content(self, sex, size): - self.sex, self.size = sex, size - pass - - def get_linksection(self): - return self.parent[self.sh.link] - - def set_linksection(self, val): - if isinstance(val, Section): - val = self.parent.shlist.find(val) - if type(val) is int: - self.sh.link = val - linksection = property(get_linksection, set_linksection) - - def get_infosection(self): - # XXX info may not be in sh list ?!? - if not self.sh.info in self.parent: - return None - return self.parent[self.sh.info] - - def set_infosection(self, val): - if isinstance(val, Section): - val = self.parent.shlist.find(val) - if type(val) is int: - self.sh.info = val - infosection = property(get_infosection, set_infosection) - - def __init__(self, parent, sh=None): - self.parent = parent - self.phparent = None - self.sh = sh - self._content = b"" - - def __repr__(self): - r = "{%(name)s ofs=%(offset)#x sz=%(size)#x addr=%(addr)#010x}" % self.sh - return r - - -class NullSection(Section): - sht = elf.SHT_NULL - - def get_name(self, ofs): - # XXX check this - return b"" - - -class ProgBits(Section): - sht = elf.SHT_PROGBITS - - -class HashSection(Section): - sht = elf.SHT_HASH - - -class NoBitsSection(Section): - sht = elf.SHT_NOBITS - - -class ShLibSection(Section): - sht = elf.SHT_SHLIB - - -class InitArray(Section): - sht = elf.SHT_INIT_ARRAY - - -class FiniArray(Section): - sht = elf.SHT_FINI_ARRAY - - -class GroupSection(Section): - sht = elf.SHT_GROUP - - -class SymTabSHIndeces(Section): - sht = elf.SHT_SYMTAB_SHNDX - - -class GNUVerSym(Section): - sht = elf.SHT_GNU_versym - - -class GNUVerNeed(Section): - sht = elf.SHT_GNU_verneed - - -class GNUVerDef(Section): - sht = elf.SHT_GNU_verdef - - -class GNULibLIst(Section): - sht = elf.SHT_GNU_LIBLIST - - -class CheckSumSection(Section): - sht = elf.SHT_CHECKSUM - - -class NoteSection(Section): - sht = elf.SHT_NOTE - - def parse_content(self, sex, size): - self.sex, self.size = sex, size - c = self.content - hsz = 12 - self.notes = [] - # XXX: c may not be aligned? - while len(c) > hsz: - note = WNhdr(self, sex, size, c) - namesz, descsz = note.namesz, note.descsz - name = c[hsz:hsz + namesz] - desc = c[hsz + namesz:hsz + namesz + descsz] - c = c[hsz + namesz + descsz:] - self.notes.append((note.type, name, desc)) - - -class Dynamic(Section): - sht = elf.SHT_DYNAMIC - - def parse_content(self, sex, size): - self.sex, self.size = sex, size - c = self.content - self.dyntab = [] - self.dynamic = {} - sz = self.sh.entsize - idx = 0 - while len(c) > sz*idx: - s = c[sz*idx:sz*(idx+1)] - idx += 1 - dyn = WDynamic(self, sex, size, s) - self.dyntab.append(dyn) - if isinstance(dyn.name, str): - self[dyn.name] = dyn - - def __setitem__(self, item, value): - if isinstance(item, bytes): - self.dynamic[item] = value - return - if isinstance(item, str): - self.symbols[item.encode()] = value - return - self.dyntab[item] = value - - def __getitem__(self, item): - if isinstance(item, bytes): - return self.dynamic[item] - if isinstance(item, str): - return self.dynamic[item.encode()] - return self.dyntab[item] - - -class StrTable(Section): - sht = elf.SHT_STRTAB - - def parse_content(self, sex, size): - self.sex, self.size = sex, size - self.res = {} - c = self.content - q = 0 - index = 0 - l = len(c) - while index < l: - p = c.find(b"\x00", index) - if p < 0: - log.warning("Missing trailing 0 for string [%s]" % c) # XXX - p = len(c) - index - self.res[index] = c[index:p] - # print q, c[:p] - index = p + 1 - # q += p+1 - # c = c[p+1:] - - def get_name(self, ofs): - return self.content[ofs:self.content.find(b'\x00', start=ofs)] - - def add_name(self, name): - name = force_bytes(name) - name = name + b"\x00" - if name in self.content: - return self.content.find(name) - n = len(self.content) - self.content = bytes(self.content) + name - return n - - def mod_name(self, name, new_name): - s = bytes(self.content) - name_b = b'\x00%s\x00' % name.encode() - if not name_b in s: - raise ValueError('Unknown name %r' % name) - self.content = s.replace( - name_b, - b'\x00%s\x00' % new_name.encode() - ) - return len(self.content) - - -class SymTable(Section): - sht = elf.SHT_SYMTAB - - def parse_content(self, sex, size): - self.sex, self.size = sex, size - c = self.content - self.symtab = [] - self.symbols = {} - sz = self.sh.entsize - index = 0 - l = len(c) - if size == 32: - WSym = WSym32 - elif size == 64: - WSym = WSym64 - else: - ValueError('unknown size') - while index < l: - s = c[index:index + sz] - index += sz - sym = WSym(self, sex, size, s) - self.symtab.append(sym) - self[sym.name] = sym - - def __getitem__(self, item): - if isinstance(item, bytes): - return self.symbols[item] - if isinstance(item, str): - return self.symbols[item.encode()] - return self.symtab[item] - - def __setitem__(self, item, value): - if isinstance(item, bytes): - self.symbols[item] = value - return - if isinstance(item, str): - self.symbols[item.encode()] = value - return - self.symtab[item] = value - - -class DynSymTable(SymTable): - sht = elf.SHT_DYNSYM - - -class RelTable(Section): - sht = elf.SHT_REL - - def parse_content(self, sex, size): - self.sex, self.size = sex, size - if size == 32: - WRel = WRel32 - elif size == 64: - WRel = WRel64 - else: - ValueError('unknown size') - c = self.content - self.reltab = [] - self.rel = {} - sz = self.sh.entsize - - idx = 0 - while len(c) > sz*idx: - s = c[sz*idx:sz*(idx+1)] - idx += 1 - rel = WRel(self, sex, size, s) - self.reltab.append(rel) - if rel.parent.linksection != self.parent.shlist[0]: - self.rel[rel.sym] = rel - - -class RelATable(RelTable): - sht = elf.SHT_RELA - -# Section List - - -class SHList(object): - - def __init__(self, parent, sex, size): - self.parent = parent - self.shlist = [] - ehdr = self.parent.Ehdr - of1 = ehdr.shoff - if not of1: # No SH table - return - for i in range(ehdr.shnum): - of2 = of1 + ehdr.shentsize - shstr = parent[of1:of2] - self.shlist.append(Section(self, sex, size, shstr=shstr)) - of1 = of2 - self._shstr = self.shlist[ehdr.shstrndx] - - for s in self.shlist: - if not isinstance(s, NoBitsSection): - s._content = StrPatchwork( - parent[s.sh.offset: s.sh.offset + s.sh.size] - ) - # Follow dependencies when initializing sections - zero = self.shlist[0] - todo = self.shlist[1:] - done = [] - while todo: - s = todo.pop(0) - if ((s.linksection == zero or s.linksection in done) and - (s.infosection in [zero, None] or s.infosection in done)): - done.append(s) - s.parse_content(sex, size) - else: - todo.append(s) - for s in self.shlist: - self.do_add_section(s) - - def do_add_section(self, section): - n = section.sh.name - if n.startswith(b"."): - n = n[1:] - n = printable(n).replace(".", "_").replace("-", "_") - setattr(self, n, section) # xxx - - def append(self, item): - self.do_add_section(item) - self.shlist.append(item) - - def __getitem__(self, item): - return self.shlist[item] - - def __repr__(self): - rep = ["# section offset size addr flags"] - for i, s in enumerate(self.shlist): - l = "%(name)-15s %(offset)08x %(size)06x %(addr)08x %(flags)x " % s.sh - l = ("%2i " % i) + l + s.__class__.__name__ - rep.append(l) - return "\n".join(rep) - - def __bytes__(self): - return b"".join( - bytes(s.sh) for s in self.shlist - ) - - def __str__(self): - if PY3: - return repr(self) - return bytes(self) - - def resize(self, sec, diff): - for s in self.shlist: - if s.sh.offset > sec.sh.offset: - s.sh.offset += diff - if self.parent.Ehdr.shoff > sec.sh.offset: - self.parent.Ehdr.shoff += diff - if self.parent.Ehdr.phoff > sec.sh.offset: - self.parent.Ehdr.phoff += diff - -# Program Header List - - -class ProgramHeader(object): - - def __init__(self, parent, sex, size, phstr): - self.parent = parent - self.ph = WPhdr(self, sex, size, phstr) - self.shlist = [] - for s in self.parent.parent.sh: - if isinstance(s, NullSection): - continue - if ((isinstance(s, NoBitsSection) and s.sh.offset == self.ph.offset + self.ph.filesz) - or self.ph.offset <= s.sh.offset < self.ph.offset + self.ph.filesz): - s.phparent = self - self.shlist.append(s) - - def resize(self, sec, diff): - self.ph.filesz += diff - self.ph.memsz += diff - self.parent.resize(sec, diff) - - -class ProgramHeader64(object): - - def __init__(self, parent, sex, size, phstr): - self.parent = parent - self.ph = WPhdr64(self, sex, size, phstr) - self.shlist = [] - for s in self.parent.parent.sh: - if isinstance(s, NullSection): - continue - if ((isinstance(s, NoBitsSection) and s.sh.offset == self.ph.offset + self.ph.filesz) - or self.ph.offset <= s.sh.offset < self.ph.offset + self.ph.filesz): - s.phparent = self - self.shlist.append(s) - - def resize(self, sec, diff): - self.ph.filesz += diff - self.ph.memsz += diff - self.parent.resize(sec, diff) - - -class PHList(object): - - def __init__(self, parent, sex, size): - self.parent = parent - self.phlist = [] - ehdr = self.parent.Ehdr - of1 = ehdr.phoff - for i in range(ehdr.phnum): - of2 = of1 + ehdr.phentsize - phstr = parent[of1:of2] - if size == 32: - self.phlist.append(ProgramHeader(self, sex, size, phstr)) - else: - self.phlist.append(ProgramHeader64(self, sex, size, phstr)) - of1 = of2 - - def __getitem__(self, item): - return self.phlist[item] - - def __repr__(self): - r = [" offset filesz vaddr memsz"] - for i, p in enumerate(self.phlist): - l = "%(offset)07x %(filesz)06x %(vaddr)08x %(memsz)07x %(type)02x %(flags)01x" % p.ph - l = ("%2i " % i) + l - r.append(l) - r.append(" " + " ".join(printable(s.sh.name) for s in p.shlist)) - return "\n".join(r) - - def __bytes__(self): - return b"".join( - bytes(p.ph) for p in self.phlist - ) - - def __str__(self): - if PY3: - return repr(self) - return self.__bytes__(self) - - def resize(self, sec, diff): - for p in self.phlist: - if p.ph.offset > sec.sh.offset: - p.ph.offset += diff - if p.ph.vaddr > sec.phparent.ph.vaddr + sec.sh.offset: - p.ph.vaddr += diff - if p.ph.paddr > sec.phparent.ph.paddr + sec.sh.offset: - p.ph.paddr += diff - - -class virt(object): - - def __init__(self, x): - self.parent = x - - def get_rvaitem(self, start, stop=None): - if stop == None: - s = self.parent.getsectionbyvad(start) - if s: - start = start - s.sh.addr - else: - s = self.parent.getphbyvad(start) - if s: - start = start - s.ph.vaddr - if not s: - return [(None, start)] - return [(s, start)] - total_len = stop - start - - virt_item = [] - while total_len: - s = self.parent.getsectionbyvad(start) - if not s: - s = self.parent.getphbyvad(start) - if not s: - raise ValueError('unknown rva address! %x' % start) - if isinstance(s, ProgramHeader) or isinstance(s, ProgramHeader64): - s_max = s.ph.filesz - s_start = start - s.ph.vaddr - s_stop = stop - s.ph.vaddr - else: - s_max = s.sh.size - s_start = start - s.sh.addr - s_stop = stop - s.sh.addr - if s_stop > s_max: - s_stop = s_max - - s_len = s_stop - s_start - if s_len == 0: - raise ValueError('empty section! %x' % start) - total_len -= s_len - start += s_len - n_item = slice(s_start, s_stop) - virt_item.append((s, n_item)) - return virt_item - - def item2virtitem(self, item): - if not type(item) is slice: # integer - return self.get_rvaitem(item) - start = item.start - stop = item.stop - assert(item.step is None) - return self.get_rvaitem(start, stop) - - def get(self, ad_start, ad_stop=None): - rva_items = self.get_rvaitem(ad_start, ad_stop) - data_out = b"" - for s, n_item in rva_items: - if not (isinstance(s, ProgramHeader) or isinstance(s, ProgramHeader64)): - data_out += s.content.__getitem__(n_item) - continue - if not type(n_item) is slice: - n_item = slice(n_item, n_item + 1, 1) - start = n_item.start + s.ph.offset - stop = n_item.stop + s.ph.offset - if n_item.step != None: - step = n_item.step + s.ph.offset - else: - step = None - n_item = slice(start, stop, step) - # data_out += self.parent.content.__s.content.__getitem__(n_item) - data_out += self.parent.content.__getitem__(n_item) - - return data_out - - def set(self, item, data): - if not type(item) is slice: - item = slice(item, item + len(data), None) - virt_item = self.item2virtitem(item) - if not virt_item: - return - off = 0 - for s, n_item in virt_item: - if isinstance(s, ProgBits): - i = slice(off, n_item.stop + off - n_item.start, n_item.step) - - data_slice = data.__getitem__(i) - s.content.__setitem__(n_item, data_slice) - off = i.stop - else: - raise ValueError('TODO XXX') - - return - - def __getitem__(self, item): - if isinstance(item, slice): - assert(item.step is None) - return self.get(item.start, item.stop) - else: - return self.get(item) - - def __setitem__(self, item, data): - if isinstance(item, slice): - rva = item.start - else: - rva = item - self.set(rva, data) - - def max_addr(self): - # the maximum virtual address is found by retrieving the maximum - # possible virtual address, either from the program entries, and - # section entries. if there is no such object, raise an error. - l = 0 - if self.parent.ph.phlist: - for phdr in self.parent.ph.phlist: - l = max(l, phdr.ph.vaddr + phdr.ph.memsz) - if self.parent.sh.shlist: - for shdr in self.parent.sh.shlist: - l = max(l, shdr.sh.addr + shdr.sh.size) - if not l: - raise ValueError('maximum virtual address not found !') - return l - - def is_addr_in(self, ad): - return self.parent.is_in_virt_address(ad) - - def find(self, pattern, start=0): - sections = [] - offset = start - for s in self.parent.ph: - s_max = s.ph.memsz # max(s.ph.filesz, s.ph.memsz) - if offset < s.ph.vaddr + s_max: - sections.append(s) - - if not sections: - return -1 - offset -= sections[0].ph.vaddr - if offset < 0: - offset = 0 - for s in sections: - data = self.parent.content[s.ph.offset:s.ph.offset + s.ph.filesz] - ret = data.find(pattern, offset) - if ret != -1: - return ret + s.ph.vaddr # self.parent.rva2virt(s.addr + ret) - offset = 0 - return -1 - -# ELF object - - -class ELF(object): - - def __init__(self, elfstr): - self._content = elfstr - self.parse_content() - - self._virt = virt(self) - - def get_virt(self): - return self._virt - virt = property(get_virt) - - content = ContentManager() - - def parse_content(self): - h = self.content[:8] - self.size = struct.unpack('B', h[4:5])[0] * 32 - self.sex = struct.unpack('B', h[5:6])[0] - self.Ehdr = WEhdr(self, self.sex, self.size, self.content) - self.sh = SHList(self, self.sex, self.size) - self.ph = PHList(self, self.sex, self.size) - - def resize(self, old, new): - pass - - def __getitem__(self, item): - return self.content[item] - - def build_content(self): - c = StrPatchwork() - c[0] = bytes(self.Ehdr) - c[self.Ehdr.phoff] = bytes(self.ph) - for s in self.sh: - c[s.sh.offset] = bytes(s.content) - c[self.Ehdr.shoff] = bytes(self.sh) - return bytes(c) - - def __bytes__(self): - return self.build_content() - - def __str__(self): - if PY3: - return repr(self) - return bytes(self) - - def getphbyvad(self, ad): - for s in self.ph: - if s.ph.vaddr <= ad < s.ph.vaddr + s.ph.memsz: - return s - - def getsectionbyvad(self, ad): - for s in self.sh: - if s.sh.addr <= ad < s.sh.addr + s.sh.size: - return s - - def getsectionbyname(self, name): - name = force_bytes(name) - for s in self.sh: - try: - if s.sh.name.strip(b'\x00') == name: - return s - except UnicodeDecodeError: - pass - return None - - def is_in_virt_address(self, ad): - for s in self.sh: - if s.sh.addr <= ad < s.sh.addr + s.sh.size: - return True - return False diff --git a/miasm/loader/minidump.py b/miasm/loader/minidump.py deleted file mode 100644 index c16473b4..00000000 --- a/miasm/loader/minidump.py +++ /dev/null @@ -1,545 +0,0 @@ -"""Constants and structures associated to Minidump format -Based on: http://amnesia.gtisc.gatech.edu/~moyix/minidump.py -""" -from future.utils import viewitems - -from future.builtins import int as int_types -from miasm.loader.new_cstruct import CStruct - -class Enumeration(object): - """Stand for an enumeration type""" - - def __init__(self, enum_info): - """enum_info: {name: value}""" - self._enum_info = enum_info - self._inv_info = dict((v, k) for k, v in viewitems(enum_info)) - - def __getitem__(self, key): - """Helper: assume that string is for key, integer is for value""" - if isinstance(key, int_types): - return self._inv_info[key] - return self._enum_info[key] - - def __getattr__(self, key): - if key in self._enum_info: - return self._enum_info[key] - raise AttributeError - - def from_value(self, value): - return self._inv_info[value] - - -class Rva(CStruct): - """Relative Virtual Address - Note: RVA in Minidump means "file offset" - """ - _fields = [("rva", "u32"), - ] - - -minidumpType = Enumeration({ - # MINIDUMP_TYPE - # https://msdn.microsoft.com/en-us/library/ms680519(v=vs.85).aspx - "MiniDumpNormal" : 0x00000000, - "MiniDumpWithDataSegs" : 0x00000001, - "MiniDumpWithFullMemory" : 0x00000002, - "MiniDumpWithHandleData" : 0x00000004, - "MiniDumpFilterMemory" : 0x00000008, - "MiniDumpScanMemory" : 0x00000010, - "MiniDumpWithUnloadedModules" : 0x00000020, - "MiniDumpWithIndirectlyReferencedMemory" : 0x00000040, - "MiniDumpFilterModulePaths" : 0x00000080, - "MiniDumpWithProcessThreadData" : 0x00000100, - "MiniDumpWithPrivateReadWriteMemory" : 0x00000200, - "MiniDumpWithoutOptionalData" : 0x00000400, - "MiniDumpWithFullMemoryInfo" : 0x00000800, - "MiniDumpWithThreadInfo" : 0x00001000, - "MiniDumpWithCodeSegs" : 0x00002000, - "MiniDumpWithoutAuxiliaryState" : 0x00004000, - "MiniDumpWithFullAuxiliaryState" : 0x00008000, - "MiniDumpWithPrivateWriteCopyMemory" : 0x00010000, - "MiniDumpIgnoreInaccessibleMemory" : 0x00020000, - "MiniDumpWithTokenInformation" : 0x00040000, - "MiniDumpWithModuleHeaders" : 0x00080000, - "MiniDumpFilterTriage" : 0x00100000, - "MiniDumpValidTypeFlags" : 0x001fffff, -}) - -class MinidumpHDR(CStruct): - """MINIDUMP_HEADER - https://msdn.microsoft.com/en-us/library/ms680378(VS.85).aspx - """ - _fields = [("Magic", "u32"), # MDMP - ("Version", "u16"), - ("ImplementationVersion", "u16"), - ("NumberOfStreams", "u32"), - ("StreamDirectoryRva", "Rva"), - ("Checksum", "u32"), - ("TimeDateStamp", "u32"), - ("Flags", "u32") - ] - -class LocationDescriptor(CStruct): - """MINIDUMP_LOCATION_DESCRIPTOR - https://msdn.microsoft.com/en-us/library/ms680383(v=vs.85).aspx - """ - _fields = [("DataSize", "u32"), - ("Rva", "Rva"), - ] - - -streamType = Enumeration({ - # MINIDUMP_STREAM_TYPE - # https://msdn.microsoft.com/en-us/library/ms680394(v=vs.85).aspx - "UnusedStream" : 0, - "ReservedStream0" : 1, - "ReservedStream1" : 2, - "ThreadListStream" : 3, - "ModuleListStream" : 4, - "MemoryListStream" : 5, - "ExceptionStream" : 6, - "SystemInfoStream" : 7, - "ThreadExListStream" : 8, - "Memory64ListStream" : 9, - "CommentStreamA" : 10, - "CommentStreamW" : 11, - "HandleDataStream" : 12, - "FunctionTableStream" : 13, - "UnloadedModuleListStream" : 14, - "MiscInfoStream" : 15, - "MemoryInfoListStream" : 16, - "ThreadInfoListStream" : 17, - "HandleOperationListStream" : 18, - "LastReservedStream" : 0xffff, -}) - -class StreamDirectory(CStruct): - """MINIDUMP_DIRECTORY - https://msdn.microsoft.com/en-us/library/ms680365(VS.85).aspx - """ - _fields = [("StreamType", "u32"), - ("Location", "LocationDescriptor"), - ] - - @property - def pretty_name(self): - return streamType[self.StreamType] - - -class FixedFileInfo(CStruct): - """VS_FIXEDFILEINFO - https://msdn.microsoft.com/en-us/library/ms646997(v=vs.85).aspx - """ - _fields = [("dwSignature", "u32"), - ("dwStrucVersion", "u32"), - ("dwFileVersionMS", "u32"), - ("dwFileVersionLS", "u32"), - ("dwProductVersionMS", "u32"), - ("dwProductVersionLS", "u32"), - ("dwFileFlagsMask", "u32"), - ("dwFileFlags", "u32"), - ("dwFileOS", "u32"), - ("dwFileType", "u32"), - ("dwFileSubtype", "u32"), - ("dwFileDateMS", "u32"), - ("dwFileDateLS", "u32"), - ] - -class MinidumpString(CStruct): - """MINIDUMP_STRING - https://msdn.microsoft.com/en-us/library/ms680395(v=vs.85).aspx - """ - _fields = [("Length", "u32"), - ("Buffer", "u08", lambda string:string.Length), - ] - -class Module(CStruct): - """MINIDUMP_MODULE - https://msdn.microsoft.com/en-us/library/ms680392(v=vs.85).aspx - """ - _fields = [("BaseOfImage", "u64"), - ("SizeOfImage", "u32"), - ("CheckSum", "u32"), - ("TimeDateStamp", "u32"), - ("ModuleNameRva", "Rva"), - ("VersionInfo", "FixedFileInfo"), - ("CvRecord", "LocationDescriptor"), - ("MiscRecord", "LocationDescriptor"), - ("Reserved0", "u64"), - ("Reserved1", "u64"), - ] - - -class ModuleList(CStruct): - """MINIDUMP_MODULE_LIST - https://msdn.microsoft.com/en-us/library/ms680391(v=vs.85).aspx - """ - _fields = [("NumberOfModules", "u32"), - ("Modules", "Module", lambda mlist:mlist.NumberOfModules), - ] - - -class MemoryDescriptor64(CStruct): - """MINIDUMP_MEMORY_DESCRIPTOR64 - https://msdn.microsoft.com/en-us/library/ms680384(v=vs.85).aspx - """ - _fields = [("StartOfMemoryRange", "u64"), - ("DataSize", "u64") - ] - - -class Memory64List(CStruct): - """MINIDUMP_MEMORY64_LIST - https://msdn.microsoft.com/en-us/library/ms680387(v=vs.85).aspx - """ - _fields = [("NumberOfMemoryRanges", "u64"), - ("BaseRva", "u64"), - ("MemoryRanges", "MemoryDescriptor64", - lambda mlist:mlist.NumberOfMemoryRanges), - ] - -class MemoryDescriptor(CStruct): - """MINIDUMP_MEMORY_DESCRIPTOR - https://msdn.microsoft.com/en-us/library/ms680384(v=vs.85).aspx - """ - _fields = [("StartOfMemoryRange", "u64"), - ("Memory", "LocationDescriptor"), - ] - -class MemoryList(CStruct): - """MINIDUMP_MEMORY_LIST - https://msdn.microsoft.com/en-us/library/ms680387(v=vs.85).aspx - """ - _fields = [("NumberOfMemoryRanges", "u32"), - ("MemoryRanges", "MemoryDescriptor", - lambda mlist:mlist.NumberOfMemoryRanges), - ] - -memProtect = Enumeration({ - # MEM PROTECT - # https://msdn.microsoft.com/en-us/library/aa366786(v=vs.85).aspx - "PAGE_NOACCESS" : 0x0001, - "PAGE_READONLY" : 0x0002, - "PAGE_READWRITE" : 0x0004, - "PAGE_WRITECOPY" : 0x0008, - "PAGE_EXECUTE" : 0x0010, - "PAGE_EXECUTE_READ" : 0x0020, - "PAGE_EXECUTE_READWRITE" : 0x0040, - "PAGE_EXECUTE_WRITECOPY" : 0x0080, - "PAGE_GUARD" : 0x0100, - "PAGE_NOCACHE" : 0x0200, - "PAGE_WRITECOMBINE" : 0x0400, -}) - -class MemoryInfo(CStruct): - """MINIDUMP_MEMORY_INFO - https://msdn.microsoft.com/en-us/library/ms680386(v=vs.85).aspx - """ - _fields = [("BaseAddress", "u64"), - ("AllocationBase", "u64"), - ("AllocationProtect", "u32"), - ("__alignment1", "u32"), - ("RegionSize", "u64"), - ("State", "u32"), - ("Protect", "u32"), - ("Type", "u32"), - ("__alignment2", "u32"), - ] - -class MemoryInfoList(CStruct): - """MINIDUMP_MEMORY_INFO_LIST - https://msdn.microsoft.com/en-us/library/ms680385(v=vs.85).aspx - """ - _fields = [("SizeOfHeader", "u32"), - ("SizeOfEntry", "u32"), - ("NumberOfEntries", "u64"), - # Fake field, for easy access to MemoryInfo elements - ("MemoryInfos", "MemoryInfo", - lambda mlist: mlist.NumberOfEntries), - ] - - -contextFlags_x86 = Enumeration({ - "CONTEXT_i386" : 0x00010000, - "CONTEXT_CONTROL" : 0x00010001, - "CONTEXT_INTEGER" : 0x00010002, - "CONTEXT_SEGMENTS" : 0x00010004, - "CONTEXT_FLOATING_POINT" : 0x00010008, - "CONTEXT_DEBUG_REGISTERS" : 0x00010010, - "CONTEXT_EXTENDED_REGISTERS" : 0x00010020, -}) - -class FloatingSaveArea(CStruct): - """FLOATING_SAVE_AREA - http://terminus.rewolf.pl/terminus/structures/ntdll/_FLOATING_SAVE_AREA_x86.html - """ - _fields = [("ControlWord", "u32"), - ("StatusWord", "u32"), - ("TagWord", "u32"), - ("ErrorOffset", "u32"), - ("ErrorSelector", "u32"), - ("DataOffset", "u32"), - ("DataSelector", "u32"), - ("RegisterArea", "80s"), - ("Cr0NpxState", "u32"), - ] - -class Context_x86(CStruct): - """CONTEXT x86 - https://msdn.microsoft.com/en-us/en-en/library/ms679284(v=vs.85).aspx - http://terminus.rewolf.pl/terminus/structures/ntdll/_CONTEXT_x86.html - """ - - MAXIMUM_SUPPORTED_EXTENSION = 512 - - def is_activated(flag): - mask = contextFlags_x86[flag] - def check_context(ctx): - if (ctx.ContextFlags & mask == mask): - return 1 - return 0 - return check_context - - _fields = [("ContextFlags", "u32"), - # DebugRegisters - ("Dr0", "u32", is_activated("CONTEXT_DEBUG_REGISTERS")), - ("Dr1", "u32", is_activated("CONTEXT_DEBUG_REGISTERS")), - ("Dr2", "u32", is_activated("CONTEXT_DEBUG_REGISTERS")), - ("Dr3", "u32", is_activated("CONTEXT_DEBUG_REGISTERS")), - ("Dr6", "u32", is_activated("CONTEXT_DEBUG_REGISTERS")), - ("Dr7", "u32", is_activated("CONTEXT_DEBUG_REGISTERS")), - - ("FloatSave", "FloatingSaveArea", - is_activated("CONTEXT_FLOATING_POINT")), - - # SegmentRegisters - ("SegGs", "u32", is_activated("CONTEXT_SEGMENTS")), - ("SegFs", "u32", is_activated("CONTEXT_SEGMENTS")), - ("SegEs", "u32", is_activated("CONTEXT_SEGMENTS")), - ("SegDs", "u32", is_activated("CONTEXT_SEGMENTS")), - # IntegerRegisters - ("Edi", "u32", is_activated("CONTEXT_INTEGER")), - ("Esi", "u32", is_activated("CONTEXT_INTEGER")), - ("Ebx", "u32", is_activated("CONTEXT_INTEGER")), - ("Edx", "u32", is_activated("CONTEXT_INTEGER")), - ("Ecx", "u32", is_activated("CONTEXT_INTEGER")), - ("Eax", "u32", is_activated("CONTEXT_INTEGER")), - # ControlRegisters - ("Ebp", "u32", is_activated("CONTEXT_CONTROL")), - ("Eip", "u32", is_activated("CONTEXT_CONTROL")), - ("SegCs", "u32", is_activated("CONTEXT_CONTROL")), - ("EFlags", "u32", is_activated("CONTEXT_CONTROL")), - ("Esp", "u32", is_activated("CONTEXT_CONTROL")), - ("SegSs", "u32", is_activated("CONTEXT_CONTROL")), - - ("ExtendedRegisters", "%ds" % MAXIMUM_SUPPORTED_EXTENSION, - is_activated("CONTEXT_EXTENDED_REGISTERS")), - ] - - -contextFlags_AMD64 = Enumeration({ - "CONTEXT_AMD64" : 0x00100000, - "CONTEXT_CONTROL" : 0x00100001, - "CONTEXT_INTEGER" : 0x00100002, - "CONTEXT_SEGMENTS" : 0x00100004, - "CONTEXT_FLOATING_POINT" : 0x00100008, - "CONTEXT_DEBUG_REGISTERS" : 0x00100010, - "CONTEXT_XSTATE" : 0x00100020, - "CONTEXT_EXCEPTION_ACTIVE" : 0x08000000, - "CONTEXT_SERVICE_ACTIVE" : 0x10000000, - "CONTEXT_EXCEPTION_REQUEST" : 0x40000000, - "CONTEXT_EXCEPTION_REPORTING" : 0x80000000, -}) - - -class M128A(CStruct): - """M128A - http://terminus.rewolf.pl/terminus/structures/ntdll/_M128A_x64.html - """ - _fields = [("Low", "u64"), - ("High", "u64"), - ] - -class Context_AMD64(CStruct): - """CONTEXT AMD64 - https://github.com/duarten/Threadjack/blob/master/WinNT.h - """ - - def is_activated(flag): - mask = contextFlags_AMD64[flag] - def check_context(ctx): - if (ctx.ContextFlags & mask == mask): - return 1 - return 0 - return check_context - - _fields = [ - - # Only used for Convenience - ("P1Home", "u64"), - ("P2Home", "u64"), - ("P3Home", "u64"), - ("P4Home", "u64"), - ("P5Home", "u64"), - ("P6Home", "u64"), - - # Control - ("ContextFlags", "u32"), - ("MxCsr", "u32"), - - # Segment & processor - # [!] activation depends on multiple flags - ("SegCs", "u16", is_activated("CONTEXT_CONTROL")), - ("SegDs", "u16", is_activated("CONTEXT_SEGMENTS")), - ("SegEs", "u16", is_activated("CONTEXT_SEGMENTS")), - ("SegFs", "u16", is_activated("CONTEXT_SEGMENTS")), - ("SegGs", "u16", is_activated("CONTEXT_SEGMENTS")), - ("SegSs", "u16", is_activated("CONTEXT_CONTROL")), - ("EFlags", "u32", is_activated("CONTEXT_CONTROL")), - - # Debug registers - ("Dr0", "u64", is_activated("CONTEXT_DEBUG_REGISTERS")), - ("Dr1", "u64", is_activated("CONTEXT_DEBUG_REGISTERS")), - ("Dr2", "u64", is_activated("CONTEXT_DEBUG_REGISTERS")), - ("Dr3", "u64", is_activated("CONTEXT_DEBUG_REGISTERS")), - ("Dr6", "u64", is_activated("CONTEXT_DEBUG_REGISTERS")), - ("Dr7", "u64", is_activated("CONTEXT_DEBUG_REGISTERS")), - - # Integer registers - # [!] activation depends on multiple flags - ("Rax", "u64", is_activated("CONTEXT_INTEGER")), - ("Rcx", "u64", is_activated("CONTEXT_INTEGER")), - ("Rdx", "u64", is_activated("CONTEXT_INTEGER")), - ("Rbx", "u64", is_activated("CONTEXT_INTEGER")), - ("Rsp", "u64", is_activated("CONTEXT_CONTROL")), - ("Rbp", "u64", is_activated("CONTEXT_INTEGER")), - ("Rsi", "u64", is_activated("CONTEXT_INTEGER")), - ("Rdi", "u64", is_activated("CONTEXT_INTEGER")), - ("R8", "u64", is_activated("CONTEXT_INTEGER")), - ("R9", "u64", is_activated("CONTEXT_INTEGER")), - ("R10", "u64", is_activated("CONTEXT_INTEGER")), - ("R11", "u64", is_activated("CONTEXT_INTEGER")), - ("R12", "u64", is_activated("CONTEXT_INTEGER")), - ("R13", "u64", is_activated("CONTEXT_INTEGER")), - ("R14", "u64", is_activated("CONTEXT_INTEGER")), - ("R15", "u64", is_activated("CONTEXT_INTEGER")), - ("Rip", "u64", is_activated("CONTEXT_CONTROL")), - - # Floating point - ("Header", "M128A", lambda ctx: 2), - ("Legacy", "M128A", lambda ctx: 8), - ("Xmm0", "M128A"), - ("Xmm1", "M128A"), - ("Xmm2", "M128A"), - ("Xmm3", "M128A"), - ("Xmm4", "M128A"), - ("Xmm5", "M128A"), - ("Xmm6", "M128A"), - ("Xmm7", "M128A"), - ("Xmm8", "M128A"), - ("Xmm9", "M128A"), - ("Xmm10", "M128A"), - ("Xmm11", "M128A"), - ("Xmm12", "M128A"), - ("Xmm13", "M128A"), - ("Xmm14", "M128A"), - ("Xmm15", "M128A"), - - - # Vector registers - ("VectorRegister", "M128A", lambda ctx: 16), - ("VectorControl", "u64"), - - # Special debug control regs - ("DebugControl", "u64"), - ("LastBranchToRip", "u64"), - ("LastBranchFromRip", "u64"), - ("LastExceptionToRip", "u64"), - ("LastExceptionFromRip", "u64"), - ] - -processorArchitecture = Enumeration({ - "PROCESSOR_ARCHITECTURE_X86" : 0, - "PROCESSOR_ARCHITECTURE_MIPS" : 1, - "PROCESSOR_ARCHITECTURE_ALPHA" : 2, - "PROCESSOR_ARCHITECTURE_PPC" : 3, - "PROCESSOR_ARCHITECTURE_SHX" : 4, - "PROCESSOR_ARCHITECTURE_ARM" : 5, - "PROCESSOR_ARCHITECTURE_IA64" : 6, - "PROCESSOR_ARCHITECTURE_ALPHA64" : 7, - "PROCESSOR_ARCHITECTURE_MSIL" : 8, - "PROCESSOR_ARCHITECTURE_AMD64" : 9, - "PROCESSOR_ARCHITECTURE_X86_WIN64" : 10, - "PROCESSOR_ARCHITECTURE_UNKNOWN" : 0xffff, -}) - -class Thread(CStruct): - """MINIDUMP_THREAD - https://msdn.microsoft.com/en-us/library/ms680517(v=vs.85).aspx - """ - - arch2context_cls = { - processorArchitecture.PROCESSOR_ARCHITECTURE_X86: Context_x86, - processorArchitecture.PROCESSOR_ARCHITECTURE_AMD64: Context_AMD64, - } - - def parse_context(self, content, offset): - loc_desc = LocationDescriptor.unpack(content, offset, self.parent_head) - - # Use the correct context depending on architecture - systeminfo = self.parent_head.systeminfo - context_cls = self.arch2context_cls.get(systeminfo.ProcessorArchitecture, - None) - if context_cls is None: - raise ValueError("Unsupported architecture: %s" % systeminfo.pretty_processor_architecture) - - ctxt = context_cls.unpack(content, loc_desc.Rva.rva, self.parent_head) - fake_loc_descriptor = LocationDescriptor(DataSize=0, Rva=Rva(rva=0)) - return ctxt, offset + len(fake_loc_descriptor) - - _fields = [("ThreadId", "u32"), - ("SuspendCount", "u32"), - ("PriorityClass", "u32"), - ("Priority", "u32"), - ("Teb", "u64"), - ("Stack", "MemoryDescriptor"), - ("ThreadContext", (parse_context, - lambda thread, value: NotImplemented)), - ] - -class ThreadList(CStruct): - """MINIDUMP_THREAD_LIST - https://msdn.microsoft.com/en-us/library/ms680515(v=vs.85).aspx - """ - _fields = [("NumberOfThreads", "u32"), - ("Threads", "Thread", - lambda mlist: mlist.NumberOfThreads), - ] - - -class SystemInfo(CStruct): - """MINIDUMP_SYSTEM_INFO - https://msdn.microsoft.com/en-us/library/ms680396(v=vs.85).aspx - """ - _fields = [("ProcessorArchitecture", "u16"), - ("ProcessorLevel", "u16"), - ("ProcessorRevision", "u16"), - ("NumberOfProcessors", "u08"), - ("ProductType", "u08"), - ("MajorVersion", "u32"), - ("MinorVersion", "u32"), - ("BuildNumber", "u32"), - ("PlatformId", "u32"), - ("CSDVersionRva", "Rva"), - ("SuiteMask", "u16"), - ("Reserved2", "u16"), - ("VendorId", "u32", lambda sinfo: 3), - ("VersionInformation", "u32"), - ("FeatureInformation", "u32"), - ("AMDExtendedCpuFeatures", "u32"), - ] - - @property - def pretty_processor_architecture(self): - return processorArchitecture[self.ProcessorArchitecture] - diff --git a/miasm/loader/minidump_init.py b/miasm/loader/minidump_init.py deleted file mode 100644 index dd37f730..00000000 --- a/miasm/loader/minidump_init.py +++ /dev/null @@ -1,194 +0,0 @@ -""" -High-level abstraction of Minidump file -""" -from builtins import range -import struct - -from miasm.loader.strpatchwork import StrPatchwork -from miasm.loader import minidump as mp - - -class MemorySegment(object): - """Stand for a segment in memory with additional information""" - - def __init__(self, offset, memory_desc, module=None, memory_info=None): - self.offset = offset - self.memory_desc = memory_desc - self.module = module - self.memory_info = memory_info - self.minidump = self.memory_desc.parent_head - - @property - def address(self): - return self.memory_desc.StartOfMemoryRange - - @property - def size(self): - if isinstance(self.memory_desc, mp.MemoryDescriptor64): - return self.memory_desc.DataSize - elif isinstance(self.memory_desc, mp.MemoryDescriptor): - return self.memory_desc.Memory.DataSize - raise TypeError - - @property - def name(self): - if not self.module: - return "" - name = mp.MinidumpString.unpack(self.minidump._content, - self.module.ModuleNameRva.rva, - self.minidump) - return b"".join( - struct.pack("B", x) for x in name.Buffer - ).decode("utf-16") - - @property - def content(self): - return self.minidump._content[self.offset:self.offset + self.size] - - @property - def protect(self): - if self.memory_info: - return self.memory_info.Protect - return None - - @property - def pretty_protect(self): - if self.protect is None: - return "UNKNOWN" - return mp.memProtect[self.protect] - - -class Minidump(object): - """Stand for a Minidump file - - Here is a few limitation: - - only < 4GB Minidump are supported (LocationDescriptor handling) - - only Stream relative to memory mapping are implemented - - Official description is available on MSDN: - https://msdn.microsoft.com/en-us/library/ms680378(VS.85).aspx - """ - - _sex = 0 - _wsize = 32 - - def __init__(self, minidump_str): - self._content = StrPatchwork(minidump_str) - - # Specific streams - self.modulelist = None - self.memory64list = None - self.memorylist = None - self.memoryinfolist = None - self.systeminfo = None - - # Get information - self.streams = [] - self.threads = None - self.parse_content() - - # Memory information - self.memory = {} # base address (virtual) -> Memory information - self.build_memory() - - def parse_content(self): - """Build structures corresponding to current content""" - - # Header - offset = 0 - self.minidumpHDR = mp.MinidumpHDR.unpack(self._content, offset, self) - assert self.minidumpHDR.Magic == 0x504d444d - - # Streams - base_offset = self.minidumpHDR.StreamDirectoryRva.rva - empty_stream = mp.StreamDirectory( - StreamType=0, - Location=mp.LocationDescriptor( - DataSize=0, - Rva=mp.Rva(rva=0) - ) - ) - streamdir_size = len(empty_stream) - for i in range(self.minidumpHDR.NumberOfStreams): - stream_offset = base_offset + i * streamdir_size - stream = mp.StreamDirectory.unpack(self._content, stream_offset, self) - self.streams.append(stream) - - # Launch specific action depending on the stream - datasize = stream.Location.DataSize - offset = stream.Location.Rva.rva - if stream.StreamType == mp.streamType.ModuleListStream: - self.modulelist = mp.ModuleList.unpack(self._content, offset, self) - elif stream.StreamType == mp.streamType.MemoryListStream: - self.memorylist = mp.MemoryList.unpack(self._content, offset, self) - elif stream.StreamType == mp.streamType.Memory64ListStream: - self.memory64list = mp.Memory64List.unpack(self._content, offset, self) - elif stream.StreamType == mp.streamType.MemoryInfoListStream: - self.memoryinfolist = mp.MemoryInfoList.unpack(self._content, offset, self) - elif stream.StreamType == mp.streamType.SystemInfoStream: - self.systeminfo = mp.SystemInfo.unpack(self._content, offset, self) - - # Some streams need the SystemInfo stream to work - for stream in self.streams: - datasize = stream.Location.DataSize - offset = stream.Location.Rva.rva - if (self.systeminfo is not None and - stream.StreamType == mp.streamType.ThreadListStream): - self.threads = mp.ThreadList.unpack(self._content, offset, self) - - - def build_memory(self): - """Build an easier to use memory view based on ModuleList and - Memory64List streams""" - - addr2module = dict((module.BaseOfImage, module) - for module in (self.modulelist.Modules if - self.modulelist else [])) - addr2meminfo = dict((memory.BaseAddress, memory) - for memory in (self.memoryinfolist.MemoryInfos if - self.memoryinfolist else [])) - - mode64 = self.minidumpHDR.Flags & mp.minidumpType.MiniDumpWithFullMemory - - if mode64: - offset = self.memory64list.BaseRva - memranges = self.memory64list.MemoryRanges - else: - memranges = self.memorylist.MemoryRanges - - for memory in memranges: - if not mode64: - offset = memory.Memory.Rva.rva - - # Create a MemorySegment with augmented information - base_address = memory.StartOfMemoryRange - module = addr2module.get(base_address, None) - meminfo = addr2meminfo.get(base_address, None) - self.memory[base_address] = MemorySegment(offset, memory, - module, meminfo) - - if mode64: - offset += memory.DataSize - - # Sanity check - if mode64: - assert all(addr in self.memory for addr in addr2module) - - def get(self, virt_start, virt_stop): - """Return the content at the (virtual addresses) - [virt_start:virt_stop]""" - - # Find the corresponding memory segment - for addr in self.memory: - if virt_start <= addr <= virt_stop: - break - else: - return b"" - - memory = self.memory[addr] - shift = addr - virt_start - last = virt_stop - addr - if last > memory.size: - raise RuntimeError("Multi-page not implemented") - - return self._content[memory.offset + shift:memory.offset + last] diff --git a/miasm/loader/new_cstruct.py b/miasm/loader/new_cstruct.py deleted file mode 100644 index 16c947a5..00000000 --- a/miasm/loader/new_cstruct.py +++ /dev/null @@ -1,267 +0,0 @@ -#! /usr/bin/env python - -from __future__ import print_function -import re -import struct - -from miasm.core.utils import force_bytes -from future.utils import PY3, viewitems, with_metaclass - -type2realtype = {} -size2type = {} -size2type_s = {} - -for t in 'B', 'H', 'I', 'Q': - s = struct.calcsize(t) - type2realtype[t] = s * 8 - size2type[s * 8] = t - -for t in 'b', 'h', 'i', 'q': - s = struct.calcsize(t) - type2realtype[t] = s * 8 - size2type_s[s * 8] = t - -type2realtype['u08'] = size2type[8] -type2realtype['u16'] = size2type[16] -type2realtype['u32'] = size2type[32] -type2realtype['u64'] = size2type[64] - -type2realtype['s08'] = size2type_s[8] -type2realtype['s16'] = size2type_s[16] -type2realtype['s32'] = size2type_s[32] -type2realtype['s64'] = size2type_s[64] - -type2realtype['d'] = 'd' -type2realtype['f'] = 'f' -type2realtype['q'] = 'q' -type2realtype['ptr'] = 'ptr' - -sex_types = {0: '<', 1: '>'} - - -def fix_size(fields, wsize): - out = [] - for name, v in fields: - if v.endswith("s"): - pass - elif v == "ptr": - v = size2type[wsize] - elif not v in type2realtype: - raise ValueError("unknown Cstruct type", v) - else: - v = type2realtype[v] - out.append((name, v)) - fields = out - return fields - - -def real_fmt(fmt, wsize): - if fmt == "ptr": - v = size2type[wsize] - elif fmt in type2realtype: - v = type2realtype[fmt] - else: - v = fmt - return v - -all_cstructs = {} - - -class Cstruct_Metaclass(type): - field_suffix = "_value" - - def __new__(cls, name, bases, dct): - for fields in dct['_fields']: - fname = fields[0] - if fname in ['parent', 'parent_head']: - raise ValueError('field name will confuse internal structs', - repr(fname)) - dct[fname] = property(dct.pop("get_" + fname, - lambda self, fname=fname: getattr( - self, fname + self.__class__.field_suffix)), - dct.pop("set_" + fname, - lambda self, v, fname=fname: setattr( - self, fname + self.__class__.field_suffix, v)), - dct.pop("del_" + fname, None)) - - o = super(Cstruct_Metaclass, cls).__new__(cls, name, bases, dct) - if name != "CStruct": - all_cstructs[name] = o - return o - - def unpack_l(cls, s, off=0, parent_head=None, _sex=None, _wsize=None): - if _sex is None and _wsize is None: - # get sex and size from parent - if parent_head is not None: - _sex = parent_head._sex - _wsize = parent_head._wsize - else: - _sex = 0 - _wsize = 32 - c = cls(_sex=_sex, _wsize=_wsize) - if parent_head is None: - parent_head = c - c.parent_head = parent_head - - of1 = off - for field in c._fields: - cpt = None - if len(field) == 2: - fname, ffmt = field - elif len(field) == 3: - fname, ffmt, cpt = field - if ffmt in type2realtype or (isinstance(ffmt, str) and re.match(r'\d+s', ffmt)): - # basic types - if cpt: - value = [] - i = 0 - while i < cpt(c): - fmt = real_fmt(ffmt, _wsize) - of2 = of1 + struct.calcsize(fmt) - value.append(struct.unpack(c.sex + fmt, s[of1:of2])[0]) - of1 = of2 - i += 1 - else: - fmt = real_fmt(ffmt, _wsize) - of2 = of1 + struct.calcsize(fmt) - if not (0 <= of1 < len(s) and 0 <= of2 < len(s)): - raise RuntimeError("not enough data") - value = struct.unpack(c.sex + fmt, s[of1:of2])[0] - elif ffmt == "sz": # null terminated special case - of2 = s.find(b'\x00', of1) - if of2 == -1: - raise ValueError('no null char in string!') - of2 += 1 - value = s[of1:of2 - 1] - elif ffmt in all_cstructs: - of2 = of1 - # sub structures - if cpt: - value = [] - i = 0 - while i < cpt(c): - v, l = all_cstructs[ffmt].unpack_l( - s, of1, parent_head, _sex, _wsize) - v.parent = c - value.append(v) - of2 = of1 + l - of1 = of2 - i += 1 - else: - value, l = all_cstructs[ffmt].unpack_l( - s, of1, parent_head, _sex, _wsize) - value.parent = c - of2 = of1 + l - elif isinstance(ffmt, tuple): - f_get, f_set = ffmt - value, of2 = f_get(c, s, of1) - else: - raise ValueError('unknown class', ffmt) - of1 = of2 - setattr(c, fname + c.__class__.field_suffix, value) - - return c, of2 - off - - def unpack(cls, s, off=0, parent_head=None, _sex=None, _wsize=None): - c, l = cls.unpack_l(s, off=off, - parent_head=parent_head, _sex=_sex, _wsize=_wsize) - return c - - -class CStruct(with_metaclass(Cstruct_Metaclass, object)): - _packformat = "" - _fields = [] - - def __init__(self, parent_head=None, _sex=None, _wsize=None, **kargs): - self.parent_head = parent_head - self._size = None - kargs = dict(kargs) - # if not sex or size: get the one of the parent - if _sex == None and _wsize == None: - if parent_head: - _sex = parent_head._sex - _wsize = parent_head._wsize - else: - # else default sex & size - _sex = 0 - _wsize = 32 - # _sex is 0 or 1, sex is '<' or '>' - self._sex = _sex - self._wsize = _wsize - if self._packformat: - self.sex = self._packformat - else: - self.sex = sex_types[_sex] - for f in self._fields: - setattr(self, f[0] + self.__class__.field_suffix, None) - if kargs: - for k, v in viewitems(kargs): - self.__dict__[k + self.__class__.field_suffix] = v - - def pack(self): - out = b'' - for field in self._fields: - cpt = None - if len(field) == 2: - fname, ffmt = field - elif len(field) == 3: - fname, ffmt, cpt = field - - value = getattr(self, fname + self.__class__.field_suffix) - if ffmt in type2realtype or (isinstance(ffmt, str) and re.match(r'\d+s', ffmt)): - # basic types - fmt = real_fmt(ffmt, self._wsize) - if cpt == None: - if value == None: - o = struct.calcsize(fmt) * b"\x00" - elif ffmt.endswith('s'): - new_value = force_bytes(value) - o = struct.pack(self.sex + fmt, new_value) - else: - o = struct.pack(self.sex + fmt, value) - else: - o = b"" - for v in value: - if value == None: - o += struct.calcsize(fmt) * b"\x00" - else: - o += struct.pack(self.sex + fmt, v) - - elif ffmt == "sz": # null terminated special case - o = value + b'\x00' - elif ffmt in all_cstructs: - # sub structures - if cpt == None: - o = bytes(value) - else: - o = b"" - for v in value: - o += bytes(v) - elif isinstance(ffmt, tuple): - f_get, f_set = ffmt - o = f_set(self, value) - - else: - raise ValueError('unknown class', ffmt) - out += o - - return out - - def __bytes__(self): - return self.pack() - - def __str__(self): - if PY3: - return repr(self) - return self.__bytes__() - - def __len__(self): - return len(self.pack()) - - def __repr__(self): - return "<%s=%s>" % (self.__class__.__name__, "/".join( - repr(getattr(self, x[0])) for x in self._fields) - ) - - def __getitem__(self, item): # to work with format strings - return getattr(self, item) diff --git a/miasm/loader/pe.py b/miasm/loader/pe.py deleted file mode 100644 index 1252e70e..00000000 --- a/miasm/loader/pe.py +++ /dev/null @@ -1,1693 +0,0 @@ -#! /usr/bin/env python - -from __future__ import print_function -from builtins import range, str -from collections import defaultdict -import logging -import struct - -from future.builtins import int as int_types -from future.utils import PY3 - -from miasm.core.utils import force_bytes -from miasm.loader.new_cstruct import CStruct -from miasm.loader.strpatchwork import StrPatchwork - -log = logging.getLogger("pepy") -console_handler = logging.StreamHandler() -console_handler.setFormatter(logging.Formatter("[%(levelname)-8s]: %(message)s")) -log.addHandler(console_handler) -log.setLevel(logging.WARN) - - -class InvalidOffset(Exception): - pass - - -class Doshdr(CStruct): - _fields = [("magic", "u16"), - ("cblp", "u16"), - ("cp", "u16"), - ("crlc", "u16"), - ("cparhdr", "u16"), - ("minalloc", "u16"), - ("maxalloc", "u16"), - ("ss", "u16"), - ("sp", "u16"), - ("csum", "u16"), - ("ip", "u16"), - ("cs", "u16"), - ("lfarlc", "u16"), - ("ovno", "u16"), - ("res", "8s"), - ("oemid", "u16"), - ("oeminfo", "u16"), - ("res2", "20s"), - ("lfanew", "u32")] - - -class NTsig(CStruct): - _fields = [("signature", "u32"), - ] - - -class Coffhdr(CStruct): - _fields = [("machine", "u16"), - ("numberofsections", "u16"), - ("timedatestamp", "u32"), - ("pointertosymboltable", "u32"), - ("numberofsymbols", "u32"), - ("sizeofoptionalheader", "u16"), - ("characteristics", "u16")] - - -class Optehdr(CStruct): - _fields = [("rva", "u32"), - ("size", "u32")] - - -def get_optehdr_num(nthdr): - numberofrva = nthdr.numberofrvaandsizes - parent = nthdr.parent_head - entry_size = 8 - if parent.Coffhdr.sizeofoptionalheader < numberofrva * entry_size + len(parent.Opthdr): - numberofrva = (parent.Coffhdr.sizeofoptionalheader - len(parent.Opthdr)) // entry_size - log.warn('Bad number of rva.. using default %d' % numberofrva) - numberofrva = 0x10 - return numberofrva - - -class Opthdr32(CStruct): - _fields = [("magic", "u16"), - ("majorlinkerversion", "u08"), - ("minorlinkerversion", "u08"), - ("SizeOfCode", "u32"), - ("sizeofinitializeddata", "u32"), - ("sizeofuninitializeddata", "u32"), - ("AddressOfEntryPoint", "u32"), - ("BaseOfCode", "u32"), - ("BaseOfData", "u32"), - ] - - -class Opthdr64(CStruct): - _fields = [("magic", "u16"), - ("majorlinkerversion", "u08"), - ("minorlinkerversion", "u08"), - ("SizeOfCode", "u32"), - ("sizeofinitializeddata", "u32"), - ("sizeofuninitializeddata", "u32"), - ("AddressOfEntryPoint", "u32"), - ("BaseOfCode", "u32"), - ] - - -class NThdr(CStruct): - _fields = [("ImageBase", "ptr"), - ("sectionalignment", "u32"), - ("filealignment", "u32"), - ("majoroperatingsystemversion", "u16"), - ("minoroperatingsystemversion", "u16"), - ("MajorImageVersion", "u16"), - ("MinorImageVersion", "u16"), - ("majorsubsystemversion", "u16"), - ("minorsubsystemversion", "u16"), - ("Reserved1", "u32"), - ("sizeofimage", "u32"), - ("sizeofheaders", "u32"), - ("CheckSum", "u32"), - ("subsystem", "u16"), - ("dllcharacteristics", "u16"), - ("sizeofstackreserve", "ptr"), - ("sizeofstackcommit", "ptr"), - ("sizeofheapreserve", "ptr"), - ("sizeofheapcommit", "ptr"), - ("loaderflags", "u32"), - ("numberofrvaandsizes", "u32"), - ("optentries", "Optehdr", lambda c:get_optehdr_num(c)) - ] - - -class Shdr(CStruct): - _fields = [("name", "8s"), - ("size", "u32"), - ("addr", "u32"), - ("rawsize", "u32"), - ("offset", "u32"), - ("pointertorelocations", "u32"), - ("pointertolinenumbers", "u32"), - ("numberofrelocations", "u16"), - ("numberoflinenumbers", "u16"), - ("flags", "u32")] - - - def get_data(self): - parent = self.parent_head - data = parent.img_rva[self.addr:self.addr + self.size] - return data - - def set_data(self, data): - parent = self.parent_head - parent.img_rva[self.addr] = data - - - data = property(get_data, set_data) - -class SHList(CStruct): - _fields = [ - ("shlist", "Shdr", lambda c:c.parent_head.Coffhdr.numberofsections)] - - def add_section(self, name="default", data=b"", **args): - s_align = self.parent_head.NThdr.sectionalignment - s_align = max(0x1000, s_align) - - f_align = self.parent_head.NThdr.filealignment - f_align = max(0x200, f_align) - size = len(data) - rawsize = len(data) - if len(self): - addr = self[-1].addr + self[-1].size - s_last = self[0] - for section in self: - if s_last.offset + s_last.rawsize < section.offset + section.rawsize: - s_last = section - offset = s_last.offset + s_last.rawsize - else: - s_null = bytes(Shdr.unpack(b"\x00" * 0x100)) - offset = self.parent_head.Doshdr.lfanew + len(self.parent_head.NTsig) + len( - self.parent_head.Coffhdr) + self.parent_head.Coffhdr.sizeofoptionalheader + len(bytes(self.parent_head.SHList) + s_null) - addr = 0x2000 - # round addr - addr = (addr + (s_align - 1)) & ~(s_align - 1) - offset = (offset + (f_align - 1)) & ~(f_align - 1) - - attrs = {"name": name, "size": size, - "addr": addr, "rawsize": rawsize, - "offset": offset, - "pointertorelocations": 0, - "pointertolinenumbers": 0, - "numberofrelocations": 0, - "numberoflinenumbers": 0, - "flags": 0xE0000020, - "data": data - } - attrs.update(args) - section = Shdr(self.parent_head, _sex=self.parent_head._sex, - _wsize=self.parent_head._wsize, **attrs) - section.data = data - - if section.rawsize > len(data): - section.data = section.data + b'\x00' * (section.rawsize - len(data)) - section.size = section.rawsize - section.data = bytes(StrPatchwork(section.data)) - section.size = max(s_align, section.size) - - self.append(section) - self.parent_head.Coffhdr.numberofsections = len(self) - - length = (section.addr + section.size + (s_align - 1)) & ~(s_align - 1) - self.parent_head.NThdr.sizeofimage = length - return section - - def align_sections(self, f_align=None, s_align=None): - if f_align == None: - f_align = self.parent_head.NThdr.filealignment - f_align = max(0x200, f_align) - if s_align == None: - s_align = self.parent_head.NThdr.sectionalignment - s_align = max(0x1000, s_align) - - if self is None: - return - - addr = self[0].offset - for section in self: - raw_off = f_align * ((addr + f_align - 1) // f_align) - section.offset = raw_off - section.rawsize = len(section.data) - addr = raw_off + section.rawsize - - def __repr__(self): - rep = ["# section offset size addr flags rawsize "] - for i, section in enumerate(self): - name = force_bytes(section.name) - out = "%-15s" % name.strip(b'\x00').decode() - out += "%(offset)08x %(size)06x %(addr)08x %(flags)08x %(rawsize)08x" % section - out = ("%2i " % i) + out - rep.append(out) - return "\n".join(rep) - - def __getitem__(self, item): - return self.shlist[item] - - def __len__(self): - return len(self.shlist) - - def append(self, section): - self.shlist.append(section) - - -class Rva(CStruct): - _fields = [("rva", "ptr"), - ] - - -class Rva32(CStruct): - _fields = [("rva", "u32"), - ] - - -class DescName(CStruct): - _fields = [("name", (lambda c, raw, off: c.gets(raw, off), - lambda c, value: c.sets(value))) - ] - - def gets(self, raw, off): - name = raw[off:raw.find(b'\x00', off)] - return name, off + len(name) + 1 - - def sets(self, value): - return force_bytes(value) + b"\x00" - - -class ImportByName(CStruct): - _fields = [("hint", "u16"), - ("name", "sz") - ] - - -class ImpDesc_e(CStruct): - _fields = [("originalfirstthunk", "u32"), - ("timestamp", "u32"), - ("forwarderchain", "u32"), - ("name", "u32"), - ("firstthunk", "u32") - ] - - -class struct_array(object): - - def __init__(self, target_class, raw, off, cstr, num=None): - self.l = [] - self.cls = target_class - self.end = None - i = 0 - if not raw: - return - - while (num == None) or (num and i < num): - entry, length = cstr.unpack_l(raw, off, - target_class.parent_head, - target_class.parent_head._sex, - target_class.parent_head._wsize) - if num == None: - if raw[off:off + length] == b'\x00' * length: - self.end = b'\x00' * length - break - self.l.append(entry) - off += length - i += 1 - - def __bytes__(self): - out = b"".join(bytes(x) for x in self.l) - if self.end is not None: - out += self.end - return out - - def __str__(self): - if PY3: - return repr(self) - return self.__bytes__() - - def __getitem__(self, item): - return self.l.__getitem__(item) - - def __len__(self): - return len(self.l) - - def append(self, entry): - self.l.append(entry) - - def insert(self, index, entry): - self.l.insert(index, entry) - - -class DirImport(CStruct): - _fields = [("impdesc", (lambda c, raw, off:c.gete(raw, off), - lambda c, value:c.sete(value)))] - - def gete(self, raw, off): - if not off: - return None, off - if self.parent_head._wsize == 32: - mask_ptr = 0x80000000 - elif self.parent_head._wsize == 64: - mask_ptr = 0x8000000000000000 - - ofend = off + \ - self.parent_head.NThdr.optentries[DIRECTORY_ENTRY_IMPORT].size - out = [] - while off < ofend: - if not 0 <= off < len(self.parent_head.img_rva): - break - imp, length = ImpDesc_e.unpack_l(raw, off) - if (raw[off:off+length] == b'\x00' * length or - imp.name == 0): - # Special case - break - if not (imp.originalfirstthunk or imp.firstthunk): - log.warning("no thunk!!") - break - - out.append(imp) - off += length - imp.dlldescname = DescName.unpack(raw, imp.name, self.parent_head) - if imp.originalfirstthunk and imp.originalfirstthunk < len(self.parent_head.img_rva): - imp.originalfirstthunks = struct_array(self, raw, - imp.originalfirstthunk, - Rva) - else: - imp.originalfirstthunks = None - - if imp.firstthunk and imp.firstthunk < len(self.parent_head.img_rva): - imp.firstthunks = struct_array(self, raw, - imp.firstthunk, - Rva) - else: - imp.firstthunks = None - imp.impbynames = [] - if imp.originalfirstthunk and imp.originalfirstthunk < len(self.parent_head.img_rva): - tmp_thunk = imp.originalfirstthunks - elif imp.firstthunk: - tmp_thunk = imp.firstthunks - for i in range(len(tmp_thunk)): - if tmp_thunk[i].rva & mask_ptr == 0: - try: - entry = ImportByName.unpack(raw, - tmp_thunk[i].rva, - self.parent_head) - except: - log.warning( - 'cannot import from add %s' % tmp_thunk[i].rva - ) - entry = 0 - imp.impbynames.append(entry) - else: - imp.impbynames.append(tmp_thunk[i].rva & (mask_ptr - 1)) - return out, off - - def sete(self, entries): - return b"".join(bytes(entry) for entry in entries) + b"\x00" * (4 * 5) - - def __len__(self): - length = (len(self.impdesc) + 1) * (5 * 4) # ImpDesc_e size - rva_size = self.parent_head._wsize // 8 - for entry in self.impdesc: - length += len(entry.dlldescname) - if entry.originalfirstthunk and self.parent_head.rva2off(entry.originalfirstthunk): - length += (len(entry.originalfirstthunks) + 1) * rva_size - if entry.firstthunk: - length += (len(entry.firstthunks) + 1) * rva_size - for imp in entry.impbynames: - if isinstance(imp, ImportByName): - length += len(imp) - return length - - def set_rva(self, rva, size=None): - self.parent_head.NThdr.optentries[DIRECTORY_ENTRY_IMPORT].rva = rva - rva_size = self.parent_head._wsize // 8 - if not size: - self.parent_head.NThdr.optentries[ - DIRECTORY_ENTRY_IMPORT].size = len(self) - else: - self.parent_head.NThdr.optentries[ - DIRECTORY_ENTRY_IMPORT].size = size - rva += (len(self.impdesc) + 1) * 5 * 4 # ImpDesc size - for entry in self.impdesc: - entry.name = rva - rva += len(entry.dlldescname) - if entry.originalfirstthunk: # and self.parent_head.rva2off(entry.originalfirstthunk): - entry.originalfirstthunk = rva - rva += (len(entry.originalfirstthunks) + 1) * rva_size - # XXX rva fthunk not patched => keep original func addr - # if entry.firstthunk: - # entry.firstthunk = rva - # rva+=(len(entry.firstthunks)+1)*self.parent_head._wsize//8 # Rva size - if entry.originalfirstthunk and entry.firstthunk: - if isinstance(entry.originalfirstthunks, struct_array): - tmp_thunk = entry.originalfirstthunks - elif isinstance(entry.firstthunks, struct_array): - tmp_thunk = entry.firstthunks - else: - raise RuntimeError("No thunk!") - elif entry.originalfirstthunk: # and self.parent_head.rva2off(entry.originalfirstthunk): - tmp_thunk = entry.originalfirstthunks - elif entry.firstthunk: - tmp_thunk = entry.firstthunks - else: - raise RuntimeError("No thunk!") - - if tmp_thunk == entry.originalfirstthunks: - entry.firstthunks = tmp_thunk - else: - entry.originalfirstthunks = tmp_thunk - for i, imp in enumerate(entry.impbynames): - if isinstance(imp, ImportByName): - tmp_thunk[i].rva = rva - rva += len(imp) - - def build_content(self, raw): - if self.parent_head._wsize == 32: - mask_ptr = 0x80000000 - elif self.parent_head._wsize == 64: - mask_ptr = 0x8000000000000000 - - dirimp = self.parent_head.NThdr.optentries[DIRECTORY_ENTRY_IMPORT] - of1 = dirimp.rva - if not of1: # No Import - return - raw[self.parent_head.rva2off(of1)] = bytes(self) - for entry in self.impdesc: - raw[self.parent_head.rva2off(entry.name)] = bytes(entry.dlldescname) - if (entry.originalfirstthunk and - self.parent_head.rva2off(entry.originalfirstthunk)): - # Add thunks list and terminating null entry - off = self.parent_head.rva2off(entry.originalfirstthunk) - raw[off] = bytes(entry.originalfirstthunks) - if entry.firstthunk: - # Add thunks list and terminating null entry - off = self.parent_head.rva2off(entry.firstthunk) - raw[off] = bytes(entry.firstthunks) - if (entry.originalfirstthunk and - self.parent_head.rva2off(entry.originalfirstthunk)): - tmp_thunk = entry.originalfirstthunks - elif entry.firstthunk: - tmp_thunk = entry.firstthunks - else: - raise RuntimeError("No thunk!") - for j, imp in enumerate(entry.impbynames): - if isinstance(imp, ImportByName): - raw[self.parent_head.rva2off(tmp_thunk[j].rva)] = bytes(imp) - - def get_dlldesc(self): - out = [] - for impdesc in self.impdesc: - dllname = impdesc.dlldescname.name - funcs = [] - for imp in impdesc.impbynames: - if isinstance(imp, ImportByName): - funcs.append(imp.name) - else: - funcs.append(imp) - entry = ({"name": dllname, "firstthunk": impdesc.firstthunk}, funcs) - out.append(entry) - return out - - def __repr__(self): - rep = ["<%s>" % self.__class__.__name__] - for i, entry in enumerate(self.impdesc): - out = "%2d %-25s %s" % (i, repr(entry.dlldescname), repr(entry)) - rep.append(out) - for index, imp in enumerate(entry.impbynames): - out = " %2d %-16s" % (index, repr(imp)) - rep.append(out) - return "\n".join(rep) - - def add_dlldesc(self, new_dll): - rva_size = self.parent_head._wsize // 8 - if self.parent_head._wsize == 32: - mask_ptr = 0x80000000 - elif self.parent_head._wsize == 64: - mask_ptr = 0x8000000000000000 - new_impdesc = [] - of1 = None - for import_descriptor, new_functions in new_dll: - if isinstance(import_descriptor.get("name"), str): - import_descriptor["name"] = import_descriptor["name"].encode() - new_functions = [ - funcname.encode() if isinstance(funcname, str) else funcname - for funcname in new_functions - ] - for attr in ["timestamp", "forwarderchain", "originalfirstthunk"]: - if attr not in import_descriptor: - import_descriptor[attr] = 0 - entry = ImpDesc_e(self.parent_head, **import_descriptor) - if entry.firstthunk != None: - of1 = entry.firstthunk - elif of1 == None: - raise RuntimeError("set fthunk") - else: - entry.firstthunk = of1 - entry.dlldescname = DescName(self.parent_head, name=entry.name) - entry.originalfirstthunk = 0 - entry.originalfirstthunks = struct_array(self, None, - None, - Rva) - entry.firstthunks = struct_array(self, None, - None, - Rva) - - impbynames = [] - for new_function in new_functions: - rva_ofirstt = Rva(self.parent_head) - if isinstance(new_function, int_types): - rva_ofirstt.rva = mask_ptr + new_function - ibn = new_function - elif isinstance(new_function, bytes): - rva_ofirstt.rva = True - ibn = ImportByName(self.parent_head) - ibn.name = new_function - ibn.hint = 0 - else: - raise RuntimeError('unknown func type %s' % new_function) - impbynames.append(ibn) - entry.originalfirstthunks.append(rva_ofirstt) - rva_func = Rva(self.parent_head) - if isinstance(ibn, ImportByName): - rva_func.rva = 0xDEADBEEF # default func addr - else: - # ord ?XXX? - rva_func.rva = rva_ofirstt.rva - entry.firstthunks.append(rva_func) - of1 += rva_size - # for null thunk - of1 += rva_size - entry.impbynames = impbynames - new_impdesc.append(entry) - if self.impdesc is None: - self.impdesc = struct_array(self, None, - None, - ImpDesc_e) - self.impdesc.l = new_impdesc - else: - for entry in new_impdesc: - self.impdesc.append(entry) - - def get_funcrva(self, dllname, funcname): - dllname = force_bytes(dllname) - funcname = force_bytes(funcname) - - rva_size = self.parent_head._wsize // 8 - if self.parent_head._wsize == 32: - mask_ptr = 0x80000000 - 1 - elif self.parent_head._wsize == 64: - mask_ptr = 0x8000000000000000 - 1 - - for entry in self.impdesc: - if entry.dlldescname.name.lower() != dllname.lower(): - continue - if entry.originalfirstthunk and self.parent_head.rva2off(entry.originalfirstthunk): - tmp_thunk = entry.originalfirstthunks - elif entry.firstthunk: - tmp_thunk = entry.firstthunks - else: - raise RuntimeError("No thunk!") - if isinstance(funcname, bytes): - for j, imp in enumerate(entry.impbynames): - if isinstance(imp, ImportByName): - if funcname == imp.name: - return entry.firstthunk + j * rva_size - elif isinstance(funcname, int_types): - for j, imp in enumerate(entry.impbynames): - if not isinstance(imp, ImportByName): - if tmp_thunk[j].rva & mask_ptr == funcname: - return entry.firstthunk + j * rva_size - else: - raise ValueError('Unknown: %s %s' % (dllname, funcname)) - - def get_funcvirt(self, dllname, funcname): - rva = self.get_funcrva(dllname, funcname) - if rva == None: - return - return self.parent_head.rva2virt(rva) - - -class ExpDesc_e(CStruct): - _fields = [("characteristics", "u32"), - ("timestamp", "u32"), - ("majorv", "u16"), - ("minorv", "u16"), - ("name", "u32"), - ("base", "u32"), - ("numberoffunctions", "u32"), - ("numberofnames", "u32"), - ("addressoffunctions", "u32"), - ("addressofnames", "u32"), - ("addressofordinals", "u32"), - ] - - -class DirExport(CStruct): - _fields = [("expdesc", (lambda c, raw, off:c.gete(raw, off), - lambda c, value:c.sete(value)))] - - def gete(self, raw, off): - off_o = off - if not off: - return None, off - off_sav = off - if off >= len(raw): - log.warn("export dir malformed!") - return None, off_o - expdesc = ExpDesc_e.unpack(raw, - off, - self.parent_head) - if self.parent_head.rva2off(expdesc.addressoffunctions) == None or \ - self.parent_head.rva2off(expdesc.addressofnames) == None or \ - self.parent_head.rva2off(expdesc.addressofordinals) == None: - log.warn("export dir malformed!") - return None, off_o - self.dlldescname = DescName.unpack(raw, expdesc.name, self.parent_head) - try: - self.f_address = struct_array(self, raw, - expdesc.addressoffunctions, - Rva32, expdesc.numberoffunctions) - self.f_names = struct_array(self, raw, - expdesc.addressofnames, - Rva32, expdesc.numberofnames) - self.f_nameordinals = struct_array(self, raw, - expdesc.addressofordinals, - Ordinal, expdesc.numberofnames) - except RuntimeError: - log.warn("export dir malformed!") - return None, off_o - for func in self.f_names: - func.name = DescName.unpack(raw, func.rva, self.parent_head) - return expdesc, off_sav - - def sete(self, _): - return bytes(self.expdesc) - - def build_content(self, raw): - direxp = self.parent_head.NThdr.optentries[DIRECTORY_ENTRY_EXPORT] - of1 = direxp.rva - if self.expdesc is None: # No Export - return - raw[self.parent_head.rva2off(of1)] = bytes(self.expdesc) - raw[self.parent_head.rva2off(self.expdesc.name)] = bytes(self.dlldescname) - raw[self.parent_head.rva2off(self.expdesc.addressoffunctions)] = bytes(self.f_address) - if self.expdesc.addressofnames != 0: - raw[self.parent_head.rva2off(self.expdesc.addressofnames)] = bytes(self.f_names) - if self.expdesc.addressofordinals != 0: - raw[self.parent_head.rva2off(self.expdesc.addressofordinals)] = bytes(self.f_nameordinals) - for func in self.f_names: - raw[self.parent_head.rva2off(func.rva)] = bytes(func.name) - - # XXX BUG names must be alphanumeric ordered - names = [func.name for func in self.f_names] - names_ = names[:] - if names != names_: - log.warn("unsorted export names, may bug") - - def set_rva(self, rva, size=None): - rva_size = self.parent_head._wsize // 8 - if self.expdesc is None: - return - self.parent_head.NThdr.optentries[DIRECTORY_ENTRY_EXPORT].rva = rva - if not size: - self.parent_head.NThdr.optentries[ - DIRECTORY_ENTRY_EXPORT].size = len(self) - else: - self.parent_head.NThdr.optentries[ - DIRECTORY_ENTRY_EXPORT].size = size - rva += len(self.expdesc) - self.expdesc.name = rva - rva += len(self.dlldescname) - self.expdesc.addressoffunctions = rva - rva += len(self.f_address) * 4 - self.expdesc.addressofnames = rva - rva += len(self.f_names) * 4 - self.expdesc.addressofordinals = rva - rva += len(self.f_nameordinals) * 2 # Ordinal size - for func in self.f_names: - func.rva = rva - rva += len(func.name) - - def __len__(self): - rva_size = self.parent_head._wsize // 8 - length = 0 - if self.expdesc is None: - return length - length += len(self.expdesc) - length += len(self.dlldescname) - length += len(self.f_address) * 4 - length += len(self.f_names) * 4 - length += len(self.f_nameordinals) * 2 # Ordinal size - for entry in self.f_names: - length += len(entry.name) - return length - - def __repr__(self): - rep = ["<%s>" % self.__class__.__name__] - if self.expdesc is None: - return "\n".join(rep) - - rep = ["<%s %d (%s) %s>" % (self.__class__.__name__, - self.expdesc.numberoffunctions, self.dlldescname, repr(self.expdesc))] - tmp_names = [[] for _ in range(self.expdesc.numberoffunctions)] - for i, entry in enumerate(self.f_names): - tmp_names[self.f_nameordinals[i].ordinal].append(entry.name) - for i, entry in enumerate(self.f_address): - tmpn = [] - if not entry.rva: - continue - out = "%2d %.8X %s" % (i + self.expdesc.base, entry.rva, repr(tmp_names[i])) - rep.append(out) - return "\n".join(rep) - - def create(self, name='default.dll'): - self.expdesc = ExpDesc_e(self.parent_head) - for attr in ["characteristics", - "timestamp", - "majorv", - "minorv", - "name", - "base", - "numberoffunctions", - "numberofnames", - "addressoffunctions", - "addressofnames", - "addressofordinals", - ]: - setattr(self.expdesc, attr, 0) - - self.dlldescname = DescName(self.parent_head) - self.dlldescname.name = name - self.f_address = struct_array(self, None, - None, - Rva32) - self.f_names = struct_array(self, None, - None, - Rva32) - self.f_nameordinals = struct_array(self, None, - None, - Ordinal) - self.expdesc.base = 1 - - def add_name(self, name, rva=0xdeadc0fe, ordinal=None): - if self.expdesc is None: - return - names = [func.name.name for func in self.f_names] - names_s = names[:] - names_s.sort() - if names_s != names: - log.warn('tab names was not sorted may bug') - names.append(name) - names.sort() - index = names.index(name) - descname = DescName(self.parent_head) - - descname.name = name - wname = Rva32(self.parent_head) - - wname.name = descname - woffset = Rva32(self.parent_head) - woffset.rva = rva - wordinal = Ordinal(self.parent_head) - # func is append to list - if ordinal is None: - wordinal.ordinal = len(self.f_address) - else: - wordinal.ordinal = ordinal - - self.f_address.append(woffset) - # self.f_names.insert(index, wname) - # self.f_nameordinals.insert(index, wordinal) - self.f_names.insert(index, wname) - self.f_nameordinals.insert(index, wordinal) - self.expdesc.numberofnames += 1 - self.expdesc.numberoffunctions += 1 - - def get_funcrva(self, f_str): - if self.expdesc is None: - return None - for i, entry in enumerate(self.f_names): - if f_str != entry.name.name: - continue - ordinal = self.f_nameordinals[i].ordinal - rva = self.f_address[ordinal].rva - return rva - return None - - def get_funcvirt(self, addr): - rva = self.get_funcrva(addr) - if rva == None: - return - return self.parent_head.rva2virt(rva) - - -class Delaydesc_e(CStruct): - _fields = [("attrs", "u32"), - ("name", "u32"), - ("hmod", "u32"), - ("firstthunk", "u32"), - ("originalfirstthunk", "u32"), - ("boundiat", "u32"), - ("unloadiat", "u32"), - ("timestamp", "u32"), - ] - - -class DirDelay(CStruct): - _fields = [("delaydesc", (lambda c, raw, off:c.gete(raw, off), - lambda c, value:c.sete(value)))] - - def gete(self, raw, off): - if not off: - return None, off - - ofend = off + \ - self.parent_head.NThdr.optentries[DIRECTORY_ENTRY_DELAY_IMPORT].size - out = [] - while off < ofend: - if off >= len(raw): - log.warn('warning bad reloc offset') - break - - delaydesc, length = Delaydesc_e.unpack_l(raw, - off, - self.parent_head) - if raw[off:off+length] == b'\x00' * length: - # Special case - break - off += length - out.append(delaydesc) - - if self.parent_head._wsize == 32: - mask_ptr = 0x80000000 - elif self.parent_head._wsize == 64: - mask_ptr = 0x8000000000000000 - - parent = self.parent_head - for entry in out: - isfromva = (entry.attrs & 1) == 0 - if isfromva: - isfromva = lambda x: parent.virt2rva(x) - else: - isfromva = lambda x: x - entry.dlldescname = DescName.unpack(raw, isfromva(entry.name), - self.parent_head) - if entry.originalfirstthunk: - addr = isfromva(entry.originalfirstthunk) - if not 0 <= addr < len(raw): - log.warning("Bad delay") - break - entry.originalfirstthunks = struct_array(self, raw, - addr, - Rva) - else: - entry.originalfirstthunks = None - - if entry.firstthunk: - entry.firstthunks = struct_array(self, raw, - isfromva(entry.firstthunk), - Rva) - else: - entry.firstthunk = None - - entry.impbynames = [] - if entry.originalfirstthunk and self.parent_head.rva2off(isfromva(entry.originalfirstthunk)): - tmp_thunk = entry.originalfirstthunks - elif entry.firstthunk: - tmp_thunk = entry.firstthunks - else: - print(ValueError("no thunk in delay dir!! ")) - return - for i in range(len(tmp_thunk)): - if tmp_thunk[i].rva & mask_ptr == 0: - imp = ImportByName.unpack(raw, - isfromva(tmp_thunk[i].rva), - self.parent_head) - entry.impbynames.append(imp) - else: - entry.impbynames.append( - isfromva(tmp_thunk[i].rva & (mask_ptr - 1))) - # print(repr(entry[-1])) - # raise ValueError('XXX to check') - return out, off - - def sete(self, entries): - return b"".join(bytes(entry) for entry in entries) + b"\x00" * (4 * 8) # DelayDesc_e - - def __len__(self): - rva_size = self.parent_head._wsize // 8 - length = (len(self.delaydesc) + 1) * (4 * 8) # DelayDesc_e - for entry in self.delaydesc: - length += len(entry.dlldescname) - if entry.originalfirstthunk and self.parent_head.rva2off(entry.originalfirstthunk): - length += (len(entry.originalfirstthunks) + 1) * rva_size - if entry.firstthunk: - length += (len(entry.firstthunks) + 1) * rva_size - for imp in entry.impbynames: - if isinstance(imp, ImportByName): - length += len(imp) - return length - - def set_rva(self, rva, size=None): - rva_size = self.parent_head._wsize // 8 - self.parent_head.NThdr.optentries[DIRECTORY_ENTRY_DELAY_IMPORT].rva = rva - if not size: - self.parent_head.NThdr.optentries[DIRECTORY_ENTRY_DELAY_IMPORT].size = len(self) - else: - self.parent_head.NThdr.optentries[DIRECTORY_ENTRY_DELAY_IMPORT].size = size - rva += (len(self.delaydesc) + 1) * (4 * 8) # DelayDesc_e - parent = self.parent_head - for entry in self.delaydesc: - isfromva = (entry.attrs & 1) == 0 - if isfromva: - isfromva = lambda x: self.parent_head.rva2virt(x) - else: - isfromva = lambda x: x - - entry.name = isfromva(rva) - rva += len(entry.dlldescname) - if entry.originalfirstthunk: # and self.parent_head.rva2off(entry.originalfirstthunk): - entry.originalfirstthunk = isfromva(rva) - rva += (len(entry.originalfirstthunks) + 1) * rva_size - # XXX rva fthunk not patched => fun addr - # if entry.firstthunk: - # entry.firstthunk = rva - # rva+=(len(entry.firstthunks)+1)*pe.Rva._size - if entry.originalfirstthunk and self.parent_head.rva2off(entry.originalfirstthunk): - tmp_thunk = entry.originalfirstthunks - elif entry.firstthunk: - tmp_thunk = entry.firstthunks - else: - raise RuntimeError("No thunk!") - for i, imp in enumerate(entry.impbynames): - if isinstance(imp, ImportByName): - tmp_thunk[i].rva = isfromva(rva) - rva += len(imp) - - def build_content(self, raw): - if len(self.parent_head.NThdr.optentries) < DIRECTORY_ENTRY_DELAY_IMPORT: - return - dirdelay = self.parent_head.NThdr.optentries[ - DIRECTORY_ENTRY_DELAY_IMPORT] - of1 = dirdelay.rva - if not of1: # No Delay Import - return - raw[self.parent_head.rva2off(of1)] = bytes(self) - for entry in self.delaydesc: - raw[self.parent_head.rva2off(entry.name)] = bytes(entry.dlldescname) - if entry.originalfirstthunk and self.parent_head.rva2off(entry.originalfirstthunk): - raw[self.parent_head.rva2off(entry.originalfirstthunk)] = bytes(entry.originalfirstthunks) - if entry.firstthunk: - raw[self.parent_head.rva2off(entry.firstthunk)] = bytes(entry.firstthunks) - if entry.originalfirstthunk and self.parent_head.rva2off(entry.originalfirstthunk): - tmp_thunk = entry.originalfirstthunks - elif entry.firstthunk: - tmp_thunk = entry.firstthunks - else: - raise RuntimeError("No thunk!") - for j, imp in enumerate(entry.impbynames): - if isinstance(imp, ImportByName): - raw[self.parent_head.rva2off(tmp_thunk[j].rva)] = bytes(imp) - - def __repr__(self): - rep = ["<%s>" % self.__class__.__name__] - for i, entry in enumerate(self.delaydesc): - out = "%2d %-25s %s" % (i, repr(entry.dlldescname), repr(entry)) - rep.append(out) - for index, func in enumerate(entry.impbynames): - out = " %2d %-16s" % (index, repr(func)) - rep.append(out) - return "\n".join(rep) - - def add_dlldesc(self, new_dll): - if self.parent_head._wsize == 32: - mask_ptr = 0x80000000 - elif self.parent_head._wsize == 64: - mask_ptr = 0x8000000000000000 - new_impdesc = [] - of1 = None - new_delaydesc = [] - for import_descriptor, new_functions in new_dll: - if isinstance(import_descriptor.get("name"), str): - import_descriptor["name"] = import_descriptor["name"].encode() - new_functions = [ - funcname.encode() if isinstance(funcname, str) else funcname - for funcname in new_functions - ] - for attr in ["attrs", "name", "hmod", "firstthunk", "originalfirstthunk", "boundiat", "unloadiat", "timestamp"]: - if not attr in import_descriptor: - import_descriptor[attr] = 0 - entry = Delaydesc_e(self.parent_head, **import_descriptor) - # entry.cstr.__dict__.update(import_descriptor) - if entry.firstthunk != None: - of1 = entry.firstthunk - elif of1 == None: - raise RuntimeError("set fthunk") - else: - entry.firstthunk = of1 - entry.dlldescname = DescName(self.parent_head, name=entry.name) - entry.originalfirstthunk = 0 - entry.originalfirstthunks = struct_array(self, None, - None, - Rva) - entry.firstthunks = struct_array(self, None, - None, - Rva) - - impbynames = [] - for new_function in new_functions: - rva_ofirstt = Rva(self.parent_head) - if isinstance(new_function, int_types): - rva_ofirstt.rva = mask_ptr + new_function - ibn = None - elif isinstance(new_function, bytes): - rva_ofirstt.rva = True - ibn = ImportByName(self.parent_head) - ibn.name = new_function - ibn.hint = 0 - else: - raise RuntimeError('unknown func type %s' % new_function) - impbynames.append(ibn) - entry.originalfirstthunks.append(rva_ofirstt) - - rva_func = Rva(self.parent_head) - if ibn != None: - rva_func.rva = 0xDEADBEEF # default func addr - else: - # ord ?XXX? - rva_func.rva = rva_ofirstt.rva - entry.firstthunks.append(rva_func) - of1 += 4 - # for null thunk - of1 += 4 - entry.impbynames = impbynames - new_delaydesc.append(entry) - if self.delaydesc is None: - self.delaydesc = struct_array(self, None, - None, - Delaydesc_e) - self.delaydesc.l = new_delaydesc - else: - for entry in new_delaydesc: - self.delaydesc.append(entry) - - def get_funcrva(self, func): - for entry in self.delaydesc: - isfromva = (entry.attrs & 1) == 0 - if isfromva: - isfromva = lambda x: self.parent_head.virt2rva(x) - else: - isfromva = lambda x: x - if entry.originalfirstthunk and self.parent_head.rva2off(isfromva(entry.originalfirstthunk)): - tmp_thunk = entry.originalfirstthunks - elif entry.firstthunk: - tmp_thunk = entry.firstthunks - else: - raise RuntimeError("No thunk!") - if isinstance(func, bytes): - for j, imp in enumerate(entry.impbynames): - if isinstance(imp, ImportByName): - if func == imp.name: - return isfromva(entry.firstthunk) + j * 4 - elif isinstance(func, int_types): - for j, imp in enumerate(entry.impbynames): - if not isinstance(imp, ImportByName): - if isfromva(tmp_thunk[j].rva & 0x7FFFFFFF) == func: - return isfromva(entry.firstthunk) + j * 4 - else: - raise ValueError('unknown func type %r' % func) - - def get_funcvirt(self, addr): - rva = self.get_funcrva(addr) - if rva == None: - return - return self.parent_head.rva2virt(rva) - - -class Rel(CStruct): - _fields = [("rva", "u32"), - ("size", "u32") - ] - - -class Reloc(CStruct): - _fields = [("rel", (lambda c, raw, off:c.gete(raw, off), - lambda c, value:c.sete(value)))] - - def gete(self, raw, off): - rel = struct.unpack('H', raw[off:off + 2])[0] - return (rel >> 12, rel & 0xfff), off + 2 - - def sete(self, value): - return struct.pack('H', (value[0] << 12) | value[1]) - - def __repr__(self): - return '<%d %d>' % (self.rel[0], self.rel[1]) - - -class DirReloc(CStruct): - _fields = [("reldesc", (lambda c, raw, off:c.gete(raw, off), - lambda c, value:c.sete(value)))] - - def gete(self, raw, off): - if not off: - return None, off - - ofend = off + \ - self.parent_head.NThdr.optentries[DIRECTORY_ENTRY_BASERELOC].size - out = [] - while off < ofend: - if off >= len(raw): - log.warn('warning bad reloc offset') - break - reldesc, length = Rel.unpack_l(raw, - off, - self.parent_head) - if reldesc.size == 0: - log.warn('warning null reldesc') - reldesc.size = length - break - of2 = off + length - if of2 + reldesc.size > len(self.parent_head.img_rva): - log.warn('relocation too big, skipping') - break - reldesc.rels = struct_array(self, raw, - of2, - Reloc, - (reldesc.size - length) // 2) # / Reloc size - reldesc.patchrel = False - out.append(reldesc) - off += reldesc.size - return out, off - - def sete(self, entries): - return b"".join( - bytes(entry) + bytes(entry.rels) - for entry in entries - ) - - def set_rva(self, rva, size=None): - if self.reldesc is None: - return - self.parent_head.NThdr.optentries[DIRECTORY_ENTRY_BASERELOC].rva = rva - if not size: - self.parent_head.NThdr.optentries[ - DIRECTORY_ENTRY_BASERELOC].size = len(self) - else: - self.parent_head.NThdr.optentries[ - DIRECTORY_ENTRY_BASERELOC].size = size - - def build_content(self, raw): - dirrel = self.parent_head.NThdr.optentries[DIRECTORY_ENTRY_BASERELOC] - dirrel.size = len(self) - of1 = dirrel.rva - if self.reldesc is None: # No Reloc - return - raw[self.parent_head.rva2off(of1)] = bytes(self) - - def __len__(self): - if self.reldesc is None: - return 0 - length = 0 - for entry in self.reldesc: - length += entry.size - return length - - def __bytes__(self): - return b"".join( - bytes(entry) + bytes(entry.rels) - for entry in self.reldesc - ) - - def __str__(self): - if PY3: - return repr(self) - return self.__bytes__() - - def __repr__(self): - rep = ["<%s>" % self.__class__.__name__] - if self.reldesc is None: - return "\n".join(rep) - for i, entry in enumerate(self.reldesc): - out = "%2d %s" % (i, repr(entry)) - rep.append(out) - """ - #display too many lines... - for ii, m in enumerate(entry.rels): - l = "\t%2d %s"%(ii, repr(m) ) - rep.append(l) - """ - out = "\t%2d rels..." % (len(entry.rels)) - rep.append(out) - return "\n".join(rep) - - def add_reloc(self, rels, rtype=3, patchrel=True): - dirrel = self.parent_head.NThdr.optentries[DIRECTORY_ENTRY_BASERELOC] - if not rels: - return - rels.sort() - all_base_ad = set([x & 0xFFFFF000 for x in rels]) - all_base_ad = list(all_base_ad) - all_base_ad.sort() - rels_by_base = defaultdict(list) - while rels: - reloc = rels.pop() - if reloc >= all_base_ad[-1]: - rels_by_base[all_base_ad[-1]].append(reloc) - else: - all_base_ad.pop() - rels_by_base[all_base_ad[-1]].append(reloc) - rels_by_base = [x for x in list(rels_by_base.items())] - rels_by_base.sort() - for o_init, rels in rels_by_base: - # o_init = rels[0]&0xFFFFF000 - offsets = struct_array(self, None, None, Reloc, 0) - for reloc_value in rels: - if (reloc_value & 0xFFFFF000) != o_init: - raise RuntimeError("relocs must be in same range") - reloc = Reloc(self.parent_head) - reloc.rel = (rtype, reloc_value - o_init) - offsets.append(reloc) - while len(offsets) & 3: - reloc = Reloc(self.parent_head) - reloc.rel = (0, 0) - offsets.append(reloc) - reldesc = Rel(self.parent_head) # Reloc(self.parent_head) - reldesc.rva = o_init - reldesc.size = (len(offsets) * 2 + 8) - reldesc.rels = offsets - reldesc.patchrel = patchrel - # if self.reldesc is None: - # self.reldesc = [] - self.reldesc.append(reldesc) - dirrel.size += reldesc.size - - def del_reloc(self, taboffset): - if self.reldesc is None: - return - for rel in self.reldesc: - of1 = rel.rva - i = 0 - while i < len(rel.rels): - reloc = rel.rels[i] - if reloc.rel[0] != 0 and reloc.rel[1] + of1 in taboffset: - print('del reloc', hex(reloc.rel[1] + of1)) - del rel.rels[i] - rel.size -= Reloc._size - else: - i += 1 - - -class DirRes(CStruct): - _fields = [("resdesc", (lambda c, raw, off:c.gete(raw, off), - lambda c, value:c.sete(value)))] - - def gete(self, raw, off): - if not off: - return None, off - if off >= len(self.parent_head.img_rva): - log.warning('cannot parse resources, %X' % off) - return None, off - - off_orig = off - ofend = off + self.parent_head.NThdr.optentries[DIRECTORY_ENTRY_RESOURCE].size - - resdesc, length = ResDesc_e.unpack_l(raw, - off, - self.parent_head) - off += length - nbr = resdesc.numberofnamedentries + resdesc.numberofidentries - - out = [] - tmp_off = off - resdesc.resentries = struct_array(self, raw, - off, - ResEntry, - nbr) - dir_todo = {off_orig: resdesc} - dir_done = {} - while dir_todo: - off, my_dir = dir_todo.popitem() - dir_done[off] = my_dir - for entry in my_dir.resentries: - off = entry.offsettosubdir - if not off: - # data dir - off = entry.offsettodata - if not 0 <= off < len(raw): - log.warn('bad resource entry') - continue - data = ResDataEntry.unpack(raw, - off, - self.parent_head) - off = data.offsettodata - data.s = StrPatchwork(raw[off:off + data.size]) - entry.data = data - continue - # subdir - if off in dir_done: - log.warn('warning recusif subdir') - continue - if not 0 <= off < len(self.parent_head.img_rva): - log.warn('bad resource entry') - continue - subdir, length = ResDesc_e.unpack_l(raw, - off, - self.parent_head) - nbr = subdir.numberofnamedentries + subdir.numberofidentries - try: - subdir.resentries = struct_array(self, raw, - off + length, - ResEntry, - nbr) - except RuntimeError: - log.warn('bad resource entry') - continue - - entry.subdir = subdir - dir_todo[off] = entry.subdir - return resdesc, off - - def build_content(self, raw): - if self.resdesc is None: - return - of1 = self.parent_head.NThdr.optentries[DIRECTORY_ENTRY_RESOURCE].rva - raw[self.parent_head.rva2off(of1)] = bytes(self.resdesc) - length = len(self.resdesc) - dir_todo = { - self.parent_head.NThdr.optentries[DIRECTORY_ENTRY_RESOURCE].rva: self.resdesc - } - of1 = of1 + length - raw[self.parent_head.rva2off(of1)] = bytes(self.resdesc.resentries) - dir_done = {} - while dir_todo: - of1, my_dir = dir_todo.popitem() - dir_done[of1] = my_dir - raw[self.parent_head.rva2off(of1)] = bytes(my_dir) - of1 += len(my_dir) - raw[self.parent_head.rva2off(of1)] = bytes(my_dir.resentries) - of_base = of1 - for entry in my_dir.resentries: - of_base += len(entry) - if entry.name_s: - raw[self.parent_head.rva2off(entry.name)] = bytes(entry.name_s) - of1 = entry.offsettosubdir - if not of1: - raw[self.parent_head.rva2off(entry.offsettodata)] = bytes(entry.data) - raw[self.parent_head.rva2off(entry.data.offsettodata)] = bytes(entry.data.s) - continue - dir_todo[of1] = entry.subdir - - def __len__(self): - length = 0 - if self.resdesc is None: - return length - dir_todo = [self.resdesc] - dir_done = [] - while dir_todo: - my_dir = dir_todo.pop() - if my_dir in dir_done: - raise ValueError('Recursive directory') - dir_done.append(my_dir) - length += len(my_dir) - length += len(my_dir.resentries) * 8 # ResEntry size - for entry in my_dir.resentries: - if not entry.offsettosubdir: - continue - if not entry.subdir in dir_todo: - dir_todo.append(entry.subdir) - else: - raise RuntimeError("recursive dir") - - dir_todo = dir_done - while dir_todo: - my_dir = dir_todo.pop() - for entry in my_dir.resentries: - if entry.name_s: - length += len(entry.name_s) - of1 = entry.offsettosubdir - if not of1: - length += 4 * 4 # WResDataEntry size - # XXX because rva may be even rounded - length += 1 - length += entry.data.size - continue - return length - - def set_rva(self, rva, size=None): - if self.resdesc is None: - return - self.parent_head.NThdr.optentries[DIRECTORY_ENTRY_RESOURCE].rva = rva - if not size: - self.parent_head.NThdr.optentries[DIRECTORY_ENTRY_RESOURCE].size = len(self) - else: - self.parent_head.NThdr.optentries[DIRECTORY_ENTRY_RESOURCE].size = size - dir_todo = [self.resdesc] - dir_done = {} - while dir_todo: - my_dir = dir_todo.pop() - dir_done[rva] = my_dir - rva += len(my_dir) - rva += len(my_dir.resentries) * 8 # ResEntry size - for entry in my_dir.resentries: - if not entry.offsettosubdir: - continue - if not entry.subdir in dir_todo: - dir_todo.append(entry.subdir) - else: - raise RuntimeError("recursive dir") - dir_todo = dir_done - dir_inv = dict([(x[1], x[0]) for x in list(dir_todo.items())]) - while dir_todo: - rva_tmp, my_dir = dir_todo.popitem() - for entry in my_dir.resentries: - if entry.name_s: - entry.name = rva - rva += len(entry.name_s) - of1 = entry.offsettosubdir - if not of1: - entry.offsettodata = rva - rva += 4 * 4 # ResDataEntry size - # XXX menu rsrc must be even aligned? - if rva % 2: - rva += 1 - entry.data.offsettodata = rva - rva += entry.data.size - continue - entry.offsettosubdir = dir_inv[entry.subdir] - - def __repr__(self): - rep = ["<%s>" % (self.__class__.__name__)] - if self.resdesc is None: - return "\n".join(rep) - dir_todo = [self.resdesc] - resources = [] - index = -1 - while dir_todo: - entry = dir_todo.pop(0) - if isinstance(entry, int): - index += entry - elif isinstance(entry, ResDesc_e): - # resources.append((index, repr(entry))) - dir_todo = [1] + entry.resentries.l + [-1] + dir_todo - elif isinstance(entry, ResEntry): - if entry.offsettosubdir: - resources.append((index, repr(entry))) - dir_todo = [entry.subdir] + dir_todo - else: - resources.append((index, repr(entry))) - else: - raise RuntimeError("zarb") - for i, resource in resources: - rep.append(' ' * 4 * i + resource) - return "\n".join(rep) - - -class Ordinal(CStruct): - _fields = [("ordinal", "u16"), - ] - - -class ResDesc_e(CStruct): - _fields = [("characteristics", "u32"), - ("timestamp", "u32"), - ("majorv", "u16"), - ("minorv", "u16"), - ("numberofnamedentries", "u16"), - ("numberofidentries", "u16") - ] - - -class SUnicode(CStruct): - _fields = [("length", "u16"), - ("value", (lambda c, raw, off:c.gets(raw, off), - lambda c, value:c.sets(value))) - ] - - def gets(self, raw, off): - value = raw[off:off + self.length * 2] - return value, off + self.length - - def sets(self, value): - return self.value - - -class ResEntry(CStruct): - _fields = [("name", (lambda c, raw, off:c._get_name(raw, off), - lambda c, value:c._set_name(value))), - ("offsettodata", (lambda c, raw, off:c._get_offset(raw, off), - lambda c, value:c._set_offset(value))) - ] - - def _get_name(self, raw, off): - self.data = None - # off = self.parent_head.rva2off(off) - name = struct.unpack('I', raw[off:off + 4])[0] - self.name_s = None - if name & 0x80000000: - name = (name & 0x7FFFFFFF) + self.parent_head.NThdr.optentries[ - DIRECTORY_ENTRY_RESOURCE].rva # XXX res rva?? - name &= 0x7FFFFFFF - if name >= len(raw): - raise RuntimeError("Bad resentry") - self.name_s = SUnicode.unpack(raw, - name, - self.parent_head) - return name, off + 4 - - def _set_name(self, name): - if self.name_s: - rva = self.parent_head.NThdr.optentries[DIRECTORY_ENTRY_RESOURCE].rva - name = (self.name - rva) + 0x80000000 - return struct.pack('I', name) - - def _get_offset(self, raw, off): - self.offsettosubdir = None - rva = self.parent_head.NThdr.optentries[DIRECTORY_ENTRY_RESOURCE].rva - offsettodata_o = struct.unpack('I', raw[off:off + 4])[0] - offsettodata = (offsettodata_o & 0x7FFFFFFF) + rva # XXX res rva?? - if offsettodata_o & 0x80000000: - self.offsettosubdir = offsettodata - return offsettodata, off + 4 - - def _set_offset(self, offset): - rva = self.parent_head.NThdr.optentries[DIRECTORY_ENTRY_RESOURCE].rva - offsettodata = offset - rva - if self.offsettosubdir: - offsettodata = (self.offsettosubdir - rva) + 0x80000000 - return struct.pack('I', offsettodata) - - def __repr__(self): - if self.name_s: - nameid = "%s" % repr(self.name_s) - else: - if self.name in RT: # and not self.offsettosubdir: - nameid = "ID %s" % RT[self.name] - else: - nameid = "ID %d" % self.name - if self.offsettosubdir: - offsettodata = "subdir: %x" % self.offsettosubdir - else: - offsettodata = "data: %x" % self.offsettodata - return "<%s %s>" % (nameid, offsettodata) - - -class ResDataEntry(CStruct): - _fields = [("offsettodata", "u32"), - ("size", "u32"), - ("codepage", "u32"), - ("reserved", "u32"), - ] - - -class Symb(CStruct): - _fields = [("name", "8s"), - ("res1", "u32"), - ("res2", "u32"), - ("res3", "u16")] - - -class DirTls(CStruct): - _fields = [ - ("data_start", "ptr"), - ("data_end", "ptr"), - ("addr_index", "ptr"), - ("callbacks", "ptr"), - ("size_of_zero", "u32"), - ("characteristics", "u32") - ] - - def build_content(self, raw): - dirtls = self.parent_head.NThdr.optentries[DIRECTORY_ENTRY_TLS] - of1 = dirtls.rva - if of1 is None: # No Tls - return - raw[self.parent_head.rva2off(of1)] = bytes(self) - - def set_rva(self, rva, size=None): - self.parent_head.NThdr.optentries[DIRECTORY_ENTRY_TLS].rva = rva - if not size: - self.parent_head.NThdr.optentries[DIRECTORY_ENTRY_TLS].size = len(self) - else: - self.parent_head.NThdr.optentries[DIRECTORY_ENTRY_TLS].size = size - - -DIRECTORY_ENTRY_EXPORT = 0 -DIRECTORY_ENTRY_IMPORT = 1 -DIRECTORY_ENTRY_RESOURCE = 2 -DIRECTORY_ENTRY_EXCEPTION = 3 -DIRECTORY_ENTRY_SECURITY = 4 -DIRECTORY_ENTRY_BASERELOC = 5 -DIRECTORY_ENTRY_DEBUG = 6 -DIRECTORY_ENTRY_COPYRIGHT = 7 -DIRECTORY_ENTRY_GLOBALPTR = 8 -DIRECTORY_ENTRY_TLS = 9 -DIRECTORY_ENTRY_LOAD_CONFIG = 10 -DIRECTORY_ENTRY_BOUND_IMPORT = 11 -DIRECTORY_ENTRY_IAT = 12 -DIRECTORY_ENTRY_DELAY_IMPORT = 13 -DIRECTORY_ENTRY_COM_DESCRIPTOR = 14 -DIRECTORY_ENTRY_RESERVED = 15 - - -RT_CURSOR = 1 -RT_BITMAP = 2 -RT_ICON = 3 -RT_MENU = 4 -RT_DIALOG = 5 -RT_STRING = 6 -RT_FONTDIR = 7 -RT_FONT = 8 -RT_ACCELERATOR = 9 -RT_RCDATA = 10 -RT_MESSAGETABLE = 11 -RT_GROUP_CURSOR = 12 -RT_GROUP_ICON = 14 -RT_VERSION = 16 -RT_DLGINCLUDE = 17 -RT_PLUGPLAY = 19 -RT_VXD = 20 -RT_ANICURSOR = 21 -RT_ANIICON = 22 -RT_HTML = 23 -RT_MANIFEST = 24 - - -RT = { - RT_CURSOR: "RT_CURSOR", - RT_BITMAP: "RT_BITMAP", - RT_ICON: "RT_ICON", - RT_MENU: "RT_MENU", - RT_DIALOG: "RT_DIALOG", - RT_STRING: "RT_STRING", - RT_FONTDIR: "RT_FONTDIR", - RT_FONT: "RT_FONT", - RT_ACCELERATOR: "RT_ACCELERATOR", - RT_RCDATA: "RT_RCDATA", - RT_MESSAGETABLE: "RT_MESSAGETABLE", - RT_GROUP_CURSOR: "RT_GROUP_CURSOR", - RT_GROUP_ICON: "RT_GROUP_ICON", - RT_VERSION: "RT_VERSION", - RT_DLGINCLUDE: "RT_DLGINCLUDE", - RT_PLUGPLAY: "RT_PLUGPLAY", - RT_VXD: "RT_VXD", - RT_ANICURSOR: "RT_ANICURSOR", - RT_ANIICON: "RT_ANIICON", - RT_HTML: "RT_HTML", - RT_MANIFEST: "RT_MANIFEST", -} diff --git a/miasm/loader/pe_init.py b/miasm/loader/pe_init.py deleted file mode 100644 index 202a7b00..00000000 --- a/miasm/loader/pe_init.py +++ /dev/null @@ -1,631 +0,0 @@ -#! /usr/bin/env python - -from __future__ import print_function - -from builtins import range -import array -from functools import reduce -import logging -import struct - -from future.builtins import int as int_types -from future.utils import PY3 - -from miasm.loader import pe -from miasm.loader.strpatchwork import StrPatchwork - -log = logging.getLogger("peparse") -console_handler = logging.StreamHandler() -console_handler.setFormatter(logging.Formatter("[%(levelname)-8s]: %(message)s")) -log.addHandler(console_handler) -log.setLevel(logging.WARN) - - -class ContentManager(object): - - def __get__(self, owner, _): - if hasattr(owner, '_content'): - return owner._content - - def __set__(self, owner, new_content): - owner.resize(len(owner._content), len(new_content)) - owner._content = new_content - - def __delete__(self, owner): - self.__set__(owner, None) - - -class ContectRva(object): - - def __init__(self, parent): - self.parent = parent - - def get(self, rva_start, rva_stop=None): - """ - Get data in RVA view starting at @rva_start, stopping at @rva_stop - @rva_start: rva start address - @rva_stop: rva stop address - """ - if rva_start is None: - raise IOError("Out of range") - if rva_start < 0: - raise IOError("Out of range") - if rva_stop is not None: - if rva_stop > len(self.parent.img_rva): - rva_stop = len(self.parent.img_rva) - if rva_start > len(self.parent.img_rva): - raise ValueError("Out of range") - return self.parent.img_rva[rva_start:rva_stop] - if rva_start > len(self.parent.img_rva): - raise ValueError("Out of range") - return self.parent.img_rva[rva_start] - - def set(self, rva, data): - """ - Set @data in RVA view starting at @start - @rva: rva start address - @data: data to set - """ - if not isinstance(rva, int_types): - raise ValueError('addr must be int/long') - - if rva < 0: - raise ValueError("Out of range") - - if rva + len(data) > len(self.parent.img_rva): - raise ValueError("Out of range") - self.parent.img_rva[rva] = data - - def __getitem__(self, item): - if isinstance(item, slice): - assert(item.step is None) - return self.get(item.start, item.stop) - return self.get(item) - - def __setitem__(self, item, data): - if isinstance(item, slice): - rva = item.start - else: - rva = item - self.set(rva, data) - - -class ContentVirtual(object): - - def __init__(self, parent): - self.parent = parent - - def __getitem__(self, item): - raise DeprecationWarning("Replace code by virt.get(start, [stop])") - - def __setitem__(self, item, data): - raise DeprecationWarning("Replace code by virt.set(start, data)") - - def __call__(self, ad_start, ad_stop=None, ad_step=None): - raise DeprecationWarning("Replace code by virt.get(start, stop)") - - def get(self, virt_start, virt_stop=None): - """ - Get data in VIRTUAL view starting at @virt_start, stopping at @virt_stop - @virt_start: virt start address - @virt_stop: virt stop address - """ - rva_start = self.parent.virt2rva(virt_start) - if virt_stop != None: - rva_stop = self.parent.virt2rva(virt_stop) - else: - rva_stop = None - return self.parent.rva.get(rva_start, rva_stop) - - def set(self, addr, data): - """ - Set @data in VIRTUAL view starting at @start - @addr: virtual start address - @data: data to set - """ - if not isinstance(addr, int_types): - raise ValueError('addr must be int/long') - self.parent.rva.set(self.parent.virt2rva(addr), data) - - def max_addr(self): - section = self.parent.SHList[-1] - length = section.addr + section.size + self.parent.NThdr.ImageBase - return int(length) - - def find(self, pattern, start=0, end=None): - if start != 0: - start = self.parent.virt2rva(start) - if end != None: - end = self.parent.virt2rva(end) - - ret = self.parent.img_rva.find(pattern, start, end) - if ret == -1: - return -1 - return self.parent.rva2virt(ret) - - def rfind(self, pattern, start=0, end=None): - if start != 0: - start = self.parent.virt2rva(start) - if end != None: - end = self.parent.virt2rva(end) - - ret = self.parent.img_rva.rfind(pattern, start, end) - if ret == -1: - return -1 - return self.parent.rva2virt(ret) - - def is_addr_in(self, addr): - return self.parent.is_in_virt_address(addr) - - - -def compute_crc(raw, olds): - out = 0 - data = raw[:] - if len(raw) % 2: - end = struct.unpack('B', data[-1:])[0] - data = data[:-1] - if (len(raw) & ~0x1) % 4: - out += struct.unpack('H', data[:2])[0] - data = data[2:] - data = array.array('I', data) - out = reduce(lambda x, y: x + y, data, out) - out -= olds - while out > 0xFFFFFFFF: - out = (out >> 32) + (out & 0xFFFFFFFF) - while out > 0xFFFF: - out = (out & 0xFFFF) + ((out >> 16) & 0xFFFF) - if len(raw) % 2: - out += end - out += len(data) - return out - - - -# PE object -class PE(object): - content = ContentManager() - - def __init__(self, pestr=None, - loadfrommem=False, - parse_resources=True, - parse_delay=True, - parse_reloc=True, - wsize=32, - **kwargs): - self._rva = ContectRva(self) - self._virt = ContentVirtual(self) - self.img_rva = StrPatchwork() - if pestr is None: - self._content = StrPatchwork() - self._sex = 0 - self._wsize = wsize - self.Doshdr = pe.Doshdr(self) - self.NTsig = pe.NTsig(self) - self.Coffhdr = pe.Coffhdr(self) - - if self._wsize == 32: - Opthdr = pe.Opthdr32 - else: - Opthdr = pe.Opthdr64 - - self.Opthdr = Opthdr(self) - self.NThdr = pe.NThdr(self) - self.NThdr.optentries = [pe.Optehdr(self) for _ in range(0x10)] - self.NThdr.CheckSum = 0 - self.SHList = pe.SHList(self) - self.SHList.shlist = [] - - self.NThdr.sizeofheaders = 0x1000 - - self.DirImport = pe.DirImport(self) - self.DirExport = pe.DirExport(self) - self.DirDelay = pe.DirDelay(self) - self.DirReloc = pe.DirReloc(self) - self.DirRes = pe.DirRes(self) - self.DirTls = pe.DirTls(self) - - self.Doshdr.magic = 0x5a4d - self.Doshdr.lfanew = 0xe0 - - self.NTsig.signature = 0x4550 - if wsize == 32: - self.Opthdr.magic = 0x10b - elif wsize == 64: - self.Opthdr.magic = 0x20b - else: - raise ValueError('unknown pe size %r' % wsize) - self.Opthdr.majorlinkerversion = 0x7 - self.Opthdr.minorlinkerversion = 0x0 - self.NThdr.filealignment = 0x1000 - self.NThdr.sectionalignment = 0x1000 - self.NThdr.majoroperatingsystemversion = 0x5 - self.NThdr.minoroperatingsystemversion = 0x1 - self.NThdr.MajorImageVersion = 0x5 - self.NThdr.MinorImageVersion = 0x1 - self.NThdr.majorsubsystemversion = 0x4 - self.NThdr.minorsubsystemversion = 0x0 - self.NThdr.subsystem = 0x3 - if wsize == 32: - self.NThdr.dllcharacteristics = 0x8000 - else: - self.NThdr.dllcharacteristics = 0x8000 - - # for createthread - self.NThdr.sizeofstackreserve = 0x200000 - self.NThdr.sizeofstackcommit = 0x1000 - self.NThdr.sizeofheapreserve = 0x100000 - self.NThdr.sizeofheapcommit = 0x1000 - - self.NThdr.ImageBase = 0x400000 - self.NThdr.sizeofheaders = 0x1000 - self.NThdr.numberofrvaandsizes = 0x10 - - self.NTsig.signature = 0x4550 - if wsize == 32: - self.Coffhdr.machine = 0x14c - elif wsize == 64: - self.Coffhdr.machine = 0x8664 - else: - raise ValueError('unknown pe size %r' % wsize) - if wsize == 32: - self.Coffhdr.characteristics = 0x10f - self.Coffhdr.sizeofoptionalheader = 0xe0 - else: - self.Coffhdr.characteristics = 0x22 # 0x2f - self.Coffhdr.sizeofoptionalheader = 0xf0 - - else: - self._content = StrPatchwork(pestr) - self.loadfrommem = loadfrommem - self.parse_content(parse_resources=parse_resources, - parse_delay=parse_delay, - parse_reloc=parse_reloc) - - def isPE(self): - if self.NTsig is None: - return False - return self.NTsig.signature == 0x4550 - - def parse_content(self, - parse_resources=True, - parse_delay=True, - parse_reloc=True): - off = 0 - self._sex = 0 - self._wsize = 32 - self.Doshdr = pe.Doshdr.unpack(self.content, off, self) - off = self.Doshdr.lfanew - if off > len(self.content): - log.warn('ntsig after eof!') - self.NTsig = None - return - self.NTsig = pe.NTsig.unpack(self.content, - off, self) - self.DirImport = None - self.DirExport = None - self.DirDelay = None - self.DirReloc = None - self.DirRes = None - - if self.NTsig.signature != 0x4550: - log.warn('not a valid pe!') - return - off += len(self.NTsig) - self.Coffhdr, length = pe.Coffhdr.unpack_l(self.content, - off, - self) - - off += length - self._wsize = ord(self.content[off+1]) * 32 - - if self._wsize == 32: - Opthdr = pe.Opthdr32 - else: - Opthdr = pe.Opthdr64 - - if len(self.content) < 0x200: - # Fix for very little PE - self.content += (0x200 - len(self.content)) * b'\x00' - - self.Opthdr, length = Opthdr.unpack_l(self.content, off, self) - self.NThdr = pe.NThdr.unpack(self.content, off + length, self) - self.img_rva[0] = self.content[:self.NThdr.sizeofheaders] - off += self.Coffhdr.sizeofoptionalheader - self.SHList = pe.SHList.unpack(self.content, off, self) - - # load section data - filealignment = self.NThdr.filealignment - sectionalignment = self.NThdr.sectionalignment - for section in self.SHList.shlist: - virt_size = (section.size // sectionalignment + 1) * sectionalignment - if self.loadfrommem: - section.offset = section.addr - if self.NThdr.sectionalignment > 0x1000: - raw_off = 0x200 * (section.offset // 0x200) - else: - raw_off = section.offset - if raw_off != section.offset: - log.warn('unaligned raw section (%x %x)!', raw_off, section.offset) - section.data = StrPatchwork() - - if section.rawsize == 0: - rounded_size = 0 - else: - if section.rawsize % filealignment: - rs = (section.rawsize // filealignment + 1) * filealignment - else: - rs = section.rawsize - rounded_size = rs - if rounded_size > virt_size: - rounded_size = min(rounded_size, section.size) - data = self.content[raw_off:raw_off + rounded_size] - section.data = data - # Pad data to page size 0x1000 - length = len(data) - data += b"\x00" * ((((length + 0xfff)) & 0xFFFFF000) - length) - self.img_rva[section.addr] = data - # Fix img_rva - self.img_rva = self.img_rva - - try: - self.DirImport = pe.DirImport.unpack(self.img_rva, - self.NThdr.optentries[ - pe.DIRECTORY_ENTRY_IMPORT].rva, - self) - except pe.InvalidOffset: - log.warning('cannot parse DirImport, skipping') - self.DirImport = pe.DirImport(self) - - try: - self.DirExport = pe.DirExport.unpack(self.img_rva, - self.NThdr.optentries[ - pe.DIRECTORY_ENTRY_EXPORT].rva, - self) - except pe.InvalidOffset: - log.warning('cannot parse DirExport, skipping') - self.DirExport = pe.DirExport(self) - - if len(self.NThdr.optentries) > pe.DIRECTORY_ENTRY_DELAY_IMPORT: - self.DirDelay = pe.DirDelay(self) - if parse_delay: - try: - self.DirDelay = pe.DirDelay.unpack(self.img_rva, - self.NThdr.optentries[ - pe.DIRECTORY_ENTRY_DELAY_IMPORT].rva, - self) - except pe.InvalidOffset: - log.warning('cannot parse DirDelay, skipping') - if len(self.NThdr.optentries) > pe.DIRECTORY_ENTRY_BASERELOC: - self.DirReloc = pe.DirReloc(self) - if parse_reloc: - try: - self.DirReloc = pe.DirReloc.unpack(self.img_rva, - self.NThdr.optentries[ - pe.DIRECTORY_ENTRY_BASERELOC].rva, - self) - except pe.InvalidOffset: - log.warning('cannot parse DirReloc, skipping') - if len(self.NThdr.optentries) > pe.DIRECTORY_ENTRY_RESOURCE: - self.DirRes = pe.DirRes(self) - if parse_resources: - self.DirRes = pe.DirRes(self) - try: - self.DirRes = pe.DirRes.unpack(self.img_rva, - self.NThdr.optentries[ - pe.DIRECTORY_ENTRY_RESOURCE].rva, - self) - except pe.InvalidOffset: - log.warning('cannot parse DirRes, skipping') - - if len(self.NThdr.optentries) > pe.DIRECTORY_ENTRY_TLS: - self.DirTls = pe.DirTls(self) - try: - self.DirTls = pe.DirTls.unpack( - self.img_rva, - self.NThdr.optentries[pe.DIRECTORY_ENTRY_TLS].rva, - self - ) - except pe.InvalidOffset: - log.warning('cannot parse DirTls, skipping') - - def resize(self, old, new): - pass - - def __getitem__(self, item): - return self.content[item] - - def __setitem__(self, item, data): - self.content.__setitem__(item, data) - return - - def getsectionbyrva(self, rva): - if self.SHList is None: - return None - for section in self.SHList.shlist: - """ - TODO CHECK: - some binaries have import rva outside section, but addresses - seems to be rounded - """ - mask = self.NThdr.sectionalignment - 1 - if section.addr <= rva < (section.addr + section.size + mask) & ~(mask): - return section - return None - - def getsectionbyvad(self, vad): - return self.getsectionbyrva(self.virt2rva(vad)) - - def getsectionbyoff(self, off): - if self.SHList is None: - return None - for section in self.SHList.shlist: - if section.offset <= off < section.offset + section.rawsize: - return section - return None - - def getsectionbyname(self, name): - if self.SHList is None: - return None - for section in self.SHList: - if section.name.strip(b'\x00').decode() == name: - return section - return None - - def is_rva_ok(self, rva): - return self.getsectionbyrva(rva) is not None - - def rva2off(self, rva): - # Special case rva in header - if rva < self.NThdr.sizeofheaders: - return rva - section = self.getsectionbyrva(rva) - if section is None: - raise pe.InvalidOffset('cannot get offset for 0x%X' % rva) - soff = (section.offset // self.NThdr.filealignment) * self.NThdr.filealignment - return rva - section.addr + soff - - def off2rva(self, off): - section = self.getsectionbyoff(off) - if section is None: - return - return off - section.offset + section.addr - - def virt2rva(self, addr): - """ - Return rva of virtual address @addr; None if addr is below ImageBase - """ - if addr is None: - return None - rva = addr - self.NThdr.ImageBase - if rva < 0: - return None - return rva - - def rva2virt(self, rva): - if rva is None: - return - return rva + self.NThdr.ImageBase - - def virt2off(self, addr): - """ - Return offset of virtual address @addr - """ - rva = self.virt2rva(addr) - if rva is None: - return None - return self.rva2off(rva) - - def off2virt(self, off): - return self.rva2virt(self.off2rva(off)) - - def is_in_virt_address(self, addr): - if addr < self.NThdr.ImageBase: - return False - addr = self.virt2rva(addr) - for section in self.SHList.shlist: - if section.addr <= addr < section.addr + section.size: - return True - return False - - def get_drva(self): - print('Deprecated: Use PE.rva instead of PE.drva') - return self._rva - - def get_rva(self): - return self._rva - - # TODO XXX remove drva api - drva = property(get_drva) - rva = property(get_rva) - - def get_virt(self): - return self._virt - - virt = property(get_virt) - - def build_content(self): - - content = StrPatchwork() - content[0] = bytes(self.Doshdr) - - for section in self.SHList.shlist: - content[section.offset:section.offset + section.rawsize] = bytes(section.data) - - # fix image size - section_last = self.SHList.shlist[-1] - size = section_last.addr + section_last.size + (self.NThdr.sectionalignment - 1) - size &= ~(self.NThdr.sectionalignment - 1) - self.NThdr.sizeofimage = size - - off = self.Doshdr.lfanew - content[off] = bytes(self.NTsig) - off += len(self.NTsig) - content[off] = bytes(self.Coffhdr) - off += len(self.Coffhdr) - off_shlist = off + self.Coffhdr.sizeofoptionalheader - content[off] = bytes(self.Opthdr) - off += len(self.Opthdr) - content[off] = bytes(self.NThdr) - off += len(self.NThdr) - # content[off] = bytes(self.Optehdr) - - off = off_shlist - content[off] = bytes(self.SHList) - - for section in self.SHList: - if off + len(bytes(self.SHList)) > section.offset: - log.warn("section offset overlap pe hdr 0x%x 0x%x" % - (off + len(bytes(self.SHList)), section.offset)) - self.DirImport.build_content(content) - self.DirExport.build_content(content) - self.DirDelay.build_content(content) - self.DirReloc.build_content(content) - self.DirRes.build_content(content) - self.DirTls.build_content(content) - - if (self.Doshdr.lfanew + len(self.NTsig) + len(self.Coffhdr)) % 4: - log.warn("non aligned coffhdr, bad crc calculation") - crcs = compute_crc(bytes(content), self.NThdr.CheckSum) - content[self.Doshdr.lfanew + len(self.NTsig) + len(self.Coffhdr) + 64] = struct.pack('I', crcs) - return bytes(content) - - def __bytes__(self): - return self.build_content() - - def __str__(self): - if PY3: - return repr(self) - return self.__bytes__() - - def export_funcs(self): - if self.DirExport is None: - print('no export dir found') - return None, None - - all_func = {} - for i, export in enumerate(self.DirExport.f_names): - all_func[export.name.name] = self.rva2virt( - self.DirExport.f_address[self.DirExport.f_nameordinals[i].ordinal].rva) - all_func[self.DirExport.f_nameordinals[i].ordinal + self.DirExport.expdesc.base] = self.rva2virt( - self.DirExport.f_address[self.DirExport.f_nameordinals[i].ordinal].rva) - # XXX todo: test if redirected export - return all_func - - def reloc_to(self, imgbase): - offset = imgbase - self.NThdr.ImageBase - if self.DirReloc is None: - log.warn('no relocation found!') - for rel in self.DirReloc.reldesc: - rva = rel.rva - for reloc in rel.rels: - reloc_type, off = reloc.rel - if reloc_type == 0 and off == 0: - continue - if reloc_type != 3: - raise NotImplementedError('Reloc type not supported') - off += rva - value = struct.unpack('I', self.rva.get(off, off + 4))[0] - value += offset - self.rva.set(off, struct.pack('I', value & 0xFFFFFFFF)) - self.NThdr.ImageBase = imgbase diff --git a/miasm/loader/strpatchwork.py b/miasm/loader/strpatchwork.py deleted file mode 100644 index e1a5de91..00000000 --- a/miasm/loader/strpatchwork.py +++ /dev/null @@ -1,106 +0,0 @@ -from array import array -import struct -from sys import maxsize - -from future.utils import PY3 - -if PY3: - - def array_frombytes(arr, value): - return arr.frombytes(value) - - def array_tobytes(arr): - return arr.tobytes() - - -else: - - def array_frombytes(arr, value): - return arr.fromstring(value) - - def array_tobytes(arr): - return arr.tostring() - - -class StrPatchwork(object): - - def __init__(self, s=b"", paddingbyte=b"\x00"): - s_raw = bytes(s) - val = array("B") - array_frombytes(val, s_raw) - self.s = val - # cache s to avoid rebuilding str after each find - self.s_cache = s_raw - self.paddingbyte = paddingbyte - - def __bytes__(self): - return array_tobytes(self.s) - - def __str__(self): - if PY3: - return repr(self) - return self.__bytes__() - - def __getitem__(self, item): - s = self.s - if isinstance(item, slice): - end = item.stop - l = len(s) - if (end is not None and l < end) and end != maxsize: - # XXX hack [x:] give 2GB limit - # This is inefficient but avoids complicated maths if step is - # not 1 - s = s[:] - - tmp = array("B") - array_frombytes(tmp, self.paddingbyte * (end - l)) - s.extend(tmp) - r = s[item] - return array_tobytes(r) - - else: - if item > len(s): - return self.paddingbyte - else: - return struct.pack("B", s[item]) - - def __setitem__(self, item, val): - if val is None: - return - val_array = array("B") - array_frombytes(val_array, bytes(val)) - if type(item) is not slice: - item = slice(item, item + len(val_array)) - end = item.stop - l = len(self.s) - if l < end: - tmp = array("B") - array_frombytes(tmp, self.paddingbyte * (end - l)) - self.s.extend(tmp) - self.s[item] = val_array - self.s_cache = None - - def __repr__(self): - return "<Patchwork %r>" % array_tobytes(self.s) - - def __len__(self): - return len(self.s) - - def __contains__(self, val): - return val in bytes(self) - - def __iadd__(self, other): - tmp = array("B") - array_frombytes(tmp, bytes(other)) - self.s.extend(tmp) - return self - - def find(self, pattern, start=0, end=None): - if not self.s_cache: - self.s_cache = array_tobytes(self.s) - return self.s_cache.find(pattern, start, end) - - def rfind(self, pattern, start=0, end=None): - if not self.s_cache: - self.s_cache = array_tobytes(self.s) - return self.s_cache.rfind(pattern, start, end) |