Guide

Installation

This package can be installed on Linux, macOS, and Windows platforms for recent (3.8+) versions of both CPython and PyPy. Wheels are provided for several configurations. The latest release can be installed from PyPI using pip:

pip install pypcode

The very latest development version can be installed from GitHub via:

pip install --user https://github.com/angr/pypcode/archive/refs/heads/master.zip

Usage Example

Disassemble with pypcode.Context.disassemble():

In [1]: from pypcode import Context
   ...: ctx = Context("x86:LE:64:default")
   ...: dx = ctx.disassemble(bytes.fromhex("483578563412c3"))
   ...: print(dx)
   ...: 
0x0/6: XOR RAX,0x12345678
0x6/1: RET 

Work with pypcode.Disassembly and pypcode.Instruction:

In [2]: (dx.instructions[0].mnem, dx.instructions[0].body)
Out[2]: ('XOR', 'RAX,0x12345678')

Translate to P-Code with pypcode.Context.translate():

In [3]: from pypcode import Context
   ...: ctx = Context("x86:LE:64:default")
   ...: tx = ctx.translate(bytes.fromhex("483578563412c3"))
   ...: print(tx)
   ...: 
IMARK ram[0:6]
CF = 0x0
OF = 0x0
RAX = RAX ^ 0x12345678
SF = RAX s< 0x0
ZF = RAX == 0x0
unique[58300:8] = RAX & 0xff
unique[58400:1] = popcount(unique[58300:8])
unique[58500:1] = unique[58400:1] & 0x1
PF = unique[58500:1] == 0x0
IMARK ram[6:1]
RIP = *[ram]RSP
RSP = RSP + 0x8
return RIP

Work with pypcode.Translation and pypcode.PcodeOp:

In [4]: tx.ops[3].opcode
Out[4]: OpCode.INT_XOR

In [5]: tx.ops[3].inputs[0].space.name
Out[5]: 'register'

In [6]: tx.ops[3].inputs[0].getRegisterName()
Out[6]: 'RAX'

Command Line Usage Example

The pypcode module can be invoked from command line to disassemble and translate supported machine code to P-code from command line. Run python -m pypcode --help for usage information.

$ python -m pypcode -b x86:LE:64:default test-x64.bin
--------------------------------------------------------------------------------
00000000/2: XOR EAX,EAX
--------------------------------------------------------------------------------
  0: CF = 0x0
  1: OF = 0x0
  2: EAX = EAX ^ EAX
  3: RAX = zext(EAX)
  4: SF = EAX s< 0x0
  5: ZF = EAX == 0x0
  6: unique[0x2580:4] = EAX & 0xff
  7: unique[0x2590:1] = popcount(unique[0x2580:4])
  8: unique[0x25a0:1] = unique[0x2590:1] & 0x1
  9: PF = unique[0x25a0:1] == 0x0

--------------------------------------------------------------------------------
00000002/2: CMP ESI,EAX
--------------------------------------------------------------------------------
  0: CF = ESI < EAX
  1: OF = sborrow(ESI, EAX)
  2: unique[0x5180:4] = ESI - EAX
  3: SF = unique[0x5180:4] s< 0x0
  4: ZF = unique[0x5180:4] == 0x0
  5: unique[0x2580:4] = unique[0x5180:4] & 0xff
  6: unique[0x2590:1] = popcount(unique[0x2580:4])
  7: unique[0x25a0:1] = unique[0x2590:1] & 0x1
  8: PF = unique[0x25a0:1] == 0x0

--------------------------------------------------------------------------------
00000004/2: JBE 0x17
--------------------------------------------------------------------------------
  0: unique[0x18f0:1] = CF || ZF
  1: if (unique[0x18f0:1]) goto ram[0x17:8]

SLEIGH & P-Code References

Extensive documentation covering SLEIGH and P-Code is available online: