pwnlib.shellcraft.arm — 为 ARM 架构设计的 shellcode

pwnlib.shellcraft.arm

Shellcraft module containing generic ARM little endian shellcodes.

pwnlib.shellcraft.arm.crash()[源代码]

Crash.

Example

>>> run_assembly(shellcraft.crash()).poll(True)
-11
pwnlib.shellcraft.arm.infloop()[源代码]

An infinite loop.

pwnlib.shellcraft.arm.itoa(v, buffer='sp', allocate_stack=True)[源代码]

Converts an integer into its string representation, and pushes it onto the stack. Uses registers r0-r5.

参数:
  • v (str, int) – Integer constant or register that contains the value to convert.
  • alloca

Example

>>> sc = shellcraft.arm.mov('r0', 0xdeadbeef)
>>> sc += shellcraft.arm.itoa('r0')
>>> sc += shellcraft.arm.linux.write(1, 'sp', 32)
>>> run_assembly(sc).recvuntil('\x00')
'3735928559\x00'
pwnlib.shellcraft.arm.memcpy(dest, src, n)[源代码]

Copies memory.

参数:
  • dest – Destination address
  • src – Source address
  • n – Number of bytes
pwnlib.shellcraft.arm.mov(dst, src)[源代码]

Move src into dest.

Support for automatically avoiding newline and null bytes has to be done.

If src is a string that is not a register, then it will locally set context.arch to ‘arm’ 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.

Examples

>>> print shellcraft.arm.mov('r0','r1').rstrip()
    mov  r0, r1
>>> print shellcraft.arm.mov('r0', 5).rstrip()
    mov  r0, #5
>>> print shellcraft.arm.mov('r0', 0x34532).rstrip()
    movw r0, #0x34532 & 0xffff
    movt r0, #0x34532 >> 16
>>> print shellcraft.arm.mov('r0', 0x101).rstrip()
    movw r0, #0x101
>>> print shellcraft.arm.mov('r0', 0xff << 14).rstrip()
    mov  r0, #0x3fc000
>>> print shellcraft.arm.mov('r0', 0xff << 15).rstrip()
    movw r0, #0x7f8000 & 0xffff
    movt r0, #0x7f8000 >> 16
>>> print shellcraft.arm.mov('r0', 0xf00d0000).rstrip()
    eor  r0, r0
    movt r0, #0xf00d0000 >> 16
>>> print shellcraft.arm.mov('r0', 0xffff00ff).rstrip()
    mvn  r0, #(0xffff00ff ^ (-1))
>>> print shellcraft.arm.mov('r0', 0x1fffffff).rstrip()
    mvn  r0, #(0x1fffffff ^ (-1))
参数:
  • dest (str) – ke destination register.
  • src (str) – Either the input register, or an immediate value.
pwnlib.shellcraft.arm.nop()[源代码]

A nop instruction.

pwnlib.shellcraft.arm.push(word, register='r12')[源代码]

Pushes a 32-bit integer onto the stack. Uses r12 as a temporary register.

r12 is defined as the inter-procedural scartch register ($ip), so this should not interfere with most usage.

参数:
  • word (int, str) – The word to push
  • tmpreg (str) – Register to use as a temporary register. R7 is used by default.
pwnlib.shellcraft.arm.pushstr(string, append_null=True, register='r7')[源代码]

Pushes a string onto the stack.

参数:
  • string (str) – The string to push.
  • append_null (bool) – Whether to append a single NULL-byte before pushing.
  • register (str) – Temporary register to use. By default, R7 is used.

Examples

>>> print shellcraft.arm.pushstr("Hello!").rstrip()
    /* push 'Hello!\x00A' */
    movw r7, #0x4100216f & 0xffff
    movt r7, #0x4100216f >> 16
    push {r7}
    movw r7, #0x6c6c6548 & 0xffff
    movt r7, #0x6c6c6548 >> 16
    push {r7}
pwnlib.shellcraft.arm.pushstr_array(reg, array)[源代码]

Pushes an array/envp-style array of pointers onto the stack.

参数:
  • 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.arm.ret(return_value=None)[源代码]

A single-byte RET instruction.

参数:return_value – Value to return

Examples

>>> with context.local(arch='arm'):
...     print enhex(asm(shellcraft.ret()))
...     print enhex(asm(shellcraft.ret(0)))
...     print enhex(asm(shellcraft.ret(0xdeadbeef)))
1eff2fe1
000020e01eff2fe1
ef0e0be3ad0e4de31eff2fe1
pwnlib.shellcraft.arm.setregs(reg_context, stack_allowed=True)[源代码]

Sets multiple registers, taking any register dependencies into account (i.e., given eax=1,ebx=eax, set ebx first).

参数:
  • reg_context (dict) – Desired register context
  • stack_allowed (bool) – Can the stack be used?

Example

>>> print shellcraft.setregs({'r0':1, 'r2':'r3'}).rstrip()
    mov  r0, #1
    mov  r2, r3
>>> print shellcraft.setregs({'r0':'r1', 'r1':'r0', 'r2':'r3'}).rstrip()
    mov  r2, r3
    eor  r0, r0, r1 /* xchg r0, r1 */
    eor  r1, r0, r1
    eor  r0, r0, r1
pwnlib.shellcraft.arm.to_thumb(reg=None, avoid=[])[源代码]

Go from ARM to THUMB mode.

pwnlib.shellcraft.arm.trap()[源代码]

A trap instruction.

pwnlib.shellcraft.arm.udiv_10(N)[源代码]

Divides r0 by 10. Result is stored in r0, N and Z flags are updated.

Code is from generated from here:
https://raw.githubusercontent.com/rofirrim/raspberry-pi-assembler/master/chapter15/magic.py
With code:
python magic.py 10 code_for_unsigned
pwnlib.shellcraft.arm.xor(key, address, count)[源代码]

XORs data a constant value.

参数:
  • key (int,str) – XOR key either as a 4-byte integer, If a string, length must be a power of two, and not longer than 4 bytes.
  • address (int) – Address of the data (e.g. 0xdead0000, ‘rsp’)
  • count (int) – Number of bytes to XOR.

Example

>>> sc  = shellcraft.read(0, 'sp', 32)
>>> sc += shellcraft.xor(0xdeadbeef, 'sp', 32)
>>> sc += shellcraft.write(1, 'sp', 32)
>>> io = run_assembly(sc)
>>> io.send(cyclic(32))
>>> result = io.recvn(32)
>>> expected = xor(cyclic(32), p32(0xdeadbeef))
>>> result == expected
True

pwnlib.shellcraft.arm.linux

Shellcraft module containing ARM shellcodes for Linux.

pwnlib.shellcraft.arm.linux.cacheflush()[源代码]

Invokes the cache-flush operation, without using any NULL or newline bytes.

Effectively is just:

mov r0, #0 mov r1, #-1 mov r2, #0 swi 0x9F0002

How this works:

… However, SWI generates a software interrupt and to the interrupt handler, 0x9F0002 is actually data and as a result will not be read via the instruction cache, so if we modify the argument to SWI in our self-modifyign code, the argument will be read correctly.
pwnlib.shellcraft.arm.linux.cat(filename, fd=1)[源代码]

Opens a file and writes its contents to the specified file descriptor.

Example

>>> f = tempfile.mktemp()
>>> write(f, 'FLAG\n')
>>> run_assembly(shellcraft.arm.linux.cat(f)).recvline()
'FLAG\n'
pwnlib.shellcraft.arm.linux.connect(host, port, network='ipv4')[源代码]

Connects to the host on the specified port. Network is either ‘ipv4’ or ‘ipv6’. Leaves the connected socket in R6.

pwnlib.shellcraft.arm.linux.dir(in_fd='r6', size=2048, allocate_stack=True)[源代码]

Reads to the stack from a directory.

参数:
  • in_fd (int/str) – File descriptor to be read from.
  • size (int) – Buffer size.
  • allocate_stack (bool) – allocate ‘size’ bytes on the stack.

You can optioanlly shave a few bytes not allocating the stack space.

The size read is left in eax.

pwnlib.shellcraft.arm.linux.echo(string, sock='1')[源代码]

Writes a string to a file descriptor

Example

>>> run_assembly(shellcraft.echo('hello\n', 1)).recvline()
'hello\n'
pwnlib.shellcraft.arm.linux.egghunter(egg, start_address = 0, double_check = True)[源代码]

Searches for an egg, which is either a four byte integer or a four byte string. The egg must appear twice in a row if double_check is True. When the egg has been found the egghunter branches to the address following it. If start_address has been specified search will start on the first address of the page that contains that address.

pwnlib.shellcraft.arm.linux.forkbomb()[源代码]

Performs a forkbomb attack.

pwnlib.shellcraft.arm.linux.forkexit()[源代码]

Attempts to fork. If the fork is successful, the parent exits.

pwnlib.shellcraft.arm.linux.killparent()[源代码]

Kills its parent process until whatever the parent is (probably init) cannot be killed any longer.

pwnlib.shellcraft.arm.linux.open_file(filepath, flags='O_RDONLY', mode=420)[源代码]

Opens a file. Leaves the file descriptor in r0.

参数:
  • filepath (str) – The file to open.
  • flags (int/str) – The flags to call open with.
  • mode (int/str) – The attribute to create the flag. Only matters of flags & O_CREAT is set.
pwnlib.shellcraft.arm.linux.sh()[源代码]

Execute a different process.

>>> p = run_assembly(shellcraft.arm.linux.sh())
>>> p.sendline('echo Hello')
>>> p.recv()
'Hello\n'
pwnlib.shellcraft.arm.linux.syscall(syscall=None, arg0=None, arg1=None, arg2=None, arg3=None, arg4=None, arg5=None, arg6=None)[源代码]
Args: [syscall_number, *args]
Does a syscall

Any of the arguments can be expressions to be evaluated by pwnlib.constants.eval().

Example

>>> print shellcraft.arm.linux.syscall(11, 1, 'sp', 2, 0).rstrip()
    /* call syscall(11, 1, 'sp', 2, 0) */
    mov  r0, #1
    mov  r1, sp
    mov  r2, #2
    eor  r3, r3 /* 0 (#0) */
    mov  r7, #0xb
    svc  0
>>> print shellcraft.arm.linux.syscall('SYS_exit', 0).rstrip()
    /* call exit(0) */
    eor  r0, r0 /* 0 (#0) */
    mov  r7, #SYS_exit /* 1 */
    svc  0
>>> print pwnlib.shellcraft.open('/home/pwn/flag').rstrip()
    /* open(file='/home/pwn/flag', oflag=0, mode=0) */
    /* push '/home/pwn/flag\x00A' */
    movw r7, #0x41006761 & 0xffff
    movt r7, #0x41006761 >> 16
    push {r7}
    movw r7, #0x6c662f6e & 0xffff
    movt r7, #0x6c662f6e >> 16
    push {r7}
    movw r7, #0x77702f65 & 0xffff
    movt r7, #0x77702f65 >> 16
    push {r7}
    movw r7, #0x6d6f682f & 0xffff
    movt r7, #0x6d6f682f >> 16
    push {r7}
    mov  r0, sp
    eor  r1, r1 /* 0 (#0) */
    eor  r2, r2 /* 0 (#0) */
    /* call open() */
    mov  r7, #SYS_open /* 5 */
    svc  0