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: