8000 Refactor unicornlib to use pybind11 by twizmwazin · Pull Request #5516 · angr/angr · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

Refactor unicornlib to use pybind11 #5516

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 13 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
174 changes: 4 additions & 170 deletions angr/state_plugins/unicorn_engine.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
import binascii
import copy
import ctypes
import importlib.resources
import importlib
import itertools
import logging
import sys
Expand Down Expand Up @@ -242,7 +242,7 @@ class StopDetails(ctypes.Structure):
]


class SimOSEnum:
class SimOSEnum(IntEnum):
"""
enum simos_t
"""
Expand Down Expand Up @@ -392,176 +392,10 @@ class _VexArchInfo(ctypes.Structure):
]


def _load_native():
if sys.platform == "darwin":
libfile = "unicornlib.dylib"
elif sys.platform in {"win32", "cygwin"}:
libfile = "unicornlib.dll"
else:
libfile = "unicornlib.so"

try:
angr_path = str(importlib.resources.files("angr") / libfile)
h = ctypes.CDLL(angr_path)

VexArch = ctypes.c_int
uc_err = ctypes.c_int
state_t = ctypes.c_void_p
stop_t = ctypes.c_int
uc_engine_t = ctypes.c_void_p

def _setup_prototype(handle, func, restype, *argtypes):
realname = "simunicorn_" + func
_setup_prototype_explicit(handle, realname, restype, *argtypes)
setattr(handle, func, getattr(handle, realname))

def _setup_prototype_explicit(handle, func, restype, *argtypes):
getattr(handle, func).restype = restype
getattr(handle, func).argtypes = argtypes

# _setup_prototype_explicit(h, 'logSetLogLevel', None, ctypes.c_uint64)
_setup_prototype(h, "setup_imports", ctypes.c_bool, ctypes.c_char_p)
_setup_prototype(
h,
"alloc",
state_t,
uc_engine_t,
ctypes.c_uint64,
ctypes.c_uint64,
ctypes.c_bool,
ctypes.c_bool,
ctypes.c_bool,
)
_setup_prototype(h, "dealloc", None, state_t)
_setup_prototype(h, "hook", None, state_t)
_setup_prototype(h, "unhook", None, state_t)
_setup_prototype(h, "start", uc_err, state_t, ctypes.c_uint64, ctypes.c_uint64)
_setup_prototype(h, "stop", None, state_t, stop_t)
_setup_prototype(h, "sync", ctypes.POINTER(MEM_PATCH), state_t)
_setup_prototype(h, "bbl_addrs", ctypes.POINTER(ctypes.c_uint64), state_t)
_setup_prototype(h, "stack_pointers", ctypes.POINTER(ctypes.c_uint64), state_t)
_setup_prototype(h, "bbl_addr_count", ctypes.c_uint64, state_t)
_setup_prototype(h, "syscall_count", ctypes.c_uint64, state_t)
_setup_prototype(h, "step", ctypes.c_uint64, state_t)
_setup_prototype(h, "activate_page", None, state_t, ctypes.c_uint64, ctypes.c_void_p, ctypes.c_void_p)
_setup_prototype(h, "set_last_block_details", None, state_t, ctypes.c_uint64, ctypes.c_int64, ctypes.c_int64)
_setup_prototype(h, "set_stops", None, state_t, ctypes.c_uint64, ctypes.POINTER(ctypes.c_uint64))
_setup_prototype(
h, "cache_page", ctypes.c_bool, state_t, ctypes.c_uint64, ctypes.c_uint64, ctypes.c_char_p, ctypes.c_uint64
)
_setup_prototype(h, "uncache_pages_touching_region", None, state_t, ctypes.c_uint64, ctypes.c_uint64)
_setup_prototype(h, "clear_page_cache", None, state_t)
_setup_prototype(h, "enable_symbolic_reg_tracking", None, state_t, VexArch, _VexArchInfo)
_setup_prototype(h, "disable_symbolic_reg_tracking", None, state_t)
_setup_prototype(h, "symbolic_register_data", None, state_t, ctypes.c_uint64, ctypes.POINTER(ctypes.c_uint64))
_setup_prototype(h, "get_symbolic_registers", ctypes.c_uint64, state_t, ctypes.POINTER(ctypes.c_uint64))
_setup_prototype(h, "is_interrupt_handled", ctypes.c_bool, state_t)
_setup_prototype(
h,
"set_cgc_syscall_details",
None,
state_t,
ctypes.c_uint32,
ctypes.c_uint64,
ctypes.c_uint32,
ctypes.c_uint64,
ctypes.c_uint64,
ctypes.c_uint32,
ctypes.c_uint64,
)
_setup_prototype(h, "process_transmit", ctypes.POINTER(TRANSMIT_RECORD), state_t, ctypes.c_uint32)
_setup_prototype(h, "set_tracking", None, state_t, ctypes.c_bool, ctypes.c_bool)
_setup_prototype(h, "executed_pages", ctypes.c_uint64, state_t)
_setup_prototype(h, "in_cache", ctypes.c_bool, state_t, ctypes.c_uint64)
if unicorn is not None:
_setup_prototype(h, "set_map_callback", None, state_t, unicorn.unicorn.UC_HOOK_MEM_INVALID_CB)
_setup_prototype(
h,
"set_vex_to_unicorn_reg_mappings",
None,
state_t,
ctypes.POINTER(ctypes.c_uint64),
ctypes.POINTER(ctypes.c_uint64),
ctypes.POINTER(ctypes.c_uint64),
ctypes.c_uint64,
)
_setup_prototype(h, "set_artificial_registers", None, state_t, ctypes.POINTER(ctypes.c_uint64), ctypes.c_uint64)
_setup_prototype(h, "get_count_of_blocks_with_symbolic_vex_stmts", ctypes.c_uint64, state_t)
_setup_prototype(
h, "get_details_of_blocks_with_symbolic_vex_stmts", None, state_t, ctypes.POINTER(BlockDetails)
)
_setup_prototype(h, "get_stop_details", StopDetails, state_t)
_setup_prototype(h, "set_register_blacklist", None, state_t, ctypes.POINTER(ctypes.c_uint64), ctypes.c_uint64)
_setup_prototype(
h,
"set_cpu_flags_details",
None,
state_t,
ctypes.POINTER(ctypes.c_uint64),
ctypes.POINTER(ctypes.c_uint64),
ctypes.POINTER(ctypes.c_uint64),
ctypes.c_uint64,
)
_setup_prototype(
h,
"set_fd_bytes",
state_t,
ctypes.c_uint64,
ctypes.c_void_p,
ctypes.c_void_p,
ctypes.c_uint64,
ctypes.c_uint64,
)
_setup_prototype(
h,
"set_random_syscall_data",
None,
state_t,
ctypes.POINTER(ctypes.c_uint64),
ctypes.POINTER(ctypes.c_uint64),
ctypes.c_uint64,
)
_setup_prototype(
h,
"set_vex_cc_reg_data",
None,
state_t,
ctypes.POINTER(ctypes.c_uint64),
ctypes.POINTER(ctypes.c_uint64),
ctypes.c_uint64,
)
_setup_prototype(h, "get_count_of_writes_to_reexecute", ctypes.c_uint64, state_t)
_setup_prototype(
h,
"get_concrete_writes_to_reexecute",
None,
state_t,
ctypes.POINTER(ctypes.c_uint64),
ctypes.POINTER(ctypes.c_uint8),
)
_setup_prototype(
h,
"set_fp_regs_fp_ops_vex_codes",
None,
state_t,
ctypes.c_uint64,
ctypes.c_uint64,
ctypes.POINTER(ctypes.c_uint64),
ctypes.c_uint32,
)

l.info("native plugin is enabled")

return h
except (OSError, AttributeError) as e:
l.error('failed loading "%s", unicorn support disabled (%s)', libfile, e)
raise ImportError("Unable to import native SimUnicorn support") from e


try:
_UC_NATIVE = _load_native()
# _UC_NATIVE.logSetLogLevel(2)
_UC_NATIVE = importlib.import_module("angr.unicornlib")
except ImportError:
print("Unable to import native unicorn support", file=sys.stderr)
_UC_NATIVE = None

if _uc is not None and _UC_NATIVE is not None and not _UC_NATIVE.setup_imports(_uc._name.encode()):
Expand Down
137 changes: 137 additions & 0 deletions angr/unicornlib.pyi
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
from collections.abc import Sequence
from enum import Enum

class State: ...

class SimOS(Enum):
CGC: int
LINUX: int
OTHER: int

class StopReason(Enum):
NORMAL: int
STOPPOINT: int
ERROR: int
SYSCALL: int
EXECNONE: int
ZEROPAGE: int
NOSTART: int
SEGFAULT: int
ZERO_DIV: int
NODECODE: int
HLT: int
VEX_LIFT_FAILED: int
SYMBOLIC_PC: int
SYMBOLIC_READ_ADDR: int
SYMBOLIC_READ_SYMBOLIC_TRACKING_DISABLED: int
SYMBOLIC_WRITE_ADDR: int
SYMBOLIC_BLOCK_EXIT_CONDITION: int
SYMBOLIC_BLOCK_EXIT_TARGET: int
UNSUPPORTED_STMT_PUTI: int
UNSUPPORTED_STMT_STOREG: int
UNSUPPORTED_STMT_LOADG: int
UNSUPPORTED_STMT_CAS: int
UNSUPPORTED_STMT_LLSC: int
UNSUPPORTED_STMT_DIRTY: int
UNSUPPORTED_STMT_UNKNOWN: int
UNSUPPORTED_EXPR_GETI: int
UNSUPPORTED_EXPR_UNKNOWN: int
UNKNOWN_MEMORY_WRITE_SIZE: int
SYSCALL_ARM: int
X86_CPUID: int

class StopDetails:
stop_reason: int
block_addr: int
block_size: int

class RegisterValue:
offset: int
# value: bytes # Not exposed due to pybind11 limitation
size: int

class SymVexStmtDetails:
stmt_idx: int
has_memory_dep: bool
memory_values: object # pointer/array, not directly exposed
memory_values_count: int

class SymBlockDetailsRet:
block_addr: int
block_size: int
block_trace_ind: int
has_symbolic_exit: bool
symbolic_stmts: object # pointer/array, not directly exposed
symbolic_stmts_count: int
register_values: object # pointer/array, not directly exposed
register_values_count: int

class TransmitRecord:
fd: int
data: object # pointer/array, not directly exposed
count: int

def alloc(
uc: object,
cache_key: int,
simos: object,
handle_symbolic_addrs: bool,
handle_symb_cond: bool,
handle_symb_syscalls: bool,
) -> State: ...
def dealloc(state: State) -> None: ...
def bbl_addrs(state: State) -> Sequence[int]: ...
def stack_pointers(state: State) -> Sequence[int]: ...
def bbl_addr_count(state: State) -> int: ...
def syscall_count(state: State) -> int: ...
def hook(state: State) -> None: ...
def unhook(state: State) -> None: ...
def start(state: State, pc: int, step: int) -> int: ...
def stop(state: State, reason: int) -> None: ...
def sync(state: State) -> object: ...
def step(state: State) -> int: ...
def set_last_block_details(state: State, block_addr: int, curr_count: int, total_count: int) -> None: ...
def set_random_syscall_data(state: State, values: Sequence[int], sizes: Sequence[int], count: int) -> None: ...
def set_stops(state: State, count: int, stops: Sequence[int]) -> None: ...
def activate_page(state: State, address: int, taint: bytes, data: bytes) -> None: ...
def executed_pages(state: State) -> int: ...
def get_stop_details(state: State) -> object: ...
def symbolic_register_data(state: State, count: int, offsets: Sequence[int]) -> None: ...
def get_symbolic_registers(state: State, output: Sequence[int]) -> int: ...
def enable_symbolic_reg_tracking(state: State, guest: int, archinfo: int) -> None: ...
def disable_symbolic_reg_tracking(state: State) -> None: ...
def is_interrupt_handled(state: State) -> bool: ...
def set_cgc_syscall_details(
state: State,
transmit_num: int,
transmit_bbl: int,
receive_num: int,
receive_bbl: int,
receive_size: int,
random_num: int,
random_bbl: int,
) -> None: ...
def process_transmit(state: State, num: int) -> object: ...
def set_fd_bytes(state: State, fd: int, input: bytes, taints: bytes, len: int, read_pos: int) -> None: ...
def cache_page(state: State, address: int, length: int, bytes: bytes, permissions: int) -> bool: ...
def uncache_pages_touching_region(state: State, address: int, length: int) -> None: ...
def clear_page_cache(state: State) -> None: ...
def set_tracking(state: State, track_bbls: bool, track_stack: bool) -> None: ...
def in_cache(state: State, address: int) -> bool: ...
def set_map_callback(state: State, cb: object) -> None: ...
def set_artificial_registers(state: State, offsets: Sequence[int], count: int) -> None: ...
def set_vex_to_unicorn_reg_mappings(
state: State, vex_offsets: Sequence[int], unicorn_ids: Sequence[int], reg_sizes: Sequence[int], count: int
) -> None: ...
def set_cpu_flags_details(
state: State, flag_vex_id: Sequence[int], uc_reg_id: Sequence[int], bitmasks: Sequence[int], count: int
) -> None: ...
def set_register_blacklist(state: State, reg_list: Sequence[int], count: int) -> None: ...
def set_vex_cc_reg_data(state: State, reg_offsets: Sequence[int], reg_sizes: Sequence[int], count: int) -> None: ...
def get_count_of_blocks_with_symbolic_vex_stmts(state: State) -> int: ...
def get_details_of_blocks_with_symbolic_vex_stmts(state: State, ret_block_details: object) -> None: ...
def get_count_of_writes_to_reexecute(state: State) -> int: ...
def get_concrete_writes_to_reexecute(state: State, addrs: Sequence[int], values: bytes) -> None: ...
def set_fp_regs_fp_ops_vex_codes(
state: State, start_offset: int, size: int, ops: Sequence[int], op_count: int
) -> None: ...
48 changes: 0 additions & 48 deletions native/unicornlib/Makefile

This file was deleted.

8 changes: 0 additions & 8 deletions native/unicornlib/Makefile-win

This file was deleted.

Loading
Loading
0