asm – (Dis)assembler

This module contains functions to assemble and disassemble code for a given target platform. By default the keystone engine assembler will be used if it is available. If it’s not available (or if the WANT_KEYSTONE environment variable is set and it’s not 1, YES or TRUE (case insensitive)), pwnypack falls back to using the nasm assembler for nasm syntax on X86 or GNU as for any other supported syntax / architecture. Disassembly is performed by ndisasm on x86 for nasm syntax. capstone is used for any other supported syntax / architecture.

Currently, the only supported architectures are x86 (both 32 and 64 bits variants) and arm (both 32 and 64 bits variants).

class pwnypack.asm.AsmSyntax[source]

Bases: enum.IntEnum

This enumeration is used to specify the assembler syntax.

att = 2

AT&T assembler syntax

intel = 1

Intel assembler syntax

nasm = 0

Netwide assembler syntax

pwnypack.asm.asm(code, addr=0, syntax=None, target=None, gnu_binutils_prefix=None)[source]

Assemble statements into machine readable code.

Parameters:
  • code (str) – The statements to assemble.
  • addr (int) – The memory address where the code will run.
  • syntax (AsmSyntax) – The input assembler syntax for x86. Defaults to nasm, ignored on other platforms.
  • target (Target) – The target architecture. The global target is used if this argument is None.
  • gnu_binutils_prefix (str) – When the syntax is AT&T, gnu binutils’ as and ld will be used. By default, it selects arm-*-as/ld for 32bit ARM targets, aarch64-*-as/ld for 64 bit ARM targets, i386-*-as/ld for 32bit X86 targets and amd64-*-as/ld for 64bit X86 targets (all for various flavors of *. This option allows you to pick a different toolchain. The prefix should always end with a ‘-‘ (or be empty).
Returns:

The assembled machine code.

Return type:

bytes

Raises:
  • SyntaxError – If the assembler statements are invalid.
  • NotImplementedError – In an unsupported target platform is specified.

Example

>>> from pwny import *
>>> asm('''
...     pop rdi
...     ret
... ''', target=Target(arch=Target.Arch.x86, bits=64))
b'_\xc3'
pwnypack.asm.disasm(code, addr=0, syntax=None, target=None)[source]

Disassemble machine readable code into human readable statements.

Parameters:
  • code (bytes) – The machine code that is to be disassembled.
  • addr (int) – The memory address of the code (used for relative references).
  • syntax (AsmSyntax) – The output assembler syntax. This defaults to nasm on x86 architectures, AT&T on all other architectures.
  • target (Target) – The architecture for which the code was written. The global target is used if this argument is None.
Returns:

The disassembled machine code.

Return type:

list of str

Raises:
  • NotImplementedError – In an unsupported target platform is specified.
  • RuntimeError – If ndisasm encounters an error.

Example

>>> from pwny import *
>>> disasm(b'_\xc3', target=Target(arch=Target.Arch.x86, bits=64))
['pop rdi', 'ret']