0day_dev/pwntools-tutorial/assembly.md
2020-08-07 21:19:09 -07:00

176 lines
4.1 KiB
Markdown

Table of Contents
=================
* [Assembly](#assembly)
* [Basic Assembly](#basic-assembly)
* [Canned assembly (shellcraft)](#canned-assembly-shellcraft)
* [Command-line Tools](#command-line-tools)
* [asm ](#asm)
* [disasm ](#disasm)
* [shellcraft ](#shellcraft)
* [Foreign Architectures](#foreign-architectures)
* [Canned Assembly](#canned-assembly)
* [Command-line Tools](#command-line-tools-1)
# Assembly
Pwntools makes it very easy to perform assembly in almost any architecture, and comes with a wide variety of canned-but-customizable shellcode ready to go out-of-the-box.
In the [`walkthrough`](walkthrough) directory, there are several longer shellcode tutorials. This page gives you the basics.
## Basic Assembly
The most basic example, is to convert assembly into shellcode.
```py
from pwn import *
print repr(asm('xor edi, edi'))
# '1\xff'
print enhex(asm('xor edi, edi'))
# 31ff
```
## Canned assembly (`shellcraft`)
The `shellcraft` module gives you pre-canned assembly. It is generally customizable. The easiest way to find out which `shellcraft` templates exist is to look at the [documentation on RTD](https://pwntools.readthedocs.org/en/latest/shellcraft.html).
```py
from pwn import *
help(shellcraft.sh)
print '---'
print shellcraft.sh()
print '---'
print enhex(asm(shellcraft.sh()))
```
```
Help on function sh in module pwnlib.shellcraft.internal:
sh()
Execute /bin/sh
---
/* push '/bin///sh\x00' */
push 0x68
push 0x732f2f2f
push 0x6e69622f
/* call execve('esp', 0, 0) */
push (SYS_execve) /* 0xb */
pop eax
mov ebx, esp
xor ecx, ecx
cdq /* edx=0 */
int 0x80
---
6a68682f2f2f73682f62696e6a0b5889e331c999cd80
```
## Command-line Tools
There are three command-line tools for interacting with assembly:
- `asm`
- `disasm`
- `shellcraft`
### `asm`
The asm tool does what it says on the tin. It provides several options for formatting the output. When the output is a terminal, it defaults to hex-encoded.
```
$ asm nop
90
```
When the output is anything else, it writes the raw data.
```
$ asm nop | xxd
0000000: 90 .
```
It also takes data on stdin if no instructions are provided on the command line.
```
$ echo 'push ebx; pop edi' | asm
535f
```
Finally, it supports a few different options for specifying the output format, via the `--format` option. Supported arguments are `raw`, `hex`, `string`, and `elf`.
```
$ asm --format=elf 'int3' > ./int3
$ ./halt
Trace/breakpoint trap (core dumped)
```
### `disasm`
Disasm is the opposite of `asm`.
```
$ disasm cd80
0: cd 80 int 0x80
$ asm nop | disasm
0: 90 nop
```
### `shellcraft`
The `shellcraft` command is the command-line interface to the internal `shellcraft` module. On the command-line, the full context must be specified, in the order of `arch.os.template`.
```
$ shellcraft i386.linux.sh
6a68682f2f2f73682f62696e6a0b5889e331c999cd80
```
## Foreign Architectures
Assembling for a foreign architecture requires that you have an appropriate version of `binutils` installed. You should see [installing.md](installing.md) for more information on this. The only change that is necessary is to set the architecture in the global context variable. You can see more information about `context` in [context.md](context.md).
```py
from pwn import *
context.arch = 'arm'
print repr(asm('mov r0, r1'))
# '\x01\x00\xa0\xe1'
print enhex(asm('mov r0, r1'))
# 0100a0e1
```
### Canned Assembly
The `shellcraft` module automatically switches to the appropriate architecture.
```py
from pwn import *
context.arch = 'arm'
print shellcraft.sh()
print enhex(asm(shellcraft.sh()))
```
```
adr r0, bin_sh
mov r2, #0
mov r1, r2
svc SYS_execve
bin_sh: .asciz "/bin/sh"
08008fe20020a0e30210a0e10b0000ef2f62696e2f736800
```
### Command-line Tools
You can also use the command line to assemble foreign-arch shellcode, by using the `--context` command-line option.
```
$ asm --context=arm 'mov r0, r1'
0100a0e1
$ shellcraft arm.linux.sh
08008fe20020a0e30210a0e10b0000ef2f62696e2f736800
```