bool idaapi type_builder_t::check_memptr(struct_filed &str_fld) { // check if it has at least two parents if ( parents.size() > 2 ) { citem_t *parent_1 = parents.back(); // check if its parent is memptr if(parent_1->is_expr() && (parent_1->op == cot_memptr)) { citem_t *parent_2 = parents[parents.size() - 2]; citem_t *parent_3 = NULL; int num = 0; int off = 0; // check presence of the helper block bool bHelper = check_helper(parent_2, off, num); if(bHelper) parent_3 = parents[parents.size() - 3]; else parent_3 = parent_2; if(parent_2->is_expr() && (parent_2->op == cot_asg)) { cexpr_t *expr = (cexpr_t *)parent_1; if(bHelper) { str_fld.offset = expr->m + off; str_fld.size = num; } else { str_fld.offset = expr->m; str_fld.size = expr->ptrsize; } return true; } } } return false; }
bool idaapi type_builder_t::check_ptr(struct_filed &str_fld) { // check if it has at least three parents if ( parents.size() > 2 ) { citem_t *parent_1 = parents.back(); int offset = 0; int parent_idx = 1; // if its parent is addition if(parent_1->is_expr() && (parent_1->op == cot_add)) { parent_idx ++; cexpr_t *expr_2 = (cexpr_t *)parent_1; // get index_value char buff[MAXSTR]; expr_2->y->print1(buff, MAXSTR, NULL); tag_remove(buff, buff, 0); offset = atoi(buff); } citem_t *parent_3 = parents[parents.size() - parent_idx]; if(parent_3->is_expr() && (parent_3->op == cot_cast)) parent_idx ++; citem_t *parent_4 = parents[parents.size() - parent_idx]; if(parent_4->is_expr() && (parent_4->op == cot_ptr)) { parent_idx ++; citem_t *parent_5 = parents[parents.size() - parent_idx]; int num_hlpr = 0; int off_hlpr = 0; bool bHelper = check_helper(parent_5, off_hlpr, num_hlpr); if(bHelper) parent_idx ++; citem_t *parent_6 = parents[parents.size() - parent_idx]; if(parent_6->is_expr() && (parent_6->op == cot_asg)) { cexpr_t *expr_4 = (cexpr_t *)parent_4; if(bHelper) { str_fld.offset = offset + off_hlpr; str_fld.size = num_hlpr; } else { str_fld.offset = offset; str_fld.size = expr_4->ptrsize; } return true; } } } return false; }
bool idaapi type_builder_t::check_ptr(cexpr_t *e, struct_filed &str_fld) { str_fld.offset = 0; str_fld.size = 0; str_fld.vftbl = BADADDR; type_reference referInfo; referInfo.init(e); qstring dbg_info; bool done = false; int par_size = parents.size(); // check if it has at least three parents if ( par_size > 2 ) { int offset = 0; int parent_idx = 1; int num = 0; int off = 0; for (size_t i = 0 ; i < parents.size() - 1 ; i ++) { citem_t *parent_i = parents[parents.size() - i - 1]; // if its parent is addition if(parent_i->is_expr() && (parent_i->op == cot_add)) { cexpr_t *expr_2 = (cexpr_t *)parent_i; // get index_value char buff[MAXSTR]; expr_2->y->print1(buff, MAXSTR, NULL); tag_remove(buff, buff, 0); int base = 10; if (strncmp(buff, "0x", 2) == 0) base = 16; offset = strtol(buff, NULL, base); referInfo.update_offset(offset); } else if(parent_i->is_expr() && (parent_i->op == cot_cast)) { referInfo.update_type((cexpr_t *)parent_i); } else if(parent_i->is_expr() && check_helper((cexpr_t *)parent_i, off, num)) { referInfo.update_hlpr(off, num); } else if(parent_i->is_expr() && (parent_i->op == cot_ptr)) { referInfo.update_size(((cexpr_t *)parent_i)->ptrsize); citem_t *parent_ii = parents[parents.size() - i - 2]; // check the r-value for a pointer to vftable if ((parent_ii->is_expr()) && (((cexpr_t *)parent_ii)->op == cot_asg) && (((cexpr_t *)parent_ii)->x == parent_i)) { ea_t vftbl = get_vftbl(((cexpr_t *)parent_ii)->y); if (vftbl != BADADDR) str_fld.vftbl = vftbl; } done = true; break; } else if(parent_i->is_expr() && (parent_i->op == cot_memptr)) { referInfo.update_offset(((cexpr_t *)parent_i)->m); referInfo.update_size(((cexpr_t *)parent_i)->ptrsize); done = true; break; } else if(parent_i->is_expr() && (parent_i->op == cot_asg)) { if (((cexpr_t *)parent_i)->y == e) { //parents[parents.size() - i]) { char expr_name[MAXSTR]; ((cexpr_t *)parent_i)->x->print1(expr_name, MAXSTR, NULL); tag_remove(expr_name, expr_name, 0); char comment[258]; memset(comment, 0x00, sizeof(comment)); sprintf_s(comment, sizeof(comment), "monitoring %s\r\n", expr_name); msg(comment); expression_to_match.push_back(expr_name); } else { get_vftbl(((cexpr_t *)parent_i)->y); } done = true; break; } else if(parent_i->is_expr() && (parent_i->op == cot_call)) { done = true; break; } } } if(done) { str_fld.offset = referInfo.get_offset(); str_fld.size = referInfo.get_size(); if (str_fld.size == 0) { str_fld.size = 4; } if (str_fld.vftbl != BADADDR) { char tmp[1024]; memset(tmp, 0x00, sizeof(tmp)); sprintf_s(tmp, sizeof(tmp), "possible vftbl reference detected at offset 0x%X, ea=0x%08X\r\n", str_fld.offset, str_fld.vftbl); msg(tmp); } } return done; }
bool idaapi type_builder_t::check_ptr(cexpr_t *e, struct_filed &str_fld) { type_reference referInfo; referInfo.init(e); qstring dbg_info; bool done = false; int par_size = parents.size(); // check if it has at least three parents if ( par_size > 2 ) { int offset = 0; int parent_idx = 1; int num = 0; int off = 0; for (size_t i = 0 ; i < parents.size() - 1 ; i ++) { citem_t *parent_i = parents[parents.size() - i - 1]; // if its parent is addition if(parent_i->is_expr() && (parent_i->op == cot_add)) { cexpr_t *expr_2 = (cexpr_t *)parent_i; // get index_value char buff[MAXSTR]; expr_2->y->print1(buff, MAXSTR, NULL); tag_remove(buff, buff, 0); offset = atoi(buff); referInfo.update_offset(offset); } else if(parent_i->is_expr() && (parent_i->op == cot_cast)) { referInfo.update_type((cexpr_t *)parent_i); } else if(parent_i->is_expr() && check_helper((cexpr_t *)parent_i, off, num)) { referInfo.update_hlpr(off, num); } else if(parent_i->is_expr() && (parent_i->op == cot_ptr)) { referInfo.update_size(((cexpr_t *)parent_i)->ptrsize); done = true; break; } else if(parent_i->is_expr() && (parent_i->op == cot_memptr)) { referInfo.update_offset(((cexpr_t *)parent_i)->m); referInfo.update_size(((cexpr_t *)parent_i)->ptrsize); done = true; break; } else if(parent_i->is_expr() && (parent_i->op == cot_asg)) { done = true; break; } else if(parent_i->is_expr() && (parent_i->op == cot_call)) { done = true; break; } } } if(done) { str_fld.offset = referInfo.get_offset(); str_fld.size = referInfo.get_size(); if (str_fld.size == 0) { str_fld.size = 4; } } return done; }