Skip to content

Commit

Permalink
Merge pull request #125 from angr/feat/aarch64
Browse files Browse the repository at this point in the history
Feat/aarch64
  • Loading branch information
Kyle-Kyle authored Jan 24, 2025
2 parents 0a412ca + bd0b233 commit 4f86ccf
Show file tree
Hide file tree
Showing 23 changed files with 1,525 additions and 728 deletions.
3 changes: 1 addition & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ Supported architectures:
* x86/x64
* ARM
* MIPS
* AARCH64

It should be relatively easy to support other architectures that are supported by `angr`.
If you'd like to use `angrop` on other architectures, please create an issue and we will look into it :)
Expand Down Expand Up @@ -138,8 +139,6 @@ Allow strings to be passed as arguments to func_call(), which are then written t

Add a function for open, read, write (for ctf's)

Allow using of angr objects such as BVV, BVS to make using symbolic values easy

The segment analysis for finding executable addresses seems to break on non-elf binaries often, such as PE files, kernel modules.

Allow setting constraints on the generated chain e.g. bytes that are valid.
Expand Down
25 changes: 22 additions & 3 deletions angrop/arch.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,9 @@ def __init__(self, project, kernel_mode=False):
self.kernel_mode = kernel_mode
self.max_sym_mem_access = 4
self.alignment = project.arch.instruction_alignment
self.max_block_size = self.alignment * 8
self.reg_set = self._get_reg_set()
self.max_block_size = None
self.fast_mode_max_block_size = None

a = project.arch
self.stack_pointer = a.register_names[a.sp_offset]
Expand All @@ -36,7 +37,8 @@ def block_make_sense(self, block):
class X86(ROPArch):
def __init__(self, project, kernel_mode=False):
super().__init__(project, kernel_mode=kernel_mode)
self.max_block_size = 20 # X86 and AMD64 have alignment of 1, 8 bytes is certainly not good enough
self.max_block_size = 20
self.fast_mode_max_block_size = 12
self.syscall_insts = {b"\xcd\x80"} # int 0x80
self.ret_insts = {b"\xc2", b"\xc3", b"\xca", b"\xcb"}
self.segment_regs = {"cs", "ds", "es", "fs", "gs", "ss"}
Expand Down Expand Up @@ -78,14 +80,20 @@ def __init__(self, project, kernel_mode=False):
super().__init__(project, kernel_mode=kernel_mode)
self.is_thumb = False # by default, we don't use thumb mode
self.alignment = self.project.arch.bytes
self.max_block_size = self.alignment * 8
self.fast_mode_max_block_size = self.alignment * 6

def set_thumb(self):
self.is_thumb = True
self.alignment = 2
self.max_block_size = self.alignment * 8
self.fast_mode_max_block_size = self.alignment * 6

def set_arm(self):
self.is_thumb = False
self.alignment = self.project.arch.bytes
self.max_block_size = self.alignment * 8
self.fast_mode_max_block_size = self.alignment * 6

def block_make_sense(self, block):
# disable conditional jumps, for now
Expand All @@ -94,11 +102,20 @@ def block_make_sense(self, block):
if insn.insn.mnemonic[-2:] in arm_conditional_postfix:
return False
return True


class AARCH64(ROPArch):
def __init__(self, project, kernel_mode=False):
super().__init__(project, kernel_mode=kernel_mode)
self.ret_insts = {b'\xc0\x03_\xd6'}
self.max_block_size = self.alignment * 10
self.fast_mode_max_block_size = self.alignment * 6

class MIPS(ROPArch):
def __init__(self, project, kernel_mode=False):
super().__init__(project, kernel_mode=kernel_mode)
self.alignment = self.project.arch.bytes
self.max_block_size = self.alignment * 8
self.fast_mode_max_block_size = self.alignment * 6

def get_arch(project, kernel_mode=False):
name = project.arch.name
Expand All @@ -109,6 +126,8 @@ def get_arch(project, kernel_mode=False):
return AMD64(project, kernel_mode=mode)
elif name.startswith('ARM'):
return ARM(project, kernel_mode=mode)
elif name == 'AARCH64':
return AARCH64(project, kernel_mode=mode)
elif name.startswith('MIPS'):
return MIPS(project, kernel_mode=mode)
else:
Expand Down
4 changes: 2 additions & 2 deletions angrop/chain_builder/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -135,13 +135,13 @@ def execve(self, path=None, path_addr=None):
return None
return self._sys_caller.execve(path=path, path_addr=path_addr)

def shift(self, length, preserve_regs=None):
def shift(self, length, preserve_regs=None, next_pc_idx=-1):
"""
build a rop chain to shift the stack to a specific value
:param length: the length of sp you want to shift
:param preserve_regs: set of registers to preserve, e.g. ('eax', 'ebx')
"""
return self._shifter.shift(length, preserve_regs=preserve_regs)
return self._shifter.shift(length, preserve_regs=preserve_regs, next_pc_idx=next_pc_idx)

def retsled(self, size, preserve_regs=None):
"""
Expand Down
Loading

0 comments on commit 4f86ccf

Please sign in to comment.