mirror of
https://github.com/angr/angr
synced 2026-08-17 12:23:11 -04:00
CFGFast: Delete the function that starts inside an instruction, not another one
drop_bad_functions() collects the address of every function that starts in the middle of an instruction, then deletes `func_addr` instead of `node_addr`. `func_addr` is whatever the loop above left behind, so the function that starts inside an instruction stays in the function manager with its node removed, and an unrelated function is deleted in its place. FunctionManager.__delitem__ checks membership before deleting, so the second and later iterations do nothing and the mistake is silent. On x86_64/windows/50e5f670... the scan lands at 0x4249f4, inside the instruction at 0x4249f1, and 0x424cc0 goes instead.
This commit is contained in:
parent
503b1be066
commit
478ae3c96c
2 changed files with 17 additions and 1 deletions
|
|
@ -4775,7 +4775,7 @@ class CFGFast(ForwardAnalysis[CFGNode, CFGNode, CFGJob, int, object], CFGBase):
|
|||
if cfg_node is not None:
|
||||
self.model.remove_node_and_graph_node(cfg_node)
|
||||
if self.kb.functions.contains_addr(node_addr):
|
||||
del self.kb.functions[func_addr]
|
||||
del self.kb.functions[node_addr]
|
||||
|
||||
def _analyze_all_function_features(self, all_funcs_completed=False):
|
||||
"""
|
||||
|
|
|
|||
|
|
@ -1031,6 +1031,22 @@ class TestCfgfast(unittest.TestCase):
|
|||
|
||||
assert len(cfg.kb.functions) < 150, f"32 KB of random data produced {len(cfg.kb.functions)} functions"
|
||||
|
||||
def test_function_starting_inside_an_instruction_is_the_one_dropped(self):
|
||||
# 0x4249f4 is where the prologue scan landed inside the `mov dword ptr [esp + 0x50], edx` at 0x4249f1,
|
||||
# so drop_bad_functions() collects it. The deletion then ran on the wrong address and took 0x424cc0,
|
||||
# an ordinary `push edi; call ...` entry, with it.
|
||||
path = os.path.join(
|
||||
test_location,
|
||||
"x86_64",
|
||||
"windows",
|
||||
"50e5f670700243535f8ff558831dbbc314b215092f523355aa7a1c26205ece37",
|
||||
)
|
||||
proj = angr.Project(path, auto_load_libs=False)
|
||||
cfg = proj.analyses.CFGFast(normalize=True)
|
||||
|
||||
assert 0x4249F4 not in cfg.kb.functions
|
||||
assert 0x424CC0 in cfg.kb.functions
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue