Není to triviální úkol. Můžete to udělat relativně snadno, pokud neberete v úvahu nepřímá volání (například virtuální funkce v C ++) a volání z jiné funkce, jako je tato:
int f () {g () ;} int g () {f ();}
Může to být mnohem komplikovanější, pokud je jedna z vašich funkcí v jiné binární podobě (například dll). Existují tedy dva způsoby, jak to udělat, statický a dynamický způsob.
Rekurzivní procházení sestavy - přístup statické analýzy
Měli byste napsat skript v IDAPython, který předává funkci a rekurzivně zpracovává každé volání. Pokud najdete aktuální funkci ve shromážděném zásobníku, funkce je rekurzivní.
Velmi jednoduchá varianta vypadá takto:
# Nezkontroloval jsem to, používejte opatrně, pozor na chyby v tomto codeimport idautilsimport idcimport idaapidef handle_function (func_start): globální zásobník, pokud func_start v zásobníku: tisk "Toto je rekurzivní funkce", hex (func_start), název (func_start) pro x v zásobníku: tisk "\ t", hex (x ) # zde vložte své přejmenování, mělo by to být idc.MakeName návrat stack.append (func_start) pro h v idautils.FuncItems (func_start): pro r v idautils.XrefsFrom (h, 0): if r.type == fl_CF nebo r.type == fl_CN: print hex (h), "-->", hex (r.to) if r.to == func_start: # Sem vložte také přejmenování pro jednoduchý rekurzivní tisk "Je to jednoduchá rekurzivní funkce, která volá sám přímo "návrat else: handl e_function (r.to) stack = stack [: - 1] pro f v idautils.Functions (): stack = [] handle_function (f)
zarážka analýza - přístup dynamické analýzy
Napište skript v IDAPython, který rozpozná všechny prology funkcí a odfiltruje všechny funkce, které nic neříkají. Na každý shromážděný prolog vložte bod přerušení a spusťte program.
Pokaždé, když se program zastaví, analyzujte zásobník programu pomocí IDAPython, abyste našli funkci, na které jste v zásobníku zastaveni. Pokud ji najdete, funkce je rekurzivní.