Port binja integration to aglib (#2676)

* port binja integration to aglib

* rem import
pull/2681/head 2025.01.20
patryk4815 11 months ago committed by GitHub
parent 4b70da5a64
commit ef9a40317f
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -706,7 +706,7 @@ def load_commands() -> None:
if pwndbg.dbg.is_gdblib_available(): if pwndbg.dbg.is_gdblib_available():
import pwndbg.commands.ai import pwndbg.commands.ai
import pwndbg.commands.attachp import pwndbg.commands.attachp
import pwndbg.commands.binja import pwndbg.commands.binja_functions
import pwndbg.commands.branch import pwndbg.commands.branch
import pwndbg.commands.cymbol import pwndbg.commands.cymbol
import pwndbg.commands.got import pwndbg.commands.got
@ -728,6 +728,7 @@ def load_commands() -> None:
import pwndbg.commands.asm import pwndbg.commands.asm
import pwndbg.commands.auxv import pwndbg.commands.auxv
import pwndbg.commands.binder import pwndbg.commands.binder
import pwndbg.commands.binja
import pwndbg.commands.canary import pwndbg.commands.canary
import pwndbg.commands.checksec import pwndbg.commands.checksec
import pwndbg.commands.comments import pwndbg.commands.comments

@ -1,15 +1,8 @@
from __future__ import annotations from __future__ import annotations
from typing import Tuple
import gdb
import pwndbg.aglib.proc
import pwndbg.aglib.regs import pwndbg.aglib.regs
import pwndbg.commands import pwndbg.commands
import pwndbg.gdblib.functions
import pwndbg.integration.binja import pwndbg.integration.binja
from pwndbg.color import message
from pwndbg.commands import CommandCategory from pwndbg.commands import CommandCategory
@ -25,49 +18,3 @@ def bn_sync(*args) -> None:
Synchronize Binary Ninja's cursor with GDB Synchronize Binary Ninja's cursor with GDB
""" """
pwndbg.integration.binja.navigate_to(pwndbg.aglib.regs.pc) pwndbg.integration.binja.navigate_to(pwndbg.aglib.regs.pc)
@pwndbg.gdblib.functions.GdbFunction()
@pwndbg.integration.binja.with_bn()
def bn_sym(name_val: gdb.Value) -> int | None:
"""Lookup a symbol's address by name from Binary Ninja."""
name = name_val.string()
addr: int | None = pwndbg.integration.binja._bn.get_symbol_addr(name)
if addr is None:
return None
return pwndbg.integration.binja.r2l(addr)
@pwndbg.gdblib.functions.GdbFunction()
@pwndbg.integration.binja.with_bn()
def bn_var(name_val: gdb.Value) -> int | None:
"""Lookup a stack variable's address by name from Binary Ninja."""
name = name_val.string()
conf_and_offset: Tuple[int, int] | None = pwndbg.integration.binja._bn.get_var_offset_from_sp(
pwndbg.integration.binja.l2r(pwndbg.aglib.regs.pc), name
)
if conf_and_offset is None:
return None
(conf, offset) = conf_and_offset
if conf < 64:
print(message.warn(f"Warning: Stack offset only has {conf / 255 * 100:.2f}% confidence"))
return pwndbg.aglib.regs.sp + offset
@pwndbg.gdblib.functions.GdbFunction()
@pwndbg.integration.binja.with_bn()
def bn_eval(expr: gdb.Value) -> int | None:
"""Parse and evaluate a Binary Ninja expression.
Docs: https://api.binary.ninja/binaryninja.binaryview-module.html#binaryninja.binaryview.BinaryView.parse_expression
Adds all registers in the current register set as magic variables (e.g. $rip).
Also adds a $piebase magic variable with the computed executable base."""
magic_vars = {}
for r in pwndbg.aglib.regs.current:
v = pwndbg.aglib.regs[r]
if v is not None:
magic_vars[r] = v
magic_vars["piebase"] = pwndbg.aglib.proc.binary_base_addr
ret: int | None = pwndbg.integration.binja._bn.parse_expr(expr.string(), magic_vars)
return ret

@ -0,0 +1,58 @@
from __future__ import annotations
from typing import Tuple
import gdb
import pwndbg.aglib.proc
import pwndbg.aglib.regs
import pwndbg.commands
import pwndbg.gdblib.functions
import pwndbg.integration.binja
from pwndbg.color import message
@pwndbg.gdblib.functions.GdbFunction()
@pwndbg.integration.binja.with_bn()
def bn_sym(name_val: gdb.Value) -> int | None:
"""Lookup a symbol's address by name from Binary Ninja."""
name = name_val.string()
addr: int | None = pwndbg.integration.binja._bn.get_symbol_addr(name)
if addr is None:
return None
return pwndbg.integration.binja.r2l(addr)
@pwndbg.gdblib.functions.GdbFunction()
@pwndbg.integration.binja.with_bn()
def bn_var(name_val: gdb.Value) -> int | None:
"""Lookup a stack variable's address by name from Binary Ninja."""
name = name_val.string()
conf_and_offset: Tuple[int, int] | None = pwndbg.integration.binja._bn.get_var_offset_from_sp(
pwndbg.integration.binja.l2r(pwndbg.aglib.regs.pc), name
)
if conf_and_offset is None:
return None
(conf, offset) = conf_and_offset
if conf < 64:
print(message.warn(f"Warning: Stack offset only has {conf / 255 * 100:.2f}% confidence"))
return pwndbg.aglib.regs.sp + offset
@pwndbg.gdblib.functions.GdbFunction()
@pwndbg.integration.binja.with_bn()
def bn_eval(expr: gdb.Value) -> int | None:
"""Parse and evaluate a Binary Ninja expression.
Docs: https://api.binary.ninja/binaryninja.binaryview-module.html#binaryninja.binaryview.BinaryView.parse_expression
Adds all registers in the current register set as magic variables (e.g. $rip).
Also adds a $piebase magic variable with the computed executable base."""
magic_vars = {}
for r in pwndbg.aglib.regs.current:
v = pwndbg.aglib.regs[r]
if v is not None:
magic_vars[r] = v
magic_vars["piebase"] = pwndbg.aglib.proc.binary_base_addr
ret: int | None = pwndbg.integration.binja._bn.parse_expr(expr.string(), magic_vars)
return ret

@ -4,12 +4,7 @@ import argparse
import pwndbg.aglib.regs import pwndbg.aglib.regs
import pwndbg.commands import pwndbg.commands
import pwndbg.dbg
import pwndbg.integration import pwndbg.integration
if pwndbg.dbg.is_gdblib_available():
import pwndbg.integration.binja
from pwndbg.commands import CommandCategory from pwndbg.commands import CommandCategory
parser = argparse.ArgumentParser( parser = argparse.ArgumentParser(

@ -20,7 +20,6 @@ from typing import List
from typing import Tuple from typing import Tuple
from typing import TypeVar from typing import TypeVar
import gdb
import pygments import pygments
import pygments.formatters import pygments.formatters
import pygments.style import pygments.style
@ -43,7 +42,9 @@ from pwndbg.aglib.nearpc import c as nearpc_color
from pwndbg.aglib.nearpc import ljust_padding from pwndbg.aglib.nearpc import ljust_padding
from pwndbg.color import message from pwndbg.color import message
from pwndbg.color import theme from pwndbg.color import theme
from pwndbg.dbg import BreakpointLocation
from pwndbg.dbg import EventType from pwndbg.dbg import EventType
from pwndbg.dbg import StopPoint
from pwndbg.lib.functions import Argument from pwndbg.lib.functions import Argument
from pwndbg.lib.functions import Function from pwndbg.lib.functions import Function
@ -219,7 +220,7 @@ def auto_update_pc() -> None:
_bn.update_pc_tag(l2r(pc)) _bn.update_pc_tag(l2r(pc))
_managed_bps: Dict[int, gdb.Breakpoint] = {} _managed_bps: Dict[int, StopPoint] = {}
@pwndbg.dbg.event_handler(EventType.START) @pwndbg.dbg.event_handler(EventType.START)
@ -232,9 +233,12 @@ def auto_update_bp() -> None:
bps: List[int] = _bn.get_bp_tags() bps: List[int] = _bn.get_bp_tags()
binja_bps = {r2l(addr) for addr in bps} binja_bps = {r2l(addr) for addr in bps}
for k in _managed_bps.keys() - binja_bps: for k in _managed_bps.keys() - binja_bps:
_managed_bps.pop(k).delete() bp = _managed_bps.pop(k)
bp.remove()
inf = pwndbg.dbg.selected_inferior()
for k in binja_bps - _managed_bps.keys(): for k in binja_bps - _managed_bps.keys():
bp = gdb.Breakpoint("*" + hex(k)) bp = inf.break_at(BreakpointLocation(k))
_managed_bps[k] = bp _managed_bps[k] = bp
@ -527,7 +531,7 @@ class BinjaProvider(pwndbg.integration.IntegrationProvider):
newest = True newest = True
# try to find the oldest frame that's earlier than the address # try to find the oldest frame that's earlier than the address
while True: while True:
upper = gdb_frame_to_dbg(dbg_frame_to_gdb(cur).older()) upper = cur.parent()
if upper is None: if upper is None:
break break
@ -556,21 +560,3 @@ class BinjaProvider(pwndbg.integration.IntegrationProvider):
return f"{var}{suffix}" return f"{var}{suffix}"
else: else:
return f"{func}:{var}{suffix}" return f"{func}:{var}{suffix}"
def dbg_frame_to_gdb(d: pwndbg.dbg_mod.Frame) -> gdb.Frame:
# TODO: fix later to aglib
from pwndbg.dbg.gdb import GDBFrame
assert isinstance(d, GDBFrame)
return d.inner
def gdb_frame_to_dbg(d: gdb.Frame | None) -> pwndbg.dbg_mod.Frame | None:
# TODO: fix later to aglib
from pwndbg.dbg.gdb import GDBFrame
if d is None:
return None
return GDBFrame(d)

Loading…
Cancel
Save