pwnlib.asm — Assembler functions

Utilities for assembling and disassembling code.

Architecture Selection

Architecture, endianness, and word size are selected by using pwnlib.context.

Any parameters which can be specified to context can also be specified as keyword arguments to either asm() or disasm().

Assembly

To assemble code, simply invoke asm() on the code to assemble.

>>> asm('mov eax, 0')
'\xb8\x00\x00\x00\x00'

Additionally, you can use constants as defined in the pwnlib.constants module.

>>> asm('mov eax, SYS_execve')
'\xb8\x0b\x00\x00\x00'

Finally, asm() is used to assemble shellcode provided by pwntools in the shellcraft module.

>>> asm(shellcraft.sh())
'jhh///sh/binj\x0bX\x89\xe31\xc9\x99\xcd\x80'

Disassembly

To disassemble code, simply invoke disasm() on the bytes to disassemble.

>>> disasm('\xb8\x0b\x00\x00\x00')
'   0:   b8 0b 00 00 00          mov    eax,0xb'
pwnlib.asm.asm(code, vma = 0, extract = True, ...) → str[source]

Runs cpp() over a given shellcode and then assembles it into bytes.

To see which architectures or operating systems are supported, look in pwnlib.contex.

To support all these architecture, we bundle the GNU assembler and objcopy with pwntools.

Parameters:
  • shellcode (str) – Assembler code to assemble.
  • vma (int) – Virtual memory address of the beginning of assembly
  • extract (bool) – Extract the raw assembly bytes from the assembled file. If False, returns the path to an ELF file with the assembly embedded.
Kwargs:
Any arguments/properties that can be set on context

Examples

>>> asm("mov eax, SYS_select", arch = 'i386', os = 'freebsd')
'\xb8]\x00\x00\x00'
>>> asm("mov eax, SYS_select", arch = 'amd64', os = 'linux')
'\xb8\x17\x00\x00\x00'
>>> asm("mov rax, SYS_select", arch = 'amd64', os = 'linux')
'H\xc7\xc0\x17\x00\x00\x00'
>>> asm("mov r0, #SYS_select", arch = 'arm', os = 'linux', bits=32)
'R\x00\xa0\xe3'
pwnlib.asm.cpp(shellcode, ...) → str[source]

Runs CPP over the given shellcode.

The output will always contain exactly one newline at the end.

Parameters:shellcode (str) – Shellcode to preprocess
Kwargs:
Any arguments/properties that can be set on context

Examples

>>> cpp("mov al, SYS_setresuid", arch = "i386", os = "linux")
'mov al, 164\n'
>>> cpp("weee SYS_setresuid", arch = "arm", os = "linux")
'weee (0+164)\n'
>>> cpp("SYS_setresuid", arch = "thumb", os = "linux")
'(0+164)\n'
>>> cpp("SYS_setresuid", os = "freebsd")
'311\n'
pwnlib.asm.disasm(data, ...) → str[source]

Disassembles a bytestring into human readable assembler.

To see which architectures are supported, look in pwnlib.contex.

To support all these architecture, we bundle the GNU objcopy and objdump with pwntools.

Parameters:
  • data (str) – Bytestring to disassemble.
  • vma (int) – Passed through to the –adjust-vma argument of objdump
  • byte (bool) – Include the hex-printed bytes in the disassembly
  • offset (bool) – Include the virtual memory address in the disassembly
Kwargs:
Any arguments/properties that can be set on context

Examples

>>> print disasm('b85d000000'.decode('hex'), arch = 'i386')
   0:   b8 5d 00 00 00          mov    eax,0x5d
>>> print disasm('b85d000000'.decode('hex'), arch = 'i386', byte = 0)
   0:   mov    eax,0x5d
>>> print disasm('b85d000000'.decode('hex'), arch = 'i386', byte = 0, offset = 0)
mov    eax,0x5d
>>> print disasm('b817000000'.decode('hex'), arch = 'amd64')
   0:   b8 17 00 00 00          mov    eax,0x17
>>> print disasm('48c7c017000000'.decode('hex'), arch = 'amd64')
   0:   48 c7 c0 17 00 00 00    mov    rax,0x17
>>> print disasm('04001fe552009000'.decode('hex'), arch = 'arm')
   0:   e51f0004        ldr     r0, [pc, #-4]   ; 0x4
   4:   00900052        addseq  r0, r0, r2, asr r0
>>> print disasm('4ff00500'.decode('hex'), arch = 'thumb', bits=32)
   0:   f04f 0005       mov.w   r0, #5
>>>
pwnlib.asm.make_elf(*a, **kw)[source]

Builds an ELF file with the specified binary data as its executable code.

Parameters:
  • data (str) – Assembled code
  • vma (int) – Load address for the ELF file

Examples

This example creates an i386 ELF that just does execve(‘/bin/sh’,...).

>>> context.clear()
>>> context.arch = 'i386'
>>> context.bits = 32
>>> filename = tempfile.mktemp()
>>> bin_sh = '6a68682f2f2f73682f62696e89e331c96a0b5899cd80'.decode('hex')
>>> data = make_elf(bin_sh)
>>> with open(filename,'wb+') as f:
...     f.write(data)
...     f.flush()
>>> os.chmod(filename,0777)
>>> p = process(filename)
>>> p.sendline('echo Hello; exit')
>>> p.recvline()
'Hello\n'
pwnlib.asm.make_elf_from_assembly(*a, **kw)[source]

Builds an ELF file with the specified assembly as its executable code.

Parameters:
  • assembly (str) – Assembly
  • vma (int) – Load address of the binary
  • extract (bool) – Whether to return the data extracted from the file created, or the path to it.
Returns:

The path to the assembled ELF (extract=False), or the data of the assembled ELF.

Example

>>> context.clear()
>>> context.arch = 'amd64'
>>> sc = 'push rbp; mov rbp, rsp;'
>>> sc += shellcraft.echo('Hello\n')
>>> sc += 'mov rsp, rbp; pop rbp; ret'
>>> solib = make_elf_from_assembly(sc, shared=1)
>>> subprocess.check_output(['echo', 'World'], env={'LD_PRELOAD': solib})
'Hello\nWorld\n'