Attempt to get information of and fix vftable at address Return TRUE along with info if valid vftable parsed at address
| 45 | // Attempt to get information of and fix vftable at address |
| 46 | // Return TRUE along with info if valid vftable parsed at address |
| 47 | bool vftable::getTableInfo(ea_t ea, vtinfo &info) |
| 48 | { |
| 49 | ZeroMemory(&info, sizeof(vtinfo)); |
| 50 | |
| 51 | // Start of a vft should have an xref and a name (auto, or user, etc). |
| 52 | // Ideal flags 32bit: FF_DWRD, FF_0OFF, FF_REF, FF_NAME, FF_DATA, FF_IVL |
| 53 | //dumpFlags(ea); |
| 54 | flags_t flags = get_flags(ea); |
| 55 | if (has_xref(flags) && has_any_name(flags) && (isEa(flags) || is_unknown(flags))) |
| 56 | { |
| 57 | // Get raw (auto-generated mangled, or user named) vft name |
| 58 | //if (!get_name(BADADDR, ea, info.name, SIZESTR(info.name))) |
| 59 | // logmsg(DEBUG, EAFORMAT" ** vftable::getTableInfo(): failed to get raw name!\n", ea); |
| 60 | |
| 61 | // Determine the vft's method count |
| 62 | ea_t start = info.start = ea; |
| 63 | while (TRUE) |
| 64 | { |
| 65 | // Should be an ea_t offset to a function here (could be unknown if dirty IDB) |
| 66 | // Ideal flags for 32bit: FF_DWRD, FF_0OFF, FF_REF, FF_NAME, FF_DATA, FF_IVL |
| 67 | //dumpFlags(ea); |
| 68 | flags_t indexFlags = get_flags(ea); |
| 69 | if (!(isEa(indexFlags) || is_unknown(indexFlags))) |
| 70 | { |
| 71 | break; |
| 72 | } |
| 73 | |
| 74 | // Look at what this (assumed vftable index) points too |
| 75 | ea_t memberPtr = getEa(ea); |
| 76 | if (!(memberPtr && (memberPtr != BADADDR))) |
| 77 | { |
| 78 | // vft's often have a zero ea_t (NULL pointer?) following, fix it |
| 79 | if (memberPtr == 0) |
| 80 | fixEa(ea); |
| 81 | |
| 82 | break; |
| 83 | } |
| 84 | |
| 85 | // Should see code for a good vft method here, but it could be dirty |
| 86 | flags_t flags = get_flags(memberPtr); |
| 87 | if (!(is_code(flags) || is_unknown(flags))) |
| 88 | { |
| 89 | break; |
| 90 | } |
| 91 | |
| 92 | if (ea != start) |
| 93 | { |
| 94 | // If we see a ref after first index it's probably the beginning of the next vft or something else |
| 95 | if (has_xref(indexFlags)) |
| 96 | { |
| 97 | break; |
| 98 | } |
| 99 | |
| 100 | // If we see a COL here it must be the start of another vftable |
| 101 | if (RTTI::_RTTICompleteObjectLocator::isValid(memberPtr)) |
| 102 | { |
| 103 | break; |
| 104 | } |
nothing calls this directly
no test coverage detected