Skip to content

Commit

Permalink
Fix bad lifting in artifact listing (#77)
Browse files Browse the repository at this point in the history
* Fix bad lifting in artifact listing

* Add the posix binary

* Update the README
  • Loading branch information
mahaloz authored Jun 3, 2024
1 parent ed73d67 commit 4b10630
Show file tree
Hide file tree
Showing 6 changed files with 43 additions and 9 deletions.
5 changes: 2 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,7 @@ for addr in deci.functions:
function = deci.functions[addr]
if function.header.type == "void":
function.header.type = "int"

deci.functions[function.addr] = function
deci.functions[function.addr] = function
```

### Headless Mode
Expand All @@ -43,7 +42,7 @@ To use headless mode you must specify a decompiler to use. You can get the tradi
```python
from libbs.api import DecompilerInterface

deci = DecompilerInterface.discover(force_decompiler="ida", headless=True)
deci = DecompilerInterface.discover(force_decompiler="ghidra", headless=True)
```

In the case of decompilers that don't have a native python library for working with, like Ghidra and IDA, you will to
Expand Down
2 changes: 1 addition & 1 deletion libbs/__init__.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
__version__ = "1.6.1"
__version__ = "1.6.2"

import logging
logging.getLogger("libbs").addHandler(logging.NullHandler())
Expand Down
22 changes: 17 additions & 5 deletions libbs/api/artifact_dict.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,18 @@ def __init__(self, artifact_cls, deci: "DecompilerInterface", error_on_duplicate
def __len__(self):
return len(self._artifact_lister())

def _lifted_art_lister(self):
d = self._artifact_lister()
d_items = list(d.items())
is_addr = hasattr(d_items[0][1], "addr")
new_d = {}
for k, v in d_items:
if is_addr:
k = self._deci.art_lifter.lift_addr(k)
new_d[k] = self._deci.art_lifter.lift(v)

return new_d

def __getitem__(self, item):
"""
Takes a lifted identifier as input and returns a lifted artifact
Expand Down Expand Up @@ -97,19 +109,19 @@ def __delitem__(self, key):
pass

def __iter__(self):
return iter(self._artifact_lister())
return iter(self._lifted_art_lister())

def __repr__(self):
return f"<{self.__class__.__name__}: {self._artifact_class.__name__} len={self.__len__()}>"

def __str__(self):
return f"{self._artifact_lister()}"
return f"{self._lifted_art_lister()}"

def keys(self):
return self._artifact_lister().keys()
return self._lifted_art_lister().keys()

def values(self):
return self._artifact_lister().values()
return self._lifted_art_lister().values()

def items(self):
return self._artifact_lister().items()
return self._lifted_art_lister().items()
3 changes: 3 additions & 0 deletions libbs/decompilers/ghidra/interface.py
Original file line number Diff line number Diff line change
Expand Up @@ -260,6 +260,9 @@ def _set_function(self, func: Function, **kwargs) -> bool:

def _get_function(self, addr, **kwargs) -> Optional[Function]:
func = self._get_nearest_function(addr)
if func is None:
return None

dec = self._ghidra_decompile(func)
# optimize on remote
stack_variable_info: Optional[List[Tuple[int, str, str, int]]] = self.ghidra.bridge.remote_eval(
Expand Down
Binary file added tests/binaries/posix_syscall
Binary file not shown.
20 changes: 20 additions & 0 deletions tests/test_decompilers.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,31 @@
BINJA_DECOMPILER: None,
}


class TestHeadlessInterfaces(unittest.TestCase):
def setUp(self):
self._generic_renamed_name = "binsync_main"
self._fauxware_path = TEST_BINARY_DIR / "fauxware"

def test_readme_example(self):
"""
TODO: Test more than just Ghidra here.
"""
deci = DecompilerInterface.discover(
force_decompiler=GHIDRA_DECOMPILER,
headless=True,
headless_dec_path=DEC_TO_HEADLESS[GHIDRA_DECOMPILER],
binary_path=TEST_BINARY_DIR / "posix_syscall",
)

for addr in deci.functions:
function = deci.functions[addr]
if function.header.type == "void":
function.header.type = "int"
deci.functions[function.addr] = function

deci.shutdown()

def test_ghidra(self):
# useful command for testing, kills all Headless-Ghidra:
# kill $(ps aux | grep 'Ghidra-Headless' | awk '{print $2}')
Expand Down

0 comments on commit 4b10630

Please sign in to comment.