|
@@ -48,10 +48,17 @@ def convert_types(*types):
|
|
|
# or bytesigs + offsets
|
|
|
ResultValues = dict[string.Template, typing.Any]
|
|
|
|
|
|
+# some virtual functions cannot be disambiguated outright, or need to check the resolved
|
|
|
+# state of the rest of the table - for the former we have to disambiguate them out-of-band
|
|
|
+#
|
|
|
+# ideally we would do some linear constraint on ordering, but for now we just spec the offset
|
|
|
+VTableConstraintDict = dict[str, dict[str, int]]
|
|
|
+
|
|
|
|
|
|
class BaseBinary:
|
|
|
path: pathlib.Path
|
|
|
angr: angr.Project
|
|
|
+ hash: str
|
|
|
_file: io.IOBase
|
|
|
_mm: mmap.mmap
|
|
|
|
|
@@ -59,8 +66,8 @@ class BaseBinary:
|
|
|
self.path = path
|
|
|
self._file = open(self.path, "rb")
|
|
|
|
|
|
- file_hash = hashlib.file_digest(self._file, "sha256")
|
|
|
- cached_proj = (cache_path or pathlib.Path()) / f"{file_hash.hexdigest()}.angr.pkl"
|
|
|
+ self.hash = hashlib.file_digest(self._file, "sha256").hexdigest()
|
|
|
+ cached_proj = (cache_path or pathlib.Path()) / f"{self.hash}.angr.pkl"
|
|
|
if not cached_proj.exists():
|
|
|
self.angr = angr.Project(self.path, load_options={"auto_load_libs": False})
|
|
|
cached_proj.write_bytes(pickle.dumps(self.angr))
|
|
@@ -83,8 +90,17 @@ class WindowsBinary(BaseBinary):
|
|
|
|
|
|
|
|
|
class LinuxBinary(BaseBinary):
|
|
|
+ vtable_constraint: VTableConstraintDict
|
|
|
+
|
|
|
def __init__(self, path: pathlib.Path, cache_path: pathlib.Path | None = None):
|
|
|
super().__init__(path, cache_path)
|
|
|
+ self.vtable_constraint = {}
|
|
|
+
|
|
|
+ constraints_file = (cache_path or pathlib.Path()) / f"{self.hash}.constraints.toml"
|
|
|
+ if constraints_file.exists():
|
|
|
+ self.vtable_constraint = msgspec.toml.decode(
|
|
|
+ constraints_file.read_bytes(), type=VTableConstraintDict
|
|
|
+ )
|
|
|
|
|
|
@functools.cached_property
|
|
|
def vtable_disambiguator(self) -> VtableDisambiguator:
|