/* #<pydoc> # Conversion options for get_strlit_contents(): STRCONV_ESCAPE = 0x00000001 # convert non-printable characters to C escapes (\n, \xNN, \uNNNN) def get_strlit_contents(ea, len, type, flags = 0): """ Get bytes contents at location, possibly converted. It works even if the string has not been created in the database yet. Note that this will <b>always</b> return a simple string of bytes (i.e., a 'str' instance), and not a string of unicode characters. If you want auto-conversion to unicode strings (that is: real strings), you should probably be using the idautils.Strings class. @param ea: linear address of the string @param len: length of the string in bytes (including terminating 0) @param type: type of the string. Represents both the character encoding, <u>and</u> the 'type' of string at the given location. @param flags: combination of STRCONV_..., to perform output conversion. @return: a bytes-filled str object. """ pass #</pydoc> */ static PyObject *py_get_strlit_contents( ea_t ea, PyObject *py_len, int32 type, int flags = 0) { uint64 len; if ( !PyW_GetNumber(py_len, &len) ) Py_RETURN_NONE; if ( len == BADADDR ) len = uint64(-1); qstring buf; if ( len != uint64(-1) && ea_t(ea + len) < ea || get_strlit_contents(&buf, ea, len, type, NULL, flags) < 0 ) { Py_RETURN_NONE; } if ( type == STRTYPE_C && buf.length() > 0 && buf.last() == '\0' ) buf.remove_last(); PYW_GIL_CHECK_LOCKED_SCOPE(); newref_t py_buf(PyString_FromStringAndSize(buf.begin(), buf.length())); py_buf.incref(); return py_buf.o; }
GCCTypeInfo *GCCTypeInfo::parseTypeInfo(ea_t ea) { if (g_KnownTypes.count(ea)) return g_KnownTypes[ea]; GCC_RTTI::type_info tmp; if (!get_bytes(&tmp, sizeof(GCC_RTTI::type_info), ea)) return 0; ea_t name_ea = tmp.__type_info_name; size_t length = get_max_strlit_length(name_ea, STRTYPE_C, ALOPT_IGNHEADS); qstring buffer; if (!get_strlit_contents(&buffer, name_ea, length, STRTYPE_C)) { return 0; } qstring name(buffer); qstring demangled_name; name = qstring("_ZTS") + name; int32 res = demangle_name(&demangled_name, name.c_str(), 0); if (res != (MT_GCC3 | M_AUTOCRT | MT_RTTI)) { return 0; } demangled_name = demangled_name.substr(19); GCCTypeInfo * result = new GCCTypeInfo(); result->ea = ea; result->typeName = demangled_name; result->vtbl = tmp.__type_info_vtable; setUnknown(ea + ea_t(offsetof(GCC_RTTI::type_info, __type_info_vtable)), sizeof(void*)); op_plain_offset(ea + ea_t(offsetof(GCC_RTTI::type_info, __type_info_vtable)), 0, ea); setUnknown(ea + ea_t(offsetof(GCC_RTTI::type_info, __type_info_name)), sizeof(void*)); op_plain_offset(ea + ea_t(offsetof(GCC_RTTI::type_info, __type_info_name)), 0, ea); MakeName(ea, demangled_name, "RTTI_", ""); if (tmp.__type_info_vtable == class_type_info_vtbl) { g_KnownTypes[ea] = result; return result; } if (tmp.__type_info_vtable == si_class_type_info_vtbl) { GCC_RTTI::__si_class_type_info si_class; if (!get_bytes(&si_class, sizeof(GCC_RTTI::__si_class_type_info), ea)) { delete result; return 0; } GCCTypeInfo *base = parseTypeInfo(si_class.base); if (base == 0) { delete result; return 0; } setUnknown(ea + ea_t(offsetof(GCC_RTTI::__si_class_type_info, base)), sizeof(void*)); op_plain_offset(ea + ea_t(offsetof(GCC_RTTI::__si_class_type_info, base)), 0, ea); result->parentsCount = 1; result->parentsTypes = new GCCParentType*[1]; result->parentsTypes[0] = new GCCParentType(); result->parentsTypes[0]->ea = base->ea; result->parentsTypes[0]->info = base; result->parentsTypes[0]->flags = 0; g_KnownTypes[ea] = result; return result; } if (tmp.__type_info_vtable != vmi_class_type_info_vtbl) { // Unknown type, ignore it delete result; return 0; } GCC_RTTI::__vmi_class_type_info vmi_class; if (!get_bytes(&vmi_class, sizeof(GCC_RTTI::__vmi_class_type_info), ea)) return 0; // vmi_class.vmi_flags; // WTF?? result->parentsCount = vmi_class.vmi_base_count; result->parentsTypes = new GCCParentType*[result->parentsCount]; ea_t addr = ea + ea_t(offsetof(GCC_RTTI::__vmi_class_type_info, vmi_bases)); setUnknown(ea + ea_t(offsetof(GCC_RTTI::__vmi_class_type_info, vmi_flags)), sizeof(void*)); create_dword(ea + ea_t(offsetof(GCC_RTTI::__vmi_class_type_info, vmi_flags)), sizeof(void *)); setUnknown(ea + ea_t(offsetof(GCC_RTTI::__vmi_class_type_info, vmi_base_count)), sizeof(int)); create_dword(ea + ea_t(offsetof(GCC_RTTI::__vmi_class_type_info, vmi_base_count)), sizeof(int)); GCC_RTTI::__base_class_info baseInfo; for (int i = 0; i < vmi_class.vmi_base_count; ++i, addr += sizeof(baseInfo)) { if (!get_bytes(&baseInfo, sizeof(baseInfo), addr)) { delete result; return 0; } GCCTypeInfo *base = parseTypeInfo(baseInfo.base); if (base == 0) { delete result; return 0; } setUnknown(addr + ea_t(offsetof(GCC_RTTI::__base_class_info, base)), sizeof(void*)); op_plain_offset(addr + offsetof(GCC_RTTI::__base_class_info, base), 0, addr); setUnknown(addr + ea_t(offsetof(GCC_RTTI::__base_class_info, vmi_offset_flags)), sizeof(void*)); create_dword(addr + ea_t(offsetof(GCC_RTTI::__base_class_info, vmi_offset_flags)), sizeof(int)); result->parentsTypes[i] = new GCCParentType(); result->parentsTypes[i]->ea = base->ea; result->parentsTypes[i]->ea = base->ea; result->parentsTypes[i]->info = base; result->parentsTypes[i]->flags = static_cast<unsigned>(baseInfo.vmi_offset_flags); qstring flags; if (baseInfo.vmi_offset_flags & baseInfo.virtual_mask) flags += " virtual_mask "; if (baseInfo.vmi_offset_flags & baseInfo.public_mask) flags += " public_mask "; if (baseInfo.vmi_offset_flags & baseInfo.offset_shift) flags += " offset_shift "; set_cmt(addr + ea_t(offsetof(GCC_RTTI::__base_class_info, vmi_offset_flags)), flags.c_str(), false); } g_KnownTypes[ea] = result; return result; }