Skip to content
Merged
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
2 changes: 1 addition & 1 deletion CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,6 @@ When connected via `decompiler connect [host] [port]`:

## Dependencies

- Core: `sortedcontainers`, `pyelftools`, `libbs>=0.12.0`
- Core: `sortedcontainers`, `pyelftools`, `declib>=4.0.1`
- External tools (Linux native symbols): `gcc`, `objcopy`
- Environment: `NO_COLOR` env var disables terminal colors
8 changes: 4 additions & 4 deletions decomp2dbg/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,10 @@

def _run_server(binary_path: str, decompiler: str, host: str, port: int):
"""Start a headless decompiler server for the given binary."""
from libbs.api import DecompilerInterface
from libbs.decompilers import GHIDRA_DECOMPILER, IDA_DECOMPILER, BINJA_DECOMPILER, ANGR_DECOMPILER
from declib.api import DecompilerInterface
from declib.decompilers import GHIDRA_DECOMPILER, IDA_DECOMPILER, BINJA_DECOMPILER, ANGR_DECOMPILER

from decomp2dbg.server import LibBSDecompilerServer
from decomp2dbg.server import DecLibDecompilerServer

decompiler_map = {
"ghidra": GHIDRA_DECOMPILER,
Expand All @@ -33,7 +33,7 @@ def _run_server(binary_path: str, decompiler: str, host: str, port: int):
project_name="d2d_server",
)

server = LibBSDecompilerServer(deci=deci, host=host, port=port)
server = DecLibDecompilerServer(deci=deci, host=host, port=port)
try:
server.start_xmlrpc_server()
except KeyboardInterrupt:
Expand Down
8 changes: 4 additions & 4 deletions decomp2dbg/d2d_server.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,9 @@

def start_server(host: str = DEFAULT_HOST, port: int = DEFAULT_PORT):
"""Start the decomp2dbg XML-RPC server."""
from decomp2dbg.server import LibBSDecompilerServer
from decomp2dbg.server import DecLibDecompilerServer

server = LibBSDecompilerServer(host=host, port=port)
server = DecLibDecompilerServer(host=host, port=port)
t = threading.Thread(target=server.start_xmlrpc_server, daemon=True)
t.start()
print(f"[+] decomp2dbg server started on {host}:{port}")
Expand Down Expand Up @@ -52,7 +52,7 @@ def _ask_and_start_server(*args, deci=None, **kwargs):

def create_plugin(*args, open_dialog_immediately=False, **kwargs):
"""Plugin entry point for all decompilers."""
from libbs.api import DecompilerInterface
from declib.api import DecompilerInterface

deci = DecompilerInterface.discover(
plugin_name="decomp2dbg",
Expand All @@ -76,7 +76,7 @@ def create_plugin(*args, open_dialog_immediately=False, **kwargs):


# =============================================================================
# LibBS generic plugin loader
# DecLib generic plugin loader
# =============================================================================
try:
import idaapi
Expand Down
4 changes: 2 additions & 2 deletions decomp2dbg/installer.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@
import textwrap
from pathlib import Path

from libbs.plugin_installer import LibBSPluginInstaller, PluginInstaller
from declib.plugin_installer import DecLibPluginInstaller, PluginInstaller


class D2dInstaller(LibBSPluginInstaller):
class D2dInstaller(DecLibPluginInstaller):
def __init__(self):
super().__init__(targets=PluginInstaller.DECOMPILERS + PluginInstaller.DEBUGGERS)
pkg_files = self.find_pkg_files("decomp2dbg")
Expand Down
6 changes: 3 additions & 3 deletions decomp2dbg/server/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@
# Unified XML-RPC server for decompiler-debugger communication.
#

from decomp2dbg.server.server import LibBSDecompilerServer, DecompilationCache
from decomp2dbg.server.server import DecLibDecompilerServer, DecompilationCache

__all__ = ['LibBSDecompilerServer', 'DecompilationCache', 'start_server']
__all__ = ['DecLibDecompilerServer', 'DecompilationCache', 'start_server']


def start_server(host: str = "localhost", port: int = 3662):
Expand All @@ -22,7 +22,7 @@ def start_server(host: str = "localhost", port: int = 3662):
"""
import threading

server = LibBSDecompilerServer(host=host, port=port)
server = DecLibDecompilerServer(host=host, port=port)
t = threading.Thread(target=server.start_xmlrpc_server, daemon=True)
t.start()
print(f"[+] decomp2dbg server started on {host}:{port}")
Expand Down
20 changes: 10 additions & 10 deletions decomp2dbg/server/server.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,18 @@
# ██║ ██║██╔══╝ ██║ ██║ ██║██║╚██╔╝██║██╔═══╝ ██╔═══╝ ██║ ██║██╔══██╗██║ ██║
# ██████╔╝███████╗╚██████╗╚██████╔╝██║ ╚═╝ ██║██║ ███████╗██████╔╝██████╔╝╚██████╔╝
# ╚═════╝ ╚══════╝ ╚═════╝ ╚═════╝ ╚═╝ ╚═╝╚═╝ ╚══════╝╚═════╝ ╚═════╝ ╚═════╝
# Unified LibBS Server
# Unified DecLib Server
#
# A unified decompiler server using libbs DecompilerInterface.
# A unified decompiler server using declib DecompilerInterface.
# Works across IDA, Binary Ninja, Ghidra (via pyhidra), and angr.
#

from xmlrpc.server import SimpleXMLRPCServer, SimpleXMLRPCRequestHandler
from typing import Dict, Optional, Tuple, Set
import sys

from libbs.api import DecompilerInterface
from libbs.artifacts import (
from declib.api import DecompilerInterface
from declib.artifacts import (
FunctionHeader, StackVariable, Comment, GlobalVariable, Struct, Decompilation
)

Expand All @@ -29,7 +29,7 @@ class DecompilationCache:
"""
Cache decompilations with inverted line maps for O(1) address lookup.

The libbs line_map provides: line_num -> Set[addresses_on_that_line]
The declib line_map provides: line_num -> Set[addresses_on_that_line]
We invert this to: address -> (func_addr, line_num) for fast curr_line lookup.
"""

Expand Down Expand Up @@ -103,11 +103,11 @@ def invalidate_all(self):
self._structs = None


class LibBSDecompilerServer:
class DecLibDecompilerServer:
"""
XML-RPC server using libbs DecompilerInterface internally.
XML-RPC server using declib DecompilerInterface internally.

Provides the same API as the original d2d servers but uses libbs
Provides the same API as the original d2d servers but uses declib
for unified decompiler access across IDA, Binary Ninja, Ghidra, and angr.
"""

Expand All @@ -134,7 +134,7 @@ def __init__(self, deci: Optional[DecompilerInterface] = None, host: str = "loca
self.global_vars()

def _register_artifact_callbacks(self):
"""Register libbs artifact change callbacks for cache invalidation."""
"""Register declib artifact change callbacks for cache invalidation."""
# Function header changes -> invalidate that function's cache
self.deci.artifact_change_callbacks[FunctionHeader].append(
lambda fh, **kw: self.cache.invalidate_function(fh.addr)
Expand Down Expand Up @@ -188,7 +188,7 @@ def base_addr(self) -> int:
def rebase_addr(self, addr: int, down: bool = False) -> int:
"""
Convert between GDB client addresses and decompiler-internal addresses
using the libbs art_lifter for correct cross-decompiler support.
using the declib art_lifter for correct cross-decompiler support.

Args:
addr: The address to convert.
Expand Down
4 changes: 2 additions & 2 deletions decomp2dbg/server/stubs/plugin.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,12 @@
"Windows" : "Follow the README to install the debugger side of the plugin."
},
"dependencies": {
"pip": ["libbs>=0.12.0"],
"pip": ["declib>=4.0.1"],
"apt": [],
"installers": [],
"other": []
},
"version": "3.11.0",
"version": "4.0.2",
"author": "Zion Basque (@mahaloz)",
"minimumbinaryninjaversion": 1200
}
7 changes: 5 additions & 2 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,11 @@ dynamic = ["version"]
description = "Symbol syncing framework for decompilers and debuggers"
readme = "README.md"
requires-python = ">=3.10"
license = {text = "BSD 2 Clause"}
license = "BSD-2-Clause"
dependencies = [
"sortedcontainers",
"pyelftools",
"libbs[ghidra]>=3.5.0",
"declib[ghidra]>=4.0.1",
]

[project.urls]
Expand All @@ -24,6 +24,9 @@ decomp2dbg = "decomp2dbg.__main__:main"
[tool.setuptools]
include-package-data = true

[tool.setuptools.package-data]
"decomp2dbg.server.stubs" = ["plugin.json"]

[tool.setuptools.dynamic]
version = {attr = "decomp2dbg.__version__"}

Expand Down
10 changes: 5 additions & 5 deletions tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,10 @@
import xmlrpc.client
from pathlib import Path

from libbs.api import DecompilerInterface
from libbs.decompilers import GHIDRA_DECOMPILER, IDA_DECOMPILER
from declib.api import DecompilerInterface
from declib.decompilers import GHIDRA_DECOMPILER, IDA_DECOMPILER

from decomp2dbg.server import LibBSDecompilerServer
from decomp2dbg.server import DecLibDecompilerServer

REPO_ROOT = Path(__file__).resolve().parent
FAUXWARE_PATH = REPO_ROOT / "testing" / "binaries" / "fauxware"
Expand All @@ -49,7 +49,7 @@ class _DecompilerTestBase(unittest.TestCase):
Base class for decompiler integration tests.

Subclasses must set:
DECOMPILER — libbs decompiler constant (e.g. "ghidra", "ida")
DECOMPILER — declib decompiler constant (e.g. "ghidra", "ida")
DECOMPILER_NAME — human-readable name for log messages
DISCOVER_KWARGS — extra kwargs passed to DecompilerInterface.discover()
START_XMLRPC — if False, skip the XML-RPC listener
Expand Down Expand Up @@ -89,7 +89,7 @@ def setUpClass(cls):

cls.deci = DecompilerInterface.discover(**discover_kwargs)

cls.server = LibBSDecompilerServer(
cls.server = DecLibDecompilerServer(
deci=cls.deci, host="localhost", port=cls.port
)

Expand Down
Loading