|
@@ -368,10 +368,7 @@ class VtableDisambiguator(angr.Analysis):
|
|
|
|
|
|
fnsyms = set(self.syms_by_addr.get(vptr) or set())
|
|
|
|
|
|
- if len(fnsyms) == 1:
|
|
|
- function_list.append(VTableFunction(table_index, fnsyms))
|
|
|
- continue
|
|
|
- elif len(fnsyms) > 1:
|
|
|
+ if len(fnsyms) > 1:
|
|
|
constrained_sym = self.get_constrained_vfn(vt, n, fnsyms)
|
|
|
if constrained_sym:
|
|
|
function_list.append(VTableFunction(table_index, {constrained_sym}))
|
|
@@ -398,24 +395,23 @@ class VtableDisambiguator(angr.Analysis):
|
|
|
function_list.append(VTableFunction(table_index, fnsyms))
|
|
|
|
|
|
for n, vfn in enumerate(function_list):
|
|
|
- if len(vfn.possible_syms) == 1:
|
|
|
- continue
|
|
|
+ # disambiguated_func_sigs may include an already unique match so we skip those
|
|
|
+ if len(vfn.possible_syms) > 1:
|
|
|
+ disambiguated_functions = set(
|
|
|
+ x
|
|
|
+ for x in vfn.possible_syms
|
|
|
+ if dh.extract_method_signature(demangler.parse(x.name))
|
|
|
+ in disambiguated_func_sigs
|
|
|
+ )
|
|
|
+ vfn.possible_syms -= disambiguated_functions
|
|
|
|
|
|
- disambiguated_functions = set(
|
|
|
- x
|
|
|
- for x in vfn.possible_syms
|
|
|
- if dh.extract_method_signature(demangler.parse(x.name))
|
|
|
- in disambiguated_func_sigs
|
|
|
- )
|
|
|
- remaining_syms = vfn.possible_syms - disambiguated_functions
|
|
|
- if len(remaining_syms) == 1:
|
|
|
- vfn.possible_syms = remaining_syms
|
|
|
+ if len(vfn.possible_syms) == 1:
|
|
|
continue
|
|
|
|
|
|
# we should never receive an empty ``VTableFunction.possible_syms``
|
|
|
# for now we need to assert that a function address is unambiguous given the context
|
|
|
vt_name = demangler.parse(vt.name)
|
|
|
- candidate_names = set(sym.name for sym in remaining_syms)
|
|
|
+ candidate_names = set(sym.name for sym in vfn.possible_syms)
|
|
|
raise Exception(
|
|
|
f"Ambiguity in {vt_name} position {n}; candidates {candidate_names}"
|
|
|
)
|