diff --git a/src/HexRaysCodeXplorer/CodeXplorer.cpp b/src/HexRaysCodeXplorer/CodeXplorer.cpp index b9eeac2..3ea2f97 100644 --- a/src/HexRaysCodeXplorer/CodeXplorer.cpp +++ b/src/HexRaysCodeXplorer/CodeXplorer.cpp @@ -393,7 +393,7 @@ static bool get_expr_name(citem_t *citem, qstring& rv) cexpr_t *e = (cexpr_t *)citem; // retrieve the name of the routine - e->print1(&rv, NULL); + print1wrapper(e, &rv, NULL); tag_remove(&rv); return true; @@ -484,7 +484,7 @@ static bool idaapi show_offset_in_windbg_format(void *ud) { show_string_in_custom_view(&vu, title, result); #if defined (__LINUX__) || defined (__MAC__) - msg(result.c_str()); + msg("%s", result.c_str()); #else OpenClipboard(0); EmptyClipboard(); @@ -705,7 +705,7 @@ int idaapi init(void) for (unsigned i = 0; i < _countof(kActionDescs); ++i) register_action(kActionDescs[i]); - install_hexrays_callback(callback, nullptr); + install_hexrays_callback((hexrays_cb_t*)callback, nullptr); logmsg(INFO, "Hex-rays version %s has been detected\n", get_hexrays_version()); inited = true; @@ -742,7 +742,7 @@ void idaapi term(void) if (inited) { logmsg(INFO, "\nHexRaysCodeXplorer plugin by @REhints terminated.\n\n\n"); - remove_hexrays_callback(callback, NULL); + remove_hexrays_callback((hexrays_cb_t*)callback, NULL); term_hexrays_plugin(); } } diff --git a/src/HexRaysCodeXplorer/Common.h b/src/HexRaysCodeXplorer/Common.h index 02c8097..130ee77 100644 --- a/src/HexRaysCodeXplorer/Common.h +++ b/src/HexRaysCodeXplorer/Common.h @@ -44,7 +44,16 @@ #pragma warning(push) #pragma warning(disable:4309 4244 4267) // disable "truncation of constant value" warning from IDA SDK, conversion from 'ssize_t' to 'int', possible loss of data #endif // __NT__ +#ifndef USE_DANGEROUS_FUNCTIONS #define USE_DANGEROUS_FUNCTIONS +#endif +#ifdef __clang__ +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wsign-compare" +#pragma clang diagnostic ignored "-Wvarargs" +#pragma clang diagnostic ignored "-Wlogical-op-parentheses" +#pragma clang diagnostic ignored "-Wunused-private-field" +#endif #include #include #include @@ -66,6 +75,42 @@ #ifdef __NT__ #pragma warning(pop) #endif // __NT__ +#ifdef __clang__ +#pragma clang diagnostic pop +#endif + +template +struct print1_accepts_qstring +{ + template struct yay_sfinae {}; + template static char test(yay_sfinae*); + template static int test(...); + static const bool value = sizeof(test(0)) == sizeof(char); +}; + +// For IDA7.1 and newer +template +void print1wrapper(std::true_type, const T *e, qstring *qbuf, const cfunc_t *func) { + e->print1(qbuf, func); +}; + +// For older SDKs +template +void print1wrapper(std::false_type, const T *e, qstring *qbuf, const cfunc_t *func) { + char lbuf[MAXSTR]; + const size_t len = e->print1(lbuf, sizeof(lbuf) - 1, func); + qstring temp(lbuf, len); + qbuf->swap(temp); +}; + +template +void print1wrapper(const T *e, qstring *qbuf, const cfunc_t *func) { + return print1wrapper( + std::integral_constant::value>(), + e, qbuf, func); +} + + #include #include diff --git a/src/HexRaysCodeXplorer/CtreeExtractor.cpp b/src/HexRaysCodeXplorer/CtreeExtractor.cpp index 8aee291..7be385e 100644 --- a/src/HexRaysCodeXplorer/CtreeExtractor.cpp +++ b/src/HexRaysCodeXplorer/CtreeExtractor.cpp @@ -112,7 +112,7 @@ void ctree_dumper_t::parse_ctree_item(citem_t *item, qstring& rv) const { case cot_call: if (e->x->op == cot_obj) { - if (get_func_name(&func_name, e->x->obj_ea) == NULL) + if (get_func_name(&func_name, e->x->obj_ea) == 0) rv.cat_sprnt(" sub_%a", e->x->obj_ea); else rv.cat_sprnt(" %s", func_name.c_str()); @@ -139,7 +139,7 @@ void ctree_dumper_t::parse_ctree_item(citem_t *item, qstring& rv) const rv.append(' '); { qstring qbuf; - e->print1(&qbuf, NULL); + print1wrapper(e, &qbuf, NULL); tag_remove(&qbuf); rv += qbuf; } @@ -262,14 +262,14 @@ void dump_ctrees_in_file(std::map &data_to_dump, const qs dump_line.cat_sprnt(";%08X", cdl.func_start); dump_line.cat_sprnt(";%08X", cdl.func_end); if ((cdl.func_name.length() > crypt_prefix_len) && (crypt_prefix_len > 0) && (cdl.func_name.find(crypto_prefix) == 0)) - dump_line.cat_sprnt(";E", cdl.func_end); + dump_line.cat_sprnt(";E"); else - dump_line.cat_sprnt(";N", cdl.func_end); + dump_line.cat_sprnt(";N"); if ((cdl.heuristic_flag)) - dump_line.cat_sprnt(";H", cdl.func_end); + dump_line.cat_sprnt(";H"); else - dump_line.cat_sprnt(";N", cdl.func_end); + dump_line.cat_sprnt(";N"); dump_line += "\n"; @@ -390,7 +390,7 @@ bool idaapi extract_all_ctrees(void *ud) va_end(va); qstring crypto_prefix = kDefaultPrefix; - if (!ask_str(&crypto_prefix, NULL, "Enter prefix of crypto function names", va)) + if (!ask_str(&crypto_prefix, 0, "Enter prefix of crypto function names", va)) return false; if(!crypto_prefix.empty()) { diff --git a/src/HexRaysCodeXplorer/CtreeGraphBuilder.cpp b/src/HexRaysCodeXplorer/CtreeGraphBuilder.cpp index b6ef625..0537ac4 100644 --- a/src/HexRaysCodeXplorer/CtreeGraphBuilder.cpp +++ b/src/HexRaysCodeXplorer/CtreeGraphBuilder.cpp @@ -102,7 +102,7 @@ void callgraph_t::get_node_label(int n, qstring& rv) const rv.append(' '); { qstring qbuf; - e->print1(&qbuf, nullptr); + print1wrapper(e, &qbuf, nullptr); tag_remove(&qbuf); rv += qbuf; } diff --git a/src/HexRaysCodeXplorer/CtreeGraphBuilder.h b/src/HexRaysCodeXplorer/CtreeGraphBuilder.h index c33a406..e6aa047 100644 --- a/src/HexRaysCodeXplorer/CtreeGraphBuilder.h +++ b/src/HexRaysCodeXplorer/CtreeGraphBuilder.h @@ -73,7 +73,7 @@ class callgraph_t callgraph_t(); - const int count() const { return node_count; } + int count() const { return node_count; } // node / func info struct nodeinfo_t diff --git a/src/HexRaysCodeXplorer/GCCObjectFormatParser.h b/src/HexRaysCodeXplorer/GCCObjectFormatParser.h index 8d42355..7608b7f 100644 --- a/src/HexRaysCodeXplorer/GCCObjectFormatParser.h +++ b/src/HexRaysCodeXplorer/GCCObjectFormatParser.h @@ -8,7 +8,7 @@ namespace GCC_RTTI { #pragma pack(push, 1) struct __vtable_info { - size_t ptrdiff; + ssize_t ptrdiff; ea_t type_info; ea_t origin[1]; }; diff --git a/src/HexRaysCodeXplorer/GCCTypeInfo.cpp b/src/HexRaysCodeXplorer/GCCTypeInfo.cpp index bf50983..cdb0a60 100644 --- a/src/HexRaysCodeXplorer/GCCTypeInfo.cpp +++ b/src/HexRaysCodeXplorer/GCCTypeInfo.cpp @@ -3,7 +3,10 @@ #include "offset.hpp" #include "Utility.h" - +#if __clang__ +// Ignore "offset of on non-standard-layout type" warning +#pragma clang diagnostic ignored "-Winvalid-offsetof" +#endif GCCTypeInfo::GCCTypeInfo() @@ -156,4 +159,4 @@ GCCTypeInfo *GCCTypeInfo::parseTypeInfo(ea_t ea) } g_KnownTypes[ea] = result; return result; -} \ No newline at end of file +} diff --git a/src/HexRaysCodeXplorer/Linux.h b/src/HexRaysCodeXplorer/Linux.h index e5fa969..2a35f13 100644 --- a/src/HexRaysCodeXplorer/Linux.h +++ b/src/HexRaysCodeXplorer/Linux.h @@ -38,8 +38,8 @@ #define BOOL bool #define TRUE true #define FALSE false -#define LPCSTR char *const -#define LPCTSTR char *const +#define LPCSTR const char * +#define LPCTSTR const char * #define LPSTR char * #define WORD uint16_t #define DWORD uint32_t diff --git a/src/HexRaysCodeXplorer/TypeExtractor.cpp b/src/HexRaysCodeXplorer/TypeExtractor.cpp index 1915aa9..96939eb 100644 --- a/src/HexRaysCodeXplorer/TypeExtractor.cpp +++ b/src/HexRaysCodeXplorer/TypeExtractor.cpp @@ -62,7 +62,7 @@ int idaapi obj_fint_t::visit_expr(cexpr_t *e) // get the variable name qstring s; - e->print1(&s, NULL); + print1wrapper(e, &s, NULL); tag_remove(&s); // check for the target variable @@ -84,7 +84,7 @@ int idaapi obj_fint_t::visit_expr(cexpr_t *e) if (target_expr->op == cot_var) { s.clear(); - target_expr->print1(&s, NULL); + print1wrapper(target_expr, &s, NULL); tag_remove(&s); var_name = s; @@ -99,7 +99,7 @@ int idaapi obj_fint_t::visit_expr(cexpr_t *e) void idaapi reset_pointer_type(cfuncptr_t cfunc, const qstring &var_name) { lvars_t * locals = cfunc->get_lvars(); - if (!locals != NULL) + if (locals == NULL) return; qvector::iterator locals_iter; @@ -137,7 +137,7 @@ bool idaapi find_var(void *ud) cexpr_t *highl_expr = (cexpr_t *)highlight; qstring s; - highlight->print1(&s, NULL); + print1wrapper(highlight, &s, NULL); tag_remove(&s); // initialize type rebuilder @@ -296,7 +296,7 @@ void idaapi dump_type_info(int file_id, const VTBL_info_t& vtbl_info, const qstr qstring line; line = key_hash + ";" + file_entry_key + ";"; - line.cat_sprnt("%p;", vtbl_info.ea_begin); + line.cat_sprnt("%a;", vtbl_info.ea_begin); line += file_entry_val + ";"; if (rtti_vftables.count(vtbl_info.ea_begin) != 0) { @@ -311,7 +311,7 @@ void idaapi dump_type_info(int file_id, const VTBL_info_t& vtbl_info, const qstr bool idaapi check_subtype(VTBL_info_t vtbl_info, qstring subtype_name) { qstring search_str; - search_str.sprnt("_%p", vtbl_info.ea_begin); + search_str.sprnt("_%a", vtbl_info.ea_begin); struc_t * struc_type = get_struc(get_struc_id(subtype_name.c_str())); if (!struc_type) @@ -399,7 +399,7 @@ bool idaapi extract_all_types(void *ud) } } else { - info_msg.cat_sprnt(" : none\n", var_name.c_str()); + info_msg.cat_sprnt(" : none\n"); logmsg(DEBUG, info_msg.c_str()); } } diff --git a/src/HexRaysCodeXplorer/TypeReconstructor.cpp b/src/HexRaysCodeXplorer/TypeReconstructor.cpp index 92345d6..a505607 100644 --- a/src/HexRaysCodeXplorer/TypeReconstructor.cpp +++ b/src/HexRaysCodeXplorer/TypeReconstructor.cpp @@ -184,7 +184,7 @@ bool idaapi type_builder_t::check_helper(citem_t *parent, int &off, int &num) if(!strcmp(get_ctype_name(expr_2->x->op), "helper")) { qstring expr; - expr_2->x->print1(&expr, NULL); + print1wrapper(expr_2->x, &expr, NULL); tag_remove(&expr); if(expr == "LOBYTE") @@ -326,7 +326,7 @@ bool idaapi type_builder_t::check_ptr(cexpr_t *e, struct_filed &str_fld) // get index_value qstring s; - expr_2->y->print1(&s, NULL); + print1wrapper(expr_2->y, &s, NULL); tag_remove(&s); int base = 10; @@ -358,7 +358,7 @@ bool idaapi type_builder_t::check_ptr(cexpr_t *e, struct_filed &str_fld) } else if(parent_i->is_expr() && (parent_i->op == cot_asg)) { if (((cexpr_t *)parent_i)->y == e) { //parents[parents.size() - i]) { qstring s; - ((cexpr_t *)parent_i)->x->print1(&s, NULL); + print1wrapper(((cexpr_t *)parent_i)->x, &s, NULL); tag_remove(&s); char comment[258]; @@ -422,7 +422,7 @@ bool idaapi type_builder_t::check_idx(struct_filed &str_fld) // get index_value qstring s; - expr_2->y->print1(&s, NULL); + print1wrapper(expr_2->y, &s, NULL); tag_remove(&s); int num = atoi(s.c_str()); @@ -454,7 +454,7 @@ int idaapi type_builder_t::visit_expr(cexpr_t *e) { // get the variable name qstring s; - e->print1(&s, NULL); + print1wrapper(e, &s, NULL); tag_remove(&s); // check for the target variable @@ -494,6 +494,12 @@ int type_builder_t::get_structure_size() tid_t type_builder_t::get_structure(const qstring& name) { tid_t struct_type_id = add_struc(BADADDR, name.c_str()); + + if (struct_type_id == BADADDR) { + // the name is ill-formed or *is already used in the program* + struct_type_id = get_struc_id(name.c_str()); + } + if (struct_type_id != BADADDR) { struc_t * struc = get_struc(struct_type_id); @@ -572,62 +578,67 @@ bool idaapi reconstruct_type_cb(void *ud) // Determine the ctree item to highlight vu.get_current_item(USE_KEYBOARD); - citem_t *highlight = vu.item.is_citem() ? vu.item.e : NULL; + lvar_t* lvar = NULL; - // highlight == NULL might happen if one chooses variable at local variables declaration statement - if (highlight != NULL) - { - // the chosen item must be an expression and of 'variable' type - if (highlight->is_expr() && (highlight->op == cot_var)) + if (vu.item.is_citem()) { + citem_t *highlight = vu.item.e; + if (highlight && highlight->is_expr() && (highlight->op == cot_var)) { + lvar = vu.item.get_lvar(); + } + } else if (vu.item.citype == VDI_LVAR) { + lvar = vu.item.get_lvar(); + } + + if (lvar != NULL) { + // initialize type rebuilder + type_builder_t type_bldr; + type_bldr.expression_to_match.insert(lvar->name); + // traverse the ctree structure + type_bldr.apply_to(&vu.cfunc->body, NULL); + + if (!type_bldr.structure.empty() && lvar != NULL) { - cexpr_t *highl_expr = (cexpr_t *)highlight; + qstring type_name{ "struct_name" }; + + if (lvar->type().is_ptr()) // doesn't make sense if it's not tbh + (void)lvar->type().get_pointed_object().get_type_name(&type_name); - // initialize type rebuilder - type_builder_t type_bldr; + if (!ask_str(&type_name, 0, "Enter type name:")) + return false; + + tid_t struct_type_id = BADADDR; + if (!type_name.empty()) { - qstring s; - highl_expr->print1(&s, NULL); - tag_remove(&s); - type_bldr.expression_to_match.insert(s); + struct_type_id = type_bldr.get_structure(type_name); } - // traverse the ctree structure - type_bldr.apply_to(&vu.cfunc->body, NULL); - // get local var information - lvar_t *lvar = vu.item.get_lvar(); - if (!type_bldr.structure.empty() && lvar != NULL) - { - qstring type_name{ "struct_name" }; - if (!ask_str(&type_name, NULL, "Enter type name:")) - return false; - if (!type_name.empty()) + if (struct_type_id != BADADDR) + { + tinfo_t new_type = create_typedef(type_name.c_str()); + if (new_type.is_correct()) { - tid_t struct_type_id = type_bldr.get_structure(type_name); - if (struct_type_id != BADADDR) + qstring type_str; + if (new_type.print(&type_str, NULL, PRTYPE_DEF | PRTYPE_MULTI)) { - tinfo_t new_type = create_typedef(type_name.c_str()); - if (new_type.is_correct()) - { - qstring type_str; - if (new_type.print(&type_str, NULL, PRTYPE_DEF | PRTYPE_MULTI)) - { - msg("New type created:\r\n%s\n", type_str.c_str()); - logmsg(DEBUG, ("New type created:\r\n%s\n", type_str.c_str())); - tinfo_t ptype = make_pointer(new_type); - vu.set_lvar_type(lvar, ptype); - vu.refresh_ctext(); - return true; - } - } + msg("New type created:\r\n%s\n", type_str.c_str()); + logmsg(DEBUG, "New type created:\r\n%s\n", type_str.c_str()); + tinfo_t ptype = make_pointer(new_type); + vu.set_lvar_type(lvar, ptype); + vu.refresh_ctext(); + return true; } } } - else - { - warning("Failed to reconstruct type, no field references have been found ...\n"); - logmsg(DEBUG, "Failed to reconstruct type, no field references have been found ...\n"); - return false; - } + + warning("Invalid type name: %s", type_name.c_str()); + logmsg(DEBUG, "Invalid type name: %s", type_name.c_str()); + return false; + } + else + { + warning("Failed to reconstruct type, no field references have been found ...\n"); + logmsg(DEBUG, "Failed to reconstruct type, no field references have been found ...\n"); + return false; } } @@ -654,7 +665,7 @@ bool idaapi reconstruct_type(cfuncptr_t cfunc, const qstring& var_name, const qs if(new_type.is_correct()) { qstring type_str = type_name; //if (new_type.print(&type_str, NULL, PRTYPE_DEF | PRTYPE_MULTI)) - logmsg(DEBUG, ("New type created: %s\n", type_str.c_str())); + logmsg(DEBUG, "New type created: %s\n", type_str.c_str()); bResult = true; }