Module refinery.lib.dotnet.disassembler.model
Expand source code Browse git
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import abc
import enum
from struct import unpack
from typing import List
class OpArgument(abc.ABC):
def __init__(
self,
size: int = 4,
has_target: bool = False,
is_num: bool = False,
is_idx: bool = False,
is_arg_num: bool = False,
is_casecnt: bool = False,
is_caseargs: bool = False,
):
self._size = size
self.has_target = has_target
self.is_num = is_num
self.is_idx = is_idx
self.is_arg_num = is_arg_num
self.is_casecnt = is_casecnt
self.is_caseargs = is_caseargs
def __len__(self):
return self._size
def __repr__(self):
bool_args = []
if self.has_target:
bool_args.append('has_target')
if self.is_num:
bool_args.append('is_num')
if self.is_idx:
bool_args.append('is_idx')
if self.is_arg_num:
bool_args.append('is_arg_num')
if self.is_casecnt:
bool_args.append('is_casecnt')
if self.is_caseargs:
bool_args.append('is_caseargs')
bool_str = '' if len(bool_args) == 0 else f" {','.join(bool_args)}"
return f"<{self.__class__.__name__} size={self._size}{bool_str}>"
def unpack(self, value) -> int:
return unpack('<I', value)[0]
class Int8(OpArgument):
def __init__(self, has_target: bool = False, is_num: bool = False):
super().__init__(1, has_target=has_target, is_num=is_num)
def unpack(self, value: bytes) -> int:
return unpack('<b', value)[0]
class Int32(OpArgument):
def __init__(
self, has_target: bool = False, is_num: bool = False, is_caseargs: bool = False
):
super().__init__(4, has_target, is_num=is_num, is_caseargs=is_caseargs)
def unpack(self, value: bytes) -> int:
return unpack('<i', value)[0]
class Int64(OpArgument):
def __init__(self, is_num: bool = False):
super().__init__(8, is_num=is_num)
def unpack(self, value: bytes) -> int:
return unpack('<q', value)[0]
class UInt8(OpArgument):
def __init__(self, is_num: bool = False, is_idx: bool = False, is_arg_num=True):
super().__init__(1, is_num=is_num, is_idx=is_idx, is_arg_num=is_arg_num)
def unpack(self, value: bytes) -> int:
return unpack('<B', value)[0]
class UInt16(OpArgument):
def __init__(
self, is_num: bool = False, is_idx: bool = False, is_arg_num: bool = False
):
super().__init__(2, is_num=is_num, is_idx=is_idx, is_arg_num=is_arg_num)
def unpack(self, value: bytes) -> int:
return unpack('<H', value)[0]
class UInt32(OpArgument):
def __init__(self, is_casecnt: bool = False):
super().__init__(4, is_casecnt=is_casecnt)
class Float32(OpArgument):
def __init__(self, is_num: bool = False):
super().__init__(4, is_num=is_num)
class Float64(OpArgument):
def __init__(self, is_num: bool = False):
super().__init__(8, is_num=is_num)
class String(OpArgument):
def unpack(self, value) -> int:
return unpack('<I', value[:-1] + b'\0')[0]
class TypeTok(OpArgument):
pass
class Field(OpArgument):
pass
class Class(OpArgument):
pass
class Method(OpArgument):
pass
class ValueType(OpArgument):
pass
class ThisType(OpArgument):
pass
class CallSiteDescr(OpArgument):
pass
class Token(OpArgument):
pass
class Etype(OpArgument):
pass
class Ctor(OpArgument):
pass
class Type(OpArgument):
pass
class TokenLabel:
def __init__(self, tid: int, value: str):
self._tid = tid
self._value = value
class OpType(str, enum.Enum):
BASE = 'Base'
OBJECT_MODEL = 'ObjectModel'
PREFIX_TO = 'PrefixTo'
class Op(abc.ABC):
"""
Specifier for a Common Intermediate Language (CIL) instruction. It is used to specify a complete list of all
available instructions in the OpRepository. Instances of this class do not represent concrete instructions during
disassembly, that what the Instruction class is for.
"""
def __init__(
self,
op_type: OpType,
code: bytes,
mnemonic: str,
arguments: List[OpArgument],
description: str,
is_switch: bool = False,
is_alias: bool = False,
):
self.op_type = op_type
self.code = code
self.mnemonic = mnemonic
self.arguments = arguments
self.description = description
self.is_switch = is_switch
self.is_alias = is_alias
def __len__(self):
return len(self.code) + sum(len(argument) for argument in self.arguments)
def __repr__(self):
return f"<Op{self.op_type.value} {self.mnemonic} arguments={self.arguments}>"
@property
def fixed_length(self):
return not self.is_switch
class Argument:
"""
Represents a concrete argument including value during dissassembly. Refer to `OpArgument` for the abstract
description of an argument.
"""
def __init__(self, data: bytes, op_argument: OpArgument):
self._data = data
self._op_argument = op_argument
@property
def value(self):
return self._op_argument.unpack(self._data)
def __repr__(self):
return f"<Argument {self._op_argument.__class__.__name__}=0x{self.value:x}>"
class Instruction:
"""
Represent a concrete instruction in memory. The `op` field carries the corresponding abstract `Op` instance
describing the data in memory.
"""
def __init__(self, data: bytes, offset: int, op: Op, arguments: List[Argument]):
self.data = data
self.offset = offset
self.op = op
self.arguments = arguments
def __len__(self):
return len(self.data)
def __repr__(self):
return f"<Instruction op={self.op} offset={self.offset} arguments={self.arguments}>"
class UnknownInstruction(Exception):
pass
class DisassemblerException(Exception):
pass
Classes
class OpArgument (size=4, has_target=False, is_num=False, is_idx=False, is_arg_num=False, is_casecnt=False, is_caseargs=False)
-
Helper class that provides a standard way to create an ABC using inheritance.
Expand source code Browse git
class OpArgument(abc.ABC): def __init__( self, size: int = 4, has_target: bool = False, is_num: bool = False, is_idx: bool = False, is_arg_num: bool = False, is_casecnt: bool = False, is_caseargs: bool = False, ): self._size = size self.has_target = has_target self.is_num = is_num self.is_idx = is_idx self.is_arg_num = is_arg_num self.is_casecnt = is_casecnt self.is_caseargs = is_caseargs def __len__(self): return self._size def __repr__(self): bool_args = [] if self.has_target: bool_args.append('has_target') if self.is_num: bool_args.append('is_num') if self.is_idx: bool_args.append('is_idx') if self.is_arg_num: bool_args.append('is_arg_num') if self.is_casecnt: bool_args.append('is_casecnt') if self.is_caseargs: bool_args.append('is_caseargs') bool_str = '' if len(bool_args) == 0 else f" {','.join(bool_args)}" return f"<{self.__class__.__name__} size={self._size}{bool_str}>" def unpack(self, value) -> int: return unpack('<I', value)[0]
Ancestors
- abc.ABC
Subclasses
- CallSiteDescr
- Class
- Ctor
- Etype
- Field
- Float32
- Float64
- Int32
- Int64
- Int8
- Method
- String
- ThisType
- Token
- Type
- TypeTok
- UInt16
- UInt32
- UInt8
- ValueType
Methods
def unpack(self, value)
-
Expand source code Browse git
def unpack(self, value) -> int: return unpack('<I', value)[0]
class Int8 (has_target=False, is_num=False)
-
Helper class that provides a standard way to create an ABC using inheritance.
Expand source code Browse git
class Int8(OpArgument): def __init__(self, has_target: bool = False, is_num: bool = False): super().__init__(1, has_target=has_target, is_num=is_num) def unpack(self, value: bytes) -> int: return unpack('<b', value)[0]
Ancestors
- OpArgument
- abc.ABC
Methods
def unpack(self, value)
-
Expand source code Browse git
def unpack(self, value: bytes) -> int: return unpack('<b', value)[0]
class Int32 (has_target=False, is_num=False, is_caseargs=False)
-
Helper class that provides a standard way to create an ABC using inheritance.
Expand source code Browse git
class Int32(OpArgument): def __init__( self, has_target: bool = False, is_num: bool = False, is_caseargs: bool = False ): super().__init__(4, has_target, is_num=is_num, is_caseargs=is_caseargs) def unpack(self, value: bytes) -> int: return unpack('<i', value)[0]
Ancestors
- OpArgument
- abc.ABC
Methods
def unpack(self, value)
-
Expand source code Browse git
def unpack(self, value: bytes) -> int: return unpack('<i', value)[0]
class Int64 (is_num=False)
-
Helper class that provides a standard way to create an ABC using inheritance.
Expand source code Browse git
class Int64(OpArgument): def __init__(self, is_num: bool = False): super().__init__(8, is_num=is_num) def unpack(self, value: bytes) -> int: return unpack('<q', value)[0]
Ancestors
- OpArgument
- abc.ABC
Methods
def unpack(self, value)
-
Expand source code Browse git
def unpack(self, value: bytes) -> int: return unpack('<q', value)[0]
class UInt8 (is_num=False, is_idx=False, is_arg_num=True)
-
Helper class that provides a standard way to create an ABC using inheritance.
Expand source code Browse git
class UInt8(OpArgument): def __init__(self, is_num: bool = False, is_idx: bool = False, is_arg_num=True): super().__init__(1, is_num=is_num, is_idx=is_idx, is_arg_num=is_arg_num) def unpack(self, value: bytes) -> int: return unpack('<B', value)[0]
Ancestors
- OpArgument
- abc.ABC
Methods
def unpack(self, value)
-
Expand source code Browse git
def unpack(self, value: bytes) -> int: return unpack('<B', value)[0]
class UInt16 (is_num=False, is_idx=False, is_arg_num=False)
-
Helper class that provides a standard way to create an ABC using inheritance.
Expand source code Browse git
class UInt16(OpArgument): def __init__( self, is_num: bool = False, is_idx: bool = False, is_arg_num: bool = False ): super().__init__(2, is_num=is_num, is_idx=is_idx, is_arg_num=is_arg_num) def unpack(self, value: bytes) -> int: return unpack('<H', value)[0]
Ancestors
- OpArgument
- abc.ABC
Methods
def unpack(self, value)
-
Expand source code Browse git
def unpack(self, value: bytes) -> int: return unpack('<H', value)[0]
class UInt32 (is_casecnt=False)
-
Helper class that provides a standard way to create an ABC using inheritance.
Expand source code Browse git
class UInt32(OpArgument): def __init__(self, is_casecnt: bool = False): super().__init__(4, is_casecnt=is_casecnt)
Ancestors
- OpArgument
- abc.ABC
class Float32 (is_num=False)
-
Helper class that provides a standard way to create an ABC using inheritance.
Expand source code Browse git
class Float32(OpArgument): def __init__(self, is_num: bool = False): super().__init__(4, is_num=is_num)
Ancestors
- OpArgument
- abc.ABC
class Float64 (is_num=False)
-
Helper class that provides a standard way to create an ABC using inheritance.
Expand source code Browse git
class Float64(OpArgument): def __init__(self, is_num: bool = False): super().__init__(8, is_num=is_num)
Ancestors
- OpArgument
- abc.ABC
class String (size=4, has_target=False, is_num=False, is_idx=False, is_arg_num=False, is_casecnt=False, is_caseargs=False)
-
Helper class that provides a standard way to create an ABC using inheritance.
Expand source code Browse git
class String(OpArgument): def unpack(self, value) -> int: return unpack('<I', value[:-1] + b'\0')[0]
Ancestors
- OpArgument
- abc.ABC
Methods
def unpack(self, value)
-
Expand source code Browse git
def unpack(self, value) -> int: return unpack('<I', value[:-1] + b'\0')[0]
class TypeTok (size=4, has_target=False, is_num=False, is_idx=False, is_arg_num=False, is_casecnt=False, is_caseargs=False)
-
Helper class that provides a standard way to create an ABC using inheritance.
Expand source code Browse git
class TypeTok(OpArgument): pass
Ancestors
- OpArgument
- abc.ABC
class Field (size=4, has_target=False, is_num=False, is_idx=False, is_arg_num=False, is_casecnt=False, is_caseargs=False)
-
Helper class that provides a standard way to create an ABC using inheritance.
Expand source code Browse git
class Field(OpArgument): pass
Ancestors
- OpArgument
- abc.ABC
class Class (size=4, has_target=False, is_num=False, is_idx=False, is_arg_num=False, is_casecnt=False, is_caseargs=False)
-
Helper class that provides a standard way to create an ABC using inheritance.
Expand source code Browse git
class Class(OpArgument): pass
Ancestors
- OpArgument
- abc.ABC
class Method (size=4, has_target=False, is_num=False, is_idx=False, is_arg_num=False, is_casecnt=False, is_caseargs=False)
-
Helper class that provides a standard way to create an ABC using inheritance.
Expand source code Browse git
class Method(OpArgument): pass
Ancestors
- OpArgument
- abc.ABC
class ValueType (size=4, has_target=False, is_num=False, is_idx=False, is_arg_num=False, is_casecnt=False, is_caseargs=False)
-
Helper class that provides a standard way to create an ABC using inheritance.
Expand source code Browse git
class ValueType(OpArgument): pass
Ancestors
- OpArgument
- abc.ABC
class ThisType (size=4, has_target=False, is_num=False, is_idx=False, is_arg_num=False, is_casecnt=False, is_caseargs=False)
-
Helper class that provides a standard way to create an ABC using inheritance.
Expand source code Browse git
class ThisType(OpArgument): pass
Ancestors
- OpArgument
- abc.ABC
class CallSiteDescr (size=4, has_target=False, is_num=False, is_idx=False, is_arg_num=False, is_casecnt=False, is_caseargs=False)
-
Helper class that provides a standard way to create an ABC using inheritance.
Expand source code Browse git
class CallSiteDescr(OpArgument): pass
Ancestors
- OpArgument
- abc.ABC
class Token (size=4, has_target=False, is_num=False, is_idx=False, is_arg_num=False, is_casecnt=False, is_caseargs=False)
-
Helper class that provides a standard way to create an ABC using inheritance.
Expand source code Browse git
class Token(OpArgument): pass
Ancestors
- OpArgument
- abc.ABC
class Etype (size=4, has_target=False, is_num=False, is_idx=False, is_arg_num=False, is_casecnt=False, is_caseargs=False)
-
Helper class that provides a standard way to create an ABC using inheritance.
Expand source code Browse git
class Etype(OpArgument): pass
Ancestors
- OpArgument
- abc.ABC
class Ctor (size=4, has_target=False, is_num=False, is_idx=False, is_arg_num=False, is_casecnt=False, is_caseargs=False)
-
Helper class that provides a standard way to create an ABC using inheritance.
Expand source code Browse git
class Ctor(OpArgument): pass
Ancestors
- OpArgument
- abc.ABC
class Type (size=4, has_target=False, is_num=False, is_idx=False, is_arg_num=False, is_casecnt=False, is_caseargs=False)
-
Helper class that provides a standard way to create an ABC using inheritance.
Expand source code Browse git
class Type(OpArgument): pass
Ancestors
- OpArgument
- abc.ABC
class TokenLabel (tid, value)
-
Expand source code Browse git
class TokenLabel: def __init__(self, tid: int, value: str): self._tid = tid self._value = value
class OpType (value, names=None, *, module=None, qualname=None, type=None, start=1)
-
An enumeration.
Expand source code Browse git
class OpType(str, enum.Enum): BASE = 'Base' OBJECT_MODEL = 'ObjectModel' PREFIX_TO = 'PrefixTo'
Ancestors
- builtins.str
- enum.Enum
Class variables
var BASE
var OBJECT_MODEL
var PREFIX_TO
class Op (op_type, code, mnemonic, arguments, description, is_switch=False, is_alias=False)
-
Specifier for a Common Intermediate Language (CIL) instruction. It is used to specify a complete list of all available instructions in the OpRepository. Instances of this class do not represent concrete instructions during disassembly, that what the Instruction class is for.
Expand source code Browse git
class Op(abc.ABC): """ Specifier for a Common Intermediate Language (CIL) instruction. It is used to specify a complete list of all available instructions in the OpRepository. Instances of this class do not represent concrete instructions during disassembly, that what the Instruction class is for. """ def __init__( self, op_type: OpType, code: bytes, mnemonic: str, arguments: List[OpArgument], description: str, is_switch: bool = False, is_alias: bool = False, ): self.op_type = op_type self.code = code self.mnemonic = mnemonic self.arguments = arguments self.description = description self.is_switch = is_switch self.is_alias = is_alias def __len__(self): return len(self.code) + sum(len(argument) for argument in self.arguments) def __repr__(self): return f"<Op{self.op_type.value} {self.mnemonic} arguments={self.arguments}>" @property def fixed_length(self): return not self.is_switch
Ancestors
- abc.ABC
Instance variables
var fixed_length
-
Expand source code Browse git
@property def fixed_length(self): return not self.is_switch
class Argument (data, op_argument)
-
Represents a concrete argument including value during dissassembly. Refer to
OpArgument
for the abstract description of an argument.Expand source code Browse git
class Argument: """ Represents a concrete argument including value during dissassembly. Refer to `OpArgument` for the abstract description of an argument. """ def __init__(self, data: bytes, op_argument: OpArgument): self._data = data self._op_argument = op_argument @property def value(self): return self._op_argument.unpack(self._data) def __repr__(self): return f"<Argument {self._op_argument.__class__.__name__}=0x{self.value:x}>"
Instance variables
var value
-
Expand source code Browse git
@property def value(self): return self._op_argument.unpack(self._data)
class Instruction (data, offset, op, arguments)
-
Represent a concrete instruction in memory. The
op
field carries the corresponding abstractOp
instance describing the data in memory.Expand source code Browse git
class Instruction: """ Represent a concrete instruction in memory. The `op` field carries the corresponding abstract `Op` instance describing the data in memory. """ def __init__(self, data: bytes, offset: int, op: Op, arguments: List[Argument]): self.data = data self.offset = offset self.op = op self.arguments = arguments def __len__(self): return len(self.data) def __repr__(self): return f"<Instruction op={self.op} offset={self.offset} arguments={self.arguments}>"
class UnknownInstruction (*args, **kwargs)
-
Common base class for all non-exit exceptions.
Expand source code Browse git
class UnknownInstruction(Exception): pass
Ancestors
- builtins.Exception
- builtins.BaseException
class DisassemblerException (*args, **kwargs)
-
Common base class for all non-exit exceptions.
Expand source code Browse git
class DisassemblerException(Exception): pass
Ancestors
- builtins.Exception
- builtins.BaseException