Board: Decomp view (progress tiers, function inspector, next up per band, deferred) and RE tools in Health; Verified tier from the emulator
This commit is contained in:
1 parent
a9efc2e5c5
commit
87631bec52
5 files changed
+331
-6
No files matched your search
+9
-4
@@ -129,14 +129,14 @@ class FunctionQueue:
|
||||
return addr in library or any(lo <= addr < hi for lo, hi in ranges)
|
||||
|
||||
# ------------------------------------------------------------------ queue
|
||||
def score(self, addr, facts, named, rejected, similar_readable=frozenset()):
|
||||
def score(self, addr, facts, named, rejected, similar_readable=frozenset(), with_convention=True):
|
||||
d = facts[addr]
|
||||
size = int(d.get("size") or 0)
|
||||
calls = [int(c, 16) if isinstance(c, str) else c for c in d.get("calls", [])]
|
||||
named_share = (sum(1 for c in calls if c in named) / len(calls)) if calls else 1.0
|
||||
score = 1.0 / (1.0 + size / 250.0) # small first
|
||||
score *= 0.5 + 0.5 * named_share # callees with names make readable code possible
|
||||
conv = self.r.convention(addr) if size <= 4000 else None
|
||||
conv = self.r.convention(addr) if with_convention and size <= 4000 else None
|
||||
if conv and conv["summary"].startswith("custom"):
|
||||
score *= 0.75 # register arguments: prototypes.h work too
|
||||
if self._category(addr) not in ("game", "unsorted"):
|
||||
@@ -186,9 +186,12 @@ class FunctionQueue:
|
||||
head = self.r.read(addr, 10) if int(facts[addr].get("size") or 0) == 10 else b""
|
||||
if head[:1] and 0xB8 <= head[0] <= 0xBF and head[5:6] == b"\xe9":
|
||||
continue # mov reg, imm32; jmp: an at-exit destructor thunk or an SEH handler stub (compiler's)
|
||||
score, reasons = self.score(addr, facts, named, rejected, similar_readable)
|
||||
score, reasons = self.score(addr, facts, named, rejected, similar_readable, with_convention=False)
|
||||
ranked.append((score, addr, reasons))
|
||||
ranked.sort(reverse=True)
|
||||
# the convention read from the bytes only lowers a score, and it is the slow part: read it for the head only
|
||||
head = [(*self.score(a, facts, named, rejected, similar_readable), a) for _, a, _ in ranked[:max(4 * n, 40)]]
|
||||
ranked = sorted(((s, a, why) for s, why, a in head), reverse=True)
|
||||
return [{"address": f"0x{a:X}", "name": self.r.name_of(a), "score": round(s, 4), "why": ", ".join(why),
|
||||
"file": statuses.get(a, (None, None))[1]} for s, a, why in ranked[:n]]
|
||||
|
||||
@@ -207,7 +210,9 @@ class FunctionQueue:
|
||||
facts, statuses, deferred = self.r._facts(), self.statuses(), self.deferrals()
|
||||
exact = {a for a, row in self._results("match_results").items()
|
||||
if str(row.get("status")) in ("match", "exact", "exact-relaxed")}
|
||||
verified = {a for a, row in self._results("diffrun_results").items() if str(row.get("verdict")) == "same"}
|
||||
# behaves the same in the emulator, with at least one trial that ran to the end in both (not 'weak')
|
||||
verified = {a for a, row in self._results("diffrun_results").items()
|
||||
if str(row.get("verdict")) == "same" and not row.get("weak")}
|
||||
library = set(self._results("library_results"))
|
||||
ranges = self.library_ranges()
|
||||
tiers = {t: {"functions": 0, "bytes": 0} for t in TIER_ORDER + ("library", "engine")}
|
||||
|
||||
Reference in new issue
Block a user