Declaratively defined shellcode¶
When using the declarative method, you create an instance of the shellcode environment which you then order to translate a list of high level operations.
There are two kinds of operations available:
SyscallInvoke
: Invoke a system call. You don’t generally create your own instances directly. Each environment provides access to any available system calls as members which you call instead.LoadRegister
: Load a register with a given value (which can be a literal value, the memory address of a piece of data or a buffer or the result of a system call).
- Examples:
The following example creates an instance of the LinuxX86 environment and assembles a piece of shellcode that just calls the exit system call.
>>> from pwny import * >>> env = sc.LinuxX86() >>> env.assemble([ ... env.sys_exit(0) ... ]) '1\xdb\xb8\x01\x00\x00\x00\xcd\x80'
To demonstrate how registers loading works, here’s an example that does the same thing but in a different way:
>>> from pwny import * >>> env = sc.LinuxX86() >>> env.assemble([ ... sc.LoadRegister(env.EAX, 0), ... env.sys_exit(env.EAX) ... ]) '1\xc0\x89\xc3\xb8\x01\x00\x00\x00\xcd\x80'
You can also use strings or bytes. If you use a unicode string, it will be UTF-8 encoded and zero-terminated. Bytes are allocated verbatim.
>>> from pwny import * >>> env = sc.LinuxX86() >>> env.assemble([ ... env.sys_write(1, u'hello', 5), ... env.sys_exit(), ... ]) '\xe8\x00\x00\x00\x00]\x83\xc5 \xba\x05\x00\x00\x00\x89\xe9\xbb\x01\x00\x00\x00\xb8\x04\x00\x00\x00\xcd\x801\xdb\xb8\x01\x00\x00\x00\xcd\x80hello\x00'
Or use lists as syscall arguments.
>>> from pwny import * >>> env = sc.LinuxX86() >>> env.assemble([ ... env.sys_execve(u'/bin/sh', [u'/bin/sh', None], None) ... ]) '\xe8\x00\x00\x00\x00]\x83\xc5\x151\xd21\xc0PU\x89\xe1\x89\xeb\xb8\x0b\x00\x00\x00\xcd\x80/bin/sh\x00'
Need a buffer to write something to? We’ve got you covered.
>>> from pwny import * >>> env = sc.LinuxX86() >>> buf = env.alloc_buffer(64) >>> env.assemble([ ... env.sys_read(0, buf, buf.length), ... env.sys_write(1, buf, buf.length), ... env.sys_exit(0) ... ]) '\xba@\x00\x00\x00\x89\xe91\xdb\xb8\x03\x00\x00\x00\xcd\x80\xba@\x00\x00\x00\x89\xe9\xbb\x01\x00\x00\x00\xb8\x04\x00\x00\x00\xcd\x801\xdb\xb8\x01\x00\x00\x00\xcd\x80'