Added a workaround to correctly handle broken registers in unicorn (#2587)

* Added a workaround to correctly handle broken registers in unicorn

* Disable emulate when unicorn report error

* Refactor: disable emulate when error
pull/2589/head
patryk4815 1 year ago committed by GitHub
parent ccb2fadce4
commit 1980aba40d
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -14,7 +14,9 @@ from typing import Dict
from typing import List
from typing import Optional
from typing import Tuple
from typing import TypeVar
import unicorn as U
from typing_extensions import ParamSpec
import pwndbg
@ -48,6 +50,7 @@ if pwndbg.dbg.is_gdblib_available():
log = logging.getLogger(__name__)
T = TypeVar("T")
P = ParamSpec("P")
theme.add_param("backtrace-prefix", "", "prefix for current backtrace label")
@ -853,6 +856,20 @@ disasm_lines = pwndbg.config.add_param(
)
def try_emulate_if_bug_disable(handler: Callable[[], T]) -> T:
try:
return handler()
except U.UcError as e:
print(
message.warn(
f"Warning: Emulation context disabled due to a Unicorn error: \n{str(e)}\n"
"If you want to enable it again, use `set emulate on`."
)
)
pwndbg.config.emulate.value = "off"
return handler()
@serve_context_history
def context_disasm(target=sys.stdout, with_banner=True, width=None):
flavor = pwndbg.dbg.x86_disassembly_flavor()
@ -865,10 +882,12 @@ def context_disasm(target=sys.stdout, with_banner=True, width=None):
if cs is not None and cs.syntax != syntax:
pwndbg.lib.cache.clear_caches()
result = pwndbg.aglib.nearpc.nearpc(
lines=disasm_lines // 2,
emulate=bool(not pwndbg.config.emulate == "off"),
use_cache=True,
result = try_emulate_if_bug_disable(
lambda: pwndbg.aglib.nearpc.nearpc(
lines=disasm_lines // 2,
emulate=bool(not pwndbg.config.emulate == "off"),
use_cache=True,
)
)
# Note: we must fetch emulate value again after disasm since

@ -286,6 +286,16 @@ class Emulator:
reg = self.get_reg_enum(name)
if reg:
if self.arch == "aarch64":
# Workaround for an issue from upstream: https://github.com/pwndbg/pwndbg/issues/2548
# Remove this after upgrading to unicorn > 2.1.1
if reg == U.arm64_const.UC_ARM64_REG_WSP:
return self.uc.reg_read(U.arm64_const.UC_ARM64_REG_SP) & 0xFFFFFFFF
elif reg == U.arm64_const.UC_ARM64_REG_XZR:
return 0
elif reg == U.arm64_const.UC_ARM64_REG_WZR:
return 0
return self.uc.reg_read(reg)
return None

Loading…
Cancel
Save