pwnlib.shellcraft.riscv64 — Shellcode for RISCV64
pwnlib.shellcraft.riscv64
Shellcraft module containing generic RISCV64 shellcodes.
- pwnlib.shellcraft.riscv64.mov(dst, src)[source]
Move src into dst without newlines and null bytes.
Registers t4 and t6 are not guaranteed to be preserved.
If src is a string that is not a register, then it will locally set context.arch to ‘riscv64’ and use
pwnlib.constants.eval()to evaluate the string. Note that this means that this shellcode can change behavior depending on the value of context.os.- Parameters:
dst (str) – The destination register.
src (str) – Either the input register, or an immediate value.
Example
>>> print(shellcraft.riscv64.mov('t0', 0).rstrip()) c.li t0, 0 >>> print(shellcraft.riscv64.mov('t0', 0x2000).rstrip()) c.lui t0, 2 /* mv t0, 0x2000 */ >>> print(shellcraft.riscv64.mov('t5', 0x601).rstrip()) xori t5, zero, 0x601 >>> print(shellcraft.riscv64.mov('t5', 0x600).rstrip()) /* mv t5, 0x600 */ xori t5, zero, 0x1ff xori t5, t5, 0x7ff >>> print(shellcraft.riscv64.mov('t6', 0x181f).rstrip()) /* mv t6, 0x181f */ lui t6, 0xffffe xori t6, t6, 0xfffffffffffff81f >>> print(shellcraft.riscv64.mov('t5', 0x40b561f).rstrip()) /* mv t5, 0x40b561f */ lui t5, 0x40b5 xori t5, t5, 0x61f >>> print(shellcraft.riscv64.mov('t0', 0xcafebabe).rstrip()) li t0, 0xcafebabe >>> print(shellcraft.riscv64.mov('a0', 't2').rstrip()) c.mv a0, t2 >>> print(shellcraft.riscv64.mov('t1', 'sp').rstrip()) c.mv t6, sp c.mv t1, t6 /* mv t1, sp */
- pwnlib.shellcraft.riscv64.push(value)[source]
Pushes a value onto the stack.
Register t4 is not guaranteed to be preserved.
- pwnlib.shellcraft.riscv64.pushstr(string, append_null=True)[source]
Pushes a string onto the stack without using null bytes or newline characters.
Example
>>> print(shellcraft.riscv64.pushstr('').rstrip()) /* push b'\x00' */ sw zero, -8(sp) addi sp, sp, -8 >>> print(shellcraft.riscv64.pushstr('a').rstrip()) /* push b'a\x00' */ /* mv t4, 0x61 */ xori t4, zero, 0x79e xori t4, t4, 0x7ff sd t4, -8(sp) addi sp, sp, -8 >>> print(shellcraft.riscv64.pushstr('aa').rstrip()) /* push b'aa\x00' */ li t4, 0x6161 sd t4, -8(sp) addi sp, sp, -8 >>> print(shellcraft.riscv64.pushstr('aaaa').rstrip()) /* push b'aaaa\x00' */ /* mv t4, 0x61616161 */ lui t4, 0x61616 xori t4, t4, 0x161 sd t4, -8(sp) addi sp, sp, -8 >>> print(shellcraft.riscv64.pushstr('aaaaa').rstrip()) /* push b'aaaaa\x00' */ li t4, 0x6161616161 sd t4, -8(sp) addi sp, sp, -8 >>> print(shellcraft.riscv64.pushstr('aaaa', append_null = False).rstrip()) /* push b'aaaa' */ /* mv t4, 0x61616161 */ lui t4, 0x61616 xori t4, t4, 0x161 sd t4, -8(sp) addi sp, sp, -8 >>> print(shellcraft.riscv64.pushstr(b'\xc3').rstrip()) /* push b'\xc3\x00' */ /* mv t4, 0xc3 */ xori t4, zero, 0x73c xori t4, t4, 0x7ff sd t4, -8(sp) addi sp, sp, -8 >>> print(shellcraft.riscv64.pushstr(b'\xc3', append_null = False).rstrip()) /* push b'\xc3' */ /* mv t4, 0xc3 */ xori t4, zero, 0x73c xori t4, t4, 0x7ff sd t4, -8(sp) addi sp, sp, -8 >>> print(enhex(asm(shellcraft.riscv64.pushstr("/bin/sh")))) b79e39349b8e7e7bb20e938ebe34b60e938efe22233cd1ff6111 >>> print(enhex(asm(shellcraft.riscv64.pushstr("")))) 232c01fe6111 >>> print(enhex(asm(shellcraft.riscv64.pushstr("\x00", append_null = False)))) 232c01fe6111
- Parameters:
string (str) – The string to push.
append_null (bool) – Whether to append a single NULL-byte before pushing.
- pwnlib.shellcraft.riscv64.pushstr_array(reg, array)[source]
Pushes an array/envp-style array of pointers onto the stack.
- Parameters:
reg (str) – Destination register to hold the pointer.
array (str,list) – Single argument or list of arguments to push. NULL termination is normalized so that each argument ends with exactly one NULL byte.
- pwnlib.shellcraft.riscv64.setregs(reg_context, stack_allowed=True)[source]
Sets multiple registers, taking any register dependencies into account (i.e., given eax=1,ebx=eax, set ebx first).
- Parameters:
reg_context (dict) – Desired register context
stack_allowed (bool) – Can the stack be used?
Example
>>> print(shellcraft.setregs({'t0':1, 'a3':'0'}).rstrip()) c.li a3, 0 c.li t0, 1 >>> print(shellcraft.setregs({'a0':'a1', 'a1':'a0', 'a2':'a1'}).rstrip()) c.mv a2, a1 c.mv t4, a1 xor a1, a0, t4 /* xchg a1, a0 */ c.mv t4, a0 xor a0, a1, t4 c.mv t4, a1 xor a1, a0, t4
pwnlib.shellcraft.riscv64.linux
Shellcraft module containing RISCV64 shellcodes for Linux.
- pwnlib.shellcraft.riscv64.linux.syscall(syscall=None, arg0=None, arg1=None, arg2=None, arg3=None, arg4=None, arg5=None)[source]
- Args: [syscall_number, *args]
Does a syscall
Any of the arguments can be expressions to be evaluated by
pwnlib.constants.eval().Example
>>> print(pwnlib.shellcraft.riscv64.linux.syscall('SYS_execve', 1, 'sp', 2, 0).rstrip()) /* call execve(1, 'sp', 2, 0) */ c.li a0, 1 c.mv a1, sp c.li a2, 2 c.li a3, 0 /* mv a7, 0xdd */ xori a7, zero, 0x722 xori a7, a7, 0x7ff ecall >>> print(pwnlib.shellcraft.riscv64.linux.syscall('SYS_execve', 2, 1, 0, 20).rstrip()) /* call execve(2, 1, 0, 0x14) */ c.li a0, 2 c.li a1, 1 c.li a2, 0 c.li a3, 0x14 /* mv a7, 0xdd */ xori a7, zero, 0x722 xori a7, a7, 0x7ff ecall >>> print(pwnlib.shellcraft.riscv64.linux.syscall().rstrip()) /* call syscall() */ ecall >>> print(pwnlib.shellcraft.riscv64.linux.syscall('a7', 'a0', 'a1').rstrip()) /* call syscall('a7', 'a0', 'a1') */ /* setregs noop */ ecall >>> print(pwnlib.shellcraft.riscv64.linux.syscall('a3', None, None, 1).rstrip()) /* call syscall('a3', ?, ?, 1) */ c.li a2, 1 c.mv a7, a3 ecall >>> print(pwnlib.shellcraft.riscv64.linux.syscall( ... 'SYS_mmap', 0, 0x1000, ... 'PROT_READ | PROT_WRITE | PROT_EXEC', ... 'MAP_PRIVATE', ... -1, 0).rstrip()) /* call mmap(0, 0x1000, 'PROT_READ | PROT_WRITE | PROT_EXEC', 'MAP_PRIVATE', -1, 0) */ c.li a0, 0 c.lui a1, 1 /* mv a1, 0x1000 */ c.li a2, 7 c.li a3, 2 c.li a4, 0xffffffffffffffff c.li a5, 0 /* mv a7, 0xde */ xori a7, zero, 0x721 xori a7, a7, 0x7ff ecall >>> print(pwnlib.shellcraft.openat('AT_FDCWD', '/home/pwn/flag').rstrip()) /* openat(fd='AT_FDCWD', file='/home/pwn/flag', oflag=0) */ /* push b'/home/pwn/flag\x00' */ li t4, 0x77702f656d6f682f sd t4, -16(sp) li t4, 0x67616c662f6e sd t4, -8(sp) addi sp, sp, -16 c.mv a1, sp xori a0, zero, 0xffffffffffffff9c c.li a2, 0 /* call openat() */ /* mv a7, 0x38 */ xori a7, zero, 0x7c7 xori a7, a7, 0x7ff ecall