Source code for pwnypack.shellcode.arm

from pwnypack.shellcode.base import BaseEnvironment
from pwnypack.shellcode.types import Register
from pwnypack.target import Target


__all__ = ['ARM']


[docs]class ARM(BaseEnvironment): """ Environment that targets a generic, unrestricted ARM architecture. """ target = None #: Target architecture, initialized in __init__. R0 = Register('r0') #: r0 register R1 = Register('r1') #: r1 register R2 = Register('r2') #: r2 register R3 = Register('r3') #: r3 register R4 = Register('r4') #: r4 register R5 = Register('r5') #: r5 register R6 = Register('r6') #: r6 register R7 = Register('r7') #: r7 register R8 = Register('r8') #: r8 register R9 = Register('r9') #: r9 register R10 = Register('r10') #: r10 register R11 = Register('r11') #: r11 register R12 = Register('r12') #: r12 register SP = Register('sp') #: sp register LR = Register('lr') #: lr register PC = Register('pc') #: pc register REGISTER_WIDTH_MAP = { 32: [R0, R1, R2, R3, R4, R5, R6, R7, R8, R9, R10, R11, R12, SP, LR, PC] } STACK_REG = SP OFFSET_REG = R6 TEMP_REG = {32: R7} PREAMBLE = [ '.global _start', '_start:', ] def __init__(self, endian=None, *args, **kwargs): self.target = Target(Target.Arch.arm, 32, endian) super(ARM, self).__init__(*args, **kwargs) def reg_push(self, reg): return ['push {%s}' % reg] def reg_pop(self, reg): return ['pop {%s}' % reg] def reg_add_imm(self, reg, value): if value < 256: return ['add %s, #%d' % (reg, value)] temp_reg = self.TEMP_REG[self.REGISTER_WIDTH[reg]] if reg is temp_reg: raise ValueError('Cannot perform large reg_add on temporary register') return ['ldr %s, =%d' % (temp_reg, value), 'add %s, %s' % (reg, temp_reg)] def reg_sub_imm(self, reg, value): if value < 256: return ['sub %s, #%d' % (reg, value)] temp_reg = self.TEMP_REG[self.REGISTER_WIDTH[reg]] if reg is temp_reg: raise ValueError('Cannot perform large reg_add on temporary register') return ['ldr %s, =%d' % (temp_reg, value), 'sub %s, %s' % (reg, temp_reg)] def reg_add_reg(self, reg1, reg2): return ['add %s, %s' % (reg1, reg2)] def reg_sub_reg(self, reg1, reg2): return ['sub %s, %s' % (reg1, reg2)] def reg_load_imm(self, reg, value): if -256 < value < 0: return ['mvn %s, #%d' % (reg, ~value)] elif not value: return ['eor %s, %s' % (reg, reg)] elif 0 < value < 256: return ['mov %s, #%d' % (reg, value)] else: return ['ldr %s, =%d' % (reg, value)] def reg_load_reg(self, dest_reg, src_reg): return ['mov %s, %s' % (dest_reg, src_reg)] def reg_load_offset(self, reg, value): return ['add %s, %s, #%d' % (reg, self.OFFSET_REG, value)] def jump_reg(self, reg): return ['bx %s' % reg]