diff --git a/irdb-libs/ir_builders/fill_in_cfg.cpp b/irdb-libs/ir_builders/fill_in_cfg.cpp index e1f694fd28c7b84093a4cb5f31aa897de958cf8d..8e131c6b5b1dc0e84669bb9755ba2cdd9518fa83 100644 --- a/irdb-libs/ir_builders/fill_in_cfg.cpp +++ b/irdb-libs/ir_builders/fill_in_cfg.cpp @@ -664,15 +664,16 @@ void PopulateCFG::ctor_detection(FileIR_t *firp) auto find_ctor_start=[&](const exeio_section_t* sec, const VirtualOffset_t end_of_ctor) -> VirtualOffset_t { // values needed later for various things - const auto ptrsize = 8; + const auto ptrsize = firp->getArchitectureBitWidth() / 8 ; const auto sec_data = sec->get_data(); const auto sec_start = sec->get_address(); // check for a null terminator at the stated end of table const auto null_term_addr=end_of_ctor-ptrsize; - const auto null_term_value= + const auto null_term_value = ptrsize == 8 ? *(uint64_t*)(sec_data+null_term_addr-sec_start) : - throw invalid_argument("Unknown ptrsize"); + ptrsize == 4 ? *(uint32_t*)(sec_data+null_term_addr-sec_start) : + throw invalid_argument("Unknown ptrsize"); // not found, return this isn't sane. if(null_term_value!=0) return 0; @@ -685,12 +686,14 @@ void PopulateCFG::ctor_detection(FileIR_t *firp) if(next_addr<sec_start) return 0; // get the table entry - const auto ctor_entry_value= + const auto ctor_entry_value = ptrsize == 8 ? *(uint64_t*)(sec_data+next_addr-sec_start) : - throw invalid_argument("Unknown ptrsize"); + ptrsize == 4 ? *(uint32_t*)(sec_data+next_addr-sec_start) : + throw invalid_argument("Unknown ptrsize"); // check for the -1 terminator - if((int64_t)ctor_entry_value==int64_t(-1)) return next_addr; + if(ptrsize == 8 && (int64_t)ctor_entry_value==int64_t(-1)) return next_addr; + if(ptrsize == 4 && (int32_t)ctor_entry_value==int32_t(-1)) return next_addr; // check if the table entry isn't a valid address const auto is_before_start = ctor_entry_value < sec->get_address() ; @@ -718,6 +721,7 @@ void PopulateCFG::ctor_detection(FileIR_t *firp) // finally, create the new scoop firp->addNewDataScoop( name, startaddr, endaddr, NULL, permissions, is_relro, the_contents); + cout << "Added ctor/dtor scoop called " << name << " at " << hex << start_vo << "-" << end_vo << endl; }; const auto text_sec = exeiop->sections[".text"]; diff --git a/irdb-libs/ir_builders/fill_in_indtargs.cpp b/irdb-libs/ir_builders/fill_in_indtargs.cpp index b13d9c2228e26c98a62176226b15c1fd3d6a996f..e8a27bd8085cbef7a199dd02df69aa487796bfed 100644 --- a/irdb-libs/ir_builders/fill_in_indtargs.cpp +++ b/irdb-libs/ir_builders/fill_in_indtargs.cpp @@ -479,6 +479,21 @@ void handle_scoop_scanning(FileIR_t* firp) // check for addresses in scoops in the text section. for(auto scoop : firp->getDataScoops()) { + if(scoop->getName() == ".ctor" || scoop->getName() == ".dtor" ) + { + const auto ptrsize = firp->getArchitectureBitWidth() / 8 ; + const auto &scoop_contents = scoop->getContents(); + for(auto i = 0u; i + ptrsize < scoop_contents.size(); i += ptrsize) + { + const auto ptr = + ptrsize == 8 ? *reinterpret_cast<const uint64_t*>(scoop_contents.c_str() + i) : + ptrsize == 4 ? *reinterpret_cast<const uint32_t*>(scoop_contents.c_str() + i) : + throw invalid_argument("Cannot map ptrsize to deref type"); + possible_target(ptr, scoop->getStart()->getVirtualOffset() + i, ibt_provenance_t::ibtp_data); + } + + } + // test if scoop was added by fill_in_cfg -- make this test better. if(scoop->getName().find("data_in_text_")==string::npos) continue; @@ -547,113 +562,6 @@ set<Instruction_t*> find_in_function(string needle, Function_t *haystack) } -#if 0 -bool backup_until(const string &insn_type_regex_str, - Instruction_t *& prev, - Instruction_t* orig, - const string & stop_if_set="", - bool recursive=false, - uint32_t max_insns=10000u, - uint32_t max_recursions=5u) -{ - - const auto find_or_build_regex=[&] (const string& s) -> regex_t& - { - // declare a freer for regexs so they go away when the program ends. - const auto regex_freer=[](regex_t* to_free) -> void - { - regfree(to_free); - delete to_free; - }; - // keep the map safe from anyone but me using it. - using regex_unique_ptr_t=unique_ptr<regex_t, decltype(regex_freer)>; - static map<string, regex_unique_ptr_t > regexs_used; - - if(s=="") - { - static regex_t empty; - return empty; - } - const auto it=regexs_used.find(s); - if(it==regexs_used.end()) - { - // allocate a new regex ptr - regexs_used.insert(pair<string,regex_unique_ptr_t>(s,move(regex_unique_ptr_t(new regex_t, regex_freer)))); - // and compile it. - auto ®ex_ptr=regexs_used.at(s); - const auto ret=regcomp(regex_ptr.get(), s.c_str(), REG_EXTENDED); - // error check - assert(ret==0); - } - return *regexs_used.at(s).get(); - }; - - - // build regexs. - const auto &preg = find_or_build_regex(insn_type_regex_str); - const auto &stop_expression = find_or_build_regex(stop_if_set); - - - prev=orig; - while(preds[prev].size()==1 && max_insns > 0) - { - // dec max for next loop - max_insns--; - - // get the only item in the list. - prev=*(preds[prev].begin()); - - - // get I7's disassembly - const auto disasm=DecodedInstruction_t::factory(prev); - - // check it's the requested type - if(regexec(&preg, disasm->getDisassembly().c_str(), 0, nullptr, 0) == 0) - return true; - - if(stop_if_set!="") - { - for(const auto operand : disasm->getOperands()) - { - if(operand->isWritten() && regexec(&stop_expression, operand->getString().c_str(), 0, nullptr, 0) == 0) - return false; - } - } - - // otherwise, try backing up again. - } - if(recursive && max_insns > 0 && max_recursions > 0 ) - { - const auto myprev=prev; - // can't just use prev because recursive call will update it. - const auto &mypreds=preds[myprev]; - for(const auto pred : mypreds) - { - prev=pred;// mark that we are here, in case we return true here. - const auto disasm=DecodedInstruction_t::factory(pred); - // check it's the requested type - if(regexec(&preg, disasm->getDisassembly().c_str(), 0, nullptr, 0) == 0) - return true; - if(stop_if_set!="") - { - for(const auto operand : disasm->getOperands()) - { - if(operand->isWritten() && regexec(&stop_expression, operand->getString().c_str(), 0, nullptr, 0) == 0) - return false; - } - } - if(backup_until(insn_type_regex_str, prev, pred, stop_if_set, recursive, max_insns, max_recursions/mypreds.size())) - return true; - - // reset for next call - prev=myprev; - } - } - return false; -} -#endif - - void check_for_arm32_switch_type1( FileIR_t *firp, Instruction_t* insn, @@ -4058,16 +3966,6 @@ set<VirtualOffset_t> forced_pins; int parseArgs(const vector<string> step_args) { - -#if 0 - if(step_args.size()<1) - { - cerr<<"Usage: <id> [--[no-]split-eh-frame] [--[no-]unpin] [addr,...]"<<endl; - exit(-1); - } -#endif - - // variant_id=stoi(step_args[0]); cout<<"Parsing parameters with argc= " << step_args.size()<<endl; // parse dash-style options.