diff --git a/irdb-libs/ir_builders/fill_in_cfg.cpp b/irdb-libs/ir_builders/fill_in_cfg.cpp index 1b2f3965a3f40429c65f892fd9e68497e89dd28d..c6c39475e321217ff464e07a19c398a2ab71989f 100644 --- a/irdb-libs/ir_builders/fill_in_cfg.cpp +++ b/irdb-libs/ir_builders/fill_in_cfg.cpp @@ -31,6 +31,16 @@ using namespace std; using namespace EXEIO; using namespace IRDB_SDK; +using namespace PopCFG; + +template < typename T > +static inline std::string to_hex_string( const T& n ) +{ + std::ostringstream stm ; + stm << std::hex<< "0x"<< n ; + return stm.str() ; +} + void PopulateCFG::populate_instruction_map ( @@ -209,7 +219,7 @@ void PopulateCFG::add_new_instructions(FileIR_t *firp) - int secnum = elfiop->sections.size(); + int secnum = exeiop->sections.size(); int secndx=0; bool found=false; @@ -218,25 +228,25 @@ void PopulateCFG::add_new_instructions(FileIR_t *firp) for (secndx=1; secndx<secnum; secndx++) { /* not a loaded section */ - if( !elfiop->sections[secndx]->isLoadable()) + if( !exeiop->sections[secndx]->isLoadable()) continue; /* loaded, and contains instruction, record the bounds */ - if( !elfiop->sections[secndx]->isExecutable()) + if( !exeiop->sections[secndx]->isExecutable()) continue; - VirtualOffset_t first=elfiop->sections[secndx]->get_address(); - VirtualOffset_t second=elfiop->sections[secndx]->get_address()+elfiop->sections[secndx]->get_size(); + VirtualOffset_t first=exeiop->sections[secndx]->get_address(); + VirtualOffset_t second=exeiop->sections[secndx]->get_address()+exeiop->sections[secndx]->get_size(); /* is the missed instruction in this section */ if(first<=missed_address && missed_address<second) { - const char* data=elfiop->sections[secndx]->get_data(); + const char* data=exeiop->sections[secndx]->get_data(); // second=data? - VirtualOffset_t offset_into_section=missed_address-elfiop->sections[secndx]->get_address(); + VirtualOffset_t offset_into_section=missed_address-exeiop->sections[secndx]->get_address(); /* disassemble the instruction */ - auto disasm_p=DecodedInstruction_t::factory(missed_address, (void*)&data[offset_into_section], elfiop->sections[secndx]->get_size()-offset_into_section ); + auto disasm_p=DecodedInstruction_t::factory(missed_address, (void*)&data[offset_into_section], exeiop->sections[secndx]->get_size()-offset_into_section ); auto &disasm=*disasm_p; @@ -376,27 +386,27 @@ void PopulateCFG::fill_in_cfg(FileIR_t *firp) bool PopulateCFG::is_in_relro_segment(const int secndx) { - ELFIO::elfio *real_elfiop = reinterpret_cast<ELFIO::elfio*>(elfiop->get_elfio()); - if(!real_elfiop) + ELFIO::elfio *real_exeiop = reinterpret_cast<ELFIO::elfio*>(exeiop->get_elfio()); + if(!real_exeiop) return false; - int segnum = real_elfiop->segments.size(); + int segnum = real_exeiop->segments.size(); - VirtualOffset_t sec_start=(VirtualOffset_t)(elfiop->sections[secndx]->get_address()); - VirtualOffset_t sec_end=(VirtualOffset_t)(elfiop->sections[secndx]->get_address() + elfiop->sections[secndx]->get_size() - 1 ); + VirtualOffset_t sec_start=(VirtualOffset_t)(exeiop->sections[secndx]->get_address()); + VirtualOffset_t sec_end=(VirtualOffset_t)(exeiop->sections[secndx]->get_address() + exeiop->sections[secndx]->get_size() - 1 ); /* look through each section */ for (int segndx=1; segndx<segnum; segndx++) { - ELFIO::Elf_Word type=real_elfiop->segments[segndx]->get_type(); + ELFIO::Elf_Word type=real_exeiop->segments[segndx]->get_type(); #ifndef PT_GNU_RELRO #define PT_GNU_RELRO 0x6474e552 /* Read-only after relocation */ #endif if(type==PT_GNU_RELRO) { - VirtualOffset_t seg_start=(VirtualOffset_t)(real_elfiop->segments[segndx]->get_virtual_address()); - VirtualOffset_t seg_end=(VirtualOffset_t)(real_elfiop->segments[segndx]->get_virtual_address() + real_elfiop->segments[segndx]->get_memory_size() - 1 ); + VirtualOffset_t seg_start=(VirtualOffset_t)(real_exeiop->segments[segndx]->get_virtual_address()); + VirtualOffset_t seg_end=(VirtualOffset_t)(real_exeiop->segments[segndx]->get_virtual_address() + real_exeiop->segments[segndx]->get_memory_size() - 1 ); // check if start lies within if(seg_start <= sec_start && sec_start <= seg_end) @@ -419,85 +429,82 @@ void PopulateCFG::fill_in_scoops(FileIR_t *firp) { auto max_base_id=firp->getMaxBaseID(); - auto secnum = elfiop->sections.size(); - auto secndx=0; + auto secnum = exeiop->sections.size(); /* look through each section */ - for (secndx=1; secndx<secnum; secndx++) + for (auto secndx=1; secndx<secnum; secndx++) { /* not a loaded section, try next section */ - if(!elfiop->sections[secndx]->isLoadable()) + if(!exeiop->sections[secndx]->isLoadable()) { - cout<<"Skipping scoop for section (not loadable) "<<elfiop->sections[secndx]->get_name()<<endl; + cout << "Skipping scoop for section (not loadable) " << exeiop->sections[secndx]->get_name() << endl; continue; } - if(elfiop->sections[secndx]->isWriteable() && elfiop->sections[secndx]->isExecutable()) + if(exeiop->sections[secndx]->isWriteable() && exeiop->sections[secndx]->isExecutable()) { ofstream fout("warning.txt"); - fout<<"Found that section "<<elfiop->sections[secndx]->get_name()<<" is both writeable and executable. Program is inherently unsafe!"<<endl; + fout << "Found that section " << exeiop->sections[secndx]->get_name() << " is both writeable and executable. Program is inherently unsafe!" << endl; } /* executable sections handled by zipr/spri. */ - if(elfiop->sections[secndx]->isExecutable()) + if(exeiop->sections[secndx]->isExecutable()) { - cout<<"Skipping scoop for section (executable) "<<elfiop->sections[secndx]->get_name()<<endl; + cout << "Skipping scoop for section (executable) " << exeiop->sections[secndx]->get_name() << endl; continue; } /* name */ - string name=elfiop->sections[secndx]->get_name(); - - /* start address */ - /* - auto startaddr=new AddressID_t(); - assert(startaddr); - startaddr->setVirtualOffset( elfiop->sections[secndx]->get_address()); - startaddr->setFileID(firp->getFile()->getBaseID()); - firp->getAddresses().insert(startaddr); - */ - auto startaddr=firp->addNewAddress(firp->getFile()->getBaseID(), elfiop->sections[secndx]->get_address()); - - /* end */ - /* - auto endaddr=new AddressID_t(); - assert(endaddr); - endaddr->setVirtualOffset( elfiop->sections[secndx]->get_address() + elfiop->sections[secndx]->get_size()-1); - endaddr->setFileID(firp->getFile()->getBaseID()); - firp->getAddresses().insert(endaddr); - */ - auto endaddr=firp->addNewAddress(firp->getFile()->getBaseID(), elfiop->sections[secndx]->get_address() + elfiop->sections[secndx]->get_size()-1); - - - string the_contents; - the_contents.resize(elfiop->sections[secndx]->get_size()); - // deal with .bss segments that are 0 init'd. - if (elfiop->sections[secndx]->get_data()) - the_contents.assign(elfiop->sections[secndx]->get_data(),elfiop->sections[secndx]->get_size()); + const auto name=string(exeiop->sections[secndx]->get_name()); -// Type_t *chunk_type=NULL; /* FIXME -- need to figure out the type system for scoops, but NULL should remain valid */ + /* start and end address */ + auto startaddr = firp->addNewAddress(firp->getFile()->getBaseID(), exeiop->sections[secndx]->get_address()); + auto endaddr = firp->addNewAddress(firp->getFile()->getBaseID(), exeiop->sections[secndx]->get_address() + exeiop->sections[secndx]->get_size()-1); + + + auto the_contents=string(exeiop->sections[secndx]->get_size(), '\0'); + // deal with .bss segments that are 0 init'd. + if (exeiop->sections[secndx]->get_data()) + the_contents.assign(exeiop->sections[secndx]->get_data(),exeiop->sections[secndx]->get_size()); /* permissions */ int permissions= - ( elfiop->sections[secndx]->isReadable() << 2 ) | - ( elfiop->sections[secndx]->isWriteable() << 1 ) | - ( elfiop->sections[secndx]->isExecutable() << 0 ) ; + ( exeiop->sections[secndx]->isReadable() << 2 ) | + ( exeiop->sections[secndx]->isWriteable() << 1 ) | + ( exeiop->sections[secndx]->isExecutable() << 0 ) ; bool is_relro=is_in_relro_segment(secndx); scoops_detected++; - /* - DataScoop_t *newscoop=new DataScoop_t(max_base_id++, name, startaddr, endaddr, NULL, permissions, is_relro, the_contents); - assert(newscoop); - firp->getDataScoops().insert(newscoop); - */ auto newscoop=firp->addNewDataScoop( name, startaddr, endaddr, NULL, permissions, is_relro, the_contents, max_base_id++ ); (void)newscoop; // just give it to the IR - cout<<"Allocated new scoop for section "<<name - <<"("<<hex<<startaddr->getVirtualOffset()<<"-" - <<hex<<endaddr->getVirtualOffset()<<")" - <<" perms="<<permissions<<" relro="<<boolalpha<<is_relro<<endl; + cout << "Allocated new scoop for section " << name + << "(" << hex << startaddr->getVirtualOffset() << "-" + << hex << endaddr->getVirtualOffset() << ")" + << " perms=" << permissions << " relro=" << boolalpha << is_relro << endl; } + for(auto extra_scoop : extra_scoops) + { + const auto start_vo = extra_scoop.first; // start and end offsets in this file + const auto end_vo = extra_scoop.second; + auto startaddr = firp->addNewAddress(firp->getFile()->getBaseID(), start_vo); // start and end address + auto endaddr = firp->addNewAddress(firp->getFile()->getBaseID(), end_vo); + const auto sec = exeiop->sections.findByAddress(start_vo); // section that contains the data + assert(sec); + const auto sec_data = sec->get_data(); // data + const auto scoop_start_ptr = sec_data+(start_vo-sec->get_address()); // relevant start of data + const auto the_contents = string(scoop_start_ptr, end_vo-start_vo+1); + const auto name = string("user_added_")+to_hex_string(start_vo); // name of new segment + const auto permissions = // permissions and relro bit. + ( sec->isReadable() << 2 ) | + ( sec->isWriteable() << 1 ) | + ( sec->isExecutable() << 0 ) ; + const auto is_relro = false; + + // finally, create the new scoop + firp->addNewDataScoop( name, startaddr, endaddr, NULL, permissions, is_relro, the_contents, max_base_id++ ); + + } } @@ -541,7 +548,7 @@ void PopulateCFG::detect_scoops_in_code(FileIR_t *firp) // find section and sanity check. - const auto sec=elfiop->sections.findByAddress(referenced_address); + const auto sec=exeiop->sections.findByAddress(referenced_address); if(sec==nullptr) continue; // only trying to do this for executable chunks, other code deals with @@ -552,27 +559,11 @@ void PopulateCFG::detect_scoops_in_code(FileIR_t *firp) const auto sec_start=sec->get_address(); const auto the_contents=string(&sec_data[referenced_address-sec_start],referenced_size); const auto fileid=firp->getFile()->getBaseID(); - - - /* - auto start_addr=new AddressID_t(BaseObj_t::NOT_IN_DATABASE,fileid,referenced_address); - assert(start_addr); - firp->getAddresses().insert(start_addr); - - auto end_addr=new AddressID_t(BaseObj_t::NOT_IN_DATABASE,fileid,referenced_address+referenced_size-1); - assert(end_addr); - firp->getAddresses().insert(end_addr); - */ auto start_addr=firp->addNewAddress(fileid,referenced_address); auto end_addr =firp->addNewAddress(fileid,referenced_address+referenced_size-1); - const auto name="data_in_text_"+to_string(referenced_address); const auto permissions=0x4; /* R-- */ const auto is_relro=false; - /* - auto newscoop=new DataScoop_t(BaseObj_t::NOT_IN_DATABASE, name, start_addr, end_addr, NULL, permissions, is_relro, the_contents); - firp->getDataScoops().insert(newscoop); - */ auto newscoop=firp->addNewDataScoop(name, start_addr, end_addr, NULL, permissions, is_relro, the_contents); (void)newscoop; @@ -581,6 +572,93 @@ void PopulateCFG::detect_scoops_in_code(FileIR_t *firp) } } +void PopulateCFG::ctor_detection(FileIR_t *firp) +{ + assert(firp); + if(do_ctor_detection == cdt_NO) return; + + const auto is_pe = firp->getArchitecture()->getFileType() == adftPE ; + if(do_ctor_detection == cdt_PE32AUTO && !is_pe) return; + + // is either a PE file and we are in auto detect mode + // or ctor_detection is yes. + assert(is_pe || do_ctor_detection == cdt_YES); + + 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 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= + ptrsize == 8 ? *(uint64_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; + + // now scan the table in reverse order for 1) valid entries, or 2) a -1 terminator. + auto next_addr=null_term_addr-ptrsize; + while(true) + { + // check for flowing + if(next_addr<sec_start) return 0; + + // get the table entry + const auto ctor_entry_value= + ptrsize == 8 ? *(uint64_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; + + // check if the table entry isn't a valid address + const auto is_before_start = ctor_entry_value < sec->get_address() ; + const auto is_after_end = ctor_entry_value > (sec->get_address()+sec->get_size()); + if(is_before_start || is_after_end) return 0; + + next_addr -= ptrsize; + } + }; + + auto create_ctor_scoop=[&](const string& name, const VirtualOffset_t& start_vo, const VirtualOffset_t& end_vo) + { + auto startaddr = firp->addNewAddress(firp->getFile()->getBaseID(), start_vo); // start and end address + auto endaddr = firp->addNewAddress(firp->getFile()->getBaseID(), end_vo); + const auto sec = exeiop->sections.findByAddress(start_vo); // section that contains the data + assert(sec); + const auto sec_data = sec->get_data(); // data + const auto scoop_start_ptr = sec_data+(start_vo-sec->get_address()); // relevant start of data + const auto the_contents = string(scoop_start_ptr, end_vo-start_vo+1); + const auto permissions = // permissions and relro bit. + ( sec->isReadable() << 2 ) | + ( sec->isWriteable() << 1 ) | + ( sec->isExecutable() << 0 ) ; + const auto is_relro = false; + + // finally, create the new scoop + firp->addNewDataScoop( name, startaddr, endaddr, NULL, permissions, is_relro, the_contents); + }; + + const auto text_sec = exeiop->sections[".text"]; + if(text_sec == nullptr) return; + const auto text_end_addr = text_sec->get_address()+text_sec->get_size(); + const auto dtor_end = text_end_addr-1; + const auto dtor_start = find_ctor_start(text_sec,text_end_addr); + if(dtor_start==0) return; + create_ctor_scoop(".dtor", dtor_start, dtor_end); + + const auto ctor_end = dtor_start-1; + const auto ctor_start = find_ctor_start(text_sec,dtor_start); + if(ctor_start==0) return; + create_ctor_scoop(".ctor", ctor_start, ctor_end); + return; + +} + void PopulateCFG::fill_in_landing_pads(FileIR_t *firp) { const auto eh_frame_rep_ptr = split_eh_frame_t::factory(firp); @@ -639,15 +717,6 @@ void PopulateCFG::fill_in_landing_pads(FileIR_t *firp) int PopulateCFG::parseArgs(const vector<string> step_args) { -#if 0 - if(step_args.size()<1) - { - cerr<<"Usage: [--fix-landing-pads | --no-fix-landing-pads]"<<endl; - return -1; - } -#endif - -// variant_id = stoi(step_args[0]); for (auto i = 0u; i < step_args.size(); ++i) { @@ -659,6 +728,27 @@ int PopulateCFG::parseArgs(const vector<string> step_args) { fix_landing_pads = false; } + else if (step_args[i]=="--extra-scoop") + { + i++; + const auto extra_scoops_str=step_args[i]; + stringstream ss(extra_scoops_str); + auto start_addr = VirtualOffset_t(0); + auto end_addr = VirtualOffset_t(0); + auto c = uint8_t(0); + ss>>hex>>start_addr>>c>>end_addr; + assert(c=='-'); + extra_scoops.insert({start_addr,end_addr}); + cout << "Recognizing request to add " << hex << start_addr << "-" << end_addr << " as a scoop."<<endl; + } + else if (step_args[i]=="--do-ctor-detection") + { + do_ctor_detection=cdt_YES; + } + else if (step_args[i]=="--no-ctor-detection") + { + do_ctor_detection=cdt_NO; + } } cout<<"fix_landing_pads="<<fix_landing_pads<<endl; @@ -674,7 +764,7 @@ void PopulateCFG::rename_start(FileIR_t *firp) if(!entry_point_insn) continue; const auto entry_point_vo = entry_point_insn->getAddress()->getVirtualOffset(); - if(entry_point_vo==elfiop->get_entry()) + if(entry_point_vo==exeiop->get_entry()) f->setName("_start"); } } @@ -696,19 +786,14 @@ int PopulateCFG::executeStep() assert(firp); cout<<"Filling in cfg for "<<firp->getFile()->getURL()<<endl; - /* get the OID of the file */ - const int elfoid=firp->getFile()->getELFOID(); - - pqxx::largeobject lo(elfoid); - lo.to_file(pqxx_interface->getTransaction(),"readeh_tmp_file.exe"); - - elfiop.reset(new exeio()); - elfiop->load(string("readeh_tmp_file.exe")); + exeiop.reset(new exeio()); + exeiop->load(string("a.ncexe")); rename_start(firp); fill_in_cfg(firp); fill_in_scoops(firp); detect_scoops_in_code(firp); + ctor_detection(firp); if (fix_landing_pads) { diff --git a/irdb-libs/ir_builders/fill_in_cfg.hpp b/irdb-libs/ir_builders/fill_in_cfg.hpp index 8af546a6a9c9ad8d46dccee1920dd4f2d75968ca..b093d166f408d7740c56f24cfb1c7dc4efdd963a 100644 --- a/irdb-libs/ir_builders/fill_in_cfg.hpp +++ b/irdb-libs/ir_builders/fill_in_cfg.hpp @@ -6,92 +6,114 @@ #include <map> #include <exeio.h> -class PopulateCFG : public IRDB_SDK::TransformStep_t +namespace PopCFG { - public: - PopulateCFG(IRDB_SDK::DatabaseID_t p_variant_id = 0, - bool p_fix_landing_pads = true - ) - : - variant_id(p_variant_id), - fix_landing_pads(p_fix_landing_pads) - { - odd_target_count = 0; - bad_target_count = 0; - bad_fallthrough_count = 0; - failed_target_count = 0U; + using namespace std; + using namespace IRDB_SDK; + using namespace EXEIO; - targets_set=0; - fallthroughs_set=0; - scoops_detected=0; + class PopulateCFG : public TransformStep_t + { + using extra_scoop_set_t = set<pair<VirtualOffset_t,VirtualOffset_t> >; + extra_scoop_set_t extra_scoops; - elfiop = std::unique_ptr<EXEIO::exeio>(nullptr); - } + public: + PopulateCFG(DatabaseID_t p_variant_id = 0, + bool p_fix_landing_pads = true + ) + : + variant_id(p_variant_id), + fix_landing_pads(p_fix_landing_pads) + { + odd_target_count = 0; + bad_target_count = 0; + bad_fallthrough_count = 0; + failed_target_count = 0U; - ~PopulateCFG(void) override - { - // do nothing (this class uses shared IRDB objects that - // are not managed by this class). - } - - std::string getStepName(void) const override - { - return std::string("fill_in_cfg"); - } - int parseArgs(const std::vector<std::string> step_args) override; - int executeStep() override; - - private: // methods - - // main workers - void fill_in_cfg(IRDB_SDK::FileIR_t *); - void fill_in_scoops(IRDB_SDK::FileIR_t *); - void detect_scoops_in_code(IRDB_SDK::FileIR_t *firp); - void fill_in_landing_pads(IRDB_SDK::FileIR_t *); - void rename_start(IRDB_SDK::FileIR_t *firp); + targets_set=0; + fallthroughs_set=0; + scoops_detected=0; + + } + + ~PopulateCFG(void) override + { + // do nothing (this class uses shared IRDB objects that + // are not managed by this class). + } + + string getStepName(void) const override + { + return string("fill_in_cfg"); + } + int parseArgs(const vector<string> step_args) override; + int executeStep() override; + + private: // methods + + // main workers + void fill_in_cfg(FileIR_t *); + void fill_in_scoops(FileIR_t *); + void detect_scoops_in_code(FileIR_t *firp); + void ctor_detection(FileIR_t *firp); + void fill_in_landing_pads(FileIR_t *); + void rename_start(FileIR_t *firp); + + + // helpers + void populate_instruction_map + ( + map< pair<DatabaseID_t,VirtualOffset_t>, + Instruction_t*>&, + FileIR_t * + ); + + void set_fallthrough + ( + map< pair<DatabaseID_t,VirtualOffset_t>, + Instruction_t*>&, + DecodedInstruction_t *, + Instruction_t *, + FileIR_t * + ); + + void set_target + ( + map< pair<DatabaseID_t,VirtualOffset_t>, + Instruction_t*>&, + DecodedInstruction_t *, + Instruction_t *, + FileIR_t * + ); + + File_t* find_file(FileIR_t *, DatabaseID_t); + void add_new_instructions(FileIR_t *); + bool is_in_relro_segment(const int); + + private: //data + + // stats + int odd_target_count=0; + int bad_target_count=0; + int bad_fallthrough_count=0; + unsigned int failed_target_count=0; - - // helpers - void populate_instruction_map - ( - std::map< std::pair<IRDB_SDK::DatabaseID_t,IRDB_SDK::VirtualOffset_t>, IRDB_SDK::Instruction_t*>&, - IRDB_SDK::FileIR_t * - ); - - void set_fallthrough - ( - std::map< std::pair<IRDB_SDK::DatabaseID_t,IRDB_SDK::VirtualOffset_t>, IRDB_SDK::Instruction_t*>&, - IRDB_SDK::DecodedInstruction_t *, IRDB_SDK::Instruction_t *, IRDB_SDK::FileIR_t * - ); - - void set_target - ( - std::map< std::pair<IRDB_SDK::DatabaseID_t,IRDB_SDK::VirtualOffset_t>, IRDB_SDK::Instruction_t*>&, - IRDB_SDK::DecodedInstruction_t *, IRDB_SDK::Instruction_t *, IRDB_SDK::FileIR_t * - ); - - IRDB_SDK::File_t* find_file(IRDB_SDK::FileIR_t *, IRDB_SDK::DatabaseID_t); - void add_new_instructions(IRDB_SDK::FileIR_t *); - bool is_in_relro_segment(const int); - - private: //data - - // stats - int odd_target_count; - int bad_target_count; - int bad_fallthrough_count; - unsigned int failed_target_count; + // check for ctor/dtors at end of .text section? + using ctor_detection_t = enum ctor_detection { cdt_PE32AUTO, cdt_YES, cdt_NO }; + + ctor_detection_t do_ctor_detection=cdt_PE32AUTO; // flexi-default: -1 means detected pe32+ files and do it, 0 means don't and 1 means do it. - size_t targets_set=0; - size_t fallthroughs_set=0; - size_t scoops_detected=0; - - // non-optional - IRDB_SDK::DatabaseID_t variant_id; - bool fix_landing_pads; - - std::unique_ptr<EXEIO::exeio> elfiop; - std::set< std::pair<IRDB_SDK::DatabaseID_t,IRDB_SDK::VirtualOffset_t> > missed_instructions; -}; + size_t targets_set=0; + size_t fallthroughs_set=0; + size_t scoops_detected=0; + + // non-optional + DatabaseID_t variant_id=BaseObj_t::NOT_IN_DATABASE; + bool fix_landing_pads=false; + + unique_ptr<exeio> exeiop; + set< pair<DatabaseID_t,VirtualOffset_t> > missed_instructions; + }; +} #endif diff --git a/irdb-libs/ir_builders/fill_in_indtargs.cpp b/irdb-libs/ir_builders/fill_in_indtargs.cpp index e843e6eb1e0f1aee278c42fae4ac4d89a5f7dbf8..cc39c346d44b7c9384affcb2f5dbaada223ec376 100644 --- a/irdb-libs/ir_builders/fill_in_indtargs.cpp +++ b/irdb-libs/ir_builders/fill_in_indtargs.cpp @@ -236,8 +236,9 @@ void mark_targets(FileIR_t *firp) /* lookup in the list of targets */ if(targets.find(addr)!=targets.end()) { - const auto isret=targets[addr].areOnlyTheseSet(ibt_provenance_t::ibtp_ret); - const auto isprintf=targets[addr].areOnlyTheseSet(ibt_provenance_t::ibtp_stars_data|ibt_provenance_t::ibtp_texttoprintf); + const auto isret = targets[addr].areOnlyTheseSet(ibt_provenance_t::ibtp_ret); + const auto isprintf = targets[addr].areOnlyTheseSet(ibt_provenance_t::ibtp_stars_data|ibt_provenance_t::ibtp_texttoprintf) && + targets[addr].isFullySet (ibt_provenance_t::ibtp_stars_data|ibt_provenance_t::ibtp_texttoprintf); if (isret) { if(getenv("IB_VERBOSE")!=nullptr) @@ -2440,7 +2441,7 @@ void read_stars_xref_file(FileIR_t* firp) for(auto insn : firp->getInstructions()) { const auto irdb_vo = insn->getAddress()->getVirtualOffset(); - const auto vo=VirtualOffset_t(irdb_vo); + const auto vo=MEDS_Annotation::VirtualOffset(irdb_vo); /* find it in the annotations */ const auto ret = annotationParser.getAnnotations().equal_range(vo); diff --git a/irdb-libs/libEXEIO/include/exeio.h b/irdb-libs/libEXEIO/include/exeio.h index f27c8556d7af114c2759766074643f751156ea5d..1bb3a06d56c6f2f7ddf745f014f2c5c8ffb02fb2 100644 --- a/irdb-libs/libEXEIO/include/exeio.h +++ b/irdb-libs/libEXEIO/include/exeio.h @@ -50,7 +50,8 @@ namespace EXEIO virtual execlass_t get_class() =0; virtual MachineType_t getMachineType() const =0; virtual virtual_offset_t get_entry() =0; - virtual void* get_elfio() { return NULL; } + virtual void* get_elfio() { return NULL; } + virtual void* get_pebliss() { return NULL; } virtual bool isDLL() =0; virtual bool isDynamicallyLinked() { return true; } @@ -120,7 +121,8 @@ namespace EXEIO virtual void dump_section_headers(std::ostream& stream) { assert(backend); backend->dump_section_headers(stream); } virtual execlass_t get_class() { assert(backend); return backend->get_class(); } virtual MachineType_t getMachineType() const { assert(backend); return backend->getMachineType(); } - virtual void* get_elfio() { assert(backend); return backend->get_elfio(); } + virtual void* get_elfio() { assert(backend); return backend->get_elfio() ; } + virtual void* get_pebliss() { assert(backend); return backend->get_pebliss(); } virtual bool isDLL() { assert(backend); return backend->isDLL(); } virtual bool isDynamicallyLinked() { assert(backend); return backend->isDynamicallyLinked(); } diff --git a/irdb-libs/libEXEIO/src/exeio_pe.h b/irdb-libs/libEXEIO/src/exeio_pe.h index 07162ee9cb71b761b7090d76f236fb1121a3a951..4cc157ff238ff68775707e0f9de913a6d080584b 100644 --- a/irdb-libs/libEXEIO/src/exeio_pe.h +++ b/irdb-libs/libEXEIO/src/exeio_pe.h @@ -29,7 +29,7 @@ namespace EXEIO bool isWriteable() const { return s->writeable(); } bool isReadable() const { return s->readable(); } bool isBSS() const { return s->empty(); } - const char* get_data() const { return s->get_raw_data().c_str(); } + const char* get_data() const { return s->get_virtual_data(b->get_section_alignment()).c_str(); } std::string get_name() const { return s->get_name(); } int get_size() const { return s->get_virtual_size(); } int get_type() const { assert(0); } // not imp'd yet @@ -160,10 +160,9 @@ namespace EXEIO return (virtual_offset_t)e->get_ep(); } + virtual bool isDLL() { return true; } - virtual bool isDLL() { assert(0); } - - + virtual void* get_pebliss() { assert(e); return (void*)e; } private: pe_bliss::pe_base* e; diff --git a/irdb-libs/libMEDSannotation/include/MEDS_AnnotationParser.hpp b/irdb-libs/libMEDSannotation/include/MEDS_AnnotationParser.hpp index a65a88db46f47686f318dd583323bd9eb1d57c51..5c493dc95a99f00bdbda4c3dafa4142e9a4d6ba2 100644 --- a/irdb-libs/libMEDSannotation/include/MEDS_AnnotationParser.hpp +++ b/irdb-libs/libMEDSannotation/include/MEDS_AnnotationParser.hpp @@ -29,31 +29,32 @@ namespace MEDS_Annotation { - -typedef std::multimap<const VirtualOffset, MEDS_AnnotationBase*> MEDS_Annotations_t; -typedef std::pair<const VirtualOffset, MEDS_AnnotationBase*> MEDS_Annotations_Pair_t; - -typedef std::multimap<const std::string, MEDS_AnnotationBase*> MEDS_FuncAnnotations_t; -typedef std::pair<const std::string, MEDS_AnnotationBase*> MEDS_Annotations_FuncPair_t; - -class MEDS_AnnotationParser -{ - public: - MEDS_AnnotationParser() {}; - MEDS_AnnotationParser(std::istream &); /* pass opened file */ - void parseFile(std::istream &); - void parseFile(const std::string &); /* pass filename */ - MEDS_Annotations_t & getAnnotations() { return m_annotations; } - MEDS_FuncAnnotations_t & getFuncAnnotations() { return m_func_annotations; } - - private: - // helpers - template <class type> bool add_if_valid(std::string line); - - // data - MEDS_Annotations_t m_annotations; - MEDS_FuncAnnotations_t m_func_annotations; -}; + using namespace std; + + using MEDS_Annotations_t = multimap<const VirtualOffset, MEDS_AnnotationBase*> ; + using MEDS_Annotations_Pair_t = pair<const VirtualOffset, MEDS_AnnotationBase*> ; + + using MEDS_FuncAnnotations_t = multimap<const string, MEDS_AnnotationBase*> ; + using MEDS_Annotations_FuncPair_t = pair<const string, MEDS_AnnotationBase*> ; + + class MEDS_AnnotationParser + { + public: + MEDS_AnnotationParser() {}; + MEDS_AnnotationParser(istream &); /* pass opened file */ + void parseFile(istream &); + void parseFile(const string &); /* pass filename */ + MEDS_Annotations_t & getAnnotations() { return m_annotations; } + MEDS_FuncAnnotations_t & getFuncAnnotations() { return m_func_annotations; } + + private: + // helpers + template <class type> bool add_if_valid(string line); + + // data + MEDS_Annotations_t m_annotations; + MEDS_FuncAnnotations_t m_func_annotations; + }; } diff --git a/irdb-libs/libMEDSannotation/include/VirtualOffset.hpp b/irdb-libs/libMEDSannotation/include/VirtualOffset.hpp index cabc12f221cbe13f9e8744bbb0e02468894f1a47..21682725304eccb04d5260cd8e730392041e9be1 100644 --- a/irdb-libs/libMEDSannotation/include/VirtualOffset.hpp +++ b/irdb-libs/libMEDSannotation/include/VirtualOffset.hpp @@ -27,32 +27,33 @@ namespace MEDS_Annotation { -typedef unsigned long long ApplicationAddress; + using namespace std; + using ApplicationAddress = uint64_t; #define DEFAULT_LIBRARY_NAME "a.out" -class VirtualOffset -{ - public: - VirtualOffset(); - VirtualOffset(const std::string &p_offset, const std::string &p_libraryName); - VirtualOffset(const std::string &p_offset); - VirtualOffset(const int p_offset); - - ApplicationAddress getOffset() const; - std::string getLibraryName() const; - - bool operator < (const VirtualOffset &p_other) const; - bool operator == (const VirtualOffset &p_other) const; - VirtualOffset& operator = (const VirtualOffset &p_other); - - const std::string to_string() const { std::ostringstream oss; oss<<getLibraryName() << "+0x"<<std::hex<<getOffset(); return oss.str(); } - const std::string toString() const { return to_string(); } - - private: - ApplicationAddress m_offset; - std::string m_libraryName; -}; + class VirtualOffset + { + public: + VirtualOffset(); + VirtualOffset(const string &p_offset, const string &p_libraryName); + VirtualOffset(const string &p_offset); + VirtualOffset(const ApplicationAddress p_offset); + + ApplicationAddress getOffset() const; + string getLibraryName() const; + + bool operator < (const VirtualOffset &p_other) const; + bool operator == (const VirtualOffset &p_other) const; + VirtualOffset& operator = (const VirtualOffset &p_other); + + const string to_string() const { ostringstream oss; oss<<getLibraryName() << "+0x"<<hex<<getOffset(); return oss.str(); } + const string toString() const { return to_string(); } + + private: + ApplicationAddress m_offset; + string m_libraryName; + }; } diff --git a/irdb-libs/libMEDSannotation/src/VirtualOffset.cpp b/irdb-libs/libMEDSannotation/src/VirtualOffset.cpp index 1e4ca4f6442438a4de9ec91f326e9c3e4aa25859..55c69949ba978161015ed5eeb7f0cd8f3ec182c5 100644 --- a/irdb-libs/libMEDSannotation/src/VirtualOffset.cpp +++ b/irdb-libs/libMEDSannotation/src/VirtualOffset.cpp @@ -20,7 +20,7 @@ #include <cstdio> #include <iostream> - +#include <inttypes.h> #include "VirtualOffset.hpp" using namespace std; @@ -29,25 +29,25 @@ using namespace MEDS_Annotation; VirtualOffset::VirtualOffset() { m_offset = 0; - m_libraryName = std::string(DEFAULT_LIBRARY_NAME); + m_libraryName = string(DEFAULT_LIBRARY_NAME); } -VirtualOffset::VirtualOffset(const std::string &p_offset, const std::string &p_libraryName) +VirtualOffset::VirtualOffset(const string &p_offset, const string &p_libraryName) { - sscanf(p_offset.c_str(), "%llx", &m_offset); + sscanf(p_offset.c_str(), "%" SCNx64, &m_offset); m_libraryName = p_libraryName; } -VirtualOffset::VirtualOffset(const std::string &p_offset) +VirtualOffset::VirtualOffset(const string &p_offset) { - sscanf(p_offset.c_str(), "%llx", &m_offset); - m_libraryName = std::string(DEFAULT_LIBRARY_NAME); + sscanf(p_offset.c_str(), "%" SCNx64, &m_offset); + m_libraryName = string(DEFAULT_LIBRARY_NAME); } -VirtualOffset::VirtualOffset(const int p_offset) +VirtualOffset::VirtualOffset(const ApplicationAddress p_offset) { m_offset = p_offset; - m_libraryName = std::string(DEFAULT_LIBRARY_NAME); + m_libraryName = string(DEFAULT_LIBRARY_NAME); } ApplicationAddress VirtualOffset::getOffset() const @@ -55,7 +55,7 @@ ApplicationAddress VirtualOffset::getOffset() const return m_offset; } -std::string VirtualOffset::getLibraryName() const +string VirtualOffset::getLibraryName() const { return m_libraryName; }