pypcode#

Pythonic interface to SLEIGH by way of the csleigh C API wrapper and CFFI.

class pypcode.OpCode(value)[source]#

Bases: Enum

1:1 mapping of C enumeration csleigh_CPUI_* to Enum

BOOL_AND = 39#
BOOL_NEGATE = 37#
BOOL_OR = 40#
BOOL_XOR = 38#
BRANCH = 4#
BRANCHIND = 6#
CALL = 7#
CALLIND = 8#
CALLOTHER = 9#
CAST = 64#
CBRANCH = 5#
COPY = 1#
CPOOLREF = 68#
EXTRACT = 71#
FLOAT_ABS = 52#
FLOAT_ADD = 47#
FLOAT_CEIL = 57#
FLOAT_DIV = 48#
FLOAT_EQUAL = 41#
FLOAT_FLOAT2FLOAT = 55#
FLOAT_FLOOR = 58#
FLOAT_INT2FLOAT = 54#
FLOAT_LESS = 43#
FLOAT_LESSEQUAL = 44#
FLOAT_MULT = 49#
FLOAT_NAN = 46#
FLOAT_NEG = 51#
FLOAT_NOTEQUAL = 42#
FLOAT_ROUND = 59#
FLOAT_SQRT = 53#
FLOAT_SUB = 50#
FLOAT_TRUNC = 56#
INDIRECT = 61#
INSERT = 70#
INT_2COMP = 24#
INT_ADD = 19#
INT_AND = 27#
INT_CARRY = 21#
INT_DIV = 33#
INT_EQUAL = 11#
INT_LEFT = 29#
INT_LESS = 15#
INT_LESSEQUAL = 16#
INT_MULT = 32#
INT_NEGATE = 25#
INT_NOTEQUAL = 12#
INT_OR = 28#
INT_REM = 35#
INT_RIGHT = 30#
INT_SBORROW = 23#
INT_SCARRY = 22#
INT_SDIV = 34#
INT_SEXT = 18#
INT_SLESS = 13#
INT_SLESSEQUAL = 14#
INT_SREM = 36#
INT_SRIGHT = 31#
INT_SUB = 20#
INT_XOR = 26#
INT_ZEXT = 17#
LOAD = 2#
MULTIEQUAL = 60#
NEW = 69#
PIECE = 62#
POPCOUNT = 72#
PTRADD = 65#
PTRSUB = 66#
RETURN = 10#
SEGMENTOP = 67#
STORE = 3#
SUBPIECE = 63#
class pypcode.SleighErrorType(value)[source]#

Bases: Enum

1:1 mapping of C enumeration csleigh_ERROR_TYPE_* to Enum

BADDATA = 3#
GENERIC = 1#
NOERROR = 0#
UNIMPL = 2#
class pypcode.ArchLanguage(archdir, ldef)[source]#

Bases: object

A specific language for an architecture. Provides access to language, pspec, and cspecs.

Parameters:
  • archdir (str) –

  • ldef (Element) –

archdir: str#
ldef: Element#
property pspec_path: str#
property slafile_path: str#
property description: str#
property pspec: Element | None#
property cspecs: Mapping[Tuple[str, str], Element]#
init_context_from_pspec(ctx)[source]#
Return type:

None

Parameters:

ctx (csleigh_Context) –

class pypcode.Arch(archname, ldefpath)[source]#

Bases: object

Main class representing an architecture describing available languages.

Parameters:
  • archname (str) –

  • ldefpath (str) –

archpath: str#
archname: str#
ldefpath: str#
ldef: ElementTree#
languages: Sequence[ArchLanguage]#
classmethod enumerate()[source]#

Enumerate all available architectures and languages.

Language definitions are sourced from definitions shipped with pypcode and can be found in processors/<architecture>/data/languages/<variant>.ldefs

Return type:

Generator[Arch, None, None]

class pypcode.Context(lang)[source]#

Bases: object

Context for translation.

Parameters:

lang (ArchLanguage) –

lang: ArchLanguage#
ctx_c: csleigh_Context#
registers#
get_cached_addr_space(cobj)[source]#

Used during translation to cache unchanging address space objects. Should not be called by pypcode users.

Return type:

Optional[AddrSpace]

Parameters:

cobj (csleigh_AddrSpace) –

set_cached_addr_space(cobj, pobj)[source]#

Used during translation to cache unchanging address space objects. Should not be called by pypcode users.

Return type:

None

Parameters:
  • cobj (csleigh_AddrSpace) –

  • pobj (AddrSpace) –

translate(code, base, max_inst=0, max_bytes=0, bb_terminating=False)[source]#

Disassemble and translate to p-code.

Parameters:
  • code (Union[bytes, bytearray]) – Buffer of machine code to translate

  • base (int) – Base address of the machine code

  • max_inst (int) – Maximum number of instructions to translate, or 0 for no limit

  • max_bytes (int) – Maximum number of bytes to translate, or 0 for no limit

  • bb_terminating (bool) – End translation at basic block boundaries

Return type:

TranslationResult

get_register_name(space, offset, size)[source]#

Call SleighBase::getRegisterName in this context.

Return type:

str

Parameters:
  • space (AddrSpace) –

  • offset (int) –

  • size (int) –

class pypcode.ContextObj(ctx)[source]#

Bases: object

Base class for objects that are context-sensitive.

Parameters:

ctx (Context) –

ctx: Context#
class pypcode.AddrSpace(ctx, cobj)[source]#

Bases: ContextObj

An address space.

Parameters:
  • ctx (Context) –

  • cobj (csleigh_AddrSpace) –

cobj: csleigh_AddrSpace#
name: str#
classmethod from_c_uncached(ctx, cobj)[source]#
Return type:

AddrSpace

Parameters:
  • ctx (Context) –

  • cobj (csleigh_AddrSpace) –

classmethod from_c(ctx, cobj)[source]#
Return type:

AddrSpace

Parameters:
  • ctx (Context) –

  • cobj (csleigh_AddrSpace) –

to_c()[source]#
Return type:

csleigh_AddrSpace

ctx: Context#
class pypcode.Address(ctx, space, offset)[source]#

Bases: ContextObj

Addresses a byte within some address space.

Parameters:
space: AddrSpace#
offset: int#
classmethod from_c(ctx, cobj)[source]#
Return type:

Address

Parameters:
  • ctx (Context) –

  • cobj (csleigh_Address) –

to_c()[source]#
Return type:

csleigh_Address

property is_constant: bool#

Return True if this address is in the constant space.

get_space_from_const()[source]#

For LOAD/STORE, the address space which is being accessed is encoded as a pointer stored in a constant space offset. See Address::getSpaceFromConst.

Return type:

AddrSpace

ctx: Context#
class pypcode.Varnode(ctx, space, offset, size)[source]#

Bases: ContextObj

Data manipulated by p-code.

Parameters:
space: AddrSpace#
offset: int#
size: int#
classmethod from_c(ctx, cobj)[source]#
Return type:

Varnode

Parameters:
  • ctx (Context) –

  • cobj (csleigh_Varnode) –

get_addr()[source]#
Return type:

Address

get_register_name()[source]#

Convenience function to call SleighBase::getRegisterName with current Varnode attributes.

Return type:

str

get_space_from_const()[source]#

Convenience function to call Address::getSpaceFromConst with current Varnode attributes.

Return type:

AddrSpace

ctx: Context#
class pypcode.SeqNum(ctx, pc, uniq, order)[source]#

Bases: ContextObj

Unique address for p-code ops translated from an instruction at pc.

Parameters:
pc: Address#
uniq: int#
order: int#
classmethod from_c(ctx, cobj)[source]#
Return type:

SeqNum

Parameters:
  • ctx (Context) –

  • cobj (csleigh_SeqNum) –

ctx: Context#
class pypcode.PcodeOp(ctx, seq, opcode, inputs, output=None)[source]#

Bases: ContextObj

A single p-code op.

Parameters:
seq: SeqNum#
opcode: OpCode#
output: Optional[Varnode]#
inputs: Sequence[Varnode]#
classmethod from_c(ctx, cobj)[source]#
Return type:

PcodeOp

Parameters:
  • ctx (Context) –

  • cobj (csleigh_PcodeOp) –

ctx: Context#
class pypcode.OpFormat[source]#

Bases: object

General op pretty-printer.

static fmt_vn(vn)[source]#
Return type:

str

Parameters:

vn (Varnode) –

fmt(op)[source]#
Return type:

str

Parameters:

op (PcodeOp) –

class pypcode.OpFormatUnary(operator)[source]#

Bases: OpFormat

General unary op pretty-printer.

Parameters:

operator (str) –

operator#
fmt(op)[source]#
Return type:

str

Parameters:

op (PcodeOp) –

static fmt_vn(vn)#
Return type:

str

Parameters:

vn (Varnode) –

class pypcode.OpFormatBinary(operator)[source]#

Bases: OpFormat

General binary op pretty-printer.

Parameters:

operator (str) –

operator#
fmt(op)[source]#
Return type:

str

Parameters:

op (PcodeOp) –

static fmt_vn(vn)#
Return type:

str

Parameters:

vn (Varnode) –

class pypcode.OpFormatFunc(operator)[source]#

Bases: OpFormat

Function-call style op pretty-printer.

Parameters:

operator (str) –

operator#
fmt(op)[source]#
Return type:

str

Parameters:

op (PcodeOp) –

static fmt_vn(vn)#
Return type:

str

Parameters:

vn (Varnode) –

class pypcode.OpFormatSpecial[source]#

Bases: OpFormat

Specialized op pretty-printers.

fmt_BRANCH(op)[source]#
Return type:

str

Parameters:

op (PcodeOp) –

fmt_BRANCHIND(op)[source]#
Return type:

str

Parameters:

op (PcodeOp) –

fmt_CALL(op)[source]#
Return type:

str

Parameters:

op (PcodeOp) –

fmt_CALLIND(op)[source]#
Return type:

str

Parameters:

op (PcodeOp) –

fmt_CBRANCH(op)[source]#
Return type:

str

Parameters:

op (PcodeOp) –

fmt_LOAD(op)[source]#
Return type:

str

Parameters:

op (PcodeOp) –

fmt_RETURN(op)[source]#
Return type:

str

Parameters:

op (PcodeOp) –

fmt_STORE(op)[source]#
Return type:

str

Parameters:

op (PcodeOp) –

fmt(op)[source]#
Return type:

str

Parameters:

op (PcodeOp) –

static fmt_vn(vn)#
Return type:

str

Parameters:

vn (Varnode) –

class pypcode.PcodePrettyPrinter[source]#

Bases: object

P-code pretty-printer.

DEFAULT_OP_FORMAT = <pypcode.OpFormat object>#
OP_FORMATS = {<OpCode.BOOL_AND: 39>: <pypcode.OpFormatBinary object>, <OpCode.BOOL_NEGATE: 37>: <pypcode.OpFormatUnary object>, <OpCode.BOOL_OR: 40>: <pypcode.OpFormatBinary object>, <OpCode.BOOL_XOR: 38>: <pypcode.OpFormatBinary object>, <OpCode.BRANCH: 4>: <pypcode.OpFormatSpecial object>, <OpCode.BRANCHIND: 6>: <pypcode.OpFormatSpecial object>, <OpCode.CALL: 7>: <pypcode.OpFormatSpecial object>, <OpCode.CALLIND: 8>: <pypcode.OpFormatSpecial object>, <OpCode.CBRANCH: 5>: <pypcode.OpFormatSpecial object>, <OpCode.COPY: 1>: <pypcode.OpFormatUnary object>, <OpCode.CPOOLREF: 68>: <pypcode.OpFormatFunc object>, <OpCode.FLOAT_ABS: 52>: <pypcode.OpFormatFunc object>, <OpCode.FLOAT_ADD: 47>: <pypcode.OpFormatBinary object>, <OpCode.FLOAT_CEIL: 57>: <pypcode.OpFormatFunc object>, <OpCode.FLOAT_DIV: 48>: <pypcode.OpFormatBinary object>, <OpCode.FLOAT_EQUAL: 41>: <pypcode.OpFormatBinary object>, <OpCode.FLOAT_FLOAT2FLOAT: 55>: <pypcode.OpFormatFunc object>, <OpCode.FLOAT_FLOOR: 58>: <pypcode.OpFormatFunc object>, <OpCode.FLOAT_INT2FLOAT: 54>: <pypcode.OpFormatFunc object>, <OpCode.FLOAT_LESS: 43>: <pypcode.OpFormatBinary object>, <OpCode.FLOAT_LESSEQUAL: 44>: <pypcode.OpFormatBinary object>, <OpCode.FLOAT_MULT: 49>: <pypcode.OpFormatBinary object>, <OpCode.FLOAT_NAN: 46>: <pypcode.OpFormatFunc object>, <OpCode.FLOAT_NEG: 51>: <pypcode.OpFormatUnary object>, <OpCode.FLOAT_NOTEQUAL: 42>: <pypcode.OpFormatBinary object>, <OpCode.FLOAT_ROUND: 59>: <pypcode.OpFormatFunc object>, <OpCode.FLOAT_SQRT: 53>: <pypcode.OpFormatFunc object>, <OpCode.FLOAT_SUB: 50>: <pypcode.OpFormatBinary object>, <OpCode.FLOAT_TRUNC: 56>: <pypcode.OpFormatFunc object>, <OpCode.INT_2COMP: 24>: <pypcode.OpFormatUnary object>, <OpCode.INT_ADD: 19>: <pypcode.OpFormatBinary object>, <OpCode.INT_AND: 27>: <pypcode.OpFormatBinary object>, <OpCode.INT_CARRY: 21>: <pypcode.OpFormatFunc object>, <OpCode.INT_DIV: 33>: <pypcode.OpFormatBinary object>, <OpCode.INT_EQUAL: 11>: <pypcode.OpFormatBinary object>, <OpCode.INT_LEFT: 29>: <pypcode.OpFormatBinary object>, <OpCode.INT_LESS: 15>: <pypcode.OpFormatBinary object>, <OpCode.INT_LESSEQUAL: 16>: <pypcode.OpFormatBinary object>, <OpCode.INT_MULT: 32>: <pypcode.OpFormatBinary object>, <OpCode.INT_NEGATE: 25>: <pypcode.OpFormatUnary object>, <OpCode.INT_NOTEQUAL: 12>: <pypcode.OpFormatBinary object>, <OpCode.INT_OR: 28>: <pypcode.OpFormatBinary object>, <OpCode.INT_REM: 35>: <pypcode.OpFormatBinary object>, <OpCode.INT_RIGHT: 30>: <pypcode.OpFormatBinary object>, <OpCode.INT_SBORROW: 23>: <pypcode.OpFormatFunc object>, <OpCode.INT_SCARRY: 22>: <pypcode.OpFormatFunc object>, <OpCode.INT_SDIV: 34>: <pypcode.OpFormatBinary object>, <OpCode.INT_SEXT: 18>: <pypcode.OpFormatFunc object>, <OpCode.INT_SLESS: 13>: <pypcode.OpFormatBinary object>, <OpCode.INT_SLESSEQUAL: 14>: <pypcode.OpFormatBinary object>, <OpCode.INT_SREM: 36>: <pypcode.OpFormatBinary object>, <OpCode.INT_SRIGHT: 31>: <pypcode.OpFormatBinary object>, <OpCode.INT_SUB: 20>: <pypcode.OpFormatBinary object>, <OpCode.INT_XOR: 26>: <pypcode.OpFormatBinary object>, <OpCode.INT_ZEXT: 17>: <pypcode.OpFormatFunc object>, <OpCode.LOAD: 2>: <pypcode.OpFormatSpecial object>, <OpCode.NEW: 69>: <pypcode.OpFormatFunc object>, <OpCode.POPCOUNT: 72>: <pypcode.OpFormatFunc object>, <OpCode.RETURN: 10>: <pypcode.OpFormatSpecial object>, <OpCode.STORE: 3>: <pypcode.OpFormatSpecial object>}#
classmethod fmt_op(op)[source]#
Return type:

str

Parameters:

op (PcodeOp) –

class pypcode.Translation(ctx, address, length, asm_mnem, asm_body, ops)[source]#

Bases: ContextObj

Translation of a machine instruction to p-code.

Parameters:
  • ctx (Context) –

  • address (Address) –

  • length (int) –

  • asm_mnem (str) –

  • asm_body (str) –

  • ops (Sequence[PcodeOp]) –

address: Address#
length: int#
ctx: Context#
asm_mnem: str#
asm_body: str#
ops: Sequence[PcodeOp]#
classmethod from_c(ctx, cobj)[source]#
Return type:

Translation

Parameters:
  • ctx (Context) –

  • cobj (csleigh_Translation) –

exception pypcode.SleighError(ctx, explain)[source]#

Bases: Exception

Base class for translation errors.

Parameters:
  • ctx (Context) –

  • explain (str) –

args#
with_traceback()#

Exception.with_traceback(tb) – set self.__traceback__ to tb and return self.

ctx: Context#
exception pypcode.UnimplError(ctx, explain, address, instruction_length)[source]#

Bases: SleighError

UnimplError exception.

Parameters:
  • ctx (Context) –

  • explain (str) –

  • address (Address) –

  • instruction_length (int) –

args#
ctx: Context#
with_traceback()#

Exception.with_traceback(tb) – set self.__traceback__ to tb and return self.

explain: str#
address: Address#
instruction_length: int#
classmethod from_c(ctx, cobj)[source]#
Return type:

UnimplError

Parameters:
  • ctx (Context) –

  • cobj (csleigh_Error) –

exception pypcode.BadDataError(ctx, explain, address)[source]#

Bases: SleighError

BadDataError exception.

Parameters:
args#
ctx: Context#
with_traceback()#

Exception.with_traceback(tb) – set self.__traceback__ to tb and return self.

explain: str#
address: Address#
classmethod from_c(ctx, cobj)[source]#
Return type:

BadDataError

Parameters:
  • ctx (Context) –

  • cobj (csleigh_Error) –

class pypcode.SleighErrorFactory[source]#

Bases: object

Generates SleighErrorType objects from csleigh errors.

classmethod from_c(ctx, cobj)[source]#
Return type:

Union[None, SleighError, UnimplError, BadDataError]

Parameters:
  • ctx (Context) –

  • cobj (csleigh_Error) –

class pypcode.TranslationResult(ctx, instructions, error=None)[source]#

Bases: ContextObj

The result of a translation.

Parameters:
ctx: Context#
instructions: Sequence[Translation]#
error: Optional[SleighError]#
classmethod from_c(ctx, cobj)[source]#
Return type:

TranslationResult

Parameters:
  • ctx (Context) –

  • cobj (csleigh_TranslationResult) –