arizvisa / ida-minsc

A plugin based on IDAPython for a functional DWIM interface. Current development against most recent IDA is in the "persistence-refactor" branch, ancient (but stable) work is in "master", so... create an issue if you want/need something backported. Use "Wiki" or "Discussions" for examples, and smash that "Star" button if you like this.
BSD 3-Clause "New" or "Revised" License
316 stars 53 forks source link

Anything that accesses `func_t.referers` from `idaapi.get_fchunk` when `func_t.flags & idaapi.FUNC_TAIL` is set can result in a null pointer dereference #154

Closed arizvisa closed 2 years ago

arizvisa commented 2 years ago

In order to check a function tail, one is supposed to use idaapi.get_fchunk to get a func_t. Once getting an instance of this type, you're then supposed to check the flags (func_t.flags) for the idaapi.FUNC_TAIL bit. At this point the func_t.referers attribute contains a dyn_ea_array of all of the referrers of this particular chunk. You can check the number of referrers by accessing func_t.referers.count.

In some cases when the count is larger than 0 (it should always be larger than 0), accessing the first element can result in a null-pointer dereference. This occurs in _ida_funcs.pyd. There's a number of places that a tail's referrers are actually checked. All of these places will likely cause IDAPython to crash.

arizvisa commented 2 years ago

I'm using the following IDAPython nn this database for DBCLIENT.DLL (6.84.8027.1) from some random software to reproduce:

a = [0x1800a45dc, 0x1800a4611, 0x1800a4659, 0x1800a468b, 0x1800a5be8, 0x1800a5c17, 0x1800a5c4b]
for ea, f in zip(a, map(idaapi.get_fchunk, a)):
    if f and f.flags & idaapi.FUNC_TAIL and f.referers.count == 1:
        print(f.referers[0])
    continue
arizvisa commented 2 years ago

This is fixed by PR #155.

arizvisa commented 2 years ago

Reflecting on the fix I wrote for this, I probably should be using idaapi.func_parent_iterator_t... :-/

Nonetheless, closing this PR as #155 was merged.