diff --git a/SConscript b/SConscript index afa8168e893ec3b7c765168429fb49dfd4cc094b..a2fc2e5252f99d7d382066d930582f5cb76d08d9 100644 --- a/SConscript +++ b/SConscript @@ -21,10 +21,10 @@ if env.GetOption('clean'): else: # check/install targ-config.h - if not os.path.isfile(os.environ['SECURITY_TRANSFORMS_HOME']+"/include/targ-config.h"): - #print "uname=", sysname, " xx ", nodename, " xx ", release, " xx ", version, " xx ", machine - shutil.copy( os.path.join(os.environ['SECURITY_TRANSFORMS_HOME'],"include",machine,"config.h"), - os.path.join(os.environ['SECURITY_TRANSFORMS_HOME'],"include","targ-config.h")) + #if not os.path.isfile(os.environ['SECURITY_TRANSFORMS_HOME']+"/include/targ-config.h"): + ##print "uname=", sysname, " xx ", nodename, " xx ", release, " xx ", version, " xx ", machine + #shutil.copy( os.path.join(os.environ['SECURITY_TRANSFORMS_HOME'],"include",machine,"config.h"), + #os.path.join(os.environ['SECURITY_TRANSFORMS_HOME'],"include","targ-config.h")) os.chdir(os.environ['SECURITY_TRANSFORMS_HOME']+"/libcapstone") print "Rebuilding libcapstone." @@ -40,17 +40,19 @@ else: -pedi = Command( target = "./testoutput", - source = "./SConscript", - action = os.environ['PEDI_HOME']+"/pedi -m manifest.txt " ) +if "PEDI_HOME" in os.environ: + pedi = Command( target = "./testoutput", + source = "./SConscript", + action = os.environ['PEDI_HOME']+"/pedi -m manifest.txt " ) -env['BASE_IRDB_LIBS']="IRDB-core", "pqxx", "pq", "EXEIO" +env['BASE_IRDB_LIBS']="irdb-core", "pqxx", "pq" if sysname != "SunOS": libPEBLISS=SConscript("pebliss/trunk/pe_lib/SConscript", variant_dir='scons_build/libPEBLISS') # setup libraries needed for linking env['BASE_IRDB_LIBS']=env['BASE_IRDB_LIBS']+("pebliss",) - Depends(pedi,libPEBLISS) + if "PEDI_HOME" in os.environ: + Depends(pedi,libPEBLISS) # pebliss requires iconv, which needs to be explicit on cygwin. if "CYGWIN" in sysname: @@ -59,29 +61,53 @@ if "CYGWIN" in sysname: Export('env') -env.Install("$SECURITY_TRANSFORMS_HOME/lib/", "$SECURITY_TRANSFORMS_HOME/libcapstone/libcapstone.so.4") -env.Command(os.environ['SECURITY_TRANSFORMS_HOME']+"/lib/libcapstone.so", os.environ['SECURITY_TRANSFORMS_HOME']+"/lib/libcapstone.so.4", "ln -s $SOURCE.abspath $TARGET.abspath") +# get the libcapstone.so.[version] file regardless of the version extension +libcapstone_path = Glob(os.environ['SECURITY_TRANSFORMS_HOME']+'/libcapstone/libcapstone.so.*') +assert len(libcapstone_path) <= 1, "More than one candidate for libcapstone.so.[version]?!" + +libcapstone_path = env.Install("$SECURITY_TRANSFORMS_HOME/lib/", libcapstone_path) + +env.Command(os.environ['SECURITY_TRANSFORMS_HOME']+"/lib/libcapstone.so", libcapstone_path, "ln -s $SOURCE.abspath $TARGET.abspath") libcapstone=os.environ['SECURITY_TRANSFORMS_HOME']+"/lib/libcapstone.so" libehp=env.SConscript("libehp/SConscript", variant_dir='scons_build/libehp') libehp=env.Install("$SECURITY_TRANSFORMS_HOME/lib", libehp); -libtransform=SConscript("libtransform/SConscript", variant_dir='scons_build/libtransform') + +libIRDBcore=env.SConscript("libIRDB-core/src/SConscript", variant_dir='scons_build/libIRDB-core') +Depends(libIRDBcore,libcapstone) + +libIRDBcfg=env.SConscript("libIRDB-cfg/src/SConscript", variant_dir='scons_build/libIRDB-cfg') +libIRDButil=env.SConscript("libIRDB-util/src/SConscript", variant_dir='scons_build/libIRDB-util') +libIRDBsyscall=env.SConscript("libIRDB-syscall/src/SConscript", variant_dir='scons_build/libIRDB-syscall') +libElfDep=SConscript("libIRDB-elfdep/src/SConscript", variant_dir='scons_build/libIRDB-elfdep') +libtransform=SConscript("libIRDB-transform/src/SConscript", variant_dir='scons_build/libIRDB-transform') libEXEIO=SConscript("libEXEIO/SConscript", variant_dir='scons_build/libEXEIO') #libbea=SConscript("beaengine/SConscript", variant_dir='scons_build/beaengine') + libMEDSannotation=SConscript("libMEDSannotation/SConscript", variant_dir='scons_build/libMEDSannotation') -libxform=SConscript("xform/SConscript", variant_dir='scons_build/libxform') -libIRDB=SConscript("libIRDB/SConscript", variant_dir='scons_build/libIRDB') -Depends(libIRDB,libcapstone) +# libxform=SConscript("xform/SConscript", variant_dir='scons_build/libxform') +# libIRDB=SConscript("libIRDB/SConscript", variant_dir='scons_build/libIRDB') +# Depends(libIRDB,libcapstone) libStructDiv=SConscript("libStructDiv/SConscript", variant_dir='scons_build/libStructDiv') -libElfDep=SConscript("libElfDep/SConscript", variant_dir='scons_build/libElfDep') - +thanos=SConscript("thanos/SConscript", variant_dir='scons_build/thanos') +rida=SConscript("rida/SConscript", variant_dir='scons_build/rida') +meds2pdb=SConscript("meds2pdb/SConscript", variant_dir='scons_build/meds2pdb') +dump_map=SConscript("dump_map/SConscript", variant_dir='scons_build/dump_map') +dump_insns=SConscript("dump_insns/SConscript", variant_dir='scons_build/dump_insns') +ir_builders=SConscript("ir_builders/SConscript", variant_dir='scons_build/ir_builders') -Depends(pedi, (libehp,libtransform,libEXEIO,libMEDSannotation,libxform,libIRDB,libStructDiv,libElfDep, libcapstone)) tools=None if 'build_tools' not in env or env['build_tools'] is None or int(env['build_tools']) == 1: tools=SConscript("tools/SConscript", variant_dir='scons_build/tools') - Depends(pedi,tools) + if "PEDI_HOME" in os.environ: + Depends(pedi,tools) -Default( pedi ) +if "PEDI_HOME" in os.environ: + Depends(pedi, (libIRDBcore, libIRDBcfg, libIRDButil, libIRDBcore, libehp,libtransform,libEXEIO,libMEDSannotation,libStructDiv,libElfDep, libcapstone, thanos, rida, meds2pdb, dump_map, dump_insns, ir_builders)) + Default( pedi ) +else: + Default(libIRDBcore, libIRDBcfg, libIRDButil, libIRDBcore, libehp,libtransform,libEXEIO,libMEDSannotation,libStructDiv,libElfDep, libcapstone, thanos, rida, meds2pdb, dump_map, dump_insns, ir_builders) + if 'build_tools' not in env or env['build_tools'] is None or int(env['build_tools']) == 1: + Default(tools) diff --git a/SConstruct b/SConstruct index 0aebd26be2fc36817236fea21f095712beb6d0a9..1fe720b55f5bd58cbaba194eed003ab966294b4f 100644 --- a/SConstruct +++ b/SConstruct @@ -15,14 +15,16 @@ env.Replace(LINKFLAGS="-fPIC -fmax-errors=2 -Wall -Werror -fmax-errors=2 ") # parse arguments env.Replace(SECURITY_TRANSFORMS_HOME=os.environ['SECURITY_TRANSFORMS_HOME']) -env.Replace(PEDI_HOME=os.environ['PEDI_HOME']) -env.Replace(SMPSA_HOME=os.environ['SMPSA_HOME']) +env.Replace(IRDB_SDK=os.environ['IRDB_SDK']) +#env.Replace(SMPSA_HOME=os.environ['SMPSA_HOME']) env.Replace(do_64bit_build=ARGUMENTS.get("do_64bit_build",None)) env.Replace(debug=ARGUMENTS.get("debug",0)) env.Replace(build_appfw=ARGUMENTS.get("build_appfw", 0)) env.Replace(build_tools=ARGUMENTS.get("build_tools", 1)) env.Replace(build_stars=ARGUMENTS.get("build_stars", 1)) env.Replace(build_cgc=ARGUMENTS.get("build_cgc", 0)) +if 'PEDI_HOME' in os.environ: + env.Replace(PEDI_HOME=os.environ['PEDI_HOME']) env.Append(LINKFLAGS=" -Wl,-unresolved-symbols=ignore-in-shared-libs ") diff --git a/cicd_tests/elfdep.sh b/cicd_tests/elfdep.sh index 9ba43c87cd0d7e134e0a9b54f5278e6faed9c0c7..9046a1eacfd745674aa806f6ecd1b60ec44de76e 100755 --- a/cicd_tests/elfdep.sh +++ b/cicd_tests/elfdep.sh @@ -5,5 +5,5 @@ set -x cd $CICD_MODULE_WORK_DIR/peasoup_umbrella source set_env_vars -cd $SECURITY_TRANSFORMS_HOME/libElfDep/test/ +cd $SECURITY_TRANSFORMS_HOME/libIRDB-elfdep/test/ ./test-elfdep.sh diff --git a/tools/dump_insns/Makefile.in b/dump_insns/Makefile.in similarity index 100% rename from tools/dump_insns/Makefile.in rename to dump_insns/Makefile.in diff --git a/tools/dump_insns/SConscript b/dump_insns/SConscript similarity index 67% rename from tools/dump_insns/SConscript rename to dump_insns/SConscript index c8e05de6c0ca04b4fd1661b60c3a4a812e166e27..a087b1bb3ea468eecca4f5a555bbbcce1f73306d 100644 --- a/tools/dump_insns/SConscript +++ b/dump_insns/SConscript @@ -7,10 +7,7 @@ myenv=env.Clone() myenv.Replace(SECURITY_TRANSFORMS_HOME=os.environ['SECURITY_TRANSFORMS_HOME']) cpppath=''' - $SECURITY_TRANSFORMS_HOME/include - $SECURITY_TRANSFORMS_HOME/libIRDB/include - $SECURITY_TRANSFORMS_HOME/libMEDSannotation/include - $SECURITY_TRANSFORMS_HOME/tools/transforms + $IRDB_SDK/include ''' @@ -22,7 +19,7 @@ myenv.Append(CPPFLAGS="-std=c++11") pgm="dump_insns.exe" LIBPATH="$SECURITY_TRANSFORMS_HOME/lib" -LIBS=Split( env.subst('$BASE_IRDB_LIBS')+ " IRDB-cfg IRDB-util transform MEDSannotation ") +LIBS=Split( env.subst('$BASE_IRDB_LIBS')+ " irdb-cfg irdb-util irdb-transform ") myenv=myenv.Clone(CPPPATH=Split(cpppath)) pgm=myenv.Program(pgm, files, LIBPATH=LIBPATH, LIBS=LIBS) #install=myenv.Install("$SECURITY_TRANSFORMS_HOME/bin/", pgm) diff --git a/libIRDB/src/syscall/SConstruct b/dump_insns/SConstruct similarity index 100% rename from libIRDB/src/syscall/SConstruct rename to dump_insns/SConstruct diff --git a/tools/dump_insns/dump_insns.cpp b/dump_insns/dump_insns.cpp similarity index 66% rename from tools/dump_insns/dump_insns.cpp rename to dump_insns/dump_insns.cpp index 7ed5b15c197e0f102f0a1f55e1d76bd7be876687..a51b71f075f94bcbf23ab525dc336ecce1c1d2f5 100644 --- a/tools/dump_insns/dump_insns.cpp +++ b/dump_insns/dump_insns.cpp @@ -20,14 +20,14 @@ #include <stdlib.h> #include <fstream> -#include <libIRDB-core.hpp> +#include <irdb-core> #include <libgen.h> #include <iomanip> #include <algorithm> using namespace std; -using namespace libIRDB; +using namespace IRDB_SDK; void usage(char* name) { @@ -48,46 +48,51 @@ int main(int argc, char **argv) string programName(argv[0]); int variantID = atoi(argv[1]); - VariantID_t *pidp=NULL; /* setup the interface to the sql server */ - pqxxDB_t pqxx_interface; - BaseObj_t::SetInterface(&pqxx_interface); + auto pqxx_interface=pqxxDB_t::factory(); + BaseObj_t::setInterface(pqxx_interface.get()); - pidp=new VariantID_t(variantID); - assert(pidp->IsRegistered()==true); + auto pidp=VariantID_t::factory(variantID); + assert(pidp->isRegistered()==true); bool one_success = false; - for(set<File_t*>::iterator it=pidp->GetFiles().begin(); - it!=pidp->GetFiles().end(); + for(set<File_t*>::iterator it=pidp->getFiles().begin(); + it!=pidp->getFiles().end(); ++it) { File_t* this_file = *it; try { - FileIR_t *firp = new FileIR_t(*pidp, this_file); + auto firp = FileIR_t::factory(pidp.get(), this_file); assert(firp && pidp); - for(auto insn : firp->GetInstructions()) + for(auto insn : firp->getInstructions()) { assert(insn); - const auto d=DecodedInstruction_t(insn); + const auto p_d=DecodedInstruction_t::factory(insn); + const auto &d=*p_d; const auto &operands=d.getOperands(); cout<<" "<<d.getDisassembly()<<endl; int op_count=0; - for(auto op : operands) + for(const auto p_op : operands) { + const auto &op=*p_op; auto readWriteString= string(); if(op.isRead()) readWriteString += "READ "; if(op.isWritten()) readWriteString += "WRITE "; - cout<<"\t"<<"operand["<<op_count<<"]="<<op.getString()<<" rw="<<readWriteString - <<boolalpha<<"isGPReg="<<op.isGeneralPurposeRegister()<<" isMem="<<op.isMemory() - << " isImm="<<op.isConstant() << endl; + cout<<"\t"<<"operand["<<op_count<<"]="<<op.getString() << boolalpha + <<" rw=" <<readWriteString + <<" isGPReg="<<op.isGeneralPurposeRegister() + <<" isMem=" <<op.isMemory() + <<" isImm=" <<op.isConstant() + <<" isPcrel="<<op.isPcrel() + << endl; op_count++; } @@ -100,11 +105,11 @@ int main(int argc, char **argv) } catch (DatabaseError_t pnide) { - cerr << programName << ": Unexpected database error: " << pnide << "file url: " << this_file->GetURL() << endl; + cerr << programName << ": Unexpected database error: " << pnide << "file url: " << this_file->getURL() << endl; } catch (...) { - cerr << programName << ": Unexpected error file url: " << this_file->GetURL() << endl; + cerr << programName << ": Unexpected error file url: " << this_file->getURL() << endl; } } // end file iterator @@ -112,7 +117,7 @@ int main(int argc, char **argv) if (one_success) { cout<<"Commiting changes...\n"; - pqxx_interface.Commit(); + pqxx_interface->commit(); } return 0; diff --git a/tools/dump_map/Makefile.in b/dump_map/Makefile.in similarity index 100% rename from tools/dump_map/Makefile.in rename to dump_map/Makefile.in diff --git a/tools/dump_map/SConscript b/dump_map/SConscript similarity index 67% rename from tools/dump_map/SConscript rename to dump_map/SConscript index 7fd50e3ef0fd84d39c08df4430b1009991c7050b..8eaf74bbfcb93d2087ada4d39f0a731348dc235e 100644 --- a/tools/dump_map/SConscript +++ b/dump_map/SConscript @@ -7,10 +7,7 @@ myenv=env.Clone() myenv.Replace(SECURITY_TRANSFORMS_HOME=os.environ['SECURITY_TRANSFORMS_HOME']) cpppath=''' - $SECURITY_TRANSFORMS_HOME/include - $SECURITY_TRANSFORMS_HOME/libIRDB/include - $SECURITY_TRANSFORMS_HOME/libMEDSannotation/include - $SECURITY_TRANSFORMS_HOME/tools/transforms + $IRDB_SDK/include ''' @@ -22,7 +19,7 @@ myenv.Append(CPPFLAGS="-std=c++11") pgm="dump_map.exe" LIBPATH="$SECURITY_TRANSFORMS_HOME/lib" -LIBS=Split( env.subst('$BASE_IRDB_LIBS')+ " IRDB-cfg IRDB-util transform MEDSannotation ") +LIBS=Split( env.subst('$BASE_IRDB_LIBS')+ " irdb-cfg irdb-util irdb-transform ") myenv=myenv.Clone(CPPPATH=Split(cpppath)) pgm=myenv.Program(pgm, files, LIBPATH=LIBPATH, LIBS=LIBS) #install=myenv.Install("$SECURITY_TRANSFORMS_HOME/bin/", pgm) diff --git a/libIRDB/src/util/SConstruct b/dump_map/SConstruct similarity index 100% rename from libIRDB/src/util/SConstruct rename to dump_map/SConstruct diff --git a/tools/dump_map/dump_map.cpp b/dump_map/dump_map.cpp similarity index 57% rename from tools/dump_map/dump_map.cpp rename to dump_map/dump_map.cpp index 9fe268d22b66bfaff9cc2857faf6b5e920a347f8..e9d996a857e6f293119a16e8fc91d29df6f2847c 100644 --- a/tools/dump_map/dump_map.cpp +++ b/dump_map/dump_map.cpp @@ -20,14 +20,14 @@ #include <stdlib.h> #include <fstream> -#include <libIRDB-core.hpp> +#include <irdb-core> #include <libgen.h> #include <iomanip> #include <algorithm> using namespace std; -using namespace libIRDB; +using namespace IRDB_SDK; void usage(char* name) { @@ -37,16 +37,16 @@ void usage(char* name) void dump_icfs(Instruction_t* insn) { - if(insn->GetIBTargets()==NULL) + if(insn->getIBTargets()==NULL) return; - cout<<"\tComplete: "<<boolalpha<<insn->GetIBTargets()->IsComplete()<<endl; - cout<<"\tModComplete: "<<boolalpha<<insn->GetIBTargets()->IsModuleComplete()<<endl; + cout<<"\tComplete: "<<boolalpha<<insn->getIBTargets()->isComplete()<<endl; + cout<<"\tModComplete: "<<boolalpha<<insn->getIBTargets()->isModuleComplete()<<endl; cout<<"\tTargets: "<<endl; - for_each(insn->GetIBTargets()->begin(), insn->GetIBTargets()->end(), [&](const Instruction_t* targ) + for_each(insn->getIBTargets()->begin(), insn->getIBTargets()->end(), [&](const Instruction_t* targ) { - const auto d=DecodedInstruction_t(targ); - cout<<"\t"<<targ->GetBaseID()<<":"<<d.getDisassembly()<<endl; + const auto d=DecodedInstruction_t::factory(targ); + cout<<"\t"<<targ->getBaseID()<<":"<<d->getDisassembly()<<endl; }); } @@ -58,37 +58,35 @@ int main(int argc, char **argv) exit(1); } - auto dump_icfs_flag=(db_id_t)BaseObj_t::NOT_IN_DATABASE; + auto dump_icfs_flag=(DatabaseID_t)BaseObj_t::NOT_IN_DATABASE; auto dump_icfs_str=getenv("DUMP_ICFS"); if(dump_icfs_str) - dump_icfs_flag=(db_id_t)strtoull(dump_icfs_str,NULL,0); + dump_icfs_flag=(DatabaseID_t)strtoull(dump_icfs_str,NULL,0); string programName(argv[0]); int variantID = atoi(argv[1]); - VariantID_t *pidp=NULL; - /* setup the interface to the sql server */ - pqxxDB_t pqxx_interface; - BaseObj_t::SetInterface(&pqxx_interface); + auto pqxx_interface=pqxxDB_t::factory(); + BaseObj_t::setInterface(pqxx_interface.get()); - pidp=new VariantID_t(variantID); - assert(pidp->IsRegistered()==true); + auto pidp=VariantID_t::factory(variantID); + assert(pidp->isRegistered()==true); bool one_success = false; - for(set<File_t*>::iterator it=pidp->GetFiles().begin(); - it!=pidp->GetFiles().end(); + for(set<File_t*>::iterator it=pidp->getFiles().begin(); + it!=pidp->getFiles().end(); ++it) { File_t* this_file = *it; try { - FileIR_t *firp = new FileIR_t(*pidp, this_file); + auto firp = FileIR_t::factory(pidp.get(), this_file); - cout<<"file: "<<this_file->GetURL()<<endl; + cout<<"file: "<<this_file->getURL()<<endl; cout<<setw(9)<<"ID"<<" " <<setw(10)<<"Addr."<<" " <<setw(10)<<"IBTA"<<" " @@ -99,29 +97,29 @@ int main(int argc, char **argv) assert(firp && pidp); - for(InstructionSet_t::iterator it=firp->GetInstructions().begin(); it!=firp->GetInstructions().end(); ++it) + for(auto it=firp->getInstructions().begin(); it!=firp->getInstructions().end(); ++it) { Instruction_t* insn=*it; assert(insn); - cout<<hex<<setw(9)<<insn->GetBaseID()<<" "<<hex<<setw(10)<<insn->GetAddress()->GetVirtualOffset(); + cout<<hex<<setw(9)<<insn->getBaseID()<<" "<<hex<<setw(10)<<insn->getAddress()->getVirtualOffset(); cout<<" "<<hex<<setw(10)<< - (insn->GetIndirectBranchTargetAddress() ? - insn->GetIndirectBranchTargetAddress()->GetVirtualOffset() : + (insn->getIndirectBranchTargetAddress() ? + insn->getIndirectBranchTargetAddress()->getVirtualOffset() : 0 ) <<" "; - cout<<hex<<setw(9)<<(insn->GetFallthrough() ? insn->GetFallthrough()->GetBaseID() : -1) << " "; - cout<<hex<<setw(9)<<(insn->GetTarget() ? insn->GetTarget()->GetBaseID() : -1) << " "; - if(insn->GetFunction() && insn->GetFunction()->GetEntryPoint()) - cout<<hex<<setw(9)<<insn->GetFunction()->GetEntryPoint()->GetBaseID(); + cout<<hex<<setw(9)<<(insn->getFallthrough() ? insn->getFallthrough()->getBaseID() : -1) << " "; + cout<<hex<<setw(9)<<(insn->getTarget() ? insn->getTarget()->getBaseID() : -1) << " "; + if(insn->getFunction() && insn->getFunction()->getEntryPoint()) + cout<<hex<<setw(9)<<insn->getFunction()->getEntryPoint()->getBaseID(); else cout<<setw(9)<<"NoFunc"; - const auto d=DecodedInstruction_t(insn); - cout<<" "<<d.getDisassembly()<<"("<<insn->GetComment()<<")"<<endl; + const auto d=DecodedInstruction_t::factory(insn); + cout<<" "<<d->getDisassembly()<<"("<<insn->getComment()<<")"<<endl; - if(dump_icfs_flag == insn->GetBaseID()) + if(dump_icfs_flag == insn->getBaseID()) dump_icfs(insn); } @@ -130,11 +128,11 @@ int main(int argc, char **argv) } catch (DatabaseError_t pnide) { - cerr << programName << ": Unexpected database error: " << pnide << "file url: " << this_file->GetURL() << endl; + cerr << programName << ": Unexpected database error: " << pnide << "file url: " << this_file->getURL() << endl; } catch (...) { - cerr << programName << ": Unexpected error file url: " << this_file->GetURL() << endl; + cerr << programName << ": Unexpected error file url: " << this_file->getURL() << endl; } } // end file iterator @@ -142,7 +140,7 @@ int main(int argc, char **argv) if (one_success) { cout<<"Commiting changes...\n"; - pqxx_interface.Commit(); + pqxx_interface->commit(); } return 0; diff --git a/include/i686/config.h b/include/i686/config.h deleted file mode 100644 index 5a5bcb937a1f358117421dc34969b7a99f325225..0000000000000000000000000000000000000000 --- a/include/i686/config.h +++ /dev/null @@ -1,61 +0,0 @@ -/* - * config.h - see below. - * - * Copyright (c) 2000, 2001, 2010 - Zephyr Software - * - * This file is part of the Strata dynamic code modification infrastructure. - * This file may be used and modified for non-commercial purposes as long as - * all copyright, permission, and nonwarranty notices are preserved. - * Redistribution is prohibited without prior written consent from Zephyr - * Software. - * - * Please contact the authors for restrictions applying to commercial use. - * - * THIS SOURCE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF - * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. - * - * Author: Zephyr Software - * e-mail: jwd@zephyr-software.com - * URL : http://www.zephyr-software.com/ - * - */ - -/* - * config.h - * target dependent types - * - * $Id: config.h,v 1.4.4.1 2007-05-22 19:01:04 jdh8d Exp $ - * - */ - -#ifndef __CONFIG_H_ -#define __CONFIG_H_ - -#include <stdint.h> -#include <inttypes.h> - - -#define MAX_OPCODE_LENGTH 15 -#define MAX_PREFIX_LENGTH 4 - - -typedef uintptr_t app_iaddr_t; - -typedef unsigned char uchar; - -/* Target specific integer types for statistics evaluator. */ -typedef int s_int32_t; -typedef unsigned s_uint32_t; -typedef long long s_int64_t; -typedef unsigned long long s_uint64_t; -typedef s_uint64_t counter_t; - -#define T_ARCH "i686" - - -#ifndef NULL -#define NULL 0 -#endif - -#endif diff --git a/include/i86pc/config.h b/include/i86pc/config.h deleted file mode 100644 index b7cbcf52ada5b42785dd2a678c7ceb0751721a98..0000000000000000000000000000000000000000 --- a/include/i86pc/config.h +++ /dev/null @@ -1,62 +0,0 @@ -/* - * config.h - see below. - * - * Copyright (c) 2000, 2001, 2010 - Zephyr Software - * - * This file is part of the Strata dynamic code modification infrastructure. - * This file may be used and modified for non-commercial purposes as long as - * all copyright, permission, and nonwarranty notices are preserved. - * Redistribution is prohibited without prior written consent from Zephyr - * Software. - * - * Please contact the authors for restrictions applying to commercial use. - * - * THIS SOURCE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF - * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. - * - * Author: Zephyr Software - * e-mail: jwd@zephyr-software.com - * URL : http://www.zephyr-software.com/ - * - */ - -/* - * config.h - * target dependent types - * - * $Id: config.h,v 1.4.4.1 2007-05-22 19:01:04 jdh8d Exp $ - * - */ - -#ifndef __CONFIG_H_ -#define __CONFIG_H_ - -#include <stdint.h> -#include <inttypes.h> - - -#define MAX_OPCODE_LENGTH 15 -#define MAX_PREFIX_LENGTH 4 - - -typedef uintptr_t app_iaddr_t; - -typedef unsigned char uchar; - -/* Target specific integer types for statistics evaluator. */ -typedef int s_int32_t; -typedef unsigned s_uint32_t; -typedef long long s_int64_t; -typedef unsigned long long s_uint64_t; -typedef s_uint64_t counter_t; - -#define T_ARCH "i686" - - -#ifndef NULL -#define NULL 0 -#endif - - -#endif diff --git a/include/x86_64/config.h b/include/x86_64/config.h deleted file mode 100644 index 25a7644c1b861d375b4eb92a20555f9f4836203c..0000000000000000000000000000000000000000 --- a/include/x86_64/config.h +++ /dev/null @@ -1,61 +0,0 @@ -/* - * config.h - see below. - * - * Copyright (c) 2000, 2001, 2010 - Zephyr Software - * - * This file is part of the Strata dynamic code modification infrastructure. - * This file may be used and modified for non-commercial purposes as long as - * all copyright, permission, and nonwarranty notices are preserved. - * Redistribution is prohibited without prior written consent from Zephyr - * Software. - * - * Please contact the authors for restrictions applying to commercial use. - * - * THIS SOURCE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF - * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. - * - * Author: Zephyr Software - * e-mail: jwd@zephyr-software.com - * URL : http://www.zephyr-software.com/ - * - */ - -/* - * config.h - * target dependent types - * - * $Id: config.h,v 1.4.4.1 2007-05-22 19:01:04 jdh8d Exp $ - * - */ - -#ifndef __CONFIG_H_ -#define __CONFIG_H_ - -#include <stdint.h> -#include <inttypes.h> - - -#define MAX_OPCODE_LENGTH 15 -#define MAX_PREFIX_LENGTH 4 - - -typedef uintptr_t app_iaddr_t; - -typedef unsigned char uchar; - -/* Target specific integer types for statistics evaluator. */ -typedef int s_int32_t; -typedef unsigned s_uint32_t; -typedef long long s_int64_t; -typedef unsigned long long s_uint64_t; -typedef s_uint64_t counter_t; - -#define T_ARCH "x86_64" - - -#ifndef NULL -#define NULL 0 -#endif - -#endif diff --git a/libIRDB/test/SConscript b/ir_builders/SConscript similarity index 77% rename from libIRDB/test/SConscript rename to ir_builders/SConscript index e01ec444ab8b37b14a3263868c3dff5620de359f..fb5eba73a4c74fbaf7a37657916c11e30cb6f271 100644 --- a/libIRDB/test/SConscript +++ b/ir_builders/SConscript @@ -11,16 +11,15 @@ installed=[] if 'build_tools' not in myenv or myenv['build_tools'] is None or int(myenv['build_tools']) == 1: cpppath=''' - $SECURITY_TRANSFORMS_HOME/include - $SECURITY_TRANSFORMS_HOME/libIRDB/include - $SECURITY_TRANSFORMS_HOME/libMEDSannotation/include + $IRDB_SDK/include $SECURITY_TRANSFORMS_HOME/libEXEIO/include $SECURITY_TRANSFORMS_HOME/libehp/include + $SECURITY_TRANSFORMS_HOME/libMEDSannotation/include/ $SECURITY_TRANSFORMS_HOME/third_party/elfio-code ''' LIBPATH="$SECURITY_TRANSFORMS_HOME/lib" - LIBS=Split( 'IRDB-cfg IRDB-util ' + env.subst('$BASE_IRDB_LIBS')+ " MEDSannotation ehp transform") + LIBS=Split( 'irdb-cfg irdb-util ' + env.subst('$BASE_IRDB_LIBS')+ " ehp irdb-transform MEDSannotation EXEIO") myenv=myenv.Clone(CPPPATH=Split(cpppath)) @@ -46,9 +45,6 @@ if 'build_tools' not in myenv or myenv['build_tools'] is None or int(myenv['buil # most programs go to $sectrans/bin pgms='''clone - generate_spri - find_strings - mark_functions_safe ''' for i in Split(pgms): # print "Registering pgm: "+ i @@ -59,10 +55,10 @@ if 'build_tools' not in myenv or myenv['build_tools'] is None or int(myenv['buil # ilr goes to $sectrans/plugins_install - pgm=myenv.Program(target="ilr.exe", source=Split("ilr.cpp"), LIBPATH=LIBPATH, LIBS=LIBS) - install=myenv.Install("$SECURITY_TRANSFORMS_HOME/plugins_install/", pgm) - Default(install) - installed=installed+install + # pgm=myenv.Program(target="ilr.exe", source=Split("ilr.cpp"), LIBPATH=LIBPATH, LIBS=LIBS) + # install=myenv.Install("$SECURITY_TRANSFORMS_HOME/plugins_install/", pgm) + # Default(install) + # installed=installed+install Return('installed') diff --git a/libIRDB/SConstruct b/ir_builders/SConstruct similarity index 100% rename from libIRDB/SConstruct rename to ir_builders/SConstruct diff --git a/libIRDB/test/build_callgraph.cpp b/ir_builders/build_callgraph.cpp similarity index 94% rename from libIRDB/test/build_callgraph.cpp rename to ir_builders/build_callgraph.cpp index 2542a41799296c1bfb9b606332f167905391c4cd..a0ca36f7209ae516387bcc5893e81674ac06714b 100644 --- a/libIRDB/test/build_callgraph.cpp +++ b/ir_builders/build_callgraph.cpp @@ -20,8 +20,8 @@ -#include <libIRDB-core.hpp> -#include <libIRDB-cfg.hpp> +#include <irdb=-sdk> +#include <irdb-cfg> #include <utils.hpp> // to_string function from libIRDB #include <iostream> #include <fstream> @@ -29,7 +29,6 @@ #include <string.h> #include <assert.h> -using namespace libIRDB; using namespace std; // @@ -62,7 +61,7 @@ main(int argc, char* argv[]) varidp=new VariantID_t(atoi(argv[1])); // A callgraph - Callgraph_t *cg=new Callgraph_t; + auto cg=Callgraph_t::factory(); assert(varidp->IsRegistered()==true); diff --git a/libIRDB/test/build_preds.cpp b/ir_builders/build_preds.cpp similarity index 100% rename from libIRDB/test/build_preds.cpp rename to ir_builders/build_preds.cpp diff --git a/libIRDB/test/calc_conflicts.cpp b/ir_builders/calc_conflicts.cpp similarity index 97% rename from libIRDB/test/calc_conflicts.cpp rename to ir_builders/calc_conflicts.cpp index c26b02d1bac99a1fb460168291d0ee72dc942eed..15dd95ead800f405a927cc48f0c4347cb866f821 100644 --- a/libIRDB/test/calc_conflicts.cpp +++ b/ir_builders/calc_conflicts.cpp @@ -43,7 +43,7 @@ int bad_fallthrough_count=0; using namespace libIRDB; using namespace std; -set< pair<db_id_t,int> > missed_instructions; +set< pair<DatabaseID_t,int> > missed_instructions; int failed_target_count=0; pqxxDB_t pqxx_interface; @@ -65,7 +65,7 @@ void count_conflicts (FileIR_t* virp) { Instruction_t *insn=*it; - virtual_offset_t vo=insn->GetAddress()->GetVirtualOffset(); + VirtualOffset_t vo=insn->GetAddress()->GetVirtualOffset(); for(int i=0;i<insn->GetDataBits().length();i++) conflict_map[(vo+i)]++; diff --git a/libIRDB/test/check_thunks.cpp b/ir_builders/check_thunks.cpp similarity index 54% rename from libIRDB/test/check_thunks.cpp rename to ir_builders/check_thunks.cpp index 22c22b63fcb897e47e5bdab5368a3809a0fda957..716b2cd30cebaa0a6a9b49a4fe26b883aa426c44 100644 --- a/libIRDB/test/check_thunks.cpp +++ b/ir_builders/check_thunks.cpp @@ -23,9 +23,8 @@ -#include <libIRDB-core.hpp> -#include <libIRDB-cfg.hpp> -#include <utils.hpp> +#include <irdb-core> +#include <algorithm> #include <iostream> #include <stdlib.h> #include <assert.h> @@ -36,7 +35,7 @@ #include "fill_in_indtargs.hpp" -using namespace libIRDB; +using namespace IRDB_SDK; using namespace std; #define HIWORD(a) ((a)&0xFFFF0000) @@ -45,35 +44,19 @@ using namespace std; /* * check_for_thunk_offsets - check non-function thunks for extra offsets */ -void check_for_thunk_offsets(FileIR_t* firp, virtual_offset_t thunk_base) +void check_for_thunk_offsets(FileIR_t* firp, VirtualOffset_t thunk_base) { - - - for( - set<Instruction_t*>::iterator it=firp->GetInstructions().begin(); - it!=firp->GetInstructions().end(); - ++it - ) + for(auto insn : firp->getInstructions()) { - // if it has a targ and fallthrough (quick test) it might be a call - Instruction_t* insn=*it; - //DISASM d; - //Disassemble(insn,d); - const auto d=DecodedInstruction_t(insn); - - //if(string(d.Instruction.Mnemonic)==string("add ")) - if(d.getMnemonic()=="add") + const auto d=DecodedInstruction_t::factory(insn); + if(d->getMnemonic()=="add") { // check that arg2 is a constant - // if(HIWORD(d.Argument2.ArgType)!=CONSTANT_TYPE+ABSOLUTE_) - if(!d.getOperand(1).isConstant()) + if(!d->getOperand(1)->isConstant()) continue; - // string add_offset=string(d.Argument2.ArgMnemonic); - //const auto add_offset=d.getOperand(1).getString(); - - virtual_offset_t addoff=d.getOperand(1).getConstant(); //strtol(add_offset.c_str(),NULL,16); + auto addoff=d->getOperand(1)->getConstant(); /* bounds check gently */ if(0<addoff && addoff<100) @@ -82,18 +65,15 @@ void check_for_thunk_offsets(FileIR_t* firp, virtual_offset_t thunk_base) possible_target(thunk_base+addoff, 0, ibt_provenance_t::ibtp_text); } // else if(string(d.Instruction.Mnemonic)==string("lea ")) - if(d.getMnemonic()=="lea") + if(d->getMnemonic()=="lea") { - // assert (d.Argument2.ArgType==MEMORY_TYPE); - assert (d.getOperand(1).isMemory()); + assert (d->getOperand(1)->isMemory()); /* no indexing please! */ - // if(d.Argument2.Memory.IndexRegister!=0) - if(d.getOperand(1).hasIndexRegister()) + if(d->getOperand(1)->hasIndexRegister()) continue; - // virtual_offset_t leaoff=d.Argument2.Memory.Displacement; - virtual_offset_t leaoff=d.getOperand(1).getMemoryDisplacement(); + auto leaoff=d->getOperand(1)->getMemoryDisplacement(); /* bounds check gently */ if(0<leaoff && leaoff<100) @@ -110,12 +90,10 @@ void check_for_thunk_offsets(FileIR_t* firp, virtual_offset_t thunk_base) void check_for_thunk_offsets(FileIR_t* firp, Instruction_t *thunk_insn, string reg, uint64_t offset) { - virtual_offset_t thunk_base=thunk_insn->GetFallthrough()->GetAddress()->GetVirtualOffset()+offset; - //virtual_offset_t thunk_call_addr=thunk_insn->GetAddress()->GetVirtualOffset(); - //virtual_offset_t thunk_call_offset=strtol(offset.c_str(),NULL,16); + auto thunk_base=thunk_insn->getFallthrough()->getAddress()->getVirtualOffset()+offset; /* don't check inserted thunk addresses */ - if(thunk_insn->GetAddress()->GetVirtualOffset()==0) + if(thunk_insn->getAddress()->getVirtualOffset()==0) return; check_for_thunk_offsets(firp,thunk_base); @@ -133,39 +111,25 @@ void check_func_for_thunk_offsets(Function_t *func, Instruction_t* thunk_insn, - virtual_offset_t thunk_base=thunk_insn->GetFallthrough()->GetAddress()->GetVirtualOffset()+offset; - //virtual_offset_t thunk_call_addr=thunk_insn->GetAddress()->GetVirtualOffset(); - //virtual_offset_t thunk_call_offset=strtol(offset.c_str(),NULL,16); + auto thunk_base=thunk_insn->getFallthrough()->getAddress()->getVirtualOffset()+offset; /* don't check inserted thunk addresses */ - if(thunk_insn->GetAddress()->GetVirtualOffset()==0) + if(thunk_insn->getAddress()->getVirtualOffset()==0) return; - for( - set<Instruction_t*>::iterator it=func->GetInstructions().begin(); - it!=func->GetInstructions().end(); - ++it - ) + for(auto insn : func->getInstructions()) { // if it has a targ and fallthrough (quick test) it might be a call - Instruction_t* insn=*it; - // DISASM d; - // Disassemble(insn,d); - const auto d=DecodedInstruction_t(insn); + const auto d=DecodedInstruction_t::factory(insn); - // if(string(d.Instruction.Mnemonic)==string("add ")) - if(d.getMnemonic()=="add") + if(d->getMnemonic()=="add") { // check that arg2 is a constant - // if(HIWORD(d.Argument2.ArgType)!=CONSTANT_TYPE+ABSOLUTE_) - if(!d.getOperand(1).isConstant()) + if(!d->getOperand(1)->isConstant()) continue; - // string add_offset=string(d.Argument2.ArgMnemonic); - // const auto add_offset=d.getOperand(1).getString(); - - virtual_offset_t addoff=d.getOperand(1).getConstant(); //strtol(add_offset.c_str(),NULL,16); + auto addoff=d->getOperand(1)->getConstant(); /* bounds check gently */ if(0<addoff && addoff<100) @@ -176,19 +140,15 @@ void check_func_for_thunk_offsets(Function_t *func, Instruction_t* thunk_insn, // <<" addoff: " << addoff << " total: "<< (thunk_base+addoff)<<endl; possible_target(thunk_base+addoff, 0, ibt_provenance_t::ibtp_text); } - // else if(string(d.Instruction.Mnemonic)==string("lea ")) - else if(d.getMnemonic()=="lea") + else if(d->getMnemonic()=="lea") { - // assert (d.Argument2.ArgType==MEMORY_TYPE); - assert (d.getOperand(1).isMemory()); + assert (d->getOperand(1)->isMemory()); /* no indexing please! */ - // if(d.Argument2.Memory.IndexRegister!=0) - if(!d.getOperand(1).hasIndexRegister()) + if(!d->getOperand(1)->hasIndexRegister()) continue; - // virtual_offset_t leaoff=d.Argument2.Memory.Displacement; - virtual_offset_t leaoff=d.getOperand(1).getMemoryDisplacement(); + VirtualOffset_t leaoff=d->getOperand(1)->getMemoryDisplacement(); /* bounds check gently */ if(0<leaoff && leaoff<100) @@ -210,20 +170,15 @@ void check_func_for_thunk_offsets(Function_t *func, Instruction_t* thunk_insn, */ bool is_thunk_load(Instruction_t* insn, string ®) { - //DISASM d; - //Disassemble(insn,d); - const auto d=DecodedInstruction_t(insn); + const auto d=DecodedInstruction_t::factory(insn); - //if(string(d.Instruction.Mnemonic)!=string("mov ")) - if(d.getMnemonic()!="mov") + if(d->getMnemonic()!="mov") return false; - //if(d.Argument2.ArgType!=MEMORY_TYPE || string(d.Argument2.ArgMnemonic)!=string("esp")) - if(!d.getOperand(1).isMemory() || d.getOperand(1).getString()!="esp") + if(!d->getOperand(1)->isMemory() || d->getOperand(1)->getString()!="esp") return false; - // reg=string(d.Argument1.ArgMnemonic); - reg=d.getOperand(0).getString(); + reg=d->getOperand(0)->getString(); return true; } @@ -232,15 +187,8 @@ bool is_thunk_load(Instruction_t* insn, string ®) */ bool is_ret(Instruction_t* insn) { - //DISASM d; - //Disassemble(insn,d); - const auto d=DecodedInstruction_t(insn); - return d.isReturn(); - -// if(d.Instruction.BranchType!=RetType) -// return false; -// -// return true; + const auto d=DecodedInstruction_t::factory(insn); + return d->isReturn(); } /* @@ -248,14 +196,12 @@ bool is_ret(Instruction_t* insn) */ bool is_pop(Instruction_t* insn, string ®) { - //DISASM d; - //Disassemble(insn,d); - const auto d=DecodedInstruction_t(insn); + const auto d=DecodedInstruction_t::factory(insn); - if(d.getMnemonic()!="pop") + if(d->getMnemonic()!="pop") return false; - reg=d.getOperand(0).getString(); + reg=d->getOperand(0)->getString(); return true; } @@ -267,29 +213,26 @@ bool is_pop(Instruction_t* insn, string ®) /* note: reg is output paramater */ bool is_thunk_call(Instruction_t* insn, string ®) { - //DISASM d; - //Disassemble(insn,d); - const auto d=DecodedInstruction_t(insn); + const auto d=DecodedInstruction_t::factory(insn); /* not a call */ - //if(d.Instruction.BranchType!=CallType) - if(!d.isCall()) + if(!d->isCall()) return false; /* no target in IRDB */ - if(insn->GetTarget()==NULL) + if(insn->getTarget()==NULL) return false; /* Target not the right type of load */ - if(!is_thunk_load(insn->GetTarget(),reg)) + if(!is_thunk_load(insn->getTarget(),reg)) return false; /* target has no FT? */ - if(!insn->GetTarget()->GetFallthrough()) + if(!insn->getTarget()->getFallthrough()) return false; /* target's FT is a return insn */ - if(!is_ret(insn->GetTarget()->GetFallthrough())) + if(!is_ret(insn->getTarget()->getFallthrough())) return false; return true; @@ -297,27 +240,24 @@ bool is_thunk_call(Instruction_t* insn, string ®) bool is_thunk_call_type2(Instruction_t* insn, string ®, Instruction_t** newinsn) { - //DISASM d; - //Disassemble(insn,d); - const auto d=DecodedInstruction_t(insn); + const auto d=DecodedInstruction_t::factory(insn); /* not a call */ - //if(d.Instruction.BranchType!=CallType) - if(!d.isCall()) + if(!d->isCall()) return false; /* no target in IRDB */ - if(insn->GetTarget()==NULL) + if(insn->getTarget()==NULL) return false; - if(insn->GetTarget() != insn->GetFallthrough()) + if(insn->getTarget() != insn->getFallthrough()) return false; /* target's FT is a return insn */ - if(!is_pop(insn->GetTarget(), reg)) + if(!is_pop(insn->getTarget(), reg)) return false; - *newinsn=insn->GetTarget()->GetFallthrough(); + *newinsn=insn->getTarget()->getFallthrough(); return true; } @@ -328,29 +268,23 @@ bool is_thunk_call_type2(Instruction_t* insn, string ®, Instruction_t** newin /* note: offset is an output parameter */ bool is_thunk_add(Instruction_t *insn, string reg, uint64_t &offset) { - //DISASM d; - //Disassemble(insn,d); - const auto d=DecodedInstruction_t(insn); + const auto d=DecodedInstruction_t::factory(insn); // make sure it's an add instruction - //if(string(d.Instruction.Mnemonic)!=string("add ")) - if(d.getMnemonic()!="add") + if(d->getMnemonic()!="add") return false; // check that it's an add of the proper reg - if(d.getOperand(0).getString()!=reg) + if(d->getOperand(0)->getString()!=reg) return false; // check that arg2 is a constant - //if(HIWORD(d.Argument2.ArgType)!=CONSTANT_TYPE+ABSOLUTE_) - if(!d.getOperand(1).isConstant()) + if(!d->getOperand(1)->isConstant()) return false; - // offset=string(d.Argument2.ArgMnemonic); - //offset=d.getOperand(1).getString(); - offset=d.getOperand(1).getConstant(); + offset=d->getOperand(1)->getConstant(); - virtual_offset_t intoff=d.getOperand(1).getConstant(); // strtol(offset.c_str(),NULL,16); + auto intoff=d->getOperand(1)->getConstant(); /* bounds check gently */ if(0<intoff && intoff<100) @@ -365,23 +299,18 @@ bool is_thunk_add(Instruction_t *insn, string reg, uint64_t &offset) void check_func_for_thunk_calls(Function_t* func) { // for each insn in the func - for( - set<Instruction_t*>::iterator it=func->GetInstructions().begin(); - it!=func->GetInstructions().end(); - ++it - ) + for(auto insn : func->getInstructions()) { // if it has a targ and fallthrough (quick test) it might be a call - Instruction_t* insn=*it; /* check if we might be calling a thunk */ - if(insn->GetFallthrough() && insn->GetTarget()) + if(insn->getFallthrough() && insn->getTarget()) { // check for a call, followed by an add of reg (note the output params of reg and offset) string reg; uint64_t offset=0; if(is_thunk_call(insn,reg) && - is_thunk_add(insn->GetFallthrough(),reg,offset)) + is_thunk_add(insn->getFallthrough(),reg,offset)) { check_func_for_thunk_offsets(func,insn,reg,offset); } @@ -394,29 +323,24 @@ void check_func_for_thunk_calls(Function_t* func) void check_non_funcs_for_thunks(FileIR_t *firp) { // for each insn in the func - for( - set<Instruction_t*>::iterator it=firp->GetInstructions().begin(); - it!=firp->GetInstructions().end(); - ++it - ) + for(auto insn : firp->getInstructions()) { // if it has a targ and fallthrough (quick test) it might be a call - Instruction_t* insn=*it; /* these instructions/thunks are checked with the functions */ /* check if we might be calling a thunk */ - if(insn->GetFallthrough() && insn->GetTarget()) + if(insn->getFallthrough() && insn->getTarget()) { // check for a call, followed by an add of reg (note the output params of reg and offset) string reg; uint64_t offset=0; if(is_thunk_call(insn,reg) && - is_thunk_add(insn->GetFallthrough(),reg,offset)) + is_thunk_add(insn->getFallthrough(),reg,offset)) { cout<<"Found non-function thunk at "<< - insn->GetAddress()->GetVirtualOffset()<<endl; + insn->getAddress()->getVirtualOffset()<<endl; check_for_thunk_offsets(firp,insn,reg,offset); } } @@ -439,47 +363,38 @@ void check_non_funcs_for_thunks(FileIR_t *firp) * If L1+k1+k2 is found, and points at a code address (outside this function?), mark it as an indirect branch target. * */ -void check_for_thunks(FileIR_t* firp, const std::set<virtual_offset_t>& thunk_bases) +void check_for_thunks(FileIR_t* firp, const std::set<VirtualOffset_t>& thunk_bases) { /* thunk bases is the module start's found for this firp */ cout<<"Starting check for thunks"<<endl; - for(set<virtual_offset_t>::iterator it=thunk_bases.begin(); it!=thunk_bases.end(); ++it) - { - virtual_offset_t offset=*it; + for(auto offset : thunk_bases) check_for_thunk_offsets(firp,offset); - } } -void find_all_module_starts(FileIR_t* firp, set<virtual_offset_t> &thunk_bases) +void find_all_module_starts(FileIR_t* firp, set<VirtualOffset_t> &thunk_bases) { thunk_bases.clear(); cout<<"Finding thunk bases"<<endl; // for each insn in the func - for( - set<Instruction_t*>::iterator it=firp->GetInstructions().begin(); - it!=firp->GetInstructions().end(); - ++it - ) + for(auto insn : firp->getInstructions()) { // if it has a targ and fallthrough (quick test) it might be a call - Instruction_t* insn=*it; - /* check if we might be calling a thunk */ - if(insn->GetFallthrough() && insn->GetTarget()) + if(insn->getFallthrough() && insn->getTarget()) { // check for a call, followed by an add of reg (note the output params of reg and offset) string reg; uint64_t offset=0; if(is_thunk_call(insn,reg) && - is_thunk_add(insn->GetFallthrough(),reg,offset)) + is_thunk_add(insn->getFallthrough(),reg,offset)) { - virtual_offset_t thunk_base=insn->GetFallthrough()->GetAddress()->GetVirtualOffset()+ offset; + auto thunk_base=insn->getFallthrough()->getAddress()->getVirtualOffset()+ offset; if(thunk_bases.find(thunk_base)==thunk_bases.end()) - cout<<"Found new thunk at "<<insn->GetAddress()->GetVirtualOffset()<<" with base: "<<hex<<thunk_base<<endl; + cout<<"Found new thunk at "<<insn->getAddress()->getVirtualOffset()<<" with base: "<<hex<<thunk_base<<endl; thunk_bases.insert(thunk_base); } Instruction_t* newinsn=NULL; @@ -487,9 +402,9 @@ void find_all_module_starts(FileIR_t* firp, set<virtual_offset_t> &thunk_bases) { if(newinsn && is_thunk_add(newinsn,reg,offset)) { - virtual_offset_t thunk_base=insn->GetFallthrough()->GetAddress()->GetVirtualOffset()+ offset; + VirtualOffset_t thunk_base=insn->getFallthrough()->getAddress()->getVirtualOffset()+ offset; if(thunk_bases.find(thunk_base)==thunk_bases.end()) - cout<<"Found new thunk at "<<insn->GetAddress()->GetVirtualOffset()<<" with base: "<<hex<<thunk_base<<endl; + cout<<"Found new thunk at "<<insn->getAddress()->getVirtualOffset()<<" with base: "<<hex<<thunk_base<<endl; thunk_bases.insert(thunk_base); } } diff --git a/libIRDB/test/check_thunks.hpp b/ir_builders/check_thunks.hpp similarity index 76% rename from libIRDB/test/check_thunks.hpp rename to ir_builders/check_thunks.hpp index ed7ce8d80dad51446ce7e8dfb1c59c0fdc364601..27b77593fce91e937501b16524d81cc9323e753b 100644 --- a/libIRDB/test/check_thunks.hpp +++ b/ir_builders/check_thunks.hpp @@ -23,10 +23,10 @@ #define check_thunks_hpp #include <set> -#include "libIRDB-core.hpp" +#include <irdb-core> -void find_all_module_starts(libIRDB::FileIR_t* firp, std::set<libIRDB::virtual_offset_t>& thunk_bases); -void check_for_thunks(libIRDB::FileIR_t* firp, const std::set<libIRDB::virtual_offset_t>& thunk_bases); +void find_all_module_starts(IRDB_SDK::FileIR_t* firp, std::set<IRDB_SDK::VirtualOffset_t>& thunk_bases); +void check_for_thunks(IRDB_SDK::FileIR_t* firp, const std::set<IRDB_SDK::VirtualOffset_t>& thunk_bases); #endif diff --git a/libIRDB/test/clone.cpp b/ir_builders/clone.cpp similarity index 76% rename from libIRDB/test/clone.cpp rename to ir_builders/clone.cpp index 73c2525d70043cc3e3dd3a43363248669a8c71e8..d5211b72361faafdeb6d11acc4b5300f103f725e 100644 --- a/libIRDB/test/clone.cpp +++ b/ir_builders/clone.cpp @@ -20,13 +20,13 @@ -#include <libIRDB-core.hpp> +#include <irdb-core> #include <iostream> #include <fstream> #include <stdlib.h> -using namespace libIRDB; +using namespace IRDB_SDK; using namespace std; int main(int argc, char* argv[]) @@ -40,28 +40,24 @@ int main(int argc, char* argv[]) /* setup the interface to the sql server */ - pqxxDB_t pqxx_interface; - BaseObj_t::SetInterface(&pqxx_interface); + auto pqxx_interface=pqxxDB_t::factory(); + BaseObj_t::setInterface(pqxx_interface.get()); - VariantID_t *pidp=NULL; - VariantID_t *newpidp=NULL; try { - pidp=new VariantID_t(atoi(argv[1])); + auto pidp=VariantID_t::factory(atoi(argv[1])); + assert(pidp->isRegistered()==true); - assert(pidp->IsRegistered()==true); - - newpidp=pidp->Clone(); - - assert(newpidp->IsRegistered()==true); + auto newpidp=pidp->clone(); + assert(newpidp->isRegistered()==true); cout<<"Cloned Variant is: "<<*newpidp << endl; // commit the changes to the db if all went well - pqxx_interface.Commit(); + pqxx_interface->commit(); - db_id_t newpid_id=newpidp->GetBaseID(); + auto newpid_id=newpidp->getBaseID(); ofstream f; f.open(argv[2]); if(!f.is_open()) @@ -80,8 +76,6 @@ int main(int argc, char* argv[]) } - delete newpidp; - delete pidp; return 0; } diff --git a/libIRDB/test/create_variant.cpp b/ir_builders/create_variant.cpp similarity index 100% rename from libIRDB/test/create_variant.cpp rename to ir_builders/create_variant.cpp diff --git a/libIRDB/test/create_variantir.cpp b/ir_builders/create_variantir.cpp similarity index 100% rename from libIRDB/test/create_variantir.cpp rename to ir_builders/create_variantir.cpp diff --git a/ir_builders/decode_test.cpp b/ir_builders/decode_test.cpp new file mode 100644 index 0000000000000000000000000000000000000000..cec74d350f6be02170266507e85b1bfe93caabd6 --- /dev/null +++ b/ir_builders/decode_test.cpp @@ -0,0 +1,16 @@ +#include <libIRDB-core.hpp> + +using namespace std; +using namespace libIRDB; + +int main() +{ + + FileIR_t::SetArchitecture(64,admtX86_64); + + for(auto i=0U; i<10*1000*1000; i++) + { + const auto d=DecodedInstruction_t(1024, "\x90", 1); + } + return 0; +} diff --git a/libIRDB/test/drop_variant.cpp b/ir_builders/drop_variant.cpp similarity index 100% rename from libIRDB/test/drop_variant.cpp rename to ir_builders/drop_variant.cpp diff --git a/libIRDB/test/fill_in_cfg.cpp b/ir_builders/fill_in_cfg.cpp similarity index 52% rename from libIRDB/test/fill_in_cfg.cpp rename to ir_builders/fill_in_cfg.cpp index 905f3bd5301070599a99ed3977cccd902ec8a15c..aa921235f685792a3e0697b6f9c9c5136553ce85 100644 --- a/libIRDB/test/fill_in_cfg.cpp +++ b/ir_builders/fill_in_cfg.cpp @@ -28,13 +28,13 @@ #include "elfio/elfio.hpp" #include "split_eh_frame.hpp" -using namespace libIRDB; using namespace std; using namespace EXEIO; +using namespace IRDB_SDK; void PopulateCFG::populate_instruction_map ( - map< pair<db_id_t,virtual_offset_t>, Instruction_t*> &insnMap, + map< pair<DatabaseID_t,VirtualOffset_t>, Instruction_t*> &insnMap, FileIR_t *firp ) { @@ -43,17 +43,12 @@ void PopulateCFG::populate_instruction_map /* for each instruction in the IR */ - for( - set<Instruction_t*>::const_iterator it=firp->GetInstructions().begin(); - it!=firp->GetInstructions().end(); - ++it - ) + for(auto insn : firp->getInstructions()) { - Instruction_t *insn=*it; - db_id_t fileID=insn->GetAddress()->GetFileID(); - virtual_offset_t vo=insn->GetAddress()->GetVirtualOffset(); + auto fileID=insn->getAddress()->getFileID(); + auto vo=insn->getAddress()->getVirtualOffset(); - pair<db_id_t,virtual_offset_t> p(fileID,vo); + auto p=pair<DatabaseID_t,VirtualOffset_t>(fileID,vo); assert(insnMap[p]==NULL); insnMap[p]=insn; @@ -63,21 +58,18 @@ void PopulateCFG::populate_instruction_map void PopulateCFG::set_fallthrough ( - map< pair<db_id_t,virtual_offset_t>, Instruction_t*> &insnMap, + map< pair<DatabaseID_t,VirtualOffset_t>, Instruction_t*> &insnMap, DecodedInstruction_t *disasm, Instruction_t *insn, FileIR_t *firp ) { assert(disasm); assert(insn); - if(insn->GetFallthrough()) + if(insn->getFallthrough()) return; // check for branches with targets if( - //(disasm->Instruction.BranchType==JmpType) || // it is a unconditional branch - //(disasm->Instruction.BranchType==RetType) // or a return - (disasm->isUnconditionalBranch() ) || // it is a unconditional branch (disasm->isReturn()) // or a return ) @@ -88,18 +80,18 @@ void PopulateCFG::set_fallthrough /* get the address of the next instrution */ - virtual_offset_t virtual_offset=insn->GetAddress()->GetVirtualOffset() + insn->GetDataBits().size(); + auto virtual_offset=insn->getAddress()->getVirtualOffset() + insn->getDataBits().size(); /* create a pair of offset/file */ - pair<db_id_t,virtual_offset_t> p(insn->GetAddress()->GetFileID(),virtual_offset); + auto p=pair<DatabaseID_t,VirtualOffset_t>(insn->getAddress()->getFileID(),virtual_offset); /* lookup the target insn from the map */ - Instruction_t *fallthrough_insn=insnMap[p]; + auto fallthrough_insn=insnMap[p]; /* sanity, note we may see odd control transfers to 0x0 */ if(fallthrough_insn==NULL && virtual_offset!=0) { - cout<<"Cannot set fallthrough for "<<std::hex<<insn->GetAddress()->GetVirtualOffset(); + cout<<"Cannot set fallthrough for "<<std::hex<<insn->getAddress()->getVirtualOffset(); cout<< " : "<<insn->getDisassembly()<<endl; bad_fallthrough_count++; } @@ -108,16 +100,16 @@ void PopulateCFG::set_fallthrough if(fallthrough_insn!=0) { fallthroughs_set++; - insn->SetFallthrough(fallthrough_insn); + insn->setFallthrough(fallthrough_insn); } else - missed_instructions.insert(pair<db_id_t,virtual_offset_t>(insn->GetAddress()->GetFileID(),virtual_offset)); + missed_instructions.insert(pair<DatabaseID_t,VirtualOffset_t>(insn->getAddress()->getFileID(),virtual_offset)); } void PopulateCFG::set_target ( - map< pair<db_id_t,virtual_offset_t>, Instruction_t*> &insnMap, + map< pair<DatabaseID_t,VirtualOffset_t>, Instruction_t*> &insnMap, DecodedInstruction_t *disasm, Instruction_t *insn, FileIR_t *firp ) { @@ -125,98 +117,94 @@ void PopulateCFG::set_target assert(insn); assert(disasm); - if(insn->GetTarget()) + if(insn->getTarget()) return; - - // check for branches with targets - if( - //(disasm->Instruction.BranchType!=0) && // it is a branch - //(disasm->Instruction.BranchType!=RetType) && // and not a return - //(disasm->Argument1.ArgType & CONSTANT_TYPE)!=0 // and has a constant argument type 1 - (disasm->isBranch()) && // it is a branch - (!disasm->isReturn()) && // and not a return - (disasm->getOperand(0).isConstant()) // and has a constant argument type 1 - ) - { -// cout<<"Found direct jump with addr=" << insn->GetAddress()->GetVirtualOffset() << -// " disasm="<<disasm->CompleteInstr<<" ArgMnemonic="<< -// disasm->Argument1.ArgMnemonic<<"."<<endl; - /* get the offset */ - // virtual_offset_t virtual_offset=strtoul(disasm->Argument1.ArgMnemonic, NULL, 16); - virtual_offset_t virtual_offset=disasm->getAddress(); + const auto &operands = disasm->getOperands(); + for(auto operand : operands) + { + // check for branches with targets + if( + disasm->isBranch() && // it is a branch + !disasm->isReturn() && // and not a return + operand->isConstant() // and has a constant argument + ) + { + // cout<<"Found direct jump with addr=" << insn->getAddress()->getVirtualOffset() << + // " disasm="<<disasm->CompleteInstr<<" ArgMnemonic="<< + // disasm->Argument1.ArgMnemonic<<"."<<endl; - /* create a pair of offset/file */ - pair<db_id_t,virtual_offset_t> p(insn->GetAddress()->GetFileID(),virtual_offset); - - /* lookup the target insn from the map */ - Instruction_t *target_insn=insnMap[p]; + /* get the offset */ + auto virtual_offset=disasm->getAddress(); - /* sanity, note we may see odd control transfers to 0x0 */ - if(target_insn==NULL) - { - unsigned char first_byte=0; - if(insn->GetFallthrough()) - first_byte=(insn->GetFallthrough()->GetDataBits().c_str())[0]; - virtual_offset_t jump_dist=virtual_offset-(insn->GetAddress()->GetVirtualOffset()+(insn->GetDataBits()).size()); - if( - // jump 1 byte forward - jump_dist == 1 && - - // and we calculated the fallthrough - insn->GetFallthrough()!=NULL && - - // and the fallthrough starts with a lock prefix - first_byte==0xf0 - ) + /* create a pair of offset/file */ + auto p=pair<DatabaseID_t,VirtualOffset_t>(insn->getAddress()->getFileID(),virtual_offset); + + /* lookup the target insn from the map */ + auto target_insn=insnMap[p]; + + /* sanity, note we may see odd control transfers to 0x0 */ + if(target_insn==NULL) { - odd_target_count++; - target_insn=insn->GetFallthrough(); + unsigned char first_byte=0; + if(insn->getFallthrough()) + first_byte=(insn->getFallthrough()->getDataBits().c_str())[0]; + VirtualOffset_t jump_dist=virtual_offset-(insn->getAddress()->getVirtualOffset()+(insn->getDataBits()).size()); + if( + // jump 1 byte forward + jump_dist == 1 && + + // and we calculated the fallthrough + insn->getFallthrough()!=NULL && + + // and the fallthrough starts with a lock prefix + first_byte==0xf0 + ) + { + odd_target_count++; + target_insn=insn->getFallthrough(); + } + else + { + if(virtual_offset!=0) + cout<<"Cannot set target (target="<< std::hex << virtual_offset << ") for "<<std::hex<<insn->getAddress()->getVirtualOffset()<<"."<<endl; + bad_target_count++; + } } - else + + /* set the target for this insn */ + if(target_insn!=0) { - if(virtual_offset!=0) - cout<<"Cannot set target (target="<< std::hex << virtual_offset << ") for "<<std::hex<<insn->GetAddress()->GetVirtualOffset()<<"."<<endl; - bad_target_count++; + targets_set++; + insn->setTarget(target_insn); } - } + else + missed_instructions.insert( pair<DatabaseID_t,VirtualOffset_t>(insn->getAddress()->getFileID(),virtual_offset)); - /* set the target for this insn */ - if(target_insn!=0) - { - targets_set++; - insn->SetTarget(target_insn); } - else - missed_instructions.insert( pair<db_id_t,virtual_offset_t>(insn->GetAddress()->GetFileID(),virtual_offset)); - } } -File_t* PopulateCFG::find_file(FileIR_t* firp, db_id_t fileid) +File_t* PopulateCFG::find_file(FileIR_t* firp, DatabaseID_t fileid) { - assert(firp->GetFile()->GetBaseID()==fileid); - return firp->GetFile(); + assert(firp->getFile()->getBaseID()==fileid); + return firp->getFile(); } void PopulateCFG::add_new_instructions(FileIR_t *firp) { int found_instructions=0; - for( - set< pair<db_id_t,virtual_offset_t> >::const_iterator it=missed_instructions.begin(); - it!=missed_instructions.end(); - ++it - ) + for(auto p : missed_instructions) { /* get the address we've missed */ - virtual_offset_t missed_address=(*it).second; + auto missed_address=p.second; /* get the address ID of the instruction that's missing the missed addressed */ - db_id_t missed_fileid=(*it).first; + auto missed_fileid=p.first; /* figure out which file we're looking at */ - File_t* filep=find_file(firp,missed_fileid); + auto filep=find_file(firp,missed_fileid); assert(filep); @@ -237,40 +225,24 @@ void PopulateCFG::add_new_instructions(FileIR_t *firp) if( !elfiop->sections[secndx]->isExecutable()) continue; - virtual_offset_t first=elfiop->sections[secndx]->get_address(); - virtual_offset_t second=elfiop->sections[secndx]->get_address()+elfiop->sections[secndx]->get_size(); + VirtualOffset_t first=elfiop->sections[secndx]->get_address(); + VirtualOffset_t second=elfiop->sections[secndx]->get_address()+elfiop->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(); // second=data? - virtual_offset_t offset_into_section=missed_address-elfiop->sections[secndx]->get_address(); + VirtualOffset_t offset_into_section=missed_address-elfiop->sections[secndx]->get_address(); /* disassemble the instruction */ - DecodedInstruction_t disasm(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], elfiop->sections[secndx]->get_size()-offset_into_section ); + auto &disasm=*disasm_p; - /* - memset(&disasm, 0, sizeof(DecodeInstruction_t)); - - disasm.Options = NasmSyntax + PrefixedNumeral; - disasm.Archi = firp->GetArchitectureBitWidth(); - disasm.EIP = (uintptr_t) &data[offset_into_section]; - disasm.SecurityBlock=elfiop->sections[secndx]->get_size()-offset_into_section; - disasm.VirtualAddr = missed_address; - */ - - - - -/* bea docs say OUT_OF_RANGE and UNKNOWN_OPCODE are defined, but they aren't */ -// #define OUT_OF_RANGE (0) -// #define UNKNOWN_OPCODE (-1) - /* if we found the instruction, but can't disassemble it, then we skip out for now */ - if(!disasm.valid()) // instr_len==OUT_OF_RANGE || instr_len==UNKNOWN_OPCODE) + if(!disasm.valid()) { if(getenv("VERBOSE_CFG")) cout<<"Found invalid insn at "<<missed_address<<endl; @@ -295,26 +267,34 @@ void PopulateCFG::add_new_instructions(FileIR_t *firp) newinsnbits[i]=data[offset_into_section+i]; /* create a new address */ - AddressID_t *newaddr=new AddressID_t(); + /* + auto newaddr=new AddressID_t(); assert(newaddr); - newaddr->SetVirtualOffset(missed_address); - newaddr->SetFileID(missed_fileid); + newaddr->setVirtualOffset(missed_address); + newaddr->setFileID(missed_fileid); + firp->getAddresses().insert(newaddr); + */ + auto newaddr=firp->addNewAddress(missed_fileid,missed_address); /* create a new instruction */ - Instruction_t *newinsn=new Instruction_t(); + /* + auto newinsn=new Instruction_t(); assert(newinsn); - newinsn->SetAddress(newaddr); - newinsn->SetDataBits(newinsnbits); - newinsn->SetComment(disasm.getDisassembly()+string(" from fill_in_cfg ")); - newinsn->SetAddress(newaddr); + newinsn->setAddress(newaddr); + newinsn->setDataBits(newinsnbits); + newinsn->setComment(disasm.getDisassembly()+string(" from fill_in_cfg ")); + firp->getInstructions().insert(newinsn); + newinsn->setAddress(newaddr); + */ + auto newinsn=firp->addNewInstruction(newaddr, nullptr, newinsnbits, disasm.getDisassembly()+string(" from fill_in_cfg "), nullptr); + (void)newinsn;// just add to IR + /* fallthrough/target/is indirect will be set later */ /* insert into the IR */ - firp->GetInstructions().insert(newinsn); - firp->GetAddresses().insert(newaddr); - cout<<"Found new instruction, "<<newinsn->GetComment()<<", at "<<std::hex<<newinsn->GetAddress()->GetVirtualOffset()<<" in file "<<"<no name yet>"<<"."<<endl; + cout<<"Found new instruction, "<<newinsn->getComment()<<", at "<<std::hex<<newinsn->getAddress()->getVirtualOffset()<<" in file "<<"<no name yet>"<<"."<<endl; found_instructions++; } @@ -341,28 +321,22 @@ void PopulateCFG::fill_in_cfg(FileIR_t *firp) failed_target_count=0; missed_instructions.clear(); - map< pair<db_id_t,virtual_offset_t>, Instruction_t*> insnMap; + map< pair<DatabaseID_t,VirtualOffset_t>, Instruction_t*> insnMap; populate_instruction_map(insnMap, firp); - cout << "Found "<<firp->GetInstructions().size()<<" instructions." <<endl; + cout << "Found "<<firp->getInstructions().size()<<" instructions." <<endl; /* for each instruction, disassemble it and set the target/fallthrough */ - for( - set<Instruction_t*>::const_iterator it=firp->GetInstructions().begin(); - it!=firp->GetInstructions().end(); - ++it - ) + for(auto insn : firp->getInstructions()) { - Instruction_t *insn=*it; - DecodedInstruction_t disasm(insn); - //memset(&disasm, 0, sizeof(DISASM)); + auto disasm=DecodedInstruction_t::factory(insn); - const auto instr_len = disasm.length(); + const auto instr_len = disasm->length(); - assert(instr_len==insn->GetDataBits().size()); + assert(instr_len==insn->getDataBits().size()); - set_fallthrough(insnMap, &disasm, insn, firp); - set_target(insnMap, &disasm, insn, firp); + set_fallthrough(insnMap, disasm.get(), insn, firp); + set_target(insnMap, disasm.get(), insn, firp); } if(bad_target_count>0) @@ -379,35 +353,23 @@ void PopulateCFG::fill_in_cfg(FileIR_t *firp) } while(missed_instructions.size()>failed_target_count); cout<<"Caution: Was unable to find instructions for these addresses:"<<hex<<endl; - for( - set< pair<db_id_t,virtual_offset_t> >::const_iterator it=missed_instructions.begin(); - it!=missed_instructions.end(); - ++it - ) + for(auto p : missed_instructions) { /* get the address we've missed */ - virtual_offset_t missed_address=(*it).second; + VirtualOffset_t missed_address=p.second; cout << missed_address << ", "; } cout<<dec<<endl; /* set the base IDs for all instructions */ - firp->SetBaseIDS(); + firp->setBaseIDS(); /* for each instruction, set the original address id to be that of the address id, as fill_in_cfg is * designed to work on only original programs. */ - for( - std::set<Instruction_t*>::const_iterator it=firp->GetInstructions().begin(); - it!=firp->GetInstructions().end(); - ++it - ) - { - Instruction_t* insn=*it; - - insn->SetOriginalAddressID(insn->GetAddress()->GetBaseID()); - } + for(auto insn : firp->getInstructions()) + insn->setOriginalAddressID(insn->getAddress()->getBaseID()); } @@ -419,10 +381,9 @@ bool PopulateCFG::is_in_relro_segment(const int secndx) return false; int segnum = real_elfiop->segments.size(); -// int segndx=0; - virtual_offset_t sec_start=(virtual_offset_t)(elfiop->sections[secndx]->get_address()); - virtual_offset_t sec_end=(virtual_offset_t)(elfiop->sections[secndx]->get_address() + elfiop->sections[secndx]->get_size() - 1 ); + 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 ); /* look through each section */ for (int segndx=1; segndx<segnum; segndx++) @@ -434,8 +395,8 @@ bool PopulateCFG::is_in_relro_segment(const int secndx) if(type==PT_GNU_RELRO) { - virtual_offset_t seg_start=(virtual_offset_t)(real_elfiop->segments[segndx]->get_virtual_address()); - virtual_offset_t seg_end=(virtual_offset_t)(real_elfiop->segments[segndx]->get_virtual_address() + real_elfiop->segments[segndx]->get_memory_size() - 1 ); + 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 ); // check if start lies within if(seg_start <= sec_start && sec_start <= seg_end) @@ -457,7 +418,7 @@ bool PopulateCFG::is_in_relro_segment(const int secndx) void PopulateCFG::fill_in_scoops(FileIR_t *firp) { - auto max_base_id=firp->GetMaxBaseID(); + auto max_base_id=firp->getMaxBaseID(); auto secnum = elfiop->sections.size(); auto secndx=0; @@ -487,18 +448,25 @@ void PopulateCFG::fill_in_scoops(FileIR_t *firp) string name=elfiop->sections[secndx]->get_name(); /* start address */ - AddressID_t *startaddr=new AddressID_t(); + /* + auto startaddr=new AddressID_t(); assert(startaddr); - startaddr->SetVirtualOffset( elfiop->sections[secndx]->get_address()); - startaddr->SetFileID(firp->GetFile()->GetBaseID()); - firp->GetAddresses().insert(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 */ - AddressID_t *endaddr=new AddressID_t(); + /* + 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); + 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()); @@ -515,20 +483,104 @@ void PopulateCFG::fill_in_scoops(FileIR_t *firp) ( elfiop->sections[secndx]->isExecutable() << 0 ) ; bool is_relro=is_in_relro_segment(secndx); - DataScoop_t *newscoop=new DataScoop_t(max_base_id++, name, startaddr, endaddr, NULL, permissions, is_relro, the_contents); 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); + 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()<<")" + <<"("<<hex<<startaddr->getVirtualOffset()<<"-" + <<hex<<endaddr->getVirtualOffset()<<")" <<" perms="<<permissions<<" relro="<<boolalpha<<is_relro<<endl; } } +void PopulateCFG::detect_scoops_in_code(FileIR_t *firp) +{ + // data for this function + auto already_scoopified=set<VirtualOffset_t>(); + + // only valid for arm64 + if(firp->getArchitecture()->getMachineType() != admtAarch64) return; + + // check each insn for an ldr with a pcrel operand. + for(auto insn : firp->getInstructions()) + { + // look for ldr's with a pcrel operand + const auto d=DecodedInstruction_t::factory(insn); + if(d->getMnemonic()!="ldr") continue; // only valid on arm. + const auto op0=d->getOperand(0); + const auto op1=d->getOperand(1); + if( !op1->isPcrel()) continue; + + // sanity check that it's a memory operation, and extract fields + assert(op1->isMemory()); + const auto referenced_address=op1->getMemoryDisplacement(); + const auto op0_str=op0->getString(); + const auto referenced_size= // could use API call? + op0_str[0]=='w' ? 4 : + op0_str[0]=='x' ? 8 : + op0_str[0]=='s' ? 4 : + op0_str[0]=='d' ? 8 : + op0_str[0]=='q' ? 16 : + throw domain_error("Cannot decode instruction size"); + ; + + // check if we've seen this address already + const auto already_seen_it=already_scoopified.find(referenced_address); + if(already_seen_it!=end(already_scoopified)) continue; + + // not seen, add it + already_scoopified.insert(referenced_address); + + + // find section and sanity check. + const auto sec=elfiop->sections.findByAddress(referenced_address); + if(sec==nullptr) continue; + + // only trying to do this for executable chunks, other code deals with + // scoops not in the .text section. + if(!sec->isExecutable()) continue; + + const auto sec_data=sec->get_data(); + 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; + + cout<< "Allocated data in text segment "<<name<<"=("<<start_addr->getVirtualOffset()<<"-" + << end_addr->getVirtualOffset()<<")"<<endl; + } +} + void PopulateCFG::fill_in_landing_pads(FileIR_t *firp) { const auto eh_frame_rep_ptr = split_eh_frame_t::factory(firp); @@ -539,14 +591,14 @@ void PopulateCFG::fill_in_landing_pads(FileIR_t *firp) map<Function_t*,set<Instruction_t*> > insns_to_add_to_funcs; - // for_each(firp->GetInstructions().begin(), firp->GetInstructions().end(), [&](Instruction_t* t) - for(const auto t : firp->GetInstructions()) + // for_each(firp->getInstructions().begin(), firp->getInstructions().end(), [&](Instruction_t* t) + for(const auto t : firp->getInstructions()) { - if(t->GetFunction()==NULL) + if(t->getFunction()==NULL) continue; auto lp=eh_frame_rep_ptr->find_lp(t); - if(lp && lp->GetFunction()==NULL) - insns_to_add_to_funcs[t->GetFunction()].insert(lp); + if(lp && lp->getFunction()==NULL) + insns_to_add_to_funcs[t->getFunction()].insert(lp); }; @@ -564,25 +616,25 @@ void PopulateCFG::fill_in_landing_pads(FileIR_t *firp) insns.erase(it); assert(insn); - if(insn->GetFunction()!=NULL) + if(insn->getFunction()!=NULL) continue; auto lp=eh_frame_rep_ptr->find_lp(insn); - if(lp && lp->GetFunction()==NULL) + if(lp && lp->getFunction()==NULL) insns.insert(lp); - insn->SetFunction(func); - cout<<" Adding "<<insn->GetBaseID()<<":"<<insn->getDisassembly()<<"@"<<hex<<insn->GetAddress()->GetVirtualOffset()<<dec<<endl; + insn->setFunction(func); + cout<<" Adding "<<insn->getBaseID()<<":"<<insn->getDisassembly()<<"@"<<hex<<insn->getAddress()->getVirtualOffset()<<dec<<endl; insn_count++; - auto target=insn->GetTarget(); - auto fallthru=insn->GetFallthrough(); + auto target=insn->getTarget(); + auto fallthru=insn->getFallthrough(); if(target) insns.insert(target); if(fallthru) insns.insert(fallthru); } - cout<<"Found LP outside of function "<<func->GetName()<<" added "<<insn_count<<" instructions"<<endl; + cout<<"Found LP outside of function "<<func->getName()<<" added "<<insn_count<<" instructions"<<endl; }; } @@ -616,30 +668,31 @@ int PopulateCFG::parseArgs(const vector<string> step_args) int PopulateCFG::executeStep(IRDBObjects_t *const irdb_objects) { - try + try { const auto pqxx_interface = irdb_objects->getDBInterface(); // now set the DB interface for THIS PLUGIN LIBRARY -- VERY IMPORTANT - BaseObj_t::SetInterface(pqxx_interface); + BaseObj_t::setInterface(pqxx_interface); const auto variant = irdb_objects->addVariant(variant_id); - for(File_t* file : variant->GetFiles()) + for(File_t* file : variant->getFiles()) { - const auto firp = irdb_objects->addFileIR(variant_id, file->GetBaseID()); + const auto firp = irdb_objects->addFileIR(variant_id, file->getBaseID()); assert(firp); - cout<<"Filling in cfg for "<<firp->GetFile()->GetURL()<<endl; + cout<<"Filling in cfg for "<<firp->getFile()->getURL()<<endl; /* get the OID of the file */ - const int elfoid=firp->GetFile()->GetELFOID(); + const int elfoid=firp->getFile()->getELFOID(); pqxx::largeobject lo(elfoid); - lo.to_file(pqxx_interface->GetTransaction(),"readeh_tmp_file.exe"); + lo.to_file(pqxx_interface->getTransaction(),"readeh_tmp_file.exe"); elfiop.reset(new exeio()); elfiop->load(string("readeh_tmp_file.exe")); fill_in_cfg(firp); fill_in_scoops(firp); + detect_scoops_in_code(firp); if (fix_landing_pads) { @@ -669,14 +722,13 @@ int PopulateCFG::executeStep(IRDBObjects_t *const irdb_objects) assert(scoops_detected > 5 ); } - return 0; } extern "C" -shared_ptr<Transform_SDK::TransformStep_t> GetTransformStep(void) +shared_ptr<TransformStep_t> getTransformStep(void) { - const shared_ptr<Transform_SDK::TransformStep_t> the_step(new PopulateCFG()); + const shared_ptr<TransformStep_t> the_step(new PopulateCFG()); return the_step; } diff --git a/libIRDB/test/fill_in_cfg.hpp b/ir_builders/fill_in_cfg.hpp similarity index 54% rename from libIRDB/test/fill_in_cfg.hpp rename to ir_builders/fill_in_cfg.hpp index 5beb37871fbc9ed11100e160271c39ac49f5e79b..93c36e48becad489a64b6fce26734a46b9335e77 100644 --- a/libIRDB/test/fill_in_cfg.hpp +++ b/ir_builders/fill_in_cfg.hpp @@ -1,15 +1,15 @@ #ifndef fill_in_cfg_hpp #define fill_in_cfg_hpp -#include <libIRDB-core.hpp> +#include <irdb-core> #include <stdlib.h> #include <map> #include <exeio.h> -class PopulateCFG : public libIRDB::Transform_SDK::TransformStep_t +class PopulateCFG : public IRDB_SDK::TransformStep_t { public: - PopulateCFG(libIRDB::db_id_t p_variant_id = 0, + PopulateCFG(IRDB_SDK::DatabaseID_t p_variant_id = 0, bool p_fix_landing_pads = true ) : @@ -39,36 +39,37 @@ class PopulateCFG : public libIRDB::Transform_SDK::TransformStep_t return std::string("fill_in_cfg"); } int parseArgs(const std::vector<std::string> step_args) override; - int executeStep(libIRDB::IRDBObjects_t *const) override; + int executeStep(IRDB_SDK::IRDBObjects_t *const) override; private: // methods // main workers - void fill_in_cfg(libIRDB::FileIR_t *); - void fill_in_scoops(libIRDB::FileIR_t *); - void fill_in_landing_pads(libIRDB::FileIR_t *); + 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 *); // helpers void populate_instruction_map ( - std::map< std::pair<libIRDB::db_id_t,libIRDB::virtual_offset_t>, libIRDB::Instruction_t*>&, - libIRDB::FileIR_t * + 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<libIRDB::db_id_t,libIRDB::virtual_offset_t>, libIRDB::Instruction_t*>&, - libIRDB::DecodedInstruction_t *, libIRDB::Instruction_t *, libIRDB::FileIR_t * + 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<libIRDB::db_id_t,libIRDB::virtual_offset_t>, libIRDB::Instruction_t*>&, - libIRDB::DecodedInstruction_t *, libIRDB::Instruction_t *, libIRDB::FileIR_t * + 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 * ); - libIRDB::File_t* find_file(libIRDB::FileIR_t *, libIRDB::db_id_t); - void add_new_instructions(libIRDB::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 @@ -84,11 +85,11 @@ class PopulateCFG : public libIRDB::Transform_SDK::TransformStep_t size_t scoops_detected=0; // non-optional - libIRDB::db_id_t variant_id; + IRDB_SDK::DatabaseID_t variant_id; bool fix_landing_pads; std::unique_ptr<EXEIO::exeio> elfiop; - std::set< std::pair<libIRDB::db_id_t,libIRDB::virtual_offset_t> > missed_instructions; + std::set< std::pair<IRDB_SDK::DatabaseID_t,IRDB_SDK::VirtualOffset_t> > missed_instructions; }; #endif diff --git a/libIRDB/test/fill_in_indtargs.cpp b/ir_builders/fill_in_indtargs.cpp similarity index 53% rename from libIRDB/test/fill_in_indtargs.cpp rename to ir_builders/fill_in_indtargs.cpp index 6281d476858d81a6c5c323d4052e1f1cc3d2a708..0eff242bbd708189b4cbe2a4613d418ed528669e 100644 --- a/libIRDB/test/fill_in_indtargs.cpp +++ b/ir_builders/fill_in_indtargs.cpp @@ -19,8 +19,8 @@ * */ -#include <libIRDB-core.hpp> -#include <libIRDB-util.hpp> +#include <irdb-core> +#include <irdb-util> #include <iostream> #include <fstream> #include <limits> @@ -43,22 +43,40 @@ #include "fill_in_indtargs.hpp" #include "libMEDSAnnotation.h" -using namespace libIRDB; +using namespace IRDB_SDK; using namespace std; using namespace EXEIO; using namespace MEDS_Annotation; + /* * defines */ -#define arch_ptr_bytes() (firp->GetArchitectureBitWidth()/8) #define ALLOF(a) begin(a),end(a) extern void read_ehframe(FileIR_t* firp, EXEIO::exeio* ); -class PopulateIndTargs_t : public libIRDB::Transform_SDK::TransformStep_t + + +class PopulateIndTargs_t : public TransformStep_t { +// record all full addresses and page-addresses found per function (or null for no function +using PerFuncAddrSet_t=set<VirtualOffset_t>; +map<Function_t*,PerFuncAddrSet_t> all_adrp_results; +map<Function_t*,PerFuncAddrSet_t> all_add_adrp_results; + +// record all full addresses and page-addresses found that are spilled to the stack +using SpillPoint_t = pair<Function_t*, VirtualOffset_t>; +map<SpillPoint_t,PerFuncAddrSet_t> spilled_add_adrp_results; +map<SpillPoint_t,PerFuncAddrSet_t> spilled_adrps; + +// record all full addresses found that are spilled to to a floating-point register (e.g., D10) +using DregSpillPoint_t = pair<Function_t*, string>; +map<DregSpillPoint_t, PerFuncAddrSet_t> spilled_to_dreg; + +map<string,PerFuncAddrSet_t> per_reg_add_adrp_results; + public: @@ -68,13 +86,13 @@ public: // the bounds of the executable sections in the pgm. -set< pair <virtual_offset_t,virtual_offset_t> > bounds; +set< pair <VirtualOffset_t,VirtualOffset_t> > bounds; // the set of (possible) targets we've found. -map<virtual_offset_t,ibt_provenance_t> targets; +map<VirtualOffset_t,ibt_provenance_t> targets; // the set of ranges represented by the eh_frame section, could be empty for non-elf files. -set< pair< virtual_offset_t, virtual_offset_t> > ranges; +set< pair< VirtualOffset_t, VirtualOffset_t> > ranges; // a way to map an instruction to its set of (direct) predecessors. map< Instruction_t* , InstructionSet_t > preds; @@ -83,16 +101,16 @@ map< Instruction_t* , InstructionSet_t > preds; map< Instruction_t*, fii_icfs > jmptables; // a map of virtual offset -> instruction for quick access. -map<virtual_offset_t,Instruction_t*> lookupInstructionMap; +map<VirtualOffset_t,Instruction_t*> lookupInstructionMap; // the set of things that are partially unpinned already. set<Instruction_t*> already_unpinned; long total_unpins=0; -void range(virtual_offset_t start, virtual_offset_t end) +void range(VirtualOffset_t start, VirtualOffset_t end) { - pair<virtual_offset_t,virtual_offset_t> foo(start,end); + pair<VirtualOffset_t,VirtualOffset_t> foo(start,end); ranges.insert(foo); } @@ -100,17 +118,12 @@ void range(virtual_offset_t start, virtual_offset_t end) /* * is_in_range - determine if an address is referenced by the eh_frame section */ -bool is_in_range(virtual_offset_t p) +bool is_in_range(VirtualOffset_t p) { - for( - set< pair <virtual_offset_t,virtual_offset_t> >::iterator it=ranges.begin(); - it!=ranges.end(); - ++it - ) + for(auto bound : ranges) { - pair<virtual_offset_t,virtual_offset_t> bound=*it; - virtual_offset_t start=bound.first; - virtual_offset_t end=bound.second; + auto start=bound.first; + auto end=bound.second; if(start<=p && p<=end) return true; } @@ -125,7 +138,7 @@ void process_ranges(FileIR_t* firp) } -bool possible_target(virtual_offset_t p, virtual_offset_t from_addr, ibt_provenance_t prov) +bool possible_target(VirtualOffset_t p, VirtualOffset_t from_addr, ibt_provenance_t prov) { if(is_possible_target(p,from_addr)) { @@ -142,23 +155,12 @@ bool possible_target(virtual_offset_t p, virtual_offset_t from_addr, ibt_provena return false; } -bool is_possible_target(virtual_offset_t p, virtual_offset_t addr) +bool is_possible_target(VirtualOffset_t p, VirtualOffset_t addr) { -/* - if(p!=(int)p) - { - return false; // can't be a pointer if it's greater than 2gb. - } -*/ - for( - set< pair <virtual_offset_t,virtual_offset_t> >::iterator it=bounds.begin(); - it!=bounds.end(); - ++it - ) + for(auto bound : bounds) { - pair<virtual_offset_t,virtual_offset_t> bound=*it; - virtual_offset_t start=bound.first; - virtual_offset_t end=bound.second; + auto start=bound.first; + auto end=bound.second; if(start<=p && p<=end) { return true; @@ -168,7 +170,7 @@ bool is_possible_target(virtual_offset_t p, virtual_offset_t addr) } -EXEIO::section* find_section(virtual_offset_t addr, EXEIO::exeio *elfiop) +EXEIO::section* find_section(VirtualOffset_t addr, EXEIO::exeio *elfiop) { for ( int i = 0; i < elfiop->sections.size(); ++i ) { @@ -184,20 +186,25 @@ EXEIO::section* find_section(virtual_offset_t addr, EXEIO::exeio *elfiop) return nullptr; } -void handle_argument(const DecodedOperand_t *arg, Instruction_t* insn, ibt_provenance_t::provtype_t pt = ibt_provenance_t::ibtp_text) +void handle_argument( + const DecodedInstruction_t& decoded_insn, + const DecodedOperand_t &arg, + Instruction_t* insn, + ibt_provenance_t::provtype_t pt = ibt_provenance_t::ibtp_text + ) { - if(arg->isMemory()) // (arg->ArgType&MEMORY_TYPE) == MEMORY_TYPE ) + if(arg.isMemory() && decoded_insn.getMnemonic()=="lea") { - if(arg->isPcrel()) // (arg->ArgType&RELATIVE_)==RELATIVE_) + if(arg.isPcrel()) { assert(insn); - assert(insn->GetAddress()); - possible_target(arg->getMemoryDisplacement() /*arg->Memory.Displacement*/+insn->GetAddress()->GetVirtualOffset()+ - insn->GetDataBits().length(), insn->GetAddress()->GetVirtualOffset(), pt); + assert(insn->getAddress()); + possible_target(arg.getMemoryDisplacement() + insn->getAddress()->getVirtualOffset() + + insn->getDataBits().length(), insn->getAddress()->getVirtualOffset(), pt); } else { - possible_target(arg->getMemoryDisplacement() /* arg->Memory.Displacement*/, insn->GetAddress()->GetVirtualOffset(), pt); + possible_target(arg.getMemoryDisplacement(), insn->getAddress()->getVirtualOffset(), pt); } } } @@ -206,16 +213,14 @@ void handle_argument(const DecodedOperand_t *arg, Instruction_t* insn, ibt_prove void lookupInstruction_init(FileIR_t *firp) { lookupInstructionMap.clear(); - for(set<Instruction_t*>::const_iterator it=firp->GetInstructions().begin(); - it!=firp->GetInstructions().end(); ++it) + for(auto insn : firp->getInstructions()) { - Instruction_t *insn=*it; - virtual_offset_t addr=insn->GetAddress()->GetVirtualOffset(); + const auto addr=insn->getAddress()->getVirtualOffset(); lookupInstructionMap[addr]=insn; } } -Instruction_t *lookupInstruction(FileIR_t *firp, virtual_offset_t virtual_offset) +Instruction_t *lookupInstruction(FileIR_t *firp, VirtualOffset_t virtual_offset) { if(lookupInstructionMap.find(virtual_offset)!=lookupInstructionMap.end()) return lookupInstructionMap[virtual_offset]; @@ -224,20 +229,15 @@ Instruction_t *lookupInstruction(FileIR_t *firp, virtual_offset_t virtual_offset void mark_targets(FileIR_t *firp) { - for( - set<Instruction_t*>::const_iterator it=firp->GetInstructions().begin(); - it!=firp->GetInstructions().end(); - ++it - ) - { - Instruction_t *insn=*it; - virtual_offset_t addr=insn->GetAddress()->GetVirtualOffset(); + for(auto insn : firp->getInstructions()) + { + auto addr=insn->getAddress()->getVirtualOffset(); /* lookup in the list of targets */ if(targets.find(addr)!=targets.end()) { - bool isret=targets[addr].areOnlyTheseSet(ibt_provenance_t::ibtp_ret); - bool 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); if (isret) { if(getenv("IB_VERBOSE")!=nullptr) @@ -250,12 +250,16 @@ void mark_targets(FileIR_t *firp) } else { + if(getenv("IB_VERBOSE")!=nullptr) + cout<<"Setting pin at "<<hex<<addr<<endl; + /* AddressID_t* newaddr = new AddressID_t; - newaddr->SetFileID(insn->GetAddress()->GetFileID()); - newaddr->SetVirtualOffset(insn->GetAddress()->GetVirtualOffset()); - - insn->SetIndirectBranchTargetAddress(newaddr); - firp->GetAddresses().insert(newaddr); + newaddr->SetFileID(insn->getAddress()->getFileID()); + newaddr->setVirtualOffset(insn->getAddress()->getVirtualOffset()); + firp->getAddresses().insert(newaddr); + */ + auto newaddr=firp->addNewAddress(insn->getAddress()->getFileID(), insn->getAddress()->getVirtualOffset()); + insn->setIndirectBranchTargetAddress(newaddr); } } } @@ -264,22 +268,21 @@ void mark_targets(FileIR_t *firp) bool CallToPrintfFollows(FileIR_t *firp, Instruction_t* insn, const string& arg_str) { - for(Instruction_t* ptr=insn->GetFallthrough(); ptr!=nullptr; ptr=ptr->GetFallthrough()) + for(auto ptr=insn->getFallthrough(); ptr!=nullptr; ptr=ptr->getFallthrough()) { - DecodedInstruction_t d(ptr); - // Disassemble(ptr,d); - if(d.getMnemonic() == string("call")) + auto d=DecodedInstruction_t ::factory(ptr); + if(d->getMnemonic() == string("call")) { // check we have a target - if(ptr->GetTarget()==nullptr) + if(ptr->getTarget()==nullptr) return false; // check the target has a function - if(ptr->GetTarget()->GetFunction()==nullptr) + if(ptr->getTarget()->getFunction()==nullptr) return false; // check if we're calling printf. - if(ptr->GetTarget()->GetFunction()->GetName().find("printf")==string::npos) + if(ptr->getTarget()->getFunction()->getName().find("printf")==string::npos) return false; // found it @@ -287,7 +290,7 @@ bool CallToPrintfFollows(FileIR_t *firp, Instruction_t* insn, const string& arg_ } // found reference to argstring, assume it's a write and exit - if(d.getDisassembly()/*string(d.CompleteInstr)*/.find(arg_str)!= string::npos) + if(d->getDisassembly().find(arg_str)!= string::npos) return false; } @@ -298,45 +301,50 @@ bool texttoprintf(FileIR_t *firp,Instruction_t* insn) { string dst=""; // note that dst is an output parameter of IsParameterWrite and an input parameter to CallFollows - if(IsParameterWrite(firp,insn, dst) && CallToPrintfFollows(firp,insn,dst)) + if(isParameterWrite(firp,insn, dst) && CallToPrintfFollows(firp,insn,dst)) { return true; } return false; } -void get_instruction_targets(FileIR_t *firp, EXEIO::exeio* elfiop, const set<virtual_offset_t>& thunk_bases) +void get_instruction_targets(FileIR_t *firp, EXEIO::exeio* elfiop, const set<VirtualOffset_t>& thunk_bases) { - for( - set<Instruction_t*>::const_iterator it=firp->GetInstructions().begin(); - it!=firp->GetInstructions().end(); - ++it - ) + for(auto insn : firp->getInstructions()) { - Instruction_t *insn=*it; - // DISASM disasm; - DecodedInstruction_t disasm(insn); - virtual_offset_t instr_len = disasm.length(); // Disassemble(insn,disasm); + auto disasm=DecodedInstruction_t::factory(insn); + VirtualOffset_t instr_len = disasm->length(); // Disassemble(insn,disasm); - assert(instr_len==insn->GetDataBits().size()); + assert(instr_len==insn->getDataBits().size()); - // work for both 32- and 64-bit. - check_for_PIC_switch_table32_type2(firp, insn,disasm, elfiop, thunk_bases); - check_for_PIC_switch_table32_type3(firp, insn,disasm, elfiop, thunk_bases); + const auto mt=firp->getArchitecture()->getMachineType(); - if (firp->GetArchitectureBitWidth()==32) - check_for_PIC_switch_table32(firp, insn,disasm, elfiop, thunk_bases); - else if (firp->GetArchitectureBitWidth()==64) - check_for_PIC_switch_table64(firp, insn,disasm, elfiop); - else - assert(0); + if(mt==admtX86_64 || mt==admtI386) + { + // work for both 32- and 64-bit. + check_for_PIC_switch_table32_type2(firp, insn, *disasm, elfiop, thunk_bases); + check_for_PIC_switch_table32_type3(firp, insn, *disasm, elfiop, thunk_bases); - check_for_nonPIC_switch_table(firp, insn,disasm, elfiop); - check_for_nonPIC_switch_table_pattern2(firp, insn,disasm, elfiop); + if (firp->getArchitectureBitWidth()==32) + check_for_PIC_switch_table32(firp, insn, *disasm, elfiop, thunk_bases); + else if (firp->getArchitectureBitWidth()==64) + check_for_PIC_switch_table64(firp, insn, *disasm, elfiop); + else + assert(0); + + check_for_nonPIC_switch_table(firp, insn, *disasm, elfiop); + check_for_nonPIC_switch_table_pattern2(firp, insn, *disasm, elfiop); + } + else if(mt==admtAarch64) + { + check_for_arm_switch_type1(firp,insn, *disasm, elfiop); + } + else + throw invalid_argument("Cannot determine machine type"); /* other branches can't indicate an indirect branch target */ - if(disasm.isBranch()) // disasm.Instruction.BranchType) + if(disasm->isBranch()) // disasm.Instruction.BranchType) continue; ibt_provenance_t::provtype_t prov=0; @@ -346,24 +354,22 @@ void get_instruction_targets(FileIR_t *firp, EXEIO::exeio* elfiop, const set<vir } else { - cout<<"TextToPrintf analysis of '"<<disasm.getDisassembly()<<"' successful at " <<hex<<insn->GetAddress()->GetVirtualOffset()<<endl; + cout<<"TextToPrintf analysis of '"<<disasm->getDisassembly()<<"' successful at " <<hex<<insn->getAddress()->getVirtualOffset()<<endl; prov=ibt_provenance_t::ibtp_texttoprintf; } /* otherwise, any immediate is a possible branch target */ - for(const auto& op: disasm.getOperands()) + for(const auto& op: disasm->getOperands()) { - if(op.isConstant()) - { - possible_target(op.getConstant() /* Instruction.Immediat*/ ,0, prov); - } + if(op->isConstant()) + possible_target(op->getConstant(), 0, prov); } for(auto i=0;i<4;i++) { - if(disasm.hasOperand(i)) + if(disasm->hasOperand(i)) { - const auto op=disasm.getOperand(i); - handle_argument(&op, insn, prov); + const auto op=disasm->getOperand(i); + handle_argument(*disasm, *op, insn, prov); } } } @@ -380,10 +386,10 @@ void get_executable_bounds(FileIR_t *firp, const section* shdr) if( !shdr->isExecutable() ) return; - virtual_offset_t first=shdr->get_address(); - virtual_offset_t second=shdr->get_address()+shdr->get_size(); + VirtualOffset_t first=shdr->get_address(); + VirtualOffset_t second=shdr->get_address()+shdr->get_size(); - bounds.insert(pair<virtual_offset_t,virtual_offset_t>(first,second)); + bounds.insert(pair<VirtualOffset_t,VirtualOffset_t>(first,second)); } @@ -410,7 +416,7 @@ void infer_targets(FileIR_t *firp, section* shdr) const char* data=shdr->get_data() ; // C(char*)malloc(shdr->sh_size); assert(arch_ptr_bytes()==4 || arch_ptr_bytes()==8); - for(int i=0;i+arch_ptr_bytes()<=shdr->get_size();i++) + for(auto i=0u;i+arch_ptr_bytes()<=(size_t)shdr->get_size();i++) { // even on 64-bit, pointers might be stored as 32-bit, as a // elf object has the 32-bit limitations. @@ -419,7 +425,7 @@ void infer_targets(FileIR_t *firp, section* shdr) if(arch_ptr_bytes()==4) p=*(int*)&data[i]; else - p=*(virtual_offset_t*)&data[i]; // 64 or 32-bit depending on sizeof uintptr_t, may need porting for cross platform analysis. + p=*(VirtualOffset_t*)&data[i]; // 64 or 32-bit depending on sizeof uintptr_t, may need porting for cross platform analysis. @@ -447,62 +453,70 @@ void infer_targets(FileIR_t *firp, section* shdr) } +void handle_scoop_scanning(FileIR_t* firp) +{ + // check for addresses in scoops in the text section. + for(auto scoop : firp->getDataScoops()) + { + // test if scoop was added by fill_in_cfg -- make this test better. + if(scoop->getName().find("data_in_text_")==string::npos) continue; + + + // at the moment, FIC only creates 4-, 8-, and 16- bytes scoops + // change this code if FIC chagnes. + if(scoop->getSize() == 4 ) + { + // may be a 4-byter, which can't hold an address. + continue; + } + if(scoop->getSize() == 8 ) + { + // check to see if the scoop has an IBTA + const auto addr=*(uint64_t*)(scoop->getContents().c_str()); + possible_target(addr, scoop->getStart()->getVirtualOffset(), ibt_provenance_t::ibtp_unknown); + } + else + { + // we may see 16 indicating that a ldr q-word happened. + // this isn't likely an IBT, so we skip scanning it. + assert(scoop->getSize() == 16 ); + } + } +} + + void print_targets() { int j=1; - for( - map<virtual_offset_t,ibt_provenance_t>::iterator it=targets.begin(); - it!=targets.end(); - ++it, j++ - ) + for(auto p : targets ) { - virtual_offset_t target=it->first; + const auto target=p.first; - cout<<std::hex<<target; + cout<<hex<<target; if(j%10 == 0) cout<<endl; else cout<<", "; + j++; } cout<<endl; } -void print_targets_oneline() -{ - int j=1; - for( - map<virtual_offset_t,ibt_provenance_t>::iterator it=targets.begin(); - it!=targets.end(); - ++it, j++ - ) - { - virtual_offset_t target=it->first; - - cout<<std::hex<<target<<","; - } - cout<<endl; -} - set<Instruction_t*> find_in_function(string needle, Function_t *haystack) { regex_t preg; - set<Instruction_t*>::const_iterator fit; set<Instruction_t*> found_instructions; assert(0 == regcomp(&preg, needle.c_str(), REG_EXTENDED)); - fit = haystack->GetInstructions().begin(); - for (; fit != haystack->GetInstructions().end(); fit++) + for (auto candidate : haystack->getInstructions()) { - Instruction_t *candidate = *fit; - //DISASM disasm; - //Disassemble(candidate,disasm); - DecodedInstruction_t disasm(candidate); + auto disasm=DecodedInstruction_t::factory(candidate); // check it's the requested type - if(regexec(&preg, disasm.getDisassembly().c_str() /*CompleteInstr*/, 0, nullptr, 0) == 0) + if(regexec(&preg, disasm->getDisassembly().c_str(), 0, nullptr, 0) == 0) { found_instructions.insert(candidate); } @@ -511,100 +525,596 @@ set<Instruction_t*> find_in_function(string needle, Function_t *haystack) return found_instructions; } -bool backup_until(const string &insn_type_regex_str, Instruction_t *& prev, Instruction_t* orig, const string & stop_if_set="", bool recursive=false) + + +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 insn_type_regex=insn_type_regex_str.c_str(); - prev=orig; - regex_t preg; - regex_t stop_expression; - assert(0 == regcomp(&preg, insn_type_regex, REG_EXTENDED)); - if(stop_if_set!="") - assert(0 == regcomp(&stop_expression, stop_if_set.c_str(), REG_EXTENDED)); + 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); - int max=10000; - while(preds[prev].size()==1 && max-- > 0) + 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 - //DISASM disasm; - //Disassemble(prev,disasm); - DecodedInstruction_t disasm(prev); - + const auto disasm=DecodedInstruction_t::factory(prev); // check it's the requested type - if(regexec(&preg, disasm.getDisassembly().c_str() /*CompleteInstr*/, 0, nullptr, 0) == 0) - { - regfree(&preg); - if(stop_if_set!="") - regfree(&stop_expression); + if(regexec(&preg, disasm->getDisassembly().c_str(), 0, nullptr, 0) == 0) return true; - } + if(stop_if_set!="") - for(auto operand : disasm.getOperands()) + { + for(const auto operand : disasm->getOperands()) { - if(operand.isWritten() && regexec(&stop_expression, operand.getString().c_str(), 0, nullptr, 0) == 0) - { - regfree(&preg); - regfree(&stop_expression); + if(operand->isWritten() && regexec(&stop_expression, operand->getString().c_str(), 0, nullptr, 0) == 0) return false; - } } + } // otherwise, try backing up again. } - if(recursive) + if(recursive && max_insns > 0 && max_recursions > 0 ) { - Instruction_t* myprev=prev; + const auto myprev=prev; // can't just use prev because recursive call will update it. - for(InstructionSet_t::iterator it=preds[myprev].begin(); - it!=preds[myprev].end(); ++it) + const auto &mypreds=preds[myprev]; + for(const auto pred : mypreds) { - Instruction_t* pred=*it; - //Disassemble(pred,disasm); - DecodedInstruction_t disasm(pred); + 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()/*CompleteInstr*/, 0, nullptr, 0) == 0) - { - regfree(&preg); - if(stop_if_set!="") - regfree(&stop_expression); + if(regexec(&preg, disasm->getDisassembly().c_str(), 0, nullptr, 0) == 0) return true; - } if(stop_if_set!="") - for(auto operand : disasm.getOperands()) + { + for(const auto operand : disasm->getOperands()) { - if(operand.isWritten() && regexec(&stop_expression, operand.getString().c_str(), 0, nullptr, 0) == 0) - { - regfree(&preg); - regfree(&stop_expression); + if(operand->isWritten() && regexec(&stop_expression, operand->getString().c_str(), 0, nullptr, 0) == 0) return false; - } } - if(backup_until(insn_type_regex, prev, pred, stop_if_set)) - { - regfree(&preg); - if(stop_if_set!="") - regfree(&stop_expression); - return true; } + 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; } } - regfree(&preg); return false; } + +void check_for_arm_switch_type1( + FileIR_t *firp, + Instruction_t* i10, + const DecodedInstruction_t &d10, + EXEIO::exeio* elfiop) +{ + ibt_provenance_t prov=ibt_provenance_t::ibtp_switchtable_type1; + +#if 0 +Sample code for this branch type: + + ; x2 gets the value of x0 + ; this probably is not normal or required, but we are not checking + ; it anyhow. This is just to understand the example. + +i1: 0x4039c4: cmp table_index_reg, #0x3 +i2: 0x4039c8: b.hi 0x4039d4 ; may also be a b.ls + + // generate switch table base address + // this code may be hard to find if the compiler optimizes it + // outside the block with the rest of the dispatch code, and/or + // spills a register. + // thus, we allow for it not to be found, and instead us any "unk" + // we return true if we've found the entry to avoid looking at unks + // if we don't need to. +i5: 0x40449c: adrp table_page_reg, 0x415000 // table page +i6: 0x4044a0: add table_base_reg, table_page_reg, #0x2b0 // table offset + // table=table_page+table_offset + // + // load from switch table +i7: 0x4044a4: ldrh table_entry_reg, [table_base_reg,table_index_reg,uxtw #1] +or +i7: 0x4044a4: ldrb table_entry_reg, [table_base_reg,table_index_reg,uxtw ] + + // calculate branch_addr+4+table[i]*4 +i8: 0x4044a8: adr branch_reg, 0x4044b4 // jump base addr +i9: 0x4044ac: add i10_reg, branch_reg, table_entry_reg, sxth #2 + // actually take the branch +i10: 0x4044b0: br i10_reg +i11: 0x4044b4: + + +notes: + +1) jump table entries are 2-bytes +2) jump table entries specify an offset from the byte after dispatch branch +3) jump table entries dont store the lower 2 bits of the offset, as they + have to be 0 due to instruction alignment + + +#endif + // sanity check the jump + if(d10.getMnemonic() != "br") return; + + // grab the reg + const auto i10_reg=d10.getOperand(0)->getString(); + + // try to find I9 + auto i9=(Instruction_t*)nullptr; + /* search for externder=sxth or sxtb */ + if(!backup_until( string()+"(add "+i10_reg+",.* sxth #2)|(add "+i10_reg+",.* sxtb #2)", /* look for this pattern. */ + i9, /* find i9 */ + i10, /* before I10 */ + "^"+i10_reg+"$" /* stop if i10_reg set */ + )) + { + return; + } + + // Extract the I9 fields. + assert(i9); + const auto d9p = DecodedInstruction_t::factory(i9); + const auto &d9 = *d9p; + const auto offset_reg = d9.getOperand(1)->getString(); + const auto table_entry_reg = d9.getOperand(2)->getString(); + + + // try to find I8 + auto i8=(Instruction_t*)nullptr; + if(!backup_until(string()+"adr "+offset_reg+",", /* look for this pattern. */ + i8, /* find i8 */ + i9, /* before I9 */ + "^"+offset_reg+"$" /* stop if offste_reg set */ + )) + return; + + + // extract the I8 fields + assert(i8); + const auto d8p = DecodedInstruction_t::factory(i8); + const auto &d8 = *d8p; + const auto jump_base_addr = d8.getOperand(1)->getConstant(); + + // try to find I7 + auto i7=(Instruction_t*)nullptr; + if(!backup_until(string()+ "(ldrh "+table_entry_reg+",)|(ldrb "+table_entry_reg+",)", /* look for this pattern. */ + i7, /* find i7 */ + i9, /* before I9 */ + "^"+table_entry_reg+"$" /* stop if index_reg set */ + )) + return; + + + // extract the I7 fields + assert(i7); + const auto d7p = DecodedInstruction_t::factory(i7); + const auto &d7 = *d7p; + const auto memory_op_string = d7.getOperand(1)->getString(); + const auto plus_pos = memory_op_string.find(" +"); + const auto table_base_reg = memory_op_string.substr(0,plus_pos); + const auto table_index_reg = memory_op_string.substr(plus_pos+3); + const auto table_entry_size = + d7.getMnemonic()=="ldrb" ? 1 : + d7.getMnemonic()=="ldrh" ? 2 : + throw invalid_argument("Unable to detected switch table entry size for ARM64"); + + // now we try to find the table base in I5 and I6 + // but we may fail due to compiler opts. Prepare for such failures + // by creating a set of possible table bases. + // If we find i5/i6 or a reload of a spilled table address, + // we will refine our guess. + auto all_table_bases= per_reg_add_adrp_results[table_base_reg]; + + // try to find I6 + auto i6=(Instruction_t*)nullptr; + if(backup_until(string()+"add "+table_base_reg+",", /* look for this pattern. */ + i6, /* find i6 */ + i7, /* before I7 */ + "^"+table_base_reg+"$", /* stop if table_base_reg set */ + true, /* look hard -- recursely examine up to 10k instructions and 500 blocks */ + 10000, + 500 + )) + { + + + // extract the I6 fields + assert(i6); + const auto d6p = DecodedInstruction_t::factory(i6); + const auto &d6 = *d6p; + const auto table_page_reg = d6.getOperand(1)->getString(); + const auto table_page_offset = d6.getOperand(2)->getConstant(); + + // try to find I5 + auto i5=(Instruction_t*)nullptr; + if(backup_until(string()+"adrp "+table_page_reg+",", /* look for this pattern. */ + i5, /* find i5 */ + i6, /* before I6 */ + "^"+table_page_reg+"$", /* stop if table_page set */ + true, /* look hard -- recursely examine up to 10k instructions and 500 blocks */ + 10000, + 500 + )) + { + // extract i5 fields + assert(i5); + const auto d5p = DecodedInstruction_t::factory(i5); + const auto &d5 = *d5p; + const auto table_page = d5.getOperand(1)->getConstant(); + const auto table_addr=table_page+table_page_offset; + all_table_bases= PerFuncAddrSet_t({table_addr}); + } + else + { + for(auto adrp_value : all_adrp_results[i10->getFunction()]) + { + all_table_bases.insert(adrp_value+table_page_offset); + } + } + } + // could not find i5/i6, it's possible (likely) that the table was just spilled and is being + // reloaded from the stack. check for that. + else if(backup_until(string()+"ldr "+table_base_reg+",", /* look for this pattern. */ + i6, /* find i6 -- the reload of the table */ + i7, /* before I7 */ + "^"+table_base_reg+"$", /* stop if table_base_reg set */ + true, /* look hard -- recursely examine up to 10k instructions and 500 blocks */ + 10000, + 500 + )) + { + assert(i6); + const auto d6p = DecodedInstruction_t::factory(i6); + const auto &d6 = *d6p; + // found reload of table address from spill location! + // reloads write to the stack with a constant offset. + const auto reload_op1=d6.getOperand(1); + assert(reload_op1->isMemory()); + const auto reload_op1_string=reload_op1->getString(); + + // needs to have a base reg, which is either sp or x29 + const auto hasbr = (reload_op1->hasBaseRegister()) ; + const auto okbr = (reload_op1_string.substr(0,2)=="sp" || reload_op1_string.substr(0,3)=="x29" ) ; + const auto hasdisp = (reload_op1->hasMemoryDisplacement()) ; + const auto hasir = (reload_op1->hasIndexRegister()) ; + const auto ok = hasbr && okbr && hasdisp && !hasir; + + if(ok) + { + // extract fields + const auto reload_disp=reload_op1->getMemoryDisplacement(); + const auto reload_loc=SpillPoint_t({i10->getFunction(),reload_disp}); + const auto &spills=spilled_add_adrp_results[reload_loc]; + if(spills.size()>0) + { + all_table_bases=spills; + cout<<"Using spilled table bases from stack!"<<endl; + } + } + + } + // also possible we couldn't find it spilled to the stack, and it's instead spilled to an FP register. + else if(backup_until(string()+"fmov "+table_base_reg+",", /* look for this pattern. */ + i6, /* find i6 -- the reload of the table from an FP reg*/ + i7, /* before I7 */ + "^"+table_base_reg+"$", /* stop if table_base_reg set */ + true, /* look hard -- recursely examine up to 10k instructions and 500 blocks */ + 10000, + 500 + )) + { + assert(i6); + const auto d6p = DecodedInstruction_t::factory(i6); + const auto &d6 = *d6p; + const auto reload_op1 = d6.getOperand(1); + const auto reload_op1_str = reload_op1->getString(); + const auto is_dreg = reload_op1_str[0]=='d'; + + if(is_dreg) + { + + const auto reload_loc = DregSpillPoint_t({i6->getFunction(), reload_op1_str}); + const auto spills = spilled_to_dreg[reload_loc]; + if(spills.size()>0) + { + all_table_bases=spills; + cout<<"Using spilled table bases from d-reg!"<<endl; + } + } + } + // end trying to find the table base. + + // try to find i1+i2 so we can assign a resonable bound on the switch table size. + // assume it's 1024 if we can't otherwise find it. + const auto max_bound=1024u; + auto my_bound=max_bound; + + // start by finding i2. + auto i2=(Instruction_t*)nullptr; + if(backup_until(string()+"(b.hi)|(b.ls)", /* look for this pattern. */ + i2, /* find i2 */ + i7, /* before I7 */ + "", /* don't stop for reg sets, just look for control flow */ + true /* recurse into other blocks */ + )) + { + /* find i1 */ + auto i1=(Instruction_t*)nullptr; + if(backup_until(string()+"cmp ", /* look for this pattern. */ + i1, /* find i1 */ + i2, /* before I2 */ + "(cmp)|(adds)|(subs)|(cmn)", /* stop for CC-setting insns -- fixme, probably not the right syntax for stop-if */ + true /* recurse into other blocks */ + )) + { + // try to verify that there's data flow from the ldr[bh] to the cmp + auto next_reg=table_index_reg; + auto prev_insn=i7; + while(true) + { + auto new_i1=(Instruction_t*)nullptr; + if(backup_until(string()+"cmp "+next_reg+",", /* look for this pattern. */ + new_i1, /* find i1 */ + prev_insn, /* before prev_insn */ + "^"+next_reg+"$", /* stop if next_reg is set */ + true /* recurse into other blocks */ + )) + { + if(i1!=new_i1) /* sanity check that we got to the same place */ + break; + const auto d1 = DecodedInstruction_t::factory(i1); + const auto d1op1 = d1->getOperand(1); + if(d1op1->isConstant()) + { + my_bound=d1op1->getConstant(); + } + break; + + } + else if(backup_until(string()+"mov "+next_reg+",", /* look for this pattern. */ + new_i1, /* find i1 */ + prev_insn, /* before I2 */ + "^"+next_reg+"$", /* stop if next_reg is set */ + true /* recurse into other blocks */ + )) + { + // track backwards on reg 2 if we find a mov <reg1>, <reg2> + const auto d1 = DecodedInstruction_t::factory(new_i1); + const auto new_d1op1 = d1->getOperand(1); + if(new_d1op1->isRegister()) + { + next_reg=new_d1op1->getString(); + continue; + } + else + { + // movd constant into table reg? wtf + break; + } + } + else + { + // no bound found + break; + } + assert(0); + } + } + + } + + const auto do_verbose=getenv("IB_VERBOSE"); + + // given: + // 1) a set of possible places for a jump table (all_table_bases) + // 2) address from which the the tables is relative (jump_base_addr) + // 3) the size of the table (my_bound) + // + // calculate any possible targets for this switch. + + // consider each jump table + auto my_targets=set<VirtualOffset_t>(); + auto valid_table_count=0u; + for(auto cur_table_addr : all_table_bases) + { + + // try to find switch table jumps + const auto i10_func=i10->getFunction(); + + // find the section with the jump table + const auto table_section=find_section(cur_table_addr,elfiop); + if(!table_section) continue; + + // if the section has no data, abort if not found + const auto table_section_data_ptr=table_section->get_data(); + if(table_section_data_ptr == nullptr ) continue; + + // get the section's adddress, abort if not loaded + const auto table_section_address=table_section->get_address(); + if(table_section_address==0) continue; + + // ARM swith tables are in ROdata, thus not exectuable and not writeable. + if( table_section->isExecutable() ) continue; + if( table_section->isWriteable() ) continue; + + // calculate how far into the section the table is. + const auto table_offset_into_section=(cur_table_addr-table_section_address); + + // calculate the actual data for the table + const auto table_data_ptr = table_section_data_ptr + table_offset_into_section; + + // calculate a stop point so we don't fall out of the section. + const auto table_section_end_ptr=table_section_data_ptr+table_section->get_size(); + + // define how to map an index in the table into an address to deref. + const auto getEntryPtr = [&](const uint64_t index) { return table_data_ptr + index*table_entry_size; }; + const auto getEntryAddr = [&](const uint64_t index) { return cur_table_addr + index*table_entry_size; }; + + if(do_verbose) + { + // log that we've found a table, etc. + cout << "Found ARM type1 at 0x"<<hex<<i10->getAddress()->getVirtualOffset() + << " with my_bound = 0x"<<hex<<my_bound + << ", table_entry_size = "<<dec<<table_entry_size + << ", jump_base_addr = 0x"<<hex<<jump_base_addr + << ", table_base_reg='"<<table_base_reg<<"'" + << ", table_index_reg='"<<table_index_reg<<"'" + << ", table_addr="<<cur_table_addr + << endl; + } + + const auto do_verbose=getenv("IB_VERBOSE") != nullptr; + + // look at each table entry + auto target_count=0U; + using OffOffProvTuple_t = tuple<VirtualOffset_t, VirtualOffset_t, ibt_provenance_t> ; + auto this_table_targets=vector<OffOffProvTuple_t>(); + for ( ; getEntryPtr(target_count)+table_entry_size < table_section_end_ptr ; target_count++ ) + { + const auto entry_ptr = getEntryPtr(target_count); + const auto entry_address = getEntryAddr(target_count); + const auto table_entry = + table_entry_size==1 ? *(int8_t* )entry_ptr : + table_entry_size==2 ? *(int16_t*)entry_ptr : + throw invalid_argument("Cannot determine how to load table entry from size"); + const auto candidate_ibta = jump_base_addr+table_entry*4; // 4 being instruction alignment factor for ARM64 + const auto ibtarget = lookupInstruction(firp, candidate_ibta); + + if(do_verbose) + cout << "\tEntry #"<<dec<<target_count<<"= ent-addr="<<hex<<entry_address + << " ent="<<hex<<+table_entry // print as int, not char. + << " ibta="<<candidate_ibta; + + // stop if we failed to find an instruction, + // or find an instruction outside the function + if( ibtarget == nullptr ) + { + if(do_verbose) + cout<<" -- no target insn!"<<endl; + break; + } + const auto ibtarget_func=ibtarget->getFunction(); + if( i10_func == nullptr ) + { + // finding switch in non-function is OK. + } + else if(ibtarget_func == nullptr ) + { + // finding target in non-function is OK + } + else if( i10_func != ibtarget_func ) + { + // finding switch in function to different function, not ok. + if(do_verbose) + cout<<" -- switch to diff func? No."<<endl; + break; + + } + + // record that we found something that looks valid-enough to try to pin + // stop if we couldn't pin. + if(!is_possible_target(candidate_ibta,entry_address)) + { + if(do_verbose) + cout<<" -- not valid target!"<<endl; + break; + } + if(firp->findScoop(candidate_ibta)!=nullptr) + { + if(do_verbose) + cout<<" -- not valid target due to data-in-text detection!"<<endl; + break; + + } + + if(do_verbose) + cout<<" -- valid target!"<<endl; + + // record this entry of the table + // this works on newer compilers and is easier to read, but older compilers.... + // this_table_targets.push_back({candidate_ibta, entry_address,prov}); + this_table_targets.push_back(make_tuple(candidate_ibta, entry_address,prov)); + + if(target_count>my_bound) + break; + + } + // allow this table if the bound was a max-bound situation. + // also allow if all the table entries were valid. + // (allow week off-by-one comparison due to inaccurancies in detecting exact bound) + if(my_bound == max_bound || target_count+1 >= my_bound) + { + // since this table is valid, add all entries to the list of IBT's for this IR. + for(auto &t : this_table_targets) + { + const auto candidate_ibta=get<0>(t); + possible_target(candidate_ibta, get<1>(t), get<2>(t)); + my_targets.insert(candidate_ibta); + } + valid_table_count++; + } + } + cout << "Across "<<dec<<all_table_bases.size()<< " tables, "<<valid_table_count<<" are valid, bound="<<my_bound + << " unique target count="<<my_targets.size()<<" entry_size="<<table_entry_size<<endl; + return; +} + + /* * check_for_PIC_switch_table32 - look for switch tables in PIC code for 32-bit code. */ -void check_for_PIC_switch_table32(FileIR_t *firp, Instruction_t* insn, DecodedInstruction_t disasm, EXEIO::exeio* elfiop, const set<virtual_offset_t> &thunk_bases) +void check_for_PIC_switch_table32(FileIR_t *firp, Instruction_t* insn, const DecodedInstruction_t& disasm, EXEIO::exeio* elfiop, const set<VirtualOffset_t> &thunk_bases) { ibt_provenance_t prov=ibt_provenance_t::ibtp_switchtable_type1; @@ -641,15 +1151,15 @@ I7: 08069391 <_gedit_app_ready+0x91> ret return; // return if it's a jump to a constant address, these are common - if(disasm.getOperand(0).isConstant() /*disasm.Argument1.ArgType&CONSTANT_TYPE*/) + if(disasm.getOperand(0)->isConstant() ) return; // return if it's a jump to a memory address - if(disasm.getOperand(0).isMemory() /*disasm.Argument1.ArgType&MEMORY_TYPE*/) + if(disasm.getOperand(0)->isMemory() ) return; - assert(disasm.getOperand(0).isRegister()); - const auto I5_reg=disasm.getOperand(0).getString(); + assert(disasm.getOperand(0)->isRegister()); + const auto I5_reg=disasm.getOperand(0)->getString(); auto jmp_reg=string(); auto add_reg=string(); @@ -661,20 +1171,22 @@ I7: 08069391 <_gedit_app_ready+0x91> ret auto mov_insn=static_cast<Instruction_t*>(nullptr); if(!backup_until(string()+"mov "+I5_reg, mov_insn, I5, I5_reg)) return; - const auto mov_insn_disasm=DecodedInstruction_t(mov_insn); - if(!mov_insn_disasm.getOperand(1).isRegister()) + const auto p_mov_insn_disasm=DecodedInstruction_t::factory(mov_insn); + const auto &mov_insn_disasm=*p_mov_insn_disasm; + if(!mov_insn_disasm.getOperand(1)->isRegister()) return; - const auto mov_reg=mov_insn_disasm.getOperand(1).getString(); + const auto mov_reg=mov_insn_disasm.getOperand(1)->getString(); if(!backup_until(string()+"add "+mov_reg, I4, mov_insn, mov_reg)) return; jmp_reg=mov_reg; } else { - const auto d4=DecodedInstruction_t(I4); + const auto p_d4=DecodedInstruction_t::factory(I4); + const auto &d4=*p_d4; if(d4.getMnemonic()=="lea") { - const auto base_reg=d4.getOperand(1).getBaseRegister(); + const auto base_reg=d4.getOperand(1)->getBaseRegister(); switch(base_reg) { case 0/*REG0*/: jmp_reg="eax"; break; @@ -689,7 +1201,7 @@ I7: 08069391 <_gedit_app_ready+0x91> ret // no base register; return; } - const auto index_reg=d4.getOperand(1).getBaseRegister(); + const auto index_reg=d4.getOperand(1)->getBaseRegister(); switch(index_reg) { case 0/*REG0*/: add_reg="eax"; break; @@ -708,9 +1220,9 @@ I7: 08069391 <_gedit_app_ready+0x91> ret else { jmp_reg=I5_reg; - if(!d4.getOperand(1).isRegister()) + if(!d4.getOperand(1)->isRegister()) return; - add_reg=d4.getOperand(1).getString(); + add_reg=d4.getOperand(1)->getString(); } } @@ -732,30 +1244,28 @@ I7: 08069391 <_gedit_app_ready+0x91> ret { //DISASM dcmp; //Disassemble(Icmp,dcmp); - DecodedInstruction_t dcmp(Icmp); - table_size = dcmp.getImmediate(); //Instruction.Immediat; + auto dcmp=DecodedInstruction_t::factory(Icmp); + table_size = dcmp->getImmediate(); //Instruction.Immediat; if(table_size<=0) table_size=std::numeric_limits<int>::max(); } // grab the offset out of the lea. - //DISASM d2; - //Disassemble(I3,d2); - DecodedInstruction_t d2(I3); + const auto p_d2=DecodedInstruction_t::factory(I3); + const auto &d2=*p_d2; // get the offset from the thunk - virtual_offset_t table_offset=d2.getAddress(); // d2.Instruction.AddrValue; + auto table_offset=d2.getAddress(); if(table_offset==0) return; - cout<<hex<<"Found switch dispatch at "<<I3->GetAddress()->GetVirtualOffset()<< " with table_offset="<<table_offset - <<" and table_size="<<table_size<<endl; + cout<<hex<<"Found switch dispatch at "<<I3->getAddress()->getVirtualOffset() + << " with table_offset="<<table_offset <<" and table_size="<<table_size<<endl; /* iterate over all thunk_bases/module_starts */ - for(set<virtual_offset_t>::iterator it=thunk_bases.begin(); it!=thunk_bases.end(); ++it) + for(auto thunk_base : thunk_bases) { - virtual_offset_t thunk_base=*it; - virtual_offset_t table_base=*it+table_offset; + VirtualOffset_t table_base=thunk_base+table_offset; // find the section with the data table EXEIO::section *pSec=find_section(table_base,elfiop); @@ -768,7 +1278,7 @@ I7: 08069391 <_gedit_app_ready+0x91> ret continue; // get the base offset into the section - virtual_offset_t offset=table_base-pSec->get_address(); + VirtualOffset_t offset=table_base-pSec->get_address(); int i; for(i=0;i<3;i++) { @@ -795,7 +1305,7 @@ I7: 08069391 <_gedit_app_ready+0x91> ret break; const int32_t *table_entry_ptr=(const int32_t*)&(secdata[offset+i*4]); - virtual_offset_t table_entry=*table_entry_ptr; + VirtualOffset_t table_entry=*table_entry_ptr; if(getenv("IB_VERBOSE")!=0) cout<<"Found switch table (thunk-relative) entry["<<dec<<i<<"], "<<hex<<thunk_base+table_entry<<endl; @@ -813,11 +1323,11 @@ I7: 08069391 <_gedit_app_ready+0x91> ret // valid switch table? may or may not have default: in the switch // table size = 8, #entries: 9 b/c of default cout << "pic32 (base pattern): table size: " << table_size << " ibtargets.size: " << ibtargets.size() << endl; - jmptables[I5].AddTargets(ibtargets); + jmptables[I5].addTargets(ibtargets); if (table_size == ibtargets.size() || table_size == (ibtargets.size()-1)) { cout << "pic32 (base pattern): valid switch table detected ibtp_switchtable_type1" << endl; - jmptables[I5].SetAnalysisStatus(ICFS_Analysis_Complete); + jmptables[I5].setAnalysisStatus(iasAnalysisComplete); } } @@ -833,7 +1343,7 @@ I7: 08069391 <_gedit_app_ready+0x91> ret -void check_for_PIC_switch_table32_type2(FileIR_t *firp, Instruction_t* insn, DecodedInstruction_t disasm, EXEIO::exeio* elfiop, const set<virtual_offset_t> &thunk_bases) +void check_for_PIC_switch_table32_type2(FileIR_t *firp, Instruction_t* insn, const DecodedInstruction_t& disasm, EXEIO::exeio* elfiop, const set<VirtualOffset_t> &thunk_bases) { ibt_provenance_t prov=ibt_provenance_t::ibtp_switchtable_type2; auto ibtargets = InstructionSet_t(); @@ -855,12 +1365,12 @@ I5: 0x809900e <text_handler+51>: jmp ecx return; // return if it's a jump to a constant address, these are common - if(disasm.getOperand(0).isConstant() /*disasm.Argument1.ArgType&CONSTANT_TYPE*/) + if(disasm.getOperand(0)->isConstant() /*disasm.Argument1.ArgType&CONSTANT_TYPE*/) return; // return if it's a jump to a memory address //if(disasm.Argument1.ArgType&MEMORY_TYPE) - if(disasm.getOperand(0).isMemory()) + if(disasm.getOperand(0)->isMemory()) return; // has to be a jump to a register now @@ -869,8 +1379,8 @@ I5: 0x809900e <text_handler+51>: jmp ecx if(!backup_until("add", I4, I5)) return; - const auto d4=DecodedInstruction_t(I4); - if(!d4.hasOperand(1) || !d4.getOperand(1).isMemory()) + const auto d4=DecodedInstruction_t::factory(I4); + if(!d4->hasOperand(1) || !d4->getOperand(1)->isMemory()) return; // found that sometimes I3 is set a different way, @@ -879,36 +1389,30 @@ I5: 0x809900e <text_handler+51>: jmp ecx // if(!backup_until("lea", I3, I4)) // return; - // grab the offset out of the lea. - //DISASM d2; - //Disassemble(I3,d2); - //DecodedInstruction_t d2(I3); - // get the offset from the thunk - virtual_offset_t table_offset=d4.getOperand(1).getMemoryDisplacement(); //d2.getAddress(); // d2.Instruction.AddrValue; + VirtualOffset_t table_offset=d4->getOperand(1)->getMemoryDisplacement(); if(table_offset==0) return; -cout<<hex<<"Found (type2) switch dispatch at "<<I5->GetAddress()->GetVirtualOffset()<< " with table_offset="<<table_offset<<endl; + cout<<hex<<"Found (type2) switch dispatch at "<<I5->getAddress()->getVirtualOffset()<< " with table_offset="<<table_offset<<endl; /* iterate over all thunk_bases/module_starts */ - for(set<virtual_offset_t>::iterator it=thunk_bases.begin(); it!=thunk_bases.end(); ++it) + for(auto thunk_base : thunk_bases ) { - virtual_offset_t thunk_base=*it; - virtual_offset_t table_base=(*it)+table_offset; + auto table_base=thunk_base+table_offset; // find the section with the data table - EXEIO::section *pSec=find_section(table_base,elfiop); + auto pSec=find_section(table_base,elfiop); if(!pSec) continue; // if the section has no data, abort - const char* secdata=pSec->get_data(); + const auto secdata=pSec->get_data(); if(!secdata) continue; // get the base offset into the section - virtual_offset_t offset=table_base-pSec->get_address(); + VirtualOffset_t offset=table_base-pSec->get_address(); int i; for(i=0;i<3;i++) { @@ -916,7 +1420,7 @@ cout<<hex<<"Found (type2) switch dispatch at "<<I5->GetAddress()->GetVirtualOffs break; const int32_t *table_entry_ptr=(const int32_t*)&(secdata[offset+i*4]); - virtual_offset_t table_entry=*table_entry_ptr; + VirtualOffset_t table_entry=*table_entry_ptr; // cout<<"Checking target base:" << std::hex << table_base+table_entry << ", " << table_base+i*4<<endl; if(!is_possible_target(table_base+table_entry,table_base+i*4) && !is_possible_target(thunk_base+table_entry,table_base+i*4)) @@ -934,7 +1438,7 @@ cout<<hex<<"Found (type2) switch dispatch at "<<I5->GetAddress()->GetVirtualOffs break; const int32_t *table_entry_ptr=(const int32_t*)&(secdata[offset+i*4]); - virtual_offset_t table_entry=*table_entry_ptr; + VirtualOffset_t table_entry=*table_entry_ptr; if(getenv("IB_VERBOSE")!=0) cout<<"Found switch table (thunk-relative) entry["<<dec<<i<<"], "<<hex<<table_base+table_entry<<" or "<<thunk_base+table_entry<<endl; @@ -959,7 +1463,7 @@ cout<<hex<<"Found (type2) switch dispatch at "<<I5->GetAddress()->GetVirtualOffs // now, try next thunk base } - jmptables[I5].AddTargets(ibtargets); + jmptables[I5].addTargets(ibtargets); } @@ -970,31 +1474,31 @@ cout<<hex<<"Found (type2) switch dispatch at "<<I5->GetAddress()->GetVirtualOffs * * nb: also works for 64-bit. */ -void check_for_PIC_switch_table32_type3(FileIR_t* firp, Instruction_t* insn, DecodedInstruction_t disasm, EXEIO::exeio* elfiop, const set<virtual_offset_t> &thunk_bases) +void check_for_PIC_switch_table32_type3(FileIR_t* firp, Instruction_t* insn, const DecodedInstruction_t& disasm, EXEIO::exeio* elfiop, const set<VirtualOffset_t> &thunk_bases) { - uint32_t ptrsize=firp->GetArchitectureBitWidth()/8; + uint32_t ptrsize=firp->getArchitectureBitWidth()/8; ibt_provenance_t prov=ibt_provenance_t::ibtp_switchtable_type3; Instruction_t* I5=insn; // check if I5 is a jump - if(strstr(disasm.getMnemonic().c_str()/*Instruction.Mnemonic*/, "jmp")==nullptr) + if(strstr(disasm.getMnemonic().c_str(), "jmp")==nullptr) return; // return if it's not a jump to a memory address - if(!(disasm.getOperand(0).isMemory())) + if(!(disasm.getOperand(0)->isMemory())) return; /* return if there's no displacement */ - if(disasm.getOperand(0).getMemoryDisplacement()==0) + if(disasm.getOperand(0)->getMemoryDisplacement()==0) return; - if(!disasm.getOperand(0).hasIndexRegister() || disasm.getOperand(0).getScaleValue()!=ptrsize) + if(!disasm.getOperand(0)->hasIndexRegister() || disasm.getOperand(0)->getScaleValue()!=ptrsize) return; // grab the table base out of the jmp. - virtual_offset_t table_base=disasm.getOperand(0).getMemoryDisplacement();//disasm.Argument1.Memory.Displacement; - if(disasm.getOperand(0).isPcrel()) - table_base+=insn->GetDataBits().size()+insn->GetAddress()->GetVirtualOffset(); + VirtualOffset_t table_base=disasm.getOperand(0)->getMemoryDisplacement(); + if(disasm.getOperand(0)->isPcrel()) + table_base+=insn->getDataBits().size()+insn->getAddress()->getVirtualOffset(); if(table_base==0) return; @@ -1009,8 +1513,8 @@ void check_for_PIC_switch_table32_type3(FileIR_t* firp, Instruction_t* insn, Dec if(backup_until("cmp ", cmp_insn, insn)) { assert(cmp_insn); - const auto cmp_decode=DecodedInstruction_t(cmp_insn); - table_max=cmp_decode.getImmediate(); + const auto cmp_decode=DecodedInstruction_t::factory(cmp_insn); + table_max=cmp_decode->getImmediate(); } @@ -1020,12 +1524,12 @@ void check_for_PIC_switch_table32_type3(FileIR_t* firp, Instruction_t* insn, Dec return; // get the base offset into the section - virtual_offset_t offset=table_base-pSec->get_address(); + VirtualOffset_t offset=table_base-pSec->get_address(); // check to see if stars already marked this complete. // if so, just figure out the table size - if(jmptables[insn].GetAnalysisStatus()==ICFS_Analysis_Complete) + if(jmptables[insn].getAnalysisStatus()==iasAnalysisComplete) { // we already know it's a type3, we can just record the type and table base. jmptables[insn].AddSwitchType(prov); @@ -1041,14 +1545,14 @@ void check_for_PIC_switch_table32_type3(FileIR_t* firp, Instruction_t* insn, Dec const void *table_entry_ptr=(const int*)&(secdata[offset+i*ptrsize]); - virtual_offset_t table_entry=0; + VirtualOffset_t table_entry=0; switch(ptrsize) { case 4: - table_entry=(virtual_offset_t)*(int*)table_entry_ptr; + table_entry=(VirtualOffset_t)*(int*)table_entry_ptr; break; case 8: - table_entry=(virtual_offset_t)*(int**)table_entry_ptr; + table_entry=(VirtualOffset_t)*(int**)table_entry_ptr; break; default: assert(0); @@ -1062,7 +1566,7 @@ void check_for_PIC_switch_table32_type3(FileIR_t* firp, Instruction_t* insn, Dec jmptables[insn].SetTableSize(i); if(getenv("IB_VERBOSE")) { - cout<<"Found type3 at "<<hex<<insn->GetAddress()->GetVirtualOffset() + cout<<"Found type3 at "<<hex<<insn->getAddress()->getVirtualOffset() <<" already complete, setting base to "<<hex<<table_base<<" and size to "<<dec<<i<<endl; } return; @@ -1077,14 +1581,14 @@ void check_for_PIC_switch_table32_type3(FileIR_t* firp, Instruction_t* insn, Dec const void *table_entry_ptr=(const int*)&(secdata[offset+i*ptrsize]); - virtual_offset_t table_entry=0; + VirtualOffset_t table_entry=0; switch(ptrsize) { case 4: - table_entry=(virtual_offset_t)*(int*)table_entry_ptr; + table_entry=(VirtualOffset_t)*(int*)table_entry_ptr; break; case 8: - table_entry=(virtual_offset_t)*(int**)table_entry_ptr; + table_entry=(VirtualOffset_t)*(int**)table_entry_ptr; break; default: assert(0); @@ -1095,8 +1599,7 @@ void check_for_PIC_switch_table32_type3(FileIR_t* firp, Instruction_t* insn, Dec /* if there's no base register and no index reg, */ /* then this jmp can't have more than one valid table entry */ - //if( disasm.Argument1.Memory.BaseRegister==0 && disasm.Argument1.Memory.IndexRegister==0 ) - if( !disasm.getOperand(0).hasBaseRegister() && !disasm.getOperand(0).hasIndexRegister()) + if( !disasm.getOperand(0)->hasBaseRegister() && !disasm.getOperand(0)->hasIndexRegister()) { /* but the table can have 1 valid entry. */ if(pSec->get_name()==".got.plt") @@ -1105,10 +1608,10 @@ void check_for_PIC_switch_table32_type3(FileIR_t* firp, Instruction_t* insn, Dec if(ibtarget) { jmptables[I5].insert(ibtarget); - jmptables[I5].SetAnalysisStatus(ICFS_Analysis_Module_Complete); + jmptables[I5].setAnalysisStatus(iasAnalysisModuleComplete); possible_target(table_entry,table_base+0*ptrsize, ibt_provenance_t::ibtp_gotplt); if(getenv("IB_VERBOSE")!=0) - cout<<hex<<"Found plt dispatch ("<<disasm.getDisassembly()<<"') at "<<I5->GetAddress()->GetVirtualOffset()<< endl; + cout<<hex<<"Found plt dispatch ("<<disasm.getDisassembly()<<"') at "<<I5->getAddress()->getVirtualOffset()<< endl; return; } } @@ -1118,7 +1621,7 @@ void check_for_PIC_switch_table32_type3(FileIR_t* firp, Instruction_t* insn, Dec possible_target(table_entry,table_base+0*ptrsize, ibt_provenance_t::ibtp_rodata); if(getenv("IB_VERBOSE")!=0) cout<<hex<<"Found constant-memory dispatch from non- .got.plt location ("<<disasm.getDisassembly()<<"') at " - <<I5->GetAddress()->GetVirtualOffset()<< endl; + <<I5->getAddress()->getVirtualOffset()<< endl; return; } if(!is_possible_target(table_entry,table_base+i*ptrsize)) @@ -1126,7 +1629,7 @@ void check_for_PIC_switch_table32_type3(FileIR_t* firp, Instruction_t* insn, Dec if(getenv("IB_VERBOSE")!=0) { cout<<hex<<"Found (type3) candidate for switch dispatch for '"<<disasm.getDisassembly()<<"' at " - <<I5->GetAddress()->GetVirtualOffset()<< " with table_base="<<table_base<<endl; + <<I5->getAddress()->getVirtualOffset()<< " with table_base="<<table_base<<endl; cout<<"Found table_entry "<<hex<<table_entry<<" is not valid\n"<<endl; } return; @@ -1134,7 +1637,7 @@ void check_for_PIC_switch_table32_type3(FileIR_t* firp, Instruction_t* insn, Dec } - cout<<hex<<"Definitely found (type3) switch dispatch at "<<I5->GetAddress()->GetVirtualOffset()<< " with table_base="<<table_base<<endl; + cout<<hex<<"Definitely found (type3) switch dispatch at "<<I5->getAddress()->getVirtualOffset()<< " with table_base="<<table_base<<endl; /* did we finish the loop or break out? */ if(i==3) @@ -1150,24 +1653,24 @@ void check_for_PIC_switch_table32_type3(FileIR_t* firp, Instruction_t* insn, Dec { if(getenv("IB_VERBOSE")!=0) { - cout<<hex<<"Switch dispatch at "<<I5->GetAddress()->GetVirtualOffset()<< " with table_base=" + cout<<hex<<"Switch dispatch at "<<I5->getAddress()->getVirtualOffset()<< " with table_base=" <<table_base<<" is complete!"<<endl; } - jmptables[insn].SetAnalysisStatus(ICFS_Analysis_Complete); + jmptables[insn].setAnalysisStatus(iasAnalysisComplete); } if((int)(offset+i*ptrsize+ptrsize) > (int)pSec->get_size() || i > table_max) return; const void *table_entry_ptr=(const int*)&(secdata[offset+i*ptrsize]); - virtual_offset_t table_entry=0; + VirtualOffset_t table_entry=0; switch(ptrsize) { case 4: - table_entry=(virtual_offset_t)*(int*)table_entry_ptr; + table_entry=(VirtualOffset_t)*(int*)table_entry_ptr; break; case 8: - table_entry=(virtual_offset_t)*(int**)table_entry_ptr; + table_entry=(VirtualOffset_t)*(int**)table_entry_ptr; break; default: assert(0); @@ -1197,7 +1700,7 @@ void check_for_PIC_switch_table32_type3(FileIR_t* firp, Instruction_t* insn, Dec * if so, see if we can trace back a few instructions to find a * the start of the table. */ -void check_for_PIC_switch_table64(FileIR_t* firp, Instruction_t* insn, DecodedInstruction_t disasm, EXEIO::exeio* elfiop) +void check_for_PIC_switch_table64(FileIR_t* firp, Instruction_t* insn, const DecodedInstruction_t& p_disasm, EXEIO::exeio* elfiop) { ibt_provenance_t prov=ibt_provenance_t::ibtp_switchtable_type4; /* here's the pattern we're looking for */ @@ -1270,14 +1773,14 @@ Note: Here the operands of the add are reversed, so lookup code was not finding Instruction_t* I5=nullptr; Instruction_t* I1=nullptr; // check if I8 is a jump - if(strstr(disasm.getMnemonic().c_str()/*Instruction.Mnemonic*/, "jmp")==nullptr) + if(strstr(p_disasm.getMnemonic().c_str(), "jmp")==nullptr) return; // return if it's a jump to a constant address, these are common - if(disasm.getOperand(0).isConstant()) //disasm.Argument1.ArgType&CONSTANT_TYPE) + if(p_disasm.getOperand(0)->isConstant()) return; // return if it's a jump to a memory address - if(disasm.getOperand(0).isMemory()) // Argument1.ArgType&MEMORY_TYPE) + if(p_disasm.getOperand(0)->isMemory()) return; // has to be a jump to a register now @@ -1290,30 +1793,29 @@ Note: Here the operands of the add are reversed, so lookup code was not finding * Backup and find the instruction that's an add or lea before I8. */ table_index_str = "(add "; - table_index_str += disasm.getOperand(0).getString(); //Argument1.ArgMnemonic; + table_index_str += p_disasm.getOperand(0)->getString(); table_index_str += "|lea "; - table_index_str += disasm.getOperand(0).getString(); //Argument1.ArgMnemonic; + table_index_str += p_disasm.getOperand(0)->getString(); table_index_str += ")"; - const auto cmp_str = string("cmp ") + disasm.getOperand(0).getString(); //Argument1.ArgMnemonic; + const auto cmp_str = string("cmp ") + p_disasm.getOperand(0)->getString(); // this was completely broken because argument2 had a null mnemonic, which we found out because getOperand(1) threw an exception. // i suspect it's attempting to find a compare of operand1 on the RHS of a compare, but i need better regex foo to get that. // for now, repeat what was working. - const auto cmp_str2 = string("cmp "); // + disasm.getOperand(1).getString(); //Argument2.ArgMnemonic; + const auto cmp_str2 = string("cmp "); if(!backup_until(table_index_str.c_str(), I7, I8)) return; - // Disassemble(I7,disasm); - disasm=DecodedInstruction_t(I7); + const auto d7=DecodedInstruction_t::factory(I7); // Check if lea instruction is being used as add (scale=1, disp=0) - if(strstr(disasm.getMnemonic().c_str() /* Instruction.Mnemonic*/, "lea")) + if(strstr(d7->getMnemonic().c_str(), "lea")) { - if(!(disasm.getOperand(1).isMemory() /*disasm.Argument2.ArgType&MEMORY_TYPE)*/)) + if(!(d7->getOperand(1)->isMemory() )) return; - if(!(disasm.getOperand(1).getScaleValue() /* .Argument2.Memory.Scale */ == 1 && disasm.getOperand(1).getMemoryDisplacement() /*Argument2.Memory.Displacement*/ == 0)) + if(!(d7->getOperand(1)->getScaleValue() == 1 && d7->getOperand(1)->getMemoryDisplacement() == 0)) return; } // backup and find the instruction that's an movsxd before I7 @@ -1326,9 +1828,8 @@ Note: Here the operands of the add are reversed, so lookup code was not finding string lea_string="lea "; - // Disassemble(I6,disasm); - disasm=DecodedInstruction_t(I6); - if( disasm.getOperand(1).isMemory() /* (disasm.Argument2.ArgType&MEMORY_TYPE) == MEMORY_TYPE*/) + const auto d6=DecodedInstruction_t::factory(I6); + if( d6->getOperand(1)->isMemory() ) { // try to be smarter for memory types. @@ -1338,9 +1839,9 @@ Note: Here the operands of the add are reversed, so lookup code was not finding * for the base of the jump table. */ string base_reg=""; - if(!disasm.getOperand(1).hasBaseRegister() /*Argument2.Memory.BaseRegister*/) + if(!d6->getOperand(1)->hasBaseRegister() ) return; - switch(disasm.getOperand(1).getBaseRegister() /*Argument2.Memory.BaseRegister*/) + switch(d6->getOperand(1)->getBaseRegister() ) { case 0/*REG0*/: base_reg="rax"; break; case 1/*REG1*/: base_reg="rcx"; break; @@ -1379,14 +1880,13 @@ Note: Here the operands of the add are reversed, so lookup code was not finding * Convert to return set */ - set<Instruction_t*>::const_iterator found_leas_it; - set<Instruction_t*> found_leas; + auto found_leas=InstructionSet_t(); - if (I6->GetFunction()) + if (I6->getFunction()) { cout << "Using find_in_function method." << endl; - found_leas=find_in_function(lea_string,I6->GetFunction()); + found_leas=find_in_function(lea_string,I6->getFunction()); } else { @@ -1407,66 +1907,58 @@ Note: Here the operands of the add are reversed, so lookup code was not finding /* * Check each one that is returned. */ - found_leas_it = found_leas.begin(); + auto found_leas_it = found_leas.begin(); for (; found_leas_it != found_leas.end(); found_leas_it++) { - Instruction_t *I5_cur = *found_leas_it; - //Disassemble(I5_cur,disasm); - disasm=DecodedInstruction_t(I5_cur); + auto I5_cur = *found_leas_it; + auto d5p=DecodedInstruction_t::factory(I5_cur); + auto &d5=*d5p; - if(!(disasm.getOperand(1).isMemory() /*Argument2.ArgType&MEMORY_TYPE*/)) - //return; + if(!(d5.getOperand(1)->isMemory() )) continue; - if(!(disasm.getOperand(1).isPcrel() /*Argument2.ArgType&RELATIVE_*/)) - //return; + if(!(d5.getOperand(1)->isPcrel() )) continue; // note that we'd normally have to add the displacement to the // instruction address (and include the instruction's size, etc. // but, fix_calls has already removed this oddity so we can relocate // the instruction. - virtual_offset_t D1=strtol(disasm.getOperand(1).getString().c_str()/*Argument2.ArgMnemonic*/, nullptr, 0); - D1+=I5_cur->GetAddress()->GetVirtualOffset(); + VirtualOffset_t D1=strtol(d5.getOperand(1)->getString().c_str(), nullptr, 0); + D1+=I5_cur->getAddress()->getVirtualOffset(); // find the section with the data table - EXEIO::section *pSec=find_section(D1,elfiop); + auto pSec=find_section(D1,elfiop); // sanity check there's a section if(!pSec) - //return; continue; const char* secdata=pSec->get_data(); // if the section has no data, abort if(!secdata) - //return; continue; auto table_size = 0U; if(backup_until(cmp_str.c_str(), I1, I8)) { - //DISASM d1; - //Disassemble(I1,d1); - DecodedInstruction_t d1(I1); - table_size = d1.getImmediate(); // Instruction.Immediat; + auto d1=DecodedInstruction_t::factory(I1); + table_size = d1->getImmediate(); // Instruction.Immediat; if (table_size <= 4) { - cout<<"pic64: found I1 ('"<<d1.getDisassembly()/*CompleteInstr*/<<"'), but could not find size of switch table"<<endl; + cout<<"pic64: found I1 ('"<<d1->getDisassembly()<<"'), but could not find size of switch table"<<endl; // set table_size to be very large, so we can still do pinning appropriately table_size=std::numeric_limits<int>::max(); } } else if(backup_until(cmp_str2.c_str(), I1, I8)) { - //DISASM d1; - //Disassemble(I1,d1); - DecodedInstruction_t d1(I1); - table_size = d1.getImmediate()/*Instruction.Immediat*/; + auto d1=DecodedInstruction_t::factory(I1); + table_size = d1->getImmediate()/*Instruction.Immediat*/; if (table_size <= 4) { // set table_size to be very large, so we can still do pinning appropriately - cout<<"pic64: found I1 ('"<<d1.getDisassembly()/*CompleteInstr*/<<"'), but could not find size of switch table"<<endl; + cout<<"pic64: found I1 ('"<<d1->getDisassembly()<<"'), but could not find size of switch table"<<endl; table_size=std::numeric_limits<int>::max(); } } @@ -1479,8 +1971,8 @@ Note: Here the operands of the add are reversed, so lookup code was not finding table_size=std::numeric_limits<int>::max(); } - set<Instruction_t *> ibtargets; - virtual_offset_t offset=D1-pSec->get_address(); + auto ibtargets=InstructionSet_t(); + auto offset=D1-pSec->get_address(); auto entry=0U; auto found_table_error = false; do @@ -1493,7 +1985,7 @@ Note: Here the operands of the add are reversed, so lookup code was not finding } const int *table_entry_ptr=(const int*)&(secdata[offset]); - virtual_offset_t table_entry=*table_entry_ptr; + VirtualOffset_t table_entry=*table_entry_ptr; if(!possible_target(D1+table_entry, 0/* from addr unknown */,prov)) { @@ -1503,13 +1995,13 @@ Note: Here the operands of the add are reversed, so lookup code was not finding if(getenv("IB_VERBOSE")) { - cout<<"Found possible table entry, at: "<< std::hex << I8->GetAddress()->GetVirtualOffset() - << " insn: " << disasm.getDisassembly()/*CompleteInstr*/<< " d1: " + cout<<"Found possible table entry, at: "<< std::hex << I8->getAddress()->getVirtualOffset() + << " insn: " << d5.getDisassembly()<< " d1: " << D1 << " table_entry:" << table_entry << " target: "<< D1+table_entry << std::dec << endl; } - Instruction_t *ibtarget = lookupInstruction(firp, D1+table_entry); + auto ibtarget = lookupInstruction(firp, D1+table_entry); if (ibtarget && ibtargets.size() <= table_size) { if(getenv("IB_VERBOSE")) @@ -1533,18 +2025,18 @@ Note: Here the operands of the add are reversed, so lookup code was not finding // table size = 8, #entries: 9 b/c of default cout << "pic64: detected table size (max_int means no found): 0x"<< hex << table_size << " #entries: 0x" << entry << " ibtargets.size: " << ibtargets.size() << endl; - jmptables[I8].AddTargets(ibtargets); + jmptables[I8].addTargets(ibtargets); // note that there may be an off-by-one error here as table size depends on whether instruction I2 is a jb or jbe. if (!found_table_error) { - cout << "pic64: valid switch table for "<<hex<<I8->GetAddress()->GetVirtualOffset() + cout << "pic64: valid switch table for "<<hex<<I8->getAddress()->getVirtualOffset() <<"detected ibtp_switchtable_type4" << endl; - jmptables[I8].SetAnalysisStatus(ICFS_Analysis_Complete); + jmptables[I8].setAnalysisStatus(iasAnalysisComplete); } else { cout << "pic64: INVALID switch table detected for, " - <<hex<<I8->GetAddress()->GetVirtualOffset()<<"type=ibtp_switchtable_type4" << endl; + <<hex<<I8->getAddress()->getVirtualOffset()<<"type=ibtp_switchtable_type4" << endl; } } } @@ -1562,7 +2054,7 @@ Note: Here the operands of the add are reversed, so lookup code was not finding nb: handles both 32 and 64 bit */ -void check_for_nonPIC_switch_table_pattern2(FileIR_t* firp, Instruction_t* insn, DecodedInstruction_t disasm, EXEIO::exeio* elfiop) +void check_for_nonPIC_switch_table_pattern2(FileIR_t* firp, Instruction_t* insn, const DecodedInstruction_t& p_disasm, EXEIO::exeio* elfiop) { ibt_provenance_t prov=ibt_provenance_t::ibtp_switchtable_type5; Instruction_t *I1 = nullptr; @@ -1571,27 +2063,23 @@ void check_for_nonPIC_switch_table_pattern2(FileIR_t* firp, Instruction_t* insn, assert(IJ); // check if IJ is a jump - //if(strstr(disasm.Instruction.Mnemonic, "jmp")==nullptr) - if(strstr(disasm.getMnemonic().c_str(), "jmp")==nullptr) + if(strstr(p_disasm.getMnemonic().c_str(), "jmp")==nullptr) return; // look for a memory type - //if(!(disasm.Argument1.ArgType&MEMORY_TYPE)) - if(!(disasm.getOperand(0).isMemory())) + if(!(p_disasm.getOperand(0)->isMemory())) return; // make sure there's a scaling factor - //if (disasm.Argument1.Memory.Scale < 4) - //if (disasm.getOperand(0).getScaleValue() < 4) assumes scale is meaningful here? - if (!disasm.getOperand(0).hasIndexRegister() || disasm.getOperand(0).getScaleValue() < 4) + if (!p_disasm.getOperand(0)->hasIndexRegister() || p_disasm.getOperand(0)->getScaleValue() < 4) return; // extract start of jmp table - virtual_offset_t table_offset = disasm.getAddress(); // disasm.Instruction.AddrValue; + VirtualOffset_t table_offset = p_disasm.getAddress(); // disasm.Instruction.AddrValue; if(table_offset==0) return; - cout<<hex<<"(nonPIC-pattern2): Found switch dispatch at 0x"<<hex<<IJ->GetAddress()->GetVirtualOffset()<< " with table_offset="<<hex<<table_offset<<dec<<endl; + cout<<hex<<"(nonPIC-pattern2): Found switch dispatch at 0x"<<hex<<IJ->getAddress()->getVirtualOffset()<< " with table_offset="<<hex<<table_offset<<dec<<endl; if(!backup_until("cmp", I1, IJ)) { @@ -1601,17 +2089,16 @@ void check_for_nonPIC_switch_table_pattern2(FileIR_t* firp, Instruction_t* insn, // extract size off the comparison // make sure not off by one - //DISASM d1; - //Disassemble(I1,d1); - DecodedInstruction_t d1(I1); - virtual_offset_t table_size = d1.getImmediate()/*d1.Instruction.Immediat*/; + auto d1p=DecodedInstruction_t::factory(I1); + auto &d1=*d1p; + VirtualOffset_t table_size = d1.getImmediate()/*d1.Instruction.Immediat*/; if (table_size <= 0) return; cout<<"(nonPIC-pattern2): size of jmp table: "<< table_size << endl; // find the section with the data table - EXEIO::section *pSec=find_section(table_offset,elfiop); + auto pSec=find_section(table_offset,elfiop); if(!pSec) { return; @@ -1623,10 +2110,10 @@ void check_for_nonPIC_switch_table_pattern2(FileIR_t* firp, Instruction_t* insn, return; // get the base offset into the section - virtual_offset_t offset=table_offset-pSec->get_address(); + auto offset=table_offset-pSec->get_address(); auto i=0U; - set<Instruction_t*> ibtargets; + InstructionSet_t ibtargets; for(i=0;i<table_size;++i) { if((int)(offset+i*arch_ptr_bytes()+sizeof(int)) > (int)pSec->get_size()) @@ -1635,8 +2122,8 @@ void check_for_nonPIC_switch_table_pattern2(FileIR_t* firp, Instruction_t* insn, return; } - const virtual_offset_t *table_entry_ptr=(const virtual_offset_t*)&(secdata[offset+i*arch_ptr_bytes()]); - virtual_offset_t table_entry=*table_entry_ptr; + const VirtualOffset_t *table_entry_ptr=(const VirtualOffset_t*)&(secdata[offset+i*arch_ptr_bytes()]); + VirtualOffset_t table_entry=*table_entry_ptr; possible_target(table_entry,0,prov); Instruction_t *ibtarget = lookupInstruction(firp, table_entry); @@ -1653,8 +2140,8 @@ void check_for_nonPIC_switch_table_pattern2(FileIR_t* firp, Instruction_t* insn, cout << "(non-PIC) valid switch table found - ibtp_switchtable_type5" << endl; - jmptables[IJ].AddTargets(ibtargets); - jmptables[IJ].SetAnalysisStatus(ICFS_Analysis_Complete); + jmptables[IJ].addTargets(ibtargets); + jmptables[IJ].setAnalysisStatus(iasAnalysisComplete); } /* @@ -1670,26 +2157,25 @@ void check_for_nonPIC_switch_table_pattern2(FileIR_t* firp, Instruction_t* insn, nb: handles both 32 and 64 bit */ -void check_for_nonPIC_switch_table(FileIR_t* firp, Instruction_t* insn, DecodedInstruction_t disasm, EXEIO::exeio* elfiop) +void check_for_nonPIC_switch_table(FileIR_t* firp, Instruction_t* insn, const DecodedInstruction_t& p_disasm, EXEIO::exeio* elfiop) { ibt_provenance_t prov=ibt_provenance_t::ibtp_switchtable_type6; Instruction_t *I1 = nullptr; - //Instruction_t *I2 = nullptr; Instruction_t *I4 = nullptr; Instruction_t *IJ = insn; if (!IJ) return; // check if IJ is a jump - if(strstr(disasm.getMnemonic().c_str()/*disasm.Instruction.Mnemonic*/, "jmp")==nullptr) + if(strstr(p_disasm.getMnemonic().c_str()/*disasm.Instruction.Mnemonic*/, "jmp")==nullptr) return; // return if it's a jump to a constant address, these are common - if(disasm.getOperand(0).isConstant() /*disasm.Argument1.ArgType&CONSTANT_TYPE*/) + if(p_disasm.getOperand(0)->isConstant() /*disasm.Argument1.ArgType&CONSTANT_TYPE*/) return; // return if it's a jump to a memory address - if(disasm.getOperand(0).isMemory() /*disasm.Argument1.ArgType&MEMORY_TYPE*/) + if(p_disasm.getOperand(0)->isMemory() /*disasm.Argument1.ArgType&MEMORY_TYPE*/) return; // has to be a jump to a register now @@ -1701,18 +2187,19 @@ void check_for_nonPIC_switch_table(FileIR_t* firp, Instruction_t* insn, DecodedI // extract start of jmp table // DISASM d4; // Disassemble(I4,d4); - DecodedInstruction_t d4(I4); + auto d4p=DecodedInstruction_t::factory(I4); + auto &d4=*d4p; // make sure there's a scaling factor - if (d4.getOperand(1).isMemory() && d4.getOperand(1).getScaleValue() /*d4.Argument2.Memory.Scale*/ < 4) + if (d4.getOperand(1)->isMemory() && d4.getOperand(1)->getScaleValue() < 4) return; - virtual_offset_t table_offset=d4.getAddress(); // d4.Instruction.AddrValue; + VirtualOffset_t table_offset=d4.getAddress(); if(table_offset==0) return; if(getenv("IB_VERBOSE")) - cout<<hex<<"(nonPIC): Found switch dispatch at 0x"<<hex<<I4->GetAddress()->GetVirtualOffset()<< " with table_offset="<<hex<<table_offset<<dec<<endl; + cout<<hex<<"(nonPIC): Found switch dispatch at 0x"<<hex<<I4->getAddress()->getVirtualOffset()<< " with table_offset="<<hex<<table_offset<<dec<<endl; if(!backup_until("cmp", I1, I4)) { @@ -1722,17 +2209,16 @@ void check_for_nonPIC_switch_table(FileIR_t* firp, Instruction_t* insn, DecodedI // extract size off the comparison // make sure not off by one - //DISASM d1; - //Disassemble(I1,d1); - DecodedInstruction_t d1(I1); - virtual_offset_t table_size = d1.getImmediate(); // d1.Instruction.Immediat; + auto d1p=DecodedInstruction_t::factory(I1); + auto &d1=*d1p; + auto table_size = d1.getImmediate(); // d1.Instruction.Immediat; if (table_size <= 0) return; if(getenv("IB_VERBOSE")) cout<<"(nonPIC): size of jmp table: "<< table_size << endl; // find the section with the data table - EXEIO::section *pSec=find_section(table_offset,elfiop); + auto pSec=find_section(table_offset,elfiop); if(!pSec) { cout<<hex<<"(nonPIC): could not find jump table in section"<<endl; @@ -1745,13 +2231,13 @@ void check_for_nonPIC_switch_table(FileIR_t* firp, Instruction_t* insn, DecodedI return; // get the base offset into the section - virtual_offset_t offset=table_offset-pSec->get_address(); + auto offset=table_offset-pSec->get_address(); auto i=0U; if(getenv("IB_VERBOSE")) - cout << hex << "offset: " << offset << " arch bit width: " << dec << firp->GetArchitectureBitWidth() << endl; + cout << hex << "offset: " << offset << " arch bit width: " << dec << firp->getArchitectureBitWidth() << endl; - set<Instruction_t*> ibtargets; + InstructionSet_t ibtargets; for(i=0;i<table_size;++i) { if((int)(offset+i*arch_ptr_bytes()+sizeof(int)) > (int)pSec->get_size()) @@ -1760,22 +2246,22 @@ void check_for_nonPIC_switch_table(FileIR_t* firp, Instruction_t* insn, DecodedI return; } - virtual_offset_t table_entry=0; - if (firp->GetArchitectureBitWidth()==32) + VirtualOffset_t table_entry=0; + if (firp->getArchitectureBitWidth()==32) { const int *table_entry_ptr=(const int*)&(secdata[offset+i*arch_ptr_bytes()]); table_entry=*table_entry_ptr; } - else if (firp->GetArchitectureBitWidth()==64) + else if (firp->getArchitectureBitWidth()==64) { - const virtual_offset_t *table_entry_ptr=(const virtual_offset_t*)&(secdata[offset+i*arch_ptr_bytes()]); + const VirtualOffset_t *table_entry_ptr=(const VirtualOffset_t*)&(secdata[offset+i*arch_ptr_bytes()]); table_entry=*table_entry_ptr; } else assert(0 && "Unknown arch size."); possible_target(table_entry, 0 /* from addr unknown */, prov); - Instruction_t *ibtarget = lookupInstruction(firp, table_entry); + auto ibtarget = lookupInstruction(firp, table_entry); if (!ibtarget) { if(getenv("IB_VERBOSE")) cout << "0x" << hex << table_entry << " is not an instruction, invalid switch table" << endl; @@ -1788,33 +2274,41 @@ void check_for_nonPIC_switch_table(FileIR_t* firp, Instruction_t* insn, DecodedI } cout << "(non-PIC) valid switch table found - prov=ibt_provenance_t::ibtp_switchtable_type6" << endl; - jmptables[IJ].AddTargets(ibtargets); - jmptables[IJ].SetAnalysisStatus(ICFS_Analysis_Complete); + jmptables[IJ].addTargets(ibtargets); + jmptables[IJ].setAnalysisStatus(iasAnalysisComplete); } void calc_preds(FileIR_t* firp) { preds.clear(); - for( - set<Instruction_t*>::const_iterator it=firp->GetInstructions().begin(); - it!=firp->GetInstructions().end(); - ++it - ) + for(auto insn : firp->getInstructions()) { - Instruction_t* insn=*it; - if(insn->GetTarget()) - preds[insn->GetTarget()].insert(insn); - if(insn->GetFallthrough()) - preds[insn->GetFallthrough()].insert(insn); + if(insn->getTarget()) + preds[insn->getTarget()].insert(insn); + if(insn->getFallthrough()) + preds[insn->getFallthrough()].insert(insn); } } +void handle_takes_address_annot(FileIR_t* firp,Instruction_t* insn, MEDS_TakesAddressAnnotation* p_takes_address_annotation) +{ + const auto referenced_addr=p_takes_address_annotation->GetReferencedAddress(); + if(p_takes_address_annotation->isCode()) + { + const auto refd_addr=referenced_addr; + possible_target(refd_addr,insn->getAddress()->getVirtualOffset(), ibt_provenance_t::ibtp_text); + } + else + { + all_add_adrp_results[insn->getFunction()].insert(referenced_addr); + } +} void handle_ib_annot(FileIR_t* firp,Instruction_t* insn, MEDS_IBAnnotation* p_ib_annotation) { if(p_ib_annotation->IsComplete()) { - jmptables[insn].SetAnalysisStatus(ICFS_Analysis_Complete); + jmptables[insn].setAnalysisStatus(iasAnalysisComplete); } } void handle_ibt_annot(FileIR_t* firp,Instruction_t* insn, MEDS_IBTAnnotation* p_ibt_annotation) @@ -1831,21 +2325,21 @@ void handle_ibt_annot(FileIR_t* firp,Instruction_t* insn, MEDS_IBTAnnotation* p_ /* meds annotations * typedef enum { SWITCH, RET, DATA, UNREACHABLE, ADDRESSED, UNKNOWN } ibt_reason_code_t; */ - //cout<<"at handl_ibt with addr="<<hex<<insn->GetAddress()->GetVirtualOffset()<<" code="<<p_ibt_annotation->GetReason()<<endl; + //cout<<"at handl_ibt with addr="<<hex<<insn->getAddress()->getVirtualOffset()<<" code="<<p_ibt_annotation->GetReason()<<endl; switch(p_ibt_annotation->GetReason()) { case MEDS_IBTAnnotation::SWITCH: case MEDS_IBTAnnotation::INDIRCALL: { - possible_target((EXEIO::virtual_offset_t)p_ibt_annotation->getVirtualOffset().getOffset(), + possible_target((VirtualOffset_t)p_ibt_annotation->getVirtualOffset().getOffset(), 0,ibt_provenance_t::ibtp_stars_switch); - libIRDB::virtual_offset_t addr=(libIRDB::virtual_offset_t)p_ibt_annotation->GetXrefAddr(); - Instruction_t* fromib=lookupInstruction(firp, addr); - Instruction_t* ibt=lookupInstruction(firp, p_ibt_annotation->getVirtualOffset().getOffset()); + auto addr=(VirtualOffset_t)p_ibt_annotation->GetXrefAddr(); + auto fromib=lookupInstruction(firp, addr); + auto ibt=lookupInstruction(firp, p_ibt_annotation->getVirtualOffset().getOffset()); if(fromib && ibt) { if(getenv("IB_VERBOSE")!=nullptr) - cout<<hex<<"Adding call/switch icfs: "<<fromib->GetAddress()->GetVirtualOffset()<<"->"<<ibt->GetAddress()->GetVirtualOffset()<<endl; + cout<<hex<<"Adding call/switch icfs: "<<fromib->getAddress()->getVirtualOffset()<<"->"<<ibt->getAddress()->getVirtualOffset()<<endl; jmptables[fromib].insert(ibt); } else @@ -1857,18 +2351,18 @@ void handle_ibt_annot(FileIR_t* firp,Instruction_t* insn, MEDS_IBTAnnotation* p_ case MEDS_IBTAnnotation::RET: { /* we are not going to mark return points as IBTs yet. that's fix-calls job */ - // possible_target((EXEIO::virtual_offset_t)p_ibt_annotation->getVirtualOffset().getOffset(), + // possible_target((VirtualOffset_t)p_ibt_annotation->getVirtualOffset().getOffset(), // 0,ibt_provenance_t::ibtp_stars_ret); - libIRDB::virtual_offset_t fromaddr=(libIRDB::virtual_offset_t)p_ibt_annotation->GetXrefAddr(); - Instruction_t* fromib=lookupInstruction(firp, fromaddr); - libIRDB::virtual_offset_t toaddr=p_ibt_annotation->getVirtualOffset().getOffset(); - Instruction_t* ibt=lookupInstruction(firp, toaddr); + auto fromaddr=(VirtualOffset_t)p_ibt_annotation->GetXrefAddr(); + auto fromib=lookupInstruction(firp, fromaddr); + auto toaddr=p_ibt_annotation->getVirtualOffset().getOffset(); + auto ibt=lookupInstruction(firp, toaddr); if(fromib && ibt) { if(getenv("IB_VERBOSE")!=nullptr) - cout<<hex<<"Adding ret icfs: "<<fromib->GetAddress()->GetVirtualOffset()<<"->"<<ibt->GetAddress()->GetVirtualOffset()<<endl; + cout<<hex<<"Adding ret icfs: "<<fromib->getAddress()->getVirtualOffset()<<"->"<<ibt->getAddress()->getVirtualOffset()<<endl; jmptables[fromib].insert(ibt); } else @@ -1879,7 +2373,7 @@ void handle_ibt_annot(FileIR_t* firp,Instruction_t* insn, MEDS_IBTAnnotation* p_ } case MEDS_IBTAnnotation::DATA: { - possible_target((EXEIO::virtual_offset_t)p_ibt_annotation->getVirtualOffset().getOffset(), + possible_target((VirtualOffset_t)p_ibt_annotation->getVirtualOffset().getOffset(), 0,ibt_provenance_t::ibtp_stars_data); if(getenv("IB_VERBOSE")!=nullptr) cout<<hex<<"detected stars data ibt at"<<p_ibt_annotation->getVirtualOffset().getOffset()<<endl; @@ -1887,7 +2381,7 @@ void handle_ibt_annot(FileIR_t* firp,Instruction_t* insn, MEDS_IBTAnnotation* p_ } case MEDS_IBTAnnotation::UNREACHABLE: { - possible_target((EXEIO::virtual_offset_t)p_ibt_annotation->getVirtualOffset().getOffset(), + possible_target((VirtualOffset_t)p_ibt_annotation->getVirtualOffset().getOffset(), 0,ibt_provenance_t::ibtp_stars_unreachable); if(getenv("IB_VERBOSE")!=nullptr) cout<<hex<<"detected stars unreachable ibt at"<<p_ibt_annotation->getVirtualOffset().getOffset()<<endl; @@ -1895,7 +2389,7 @@ void handle_ibt_annot(FileIR_t* firp,Instruction_t* insn, MEDS_IBTAnnotation* p_ } case MEDS_IBTAnnotation::ADDRESSED: { - possible_target((EXEIO::virtual_offset_t)p_ibt_annotation->getVirtualOffset().getOffset(), + possible_target((VirtualOffset_t)p_ibt_annotation->getVirtualOffset().getOffset(), 0,ibt_provenance_t::ibtp_stars_addressed); if(getenv("IB_VERBOSE")!=nullptr) cout<<hex<<"detected stars addresssed ibt at"<<p_ibt_annotation->getVirtualOffset().getOffset()<<endl; @@ -1903,7 +2397,7 @@ void handle_ibt_annot(FileIR_t* firp,Instruction_t* insn, MEDS_IBTAnnotation* p_ } case MEDS_IBTAnnotation::UNKNOWN: { - possible_target((EXEIO::virtual_offset_t)p_ibt_annotation->getVirtualOffset().getOffset(), + possible_target((VirtualOffset_t)p_ibt_annotation->getVirtualOffset().getOffset(), 0,ibt_provenance_t::ibtp_stars_unknown); if(getenv("IB_VERBOSE")!=nullptr) cout<<hex<<"detected stars unknown ibt at"<<p_ibt_annotation->getVirtualOffset().getOffset()<<endl; @@ -1921,24 +2415,18 @@ void handle_ibt_annot(FileIR_t* firp,Instruction_t* insn, MEDS_IBTAnnotation* p_ void read_stars_xref_file(FileIR_t* firp) { - string BINARY_NAME="a.ncexe"; - string SHARED_OBJECTS_DIR="shared_objects"; + const auto BINARY_NAME=string("a.ncexe"); + const auto SHARED_OBJECTS_DIR=string("shared_objects"); - string fileBasename = basename((char*)firp->GetFile()->GetURL().c_str()); - int ibs=0; - int ibts=0; + const auto fileBasename = string(basename((char*)firp->getFile()->getURL().c_str())); - MEDS_AnnotationParser annotationParser; - string annotationFilename; + auto annotationParser=MEDS_AnnotationParser(); // need to map filename to integer annotation file produced by STARS // this should be retrieved from the IRDB but for now, we use files to store annotations // convention from within the peasoup subdirectory is: // a.ncexe.infoannot // shared_objects/<shared-lib-filename>.infoannot - if (fileBasename==BINARY_NAME) - annotationFilename = BINARY_NAME; - else - annotationFilename = SHARED_OBJECTS_DIR + "/" + fileBasename ; + const auto annotationFilename =(fileBasename==BINARY_NAME) ? BINARY_NAME : SHARED_OBJECTS_DIR + "/" + fileBasename ; try { @@ -1949,75 +2437,54 @@ void read_stars_xref_file(FileIR_t* firp) cout<<"Warning: annotation parser reports error: "<<s<<endl; } - for( - set<Instruction_t*>::const_iterator it=firp->GetInstructions().begin(); - it!=firp->GetInstructions().end(); - ++it - ) + for(auto insn : firp->getInstructions()) { - Instruction_t* insn=*it; - virtual_offset_t irdb_vo = insn->GetAddress()->GetVirtualOffset(); - VirtualOffset vo(irdb_vo); + const auto irdb_vo = insn->getAddress()->getVirtualOffset(); + const auto vo=VirtualOffset_t(irdb_vo); /* find it in the annotations */ - pair<MEDS_Annotations_t::iterator,MEDS_Annotations_t::iterator> ret; - ret = annotationParser.getAnnotations().equal_range(vo); - MEDS_IBAnnotation* p_ib_annotation; - MEDS_IBTAnnotation* p_ibt_annotation; + const auto ret = annotationParser.getAnnotations().equal_range(vo); /* for each annotation for this instruction */ - for (MEDS_Annotations_t::iterator ait = ret.first; ait != ret.second; ++ait) + for (auto ait = ret.first; ait != ret.second; ++ait) { /* is this annotation a funcSafe annotation? */ - p_ib_annotation=dynamic_cast<MEDS_IBAnnotation*>(ait->second); + const auto p_ib_annotation=dynamic_cast<MEDS_IBAnnotation*>(ait->second); + const auto p_ibt_annotation=dynamic_cast<MEDS_IBTAnnotation*>(ait->second); + const auto p_takes_address_annotation=dynamic_cast<MEDS_TakesAddressAnnotation*>(ait->second); if(p_ib_annotation && p_ib_annotation->isValid()) - { - ibs++; handle_ib_annot(firp,insn,p_ib_annotation); - } - p_ibt_annotation=dynamic_cast<MEDS_IBTAnnotation*>(ait->second); - if(p_ibt_annotation && p_ibt_annotation->isValid()) - { - ibts++; + else if(p_ibt_annotation && p_ibt_annotation->isValid()) handle_ibt_annot(firp,insn,p_ibt_annotation); - } + else if(p_takes_address_annotation && p_takes_address_annotation->isValid()) + handle_takes_address_annot(firp,insn,p_takes_address_annotation); } } - - cout<<"Found "<<ibs<<" ibs and "<<ibts<<" ibts in the STARSxref file."<<endl; - } void process_dynsym(FileIR_t* firp) { auto dynsymfile = popen("$PS_OBJDUMP -T readeh_tmp_file.exe | $PS_GREP '^[0-9]\\+' | $PS_GREP -v UND | awk '{print $1;}' | $PS_GREP -v '^$'", "r"); - assert(dynsymfile); + if(!dynsymfile) + { + perror("Cannot open readeh_tmp_file.exe"); + exit(2); + } auto target=(unsigned int)0; while( fscanf(dynsymfile, "%x", &target) != -1) { - possible_target((virtual_offset_t)target,0,ibt_provenance_t::ibtp_dynsym); + possible_target((VirtualOffset_t)target,0,ibt_provenance_t::ibtp_dynsym); } } ICFS_t* setup_hellnode(FileIR_t* firp, EXEIO::exeio* elfiop, ibt_provenance_t allowed) { - ICFS_t* hn=new ICFS_t(ICFS_Analysis_Module_Complete); + auto hn=firp->addNewICFS(nullptr, {}, iasAnalysisModuleComplete); - for( - set<Instruction_t*>::const_iterator it=firp->GetInstructions().begin(); - it!=firp->GetInstructions().end(); - ++it - ) + for(auto insn: firp->getInstructions()) { - Instruction_t* insn=*it; - - /* - if(insn->GetIndirectBranchTargetAddress() == nullptr) - continue; - */ - - ibt_provenance_t prov=targets[insn->GetAddress()->GetVirtualOffset()]; + auto prov=targets[insn->getAddress()->getVirtualOffset()]; if(prov.isEmpty()) continue; @@ -2029,7 +2496,7 @@ ICFS_t* setup_hellnode(FileIR_t* firp, EXEIO::exeio* elfiop, ibt_provenance_t al } if(hn->size() < 1000 && !elfiop->isDynamicallyLinked()) - hn->SetAnalysisStatus(ICFS_Analysis_Complete); + hn->setAnalysisStatus(iasAnalysisComplete); return hn; } @@ -2073,7 +2540,7 @@ ICFS_t* setup_call_hellnode(FileIR_t* firp, EXEIO::exeio* elfiop) * ibt_provenance_t::ibtp_switchtable_type10 */ - ICFS_t* ret=setup_hellnode(firp,elfiop,allowed); + auto ret=setup_hellnode(firp,elfiop,allowed); cout<<"# ATTRIBUTE fill_in_indtargs::call_hellnode_size="<<dec<<ret->size()<<endl; return ret; @@ -2117,7 +2584,7 @@ ICFS_t* setup_jmp_hellnode(FileIR_t* firp, EXEIO::exeio* elfiop) * ibt_provenance_t::ibtp_switchtable_type10 */ - ICFS_t* ret=setup_hellnode(firp,elfiop,allowed); + auto ret=setup_hellnode(firp,elfiop,allowed); cout<<"# ATTRIBUTE fill_in_indtargs::jmp_hellnode_size="<<dec<<ret->size()<<endl; return ret; @@ -2166,7 +2633,7 @@ ICFS_t* setup_ret_hellnode(FileIR_t* firp, EXEIO::exeio* elfiop) * ibt_provenance_t::ibtp_gotplt */ - ICFS_t* ret_hell_node=setup_hellnode(firp,elfiop,allowed); + auto ret_hell_node=setup_hellnode(firp,elfiop,allowed); cout<<"# ATTRIBUTE fill_in_indtargs::basicret_hellnode_size="<<dec<<ret_hell_node->size()<<endl; cout<<"# ATTRIBUTE fill_in_indtargs::fullret_hellnode_size="<<dec<<ret_hell_node->size()<<endl; @@ -2178,19 +2645,12 @@ void mark_return_points(FileIR_t* firp) { // add unmarked return points. fix_calls will deal with whether they need to be pinned or not later. - for( - InstructionSet_t::const_iterator it=firp->GetInstructions().begin(); - it!=firp->GetInstructions().end(); - ++it - ) + for(auto insn : firp->getInstructions()) { - Instruction_t* insn=*it; - //DISASM d; - //Disassemble(insn,d); - DecodedInstruction_t d(insn); - if(string("call")==d.getMnemonic() /*.Instruction.Mnemonic*/ && insn->GetFallthrough()) + auto d=DecodedInstruction_t::factory(insn); + if(string("call")==d->getMnemonic() && insn->getFallthrough()) { - targets[insn->GetFallthrough()->GetAddress()->GetVirtualOffset()].add(ibt_provenance_t::ibtp_ret); + targets[insn->getFallthrough()->getAddress()->getVirtualOffset()].add(ibt_provenance_t::ibtp_ret); } } } @@ -2199,25 +2659,19 @@ void mark_return_points(FileIR_t* firp) void print_icfs(FileIR_t* firp) { cout<<"Printing ICFS sets."<<endl; - for( - InstructionSet_t::const_iterator it=firp->GetInstructions().begin(); - it!=firp->GetInstructions().end(); - ++it - ) + for(auto insn : firp->getInstructions()) { - Instruction_t* insn=*it; - ICFS_t *icfs=insn->GetIBTargets(); + auto icfs=insn->getIBTargets(); // not an IB if(!icfs) continue; - cout<<hex<<insn->GetAddress()->GetVirtualOffset()<<" -> "; + cout<<hex<<insn->getAddress()->getVirtualOffset()<<" -> "; - for(ICFS_t::const_iterator icfsit=icfs->begin(); icfsit!=icfs->end(); ++icfsit) + for(auto target : *icfs) { - Instruction_t* target=*icfsit; - cout<<hex<<target->GetAddress()->GetVirtualOffset()<<" "; + cout<<hex<<target->getAddress()->getVirtualOffset()<<" "; } cout<<endl; } @@ -2245,51 +2699,44 @@ void setup_icfs(FileIR_t* firp, EXEIO::exeio* elfiop) // setup calls, jmps and ret hell nodes. - ICFS_t *call_hell = setup_call_hellnode(firp,elfiop); - firp->GetAllICFS().insert(call_hell); - - ICFS_t *jmp_hell = setup_jmp_hellnode(firp,elfiop); - firp->GetAllICFS().insert(jmp_hell); - - ICFS_t *ret_hell = setup_ret_hellnode(firp,elfiop); - firp->GetAllICFS().insert(ret_hell); - + auto call_hell = setup_call_hellnode(firp,elfiop); + auto jmp_hell = setup_jmp_hellnode(firp,elfiop); + auto ret_hell = setup_ret_hellnode(firp,elfiop); // for each instruction - for( - set<Instruction_t*>::const_iterator it=firp->GetInstructions().begin(); - it!=firp->GetInstructions().end(); - ++it - ) + for(auto insn : firp->getInstructions()) { // if we already got it complete (via stars or FII) - Instruction_t* insn=*it; - - if(insn->GetIndirectBranchTargetAddress()!=nullptr) + if(insn->getIndirectBranchTargetAddress()!=nullptr) total_ibta_set++; // warning check - ibt_provenance_t prov=targets[insn->GetAddress()->GetVirtualOffset()]; + ibt_provenance_t prov=targets[insn->getAddress()->getVirtualOffset()]; // stars calls it data, but printw arning if we didn't find it in data or as a printf addr. if(prov.isPartiallySet(stars_data) && !prov.isPartiallySet(non_stars_data)) { //ofstream fout("warning.txt", ofstream::out | ofstream::app); - cerr<<"STARS found an IBT in data that FII wasn't able to classify at "<<hex<<insn->GetAddress()->GetVirtualOffset()<<"."<<endl; + cerr<<"STARS found an IBT in data that FII wasn't able to classify at "<<hex<<insn->getAddress()->getVirtualOffset()<<"."<<endl; } // create icfs for complete jump tables. - if(jmptables[insn].IsComplete()) + if(jmptables[insn].isComplete()) { + // get the strcuture into the IRDB - ICFS_t* nn=new ICFS_t(jmptables[insn]); + /* + auto nn=new ICFS_t(jmptables[insn]); firp->GetAllICFS().insert(nn); insn->SetIBTargets(nn); + */ + auto nn=firp->addNewICFS(insn,jmptables[insn]); + if(getenv("IB_VERBOSE")!=0) { - cout<<"IB complete for "<<hex<<insn->GetAddress()->GetVirtualOffset() + cout<<"IB complete for "<<hex<<insn->getAddress()->getVirtualOffset() <<":"<<insn->getDisassembly()<<" with "<<dec<<nn->size()<<" targets."<<endl; } @@ -2298,32 +2745,28 @@ void setup_icfs(FileIR_t* firp, EXEIO::exeio* elfiop) } // disassemble the instruction, and figure out which type of hell node we need. - //DISASM d; - //Disassemble(insn,d); - DecodedInstruction_t d(insn); - if(d.isReturn()) // string("ret")==d.getMnemonic() /*Instruction.Mnemonic*/ || string("retn")==d.getMnemonic() /*d.Instruction.Mnemonic*/) + auto d=DecodedInstruction_t::factory(insn); + if(d->isReturn()) { if(getenv("IB_VERBOSE")!=0) - cout<<"using ret hell node for "<<hex<<insn->GetAddress()->GetVirtualOffset()<<endl; - insn->SetIBTargets(ret_hell); + cout<<"using ret hell node for "<<hex<<insn->getAddress()->getVirtualOffset()<<endl; + insn->setIBTargets(ret_hell); ret_hell->insert(ALLOF(jmptables[insn])); // insert any partially analyzed results from rets. } - //else if ( (string("call ")==d.Instruction.Mnemonic) && ((d.Argument1.ArgType&0xffff0000&CONSTANT_TYPE)!=CONSTANT_TYPE)) - else if ( d.isCall() /* (string("call")==d.getMnemonic()) */ && (!d.getOperand(0).isConstant())) + else if ( d->isCall() && (!d->getOperand(0)->isConstant())) { if(getenv("IB_VERBOSE")!=0) - cout<<"using call hell node for "<<hex<<insn->GetAddress()->GetVirtualOffset()<<endl; + cout<<"using call hell node for "<<hex<<insn->getAddress()->getVirtualOffset()<<endl; // indirect call - insn->SetIBTargets(call_hell); + insn->setIBTargets(call_hell); call_hell->insert(ALLOF(jmptables[insn])); // insert any partially analyzed results from calls. } - //else if ( (string("jmp ")==d.Instruction.Mnemonic) && ((d.Argument1.ArgType&0xffff0000&CONSTANT_TYPE)!=CONSTANT_TYPE)) - else if ( d.isUnconditionalBranch() /*(string("jmp")==d.getMnemonic()) */&& (!d.getOperand(0).isConstant())) + else if ( d->isUnconditionalBranch() && (!d->getOperand(0)->isConstant())) { if(getenv("IB_VERBOSE")!=0) - cout<<"using jmp hell node for "<<hex<<insn->GetAddress()->GetVirtualOffset()<<endl; + cout<<"using jmp hell node for "<<hex<<insn->getAddress()->getVirtualOffset()<<endl; // indirect jmp - insn->SetIBTargets(jmp_hell); + insn->setIBTargets(jmp_hell); jmp_hell->insert(ALLOF(jmptables[insn])); // insert any partially analyzed results from jmps. } @@ -2341,47 +2784,37 @@ void unpin_elf_tables(FileIR_t *firp, int64_t do_unpin_opt) map<string,int> unpin_counts; map<string,int> missed_unpins; - for( - DataScoopSet_t::iterator it=firp->GetDataScoops().begin(); - it!=firp->GetDataScoops().end(); - ++it - ) + for(auto scoop : firp->getDataScoops()) { // 4 or 8 - int ptrsize=firp->GetArchitectureBitWidth()/8; - - DataScoop_t* scoop=*it; - const char *scoop_contents=scoop->GetContents().c_str(); - if(scoop->GetName()==".init_array" || scoop->GetName()==".fini_array" || scoop->GetName()==".got.plt" || scoop->GetName()==".got") + const auto ptrsize=firp->getArchitectureBitWidth()/8; + const char *scoop_contents=scoop->getContents().c_str(); + if(scoop->getName()==".init_array" || scoop->getName()==".fini_array" || scoop->getName()==".got.plt" || scoop->getName()==".got") { - auto start_offset=0U; - if(scoop->GetName()==".got.plt") + const auto start_offset= (scoop->getName()==".got.plt") ? 3*ptrsize : 0u; + for(auto i=start_offset; i+ptrsize <= scoop->getSize() ; i+=ptrsize) { - // .got.plt has a start index of 4 pointers into the section. - start_offset=4*ptrsize; - } - for(auto i=start_offset; i+ptrsize <= scoop->GetSize() ; i+=ptrsize) - { - virtual_offset_t vo; - if(ptrsize==4) - /* get int, 4 bytes */ - vo=(virtual_offset_t)*(uint32_t*)&scoop_contents[i]; - else if(ptrsize==8) - /* get long long, 8 bytes */ - vo=(virtual_offset_t)*(uint64_t*)&scoop_contents[i]; - else - assert(0); + const auto vo= + ptrsize==4 ? (VirtualOffset_t)*(uint32_t*)&scoop_contents[i] : + ptrsize==8 ? (VirtualOffset_t)*(uint64_t*)&scoop_contents[i] : + throw domain_error("Invalid ptr size"); - Instruction_t* insn=lookupInstruction(firp,vo); + auto insn=lookupInstruction(firp,vo); - // OK for .got scoop to miss - if(scoop->GetName()==".got" && insn==nullptr) + // OK for .got scoop to miss, some entries are empty. + if(scoop->getName()==".got" && insn==nullptr) { if(getenv("UNPIN_VERBOSE")!=0) - cout<<"Skipping "<<scoop->GetName()<<" unpin for "<<hex<<vo<<" due to no instruction at vo"<<endl; + cout<<"Skipping "<<scoop->getName()<<" unpin for "<<hex<<vo<<" due to no instruction at vo"<<endl; continue; } + if(vo==0) + { + // some segments may be null terminated. + assert(i+ptrsize==scoop->getSize()); + break; + } // these asserts are probably overkill, but want them for sanity checking for now. assert(insn); @@ -2390,8 +2823,8 @@ void unpin_elf_tables(FileIR_t *firp, int64_t do_unpin_opt) if( targets[vo].areOnlyTheseSet( ibt_provenance_t::ibtp_initarray | ibt_provenance_t::ibtp_finiarray | - ibt_provenance_t::ibtp_gotplt | - ibt_provenance_t::ibtp_got | + ibt_provenance_t::ibtp_gotplt | + ibt_provenance_t::ibtp_got | ibt_provenance_t::ibtp_stars_data) ) { @@ -2420,78 +2853,69 @@ void unpin_elf_tables(FileIR_t *firp, int64_t do_unpin_opt) if(allow_unpin || already_unpinned.find(insn)!=already_unpinned.end()) { + // mark as unpinned already_unpinned.insert(insn); - unpin_counts[scoop->GetName()]++; - - Relocation_t* nr=new Relocation_t(); - assert(nr); - nr->SetType("data_to_insn_ptr"); - nr->SetOffset(i); - nr->SetWRT(insn); + unpin_counts[scoop->getName()]++; // add reloc to IR. - firp->GetRelocations().insert(nr); - scoop->GetRelocations().insert(nr); + auto nr=firp->addNewRelocation(scoop, i, "data_to_insn_ptr", insn); + assert(nr); + /* + Relocation_t* nr=new Relocation_t(BaseObj_t::NOT_IN_DATABASE, i, "data_to_insn_ptr", insn); + firp->getRelocations().insert(nr); + scoop->getRelocations().insert(nr); + */ if(getenv("UNPIN_VERBOSE")!=0) - cout<<"Unpinning "+scoop->GetName()+" entry at offset "<<dec<<i<<endl; - if(insn->GetIndirectBranchTargetAddress()==nullptr) + cout<<"Unpinning "+scoop->getName()+" entry at offset "<<dec<<i<<endl; + if(insn->getIndirectBranchTargetAddress()==nullptr) { - auto newaddr = new AddressID_t; + // add ibta to mark as unpipnned + const auto fileid=insn->getAddress()->getFileID(); + /* + auto newaddr = new AddressID_t(BaseObj_t::NOT_IN_DATABASE,fileid,0); assert(newaddr); - newaddr->SetFileID(insn->GetAddress()->GetFileID()); - newaddr->SetVirtualOffset(0); // unpinne - - firp->GetAddresses().insert(newaddr); - insn->SetIndirectBranchTargetAddress(newaddr); + firp->getAddresses().insert(newaddr); + */ + auto newaddr=firp->addNewAddress(fileid,0); + insn->setIndirectBranchTargetAddress(newaddr); } else { - insn->GetIndirectBranchTargetAddress()->SetVirtualOffset(0); + // just mark as unpinned. + insn->getIndirectBranchTargetAddress()->setVirtualOffset(0); } } } else { if(getenv("UNPIN_VERBOSE")!=0) - cout<<"Skipping "<<scoop->GetName()<<" unpin for "<<hex<<vo<<" due to other references at offset="<<dec<<i<<endl; - missed_unpins[scoop->GetName()]++; + cout<<"Skipping "<<scoop->getName()<<" unpin for "<<hex<<vo<<" due to other references at offset="<<dec<<i<<endl; + missed_unpins[scoop->getName()]++; } } } - else if(scoop->GetName()==".dynsym") + else if(scoop->getName()==".dynsym") { - Elf64_Sym *sym64=nullptr; - Elf32_Sym *sym32=nullptr; - int ptrsize=0; - int symsize=0; - const char* scoop_contents=scoop->GetContents().c_str(); - switch(firp->GetArchitectureBitWidth()) - { - case 64: - ptrsize=8; - symsize=sizeof(Elf64_Sym); - break; - case 32: - ptrsize=4; - symsize=sizeof(Elf32_Sym); - break; - default: - assert(0); - - } + const auto ptrsize=firp->getArchitectureBitWidth()/8; + const auto scoop_contents=scoop->getContents().c_str(); + const auto symsize= + ptrsize==8 ? sizeof(Elf64_Sym) : + ptrsize==4 ? sizeof(Elf32_Sym) : + throw domain_error("Cannot detect ptr size -> ELF symbol mapping"); + auto table_entry_no=0U; - for(auto i=0U;i+symsize<scoop->GetSize(); i+=symsize, table_entry_no++) + for(auto i=0U;i+symsize<scoop->getSize(); i+=symsize, table_entry_no++) { int addr_offset=0; - virtual_offset_t vo=0; + VirtualOffset_t vo=0; int st_info_field=0; int shndx=0; switch(ptrsize) { case 4: { - sym32=(Elf32_Sym*)&scoop_contents[i]; + auto sym32=(Elf32_Sym*)&scoop_contents[i]; addr_offset=(uintptr_t)&(sym32->st_value)-(uintptr_t)sym32; vo=sym32->st_value; st_info_field=sym32->st_info; @@ -2500,16 +2924,15 @@ void unpin_elf_tables(FileIR_t *firp, int64_t do_unpin_opt) } case 8: { - sym64=(Elf64_Sym*)&scoop_contents[i]; + auto sym64=(Elf64_Sym*)&scoop_contents[i]; addr_offset=(uintptr_t)&(sym64->st_value)-(uintptr_t)sym64; vo=sym64->st_value; st_info_field=sym64->st_info; shndx=sym64->st_shndx; break; - break; } default: - assert(0); + throw domain_error("Invalid pointer size"); } // this is good for both 32- and 64-bit. @@ -2517,8 +2940,7 @@ void unpin_elf_tables(FileIR_t *firp, int64_t do_unpin_opt) if(shndx!=SHN_UNDEF && type==STT_FUNC) { - Instruction_t* insn=lookupInstruction(firp,vo); - + auto insn=lookupInstruction(firp,vo); // these asserts are probably overkill, but want them for sanity checking for now. assert(insn); @@ -2546,37 +2968,41 @@ void unpin_elf_tables(FileIR_t *firp, int64_t do_unpin_opt) // when/if these asserts fail, convert to if and guard the reloc creation. - unpin_counts[scoop->GetName()]++; - Relocation_t* nr=new Relocation_t(); + unpin_counts[scoop->getName()]++; + /* + auto nr=new Relocation_t(BaseObj_t::NOT_IN_DATABASE, i+addr_offset, "data_to_insn_ptr", insn); assert(nr); - nr->SetType("data_to_insn_ptr"); - nr->SetOffset(i+addr_offset); - nr->SetWRT(insn); // add reloc to IR. - firp->GetRelocations().insert(nr); - scoop->GetRelocations().insert(nr); + firp->getRelocations().insert(nr); + scoop->getRelocations().insert(nr); + */ + auto nr=firp->addNewRelocation(scoop, i+addr_offset, "data_to_insn_ptr", insn); + (void)nr; - if(insn->GetIndirectBranchTargetAddress()==nullptr) + if(insn->getIndirectBranchTargetAddress()==nullptr) { + /* auto newaddr = new AddressID_t; assert(newaddr); - newaddr->SetFileID(insn->GetAddress()->GetFileID()); - newaddr->SetVirtualOffset(0); // unpinne + newaddr->SetFileID(insn->getAddress()->getFileID()); + newaddr->setVirtualOffset(0); // unpinne - firp->GetAddresses().insert(newaddr); - insn->SetIndirectBranchTargetAddress(newaddr); + firp->getAddresses().insert(newaddr); + */ + auto newaddr=firp->addNewAddress(insn->getAddress()->getFileID(),0); + insn->setIndirectBranchTargetAddress(newaddr); } else { - insn->GetIndirectBranchTargetAddress()->SetVirtualOffset(0); + insn->getIndirectBranchTargetAddress()->setVirtualOffset(0); } } else { if(getenv("UNPIN_VERBOSE")!=0) cout<<"Skipping .dynsm unpin for "<<hex<<vo<<" due to other references."<<dec<<i<<endl; - missed_unpins[scoop->GetName()]++; + missed_unpins[scoop->getName()]++; } } } @@ -2584,7 +3010,7 @@ void unpin_elf_tables(FileIR_t *firp, int64_t do_unpin_opt) else { if(getenv("UNPIN_VERBOSE")!=0) - cout<<"Skipping unpin of section "<<scoop->GetName()<<endl; + cout<<"Skipping unpin of section "<<scoop->getName()<<endl; } } @@ -2609,16 +3035,11 @@ void unpin_elf_tables(FileIR_t *firp, int64_t do_unpin_opt) } -DataScoop_t* find_scoop(FileIR_t *firp, const virtual_offset_t &vo) +DataScoop_t* find_scoop(FileIR_t *firp, const VirtualOffset_t &vo) { - for( - DataScoopSet_t::iterator it=firp->GetDataScoops().begin(); - it!=firp->GetDataScoops().end(); - ++it - ) + for(auto s : firp->getDataScoops()) { - DataScoop_t* s=*it; - if( s->GetStart()->GetVirtualOffset()<=vo && vo<s->GetEnd()->GetVirtualOffset() ) + if( s->getStart()->getVirtualOffset()<=vo && vo<s->getEnd()->getVirtualOffset() ) return s; } return nullptr; @@ -2637,7 +3058,7 @@ void unpin_type3_switchtable(FileIR_t* firp,Instruction_t* insn,DataScoop_t* sco if(getenv("UNPIN_VERBOSE")) { - cout<<"Unpinning type3 switch, dispatch is "<<hex<<insn->GetAddress()->GetVirtualOffset()<<":" + cout<<"Unpinning type3 switch, dispatch is "<<hex<<insn->getAddress()->getVirtualOffset()<<":" <<insn->getDisassembly()<<" with tabSz="<<jmptables[insn].GetTableSize()<<endl; } @@ -2653,34 +3074,34 @@ void unpin_type3_switchtable(FileIR_t* firp,Instruction_t* insn,DataScoop_t* sco ibt_provenance_t::ibtp_stars_switch ; // found as stars switch // ptr size - int ptrsize=firp->GetArchitectureBitWidth()/8; + int ptrsize=firp->getArchitectureBitWidth()/8; // offset from start of scoop - virtual_offset_t scoop_off=jmptables[insn].GetTableStart() - scoop->GetStart()->GetVirtualOffset(); + VirtualOffset_t scoop_off=jmptables[insn].GetTableStart() - scoop->getStart()->getVirtualOffset(); // scoop contents - const char *scoop_contents=scoop->GetContents().c_str(); + const char *scoop_contents=scoop->getContents().c_str(); for(int i=0; i<jmptables[insn].GetTableSize(); i++) { // grab the value out of the scoop - virtual_offset_t table_entry=0; + VirtualOffset_t table_entry=0; switch(ptrsize) { case 4: - table_entry=(virtual_offset_t)*(int*)&scoop_contents[scoop_off]; + table_entry=(VirtualOffset_t)*(int*)&scoop_contents[scoop_off]; break; case 8: - table_entry=(virtual_offset_t)*(int**)&scoop_contents[scoop_off]; + table_entry=(VirtualOffset_t)*(int**)&scoop_contents[scoop_off]; break; default: assert(0); } // verify we have an instruction. - Instruction_t* ibt=lookupInstruction(firp,table_entry); + auto ibt=lookupInstruction(firp,table_entry); if(ibt) { // which isn't otherwise addressed. @@ -2711,32 +3132,37 @@ void unpin_type3_switchtable(FileIR_t* firp,Instruction_t* insn,DataScoop_t* sco cout<<"Unpinning switch entry ["<<dec<<i<<"] for ibt="<<hex<<table_entry<<", scoop_off="<<scoop_off<<endl; already_unpinned.insert(ibt); - Relocation_t* nr=new Relocation_t(); - assert(nr); - nr->SetType("data_to_insn_ptr"); - nr->SetOffset(scoop_off); - nr->SetWRT(ibt); // add reloc to IR. - firp->GetRelocations().insert(nr); - scoop->GetRelocations().insert(nr); + /* + auto nr=new Relocation_t(BaseObj_t::NOT_IN_DATABASE, scoop_off, "data_to_insn_ptr", ibt); + assert(nr); + firp->getRelocations().insert(nr); + scoop->getRelocations().insert(nr); + */ + auto nr=firp->addNewRelocation(scoop,scoop_off, "data_to_insn_ptr", ibt); + (void)nr; + // remove rodata reference for hell nodes. targets[table_entry]=newprov; switch_targs.insert(ibt); - if(ibt->GetIndirectBranchTargetAddress()==nullptr) + if(ibt->getIndirectBranchTargetAddress()==nullptr) { + /* auto newaddr = new AddressID_t; assert(newaddr); - newaddr->SetFileID(ibt->GetAddress()->GetFileID()); - newaddr->SetVirtualOffset(0); // unpinne + newaddr->SetFileID(ibt->getAddress()->getFileID()); + newaddr->setVirtualOffset(0); // unpinne - firp->GetAddresses().insert(newaddr); - ibt->SetIndirectBranchTargetAddress(newaddr); + firp->getAddresses().insert(newaddr); + */ + auto newaddr=firp->addNewAddress(ibt->getAddress()->getFileID(),0); + ibt->setIndirectBranchTargetAddress(newaddr); } else { - ibt->GetIndirectBranchTargetAddress()->SetVirtualOffset(0); + ibt->getIndirectBranchTargetAddress()->setVirtualOffset(0); } } } @@ -2759,8 +3185,8 @@ void unpin_switches(FileIR_t *firp, int do_unpin_opt) // for each instruction for( - set<Instruction_t*>::const_iterator it=firp->GetInstructions().begin(); - it!=firp->GetInstructions().end(); + set<Instruction_t*>::const_iterator it=firp->getInstructions().begin(); + it!=firp->getInstructions().end(); ++it ) @@ -2774,10 +3200,10 @@ void unpin_switches(FileIR_t *firp, int do_unpin_opt) continue; // sanity check we have a good switch - if(insn->GetIBTargets()==nullptr) continue; + if(insn->getIBTargets()==nullptr) continue; // sanity check we have a good switch - if(insn->GetIBTargets()->GetAnalysisStatus()!=ICFS_Analysis_Complete) continue; + if(insn->getIBTargets()->getAnalysisStatus()!=iasAnalysisComplete) continue; // find the scoop, try next if we fail. DataScoop_t* scoop=find_scoop(firp,jmptables[insn].GetTableStart()); @@ -2798,23 +3224,13 @@ void print_unpins(FileIR_t *firp) if(getenv("UNPIN_VERBOSE") == nullptr) return; - for( - DataScoopSet_t::iterator it=firp->GetDataScoops().begin(); - it!=firp->GetDataScoops().end(); - ++it - ) + for(auto scoop : firp->getDataScoops()) { - DataScoop_t* scoop=*it; assert(scoop); - for( - RelocationSet_t::iterator rit=scoop->GetRelocations().begin(); - rit!=scoop->GetRelocations().end(); - ++rit - ) + for(auto reloc : scoop->getRelocations()) { - Relocation_t* reloc=*rit; assert(reloc); - cout<<"Found relocation in "<<scoop->GetName()<<" of type "<<reloc->GetType()<<" at offset "<<hex<<reloc->GetOffset()<<endl; + cout<<"Found relocation in "<<scoop->getName()<<" of type "<<reloc->getType()<<" at offset "<<hex<<reloc->getOffset()<<endl; } } } @@ -2827,6 +3243,255 @@ void unpin_well_analyzed_ibts(FileIR_t *firp, int64_t do_unpin_opt) print_unpins(firp); } +bool find_arm_address_gen(Instruction_t* insn, const string& reg, VirtualOffset_t& address, bool& page_only) +{ + // init output args, just in case. + address=0; + page_only=true; + + auto adrp_insn=(Instruction_t*)nullptr; + if(backup_until(string()+"adrp "+reg+",", /* to find */ + adrp_insn, /* return insn here */ + insn, /* look before here */ + "^"+reg+"$", /* stop if reg is set */ + true)) /* try hard to find the other half, more expensive */ + { + assert(adrp_insn); + const auto adrp_disasm=DecodedInstruction_t::factory(adrp_insn); + const auto page_no=adrp_disasm->getOperand(1)->getConstant(); + + cout<<"Found spilled page_no at "<<hex<<insn->getAddress()->getVirtualOffset()<<" in: "<<endl; + cout<<"\t"<<adrp_disasm->getDisassembly()<<endl; + cout<<"\t"<<insn->getDisassembly()<<endl; + page_only=true; + address=page_no; + return true; + } + + auto add_insn=(Instruction_t*)nullptr; + if(backup_until(string()+"add "+reg+",", /* to find */ + add_insn, /* return insn here */ + insn, /* look before here */ + "^"+reg+"$", /* stop if reg is set */ + true)) /* try hard to find the other half, more expensive */ + { + assert(add_insn); + const auto add_disasm=DecodedInstruction_t::factory(add_insn); + const auto add_op1=add_disasm->getOperand(1); + const auto add_op2=add_disasm->getOperand(2); + if(!add_op1->isRegister()) return false; + if( add_op1->getString()=="x29") return false; // skip arm SP. + if(!add_op2->isConstant()) return false; + + const auto add_op1_reg=add_op1->getString(); + const auto add_op2_constant=add_op2->getConstant(); + + // try to find an adrp + auto adrp_insn=(Instruction_t*)nullptr; + if(!backup_until(string()+"adrp "+add_op1_reg+",", /* to find */ + adrp_insn, /* return insn here */ + add_insn, /* look before here */ + "^"+add_op1_reg+"$", /* stop if reg is set */ + true)) /* try hard to find the other half, more expensive */ + return false; + assert(adrp_insn); + + const auto adrp_disasm=DecodedInstruction_t::factory(adrp_insn); + const auto adrp_page=adrp_disasm->getOperand(1)->getConstant(); + const auto spilled_address=adrp_page+add_op2_constant; + cout<<"Found spilled address at "<<hex<<insn->getAddress()->getVirtualOffset()<<" in: "<<endl; + cout<<"\t"<<adrp_disasm->getDisassembly()<<endl; + cout<<"\t"<<add_disasm->getDisassembly()<<endl; + cout<<"\t"<<insn->getDisassembly()<<endl; + page_only=false; + address=spilled_address; + return true; + } + return false; +} + +void find_all_arm_unks(FileIR_t* firp) +{ + const auto reg_to_spilled_addr=[&](Instruction_t* insn, const string ®, const SpillPoint_t& spill_loc) + { + + auto page_only=true; + auto address=VirtualOffset_t(0); + if(find_arm_address_gen(insn,reg, address, page_only)) + { + if(page_only) + spilled_adrps[spill_loc].insert(address); + else + spilled_add_adrp_results[spill_loc].insert(address); + } + }; + const auto do_verbose=getenv("IB_VERBOSE"); + /* only valid for arm */ + if(firp->getArchitecture()->getMachineType() != admtAarch64) return; + + /* find adrps */ + for(auto insn : firp->getInstructions()) + { + const auto d=DecodedInstruction_t::factory(insn); + if(d->getMnemonic()!="adrp") continue; + const auto op1=d->getOperand(1); + const auto op1_constant=op1->getConstant(); + all_adrp_results[insn->getFunction()].insert(op1_constant); + } + + /* find add/adrp pairs */ + for(auto insn : firp->getInstructions()) + { + const auto d=DecodedInstruction_t::factory(insn); + if(d->getMnemonic()!="add") continue; + if(!d->hasOperand(1)) continue; + if(!d->hasOperand(2)) continue; + const auto op0=d->getOperand(1); + const auto op1=d->getOperand(1); + const auto op2=d->getOperand(2); + if(!op1->isRegister()) continue; + if(op1->getString()=="x29") continue; // skip arm SP. + if(!op2->isConstant()) continue; + + const auto op1_reg=op1->getString(); + const auto op2_constant=op2->getConstant(); + + // try to find an adrp + auto adrp_insn=(Instruction_t*)nullptr; + if(!backup_until(string()+"adrp "+op1_reg+",", /* to find */ + adrp_insn, /* return insn here */ + insn, /* look before here */ + "^"+op1_reg+"$", /* stop if reg is set */ + true)) /* try hard to find the other half, more expensive */ + continue; + assert(adrp_insn); + + const auto adrp_disasm=DecodedInstruction_t::factory(adrp_insn); + const auto adrp_page=adrp_disasm->getOperand(1)->getConstant(); + const auto unk_value=adrp_page+op2_constant; + + all_add_adrp_results [ insn->getFunction() ].insert(unk_value); + all_add_adrp_results [ adrp_insn->getFunction()].insert(unk_value); + per_reg_add_adrp_results [ op0->getString() ].insert(unk_value); + + /* check for scoops at the unk address. + * if found, we assume that the unk points at data. + * else, we mark it as a possible code target. + */ + if(firp->findScoop(unk_value)==nullptr) + possible_target(unk_value, 0, ibt_provenance_t::ibtp_text); + + /* verbose logging */ + if(do_verbose) + cout << "Detected ARM unk="<<hex<<unk_value<<" for "<<d->getDisassembly() + << " and "<<adrp_disasm->getDisassembly()<<endl; + + } + /* find spilled adrp's and add/adrp pairs + * looking for these patterns: + * + * adrp reg1, #page_no + * add reg2, reg1, #page_offset + * str reg2, [x29, #spill loc] ; or sp instead of x29 + * + * or + * + * adrp reg1, #page_no + * str reg1, [x29, #spill loc] ; or sp instead of x29 + * + * we record these later, in case we find a switch dispatch that has a spilled jump table address. + */ + for(auto insn : firp->getInstructions()) + { + // look for a spill of an address + const auto d=DecodedInstruction_t::factory(insn); + + // spills are str instructions + if(d->getMnemonic()!="str") continue; + + // spills of an address are writing an X register. + const auto spill_op0_reg=d->getOperand(0)->getString(); + if(spill_op0_reg[0]!='x') continue; + + // spills write to the stack with a constant offset. + const auto spill_op1=d->getOperand(1); + assert(spill_op1->isMemory()); + const auto spill_op1_string=spill_op1->getString(); + // needs to have a base reg, which is either sp or x29 + if(!spill_op1->hasBaseRegister()) continue; + if( spill_op1_string.substr(0,2)!="sp" && spill_op1_string.substr(0,3)!="x29" ) continue; + if(!spill_op1->hasMemoryDisplacement()) continue; + if( spill_op1->hasIndexRegister()) continue; + + const auto spill_disp=spill_op1->getMemoryDisplacement(); + + // found str <x-reg> [sp+const] + + reg_to_spilled_addr(insn, spill_op0_reg, SpillPoint_t({insn->getFunction(),spill_disp })); + + + } + for(auto insn : firp->getInstructions()) + { + // look for a spill of an address + const auto d=DecodedInstruction_t::factory(insn); + + // spills are str instructions + if(d->getMnemonic()!="stp") continue; + + // spills of an address are writing an X register. + const auto spill_op0_reg=d->getOperand(0)->getString(); + const auto spill_op1_reg=d->getOperand(1)->getString(); + if(spill_op0_reg[0]!='x') continue; + + // spills write to the stack with a constant offset. + const auto spill_op2=d->getOperand(2); + assert(spill_op2->isMemory()); + const auto spill_op2_string=spill_op2->getString(); + // needs to have a base reg, which is either sp or x29 + if(!spill_op2->hasBaseRegister()) continue; + if( spill_op2_string.substr(0,2)!="sp" && spill_op2_string.substr(0,3)!="x29" ) continue; + if(!spill_op2->hasMemoryDisplacement()) continue; + if( spill_op2->hasIndexRegister()) continue; + + const auto spill_disp=spill_op2->getMemoryDisplacement(); + + // found stp <xreg> <xreg> [sp+const] + + reg_to_spilled_addr(insn, spill_op0_reg, SpillPoint_t({insn->getFunction(),spill_disp })); + reg_to_spilled_addr(insn, spill_op1_reg, SpillPoint_t({insn->getFunction(),spill_disp+8})); + + + } + + // look for spilling an address into a d-register. + for(auto insn : firp->getInstructions()) + { + // look for moves to d-regs via fmov. + const auto d = DecodedInstruction_t::factory(insn); + if( d->getMnemonic()!="fmov" ) continue; + + // look for a spill of an address + const auto op0 = d->getOperand(0); + const auto op1 = d->getOperand(1); + const auto op0_str = op0->getString(); + const auto op1_str = op1->getString(); + + // spills to d-regs are fmov instructions with a d-reg dest and an xreg src. + if( op0_str[0] !='d' ) continue; + if( op1_str[0] !='x' ) continue; + + auto page_only=true; + auto address=VirtualOffset_t(0); + if(find_arm_address_gen(insn,op1_str, address, page_only)) + { + const auto spill_loc = DregSpillPoint_t({insn->getFunction(), op0_str}); + spilled_to_dreg[spill_loc].insert(address); + + } + } + +} /* @@ -2834,7 +3499,9 @@ void unpin_well_analyzed_ibts(FileIR_t *firp, int64_t do_unpin_opt) */ void fill_in_indtargs(FileIR_t* firp, exeio* elfiop, int64_t do_unpin_opt) { - set<virtual_offset_t> thunk_bases; + calc_preds(firp); + + set<VirtualOffset_t> thunk_bases; find_all_module_starts(firp,thunk_bases); // reset global vars @@ -2845,7 +3512,6 @@ void fill_in_indtargs(FileIR_t* firp, exeio* elfiop, int64_t do_unpin_opt) already_unpinned.clear(); lookupInstruction_init(firp); - calc_preds(firp); int secnum = elfiop->sections.size(); int secndx=0; @@ -2857,16 +3523,19 @@ void fill_in_indtargs(FileIR_t* firp, exeio* elfiop, int64_t do_unpin_opt) /* import info from stars */ read_stars_xref_file(firp); + /* and find any unks ourselves, as stars is unreliable */ + find_all_arm_unks(firp); + + /* look through each section and look for target possibilities */ for (secndx=0; secndx<secnum; secndx++) infer_targets(firp, elfiop->sections[secndx]); + + handle_scoop_scanning(firp); /* should move to separate function */ - auto forced_iterator = forced_pins.begin(); - for (; forced_iterator != forced_pins.end(); forced_iterator++) - { - possible_target(*forced_iterator, 0, ibt_provenance_t::ibtp_user); - } + for(auto pin : forced_pins ) + possible_target(pin, 0, ibt_provenance_t::ibtp_user); /* look through the instructions in the program for targets */ get_instruction_targets(firp, elfiop, thunk_bases); @@ -2897,11 +3566,6 @@ void fill_in_indtargs(FileIR_t* firp, exeio* elfiop, int64_t do_unpin_opt) print_targets(); cout<<"========================================="<<endl; - cout<<"========================================="<<endl; - cout<<"# ATTRIBUTE oneline_indirect_targets="; - print_targets_oneline(); - cout<<"========================================="<<endl; - // try to setup an ICFS for every IB. setup_icfs(firp, elfiop); @@ -2913,8 +3577,8 @@ void fill_in_indtargs(FileIR_t* firp, exeio* elfiop, int64_t do_unpin_opt) bool split_eh_frame_opt=true; int64_t do_unpin_opt=numeric_limits<int64_t>::max() ; -db_id_t variant_id=BaseObj_t::NOT_IN_DATABASE; -set<virtual_offset_t> forced_pins; +DatabaseID_t variant_id=BaseObj_t::NOT_IN_DATABASE; +set<VirtualOffset_t> forced_pins; int parseArgs(const vector<string> step_args) { @@ -2979,7 +3643,7 @@ int parseArgs(const vector<string> step_args) for (; argc_iter < step_args.size(); argc_iter++) { char *end_ptr; - virtual_offset_t offset = strtol(step_args[argc_iter].c_str(), &end_ptr, 0); + VirtualOffset_t offset = strtol(step_args[argc_iter].c_str(), &end_ptr, 0); if (*end_ptr == '\0') { cout << "force pinning: 0x" << std::hex << offset << endl; @@ -3001,7 +3665,7 @@ int executeStep(IRDBObjects_t *const irdb_objects) { /* setup the interface to the sql server */ const auto pqxx_interface=irdb_objects->getDBInterface(); - BaseObj_t::SetInterface(pqxx_interface); + BaseObj_t::setInterface(pqxx_interface); auto pidp = irdb_objects->addVariant(variant_id); assert(pidp); @@ -3009,28 +3673,28 @@ int executeStep(IRDBObjects_t *const irdb_objects) // pidp=new VariantID_t(atoi(argv[1])); - assert(pidp->IsRegistered()==true); + assert(pidp->isRegistered()==true); cout<<"New Variant, after reading registration, is: "<<*pidp << endl; - for(const auto &this_file : pidp->GetFiles()) + for(const auto &this_file : pidp->getFiles()) { assert(this_file); - cout<<"Analyzing file "<<this_file->GetURL()<<endl; + cout<<"Analyzing file "<<this_file->getURL()<<endl; // read the db - auto firp = irdb_objects->addFileIR(variant_id, this_file->GetBaseID()); + auto firp = irdb_objects->addFileIR(variant_id, this_file->getBaseID()); // firp=new FileIR_t(*pidp, this_file); assert(firp); - firp->SetBaseIDS(); - firp->AssembleRegistry(); + firp->setBaseIDS(); + firp->assembleRegistry(); // read the executeable file - int elfoid=firp->GetFile()->GetELFOID(); + int elfoid=firp->getFile()->getELFOID(); pqxx::largeobject lo(elfoid); - lo.to_file(pqxx_interface->GetTransaction(),"readeh_tmp_file.exe"); + lo.to_file(pqxx_interface->getTransaction(),"readeh_tmp_file.exe"); auto elfiop=unique_ptr<EXEIO::exeio>(new EXEIO::exeio); elfiop->load(string("readeh_tmp_file.exe")); @@ -3073,27 +3737,25 @@ std::string getStepName(void) const override }; -shared_ptr<Transform_SDK::TransformStep_t> curInvocation; +shared_ptr<TransformStep_t> curInvocation; -bool possible_target(virtual_offset_t p, virtual_offset_t from_addr, ibt_provenance_t prov) +bool possible_target(VirtualOffset_t p, VirtualOffset_t from_addr, ibt_provenance_t prov) { assert(curInvocation); return (dynamic_cast<PopulateIndTargs_t*>(curInvocation.get()))->possible_target(p,from_addr,prov); } -void range(virtual_offset_t start, virtual_offset_t end) +void range(VirtualOffset_t start, VirtualOffset_t end) { assert(curInvocation); return (dynamic_cast<PopulateIndTargs_t*>(curInvocation.get()))->range(start,end); } extern "C" -shared_ptr<Transform_SDK::TransformStep_t> GetTransformStep(void) +shared_ptr<TransformStep_t> getTransformStep(void) { curInvocation.reset(new PopulateIndTargs_t()); return curInvocation; - - //return shared_ptr<Transform_SDK::TransformStep_t>(new PopulateIndTargs_t()); } diff --git a/libIRDB/test/fill_in_indtargs.hpp b/ir_builders/fill_in_indtargs.hpp similarity index 75% rename from libIRDB/test/fill_in_indtargs.hpp rename to ir_builders/fill_in_indtargs.hpp index 9b7edc68ed668354128caa97e3bae001bed7d214..dd0500d1f5ce03c7760387d5739c80d5cdbf1ad2 100644 --- a/libIRDB/test/fill_in_indtargs.hpp +++ b/ir_builders/fill_in_indtargs.hpp @@ -19,7 +19,7 @@ * */ -#include <libIRDB-core.hpp> +#include <irdb-core> #include <iostream> #include <limits> #include <stdlib.h> @@ -36,14 +36,11 @@ #include <exeio.h> #include "check_thunks.hpp" -using namespace libIRDB; -using namespace std; -using namespace EXEIO; /* * defines */ -#define arch_ptr_bytes() (firp->GetArchitectureBitWidth()/8) +#define arch_ptr_bytes() (firp->getArchitectureBitWidth()/8u) /* * global variables @@ -61,7 +58,7 @@ static inline std::ostream& operator<<(std::ostream& out, const ibt_provenance_t class ibt_provenance_t { public: - typedef unsigned int provtype_t; + typedef uint32_t provtype_t; ibt_provenance_t() : value(0) { }; @@ -114,7 +111,7 @@ class ibt_provenance_t private: provtype_t value; - friend ostream& operator<<(ostream& out, const ibt_provenance_t& prov); + friend std::ostream& operator<<(std::ostream& out, const ibt_provenance_t& prov); }; @@ -169,16 +166,16 @@ static inline std::ostream& operator<<(std::ostream& out, const ibt_provenance_t * Forward prototypes */ -bool is_possible_target(virtual_offset_t p, virtual_offset_t addr); -bool possible_target(virtual_offset_t p, virtual_offset_t from_addr, ibt_provenance_t prov=ibt_provenance_t::ibtp_unknown); +bool is_possible_target(IRDB_SDK::VirtualOffset_t p, IRDB_SDK::VirtualOffset_t addr); +bool possible_target(IRDB_SDK::VirtualOffset_t p, IRDB_SDK::VirtualOffset_t from_addr, ibt_provenance_t prov=ibt_provenance_t::ibtp_unknown); -class fii_icfs : public ICFS_t +class fii_icfs : public IRDB_SDK::InstructionSet_t { public: // get/set table start - virtual_offset_t GetTableStart() {return table_start; } - void SetTableStart(virtual_offset_t s) {table_start=s; } + IRDB_SDK::VirtualOffset_t GetTableStart() {return table_start; } + void SetTableStart(IRDB_SDK::VirtualOffset_t s) {table_start=s; } // get/set switch type ibt_provenance_t GetSwitchType() { return switch_type; } @@ -187,13 +184,40 @@ class fii_icfs : public ICFS_t // get/set table size int GetTableSize() { return table_size; } void SetTableSize(int s) { table_size=s; } + + void addTargets(const IRDB_SDK::InstructionSet_t &other) + { + insert(std::begin(other), std::end(other)); + } + bool isIncomplete() const { + return getAnalysisStatus() == IRDB_SDK::iasAnalysisIncomplete; + } + + bool isComplete() const { + return getAnalysisStatus() == IRDB_SDK::iasAnalysisComplete; + } + + bool isModuleComplete() const { + return getAnalysisStatus() == IRDB_SDK::iasAnalysisModuleComplete; + } + + void setAnalysisStatus(const IRDB_SDK::ICFSAnalysisStatus_t p_status) { + m_icfs_analysis_status = p_status; + } + + IRDB_SDK::ICFSAnalysisStatus_t getAnalysisStatus() const { + return m_icfs_analysis_status; + } + + private: - virtual_offset_t table_start; + IRDB_SDK::VirtualOffset_t table_start; ibt_provenance_t switch_type; int table_size; + IRDB_SDK::ICFSAnalysisStatus_t m_icfs_analysis_status; }; -void split_eh_frame(FileIR_t* firp); +void split_eh_frame(IRDB_SDK::FileIR_t* firp); diff --git a/libIRDB/test/find_strings.cpp b/ir_builders/find_strings.cpp similarity index 99% rename from libIRDB/test/find_strings.cpp rename to ir_builders/find_strings.cpp index 711f78484c5371b7917b50df27aebbe5dc5c8a87..e1f7146d093f6f81d99ae6a029d99e919fef350b 100644 --- a/libIRDB/test/find_strings.cpp +++ b/ir_builders/find_strings.cpp @@ -21,7 +21,7 @@ #include <libIRDB-core.hpp> -#include <libIRDB-cfg.hpp> +#include <irdb-cfg.hpp> #include <iostream> #include <stdlib.h> #include <cctype> @@ -65,7 +65,7 @@ typedef struct elf_info { ::Elf64_Addr got; #endif int secnum; - virtual_offset_t got; + VirtualOffset_t got; char const **sec_data; exeio *elfiop; } elf_info_t; diff --git a/libIRDB/test/fix_calls.cpp b/ir_builders/fix_calls.cpp similarity index 67% rename from libIRDB/test/fix_calls.cpp rename to ir_builders/fix_calls.cpp index a2bb674d280e9f89db41195c88ec1470b57b5867..b35c6f5098993cc18abfb1137cc0837508a46ca5 100644 --- a/libIRDB/test/fix_calls.cpp +++ b/ir_builders/fix_calls.cpp @@ -19,9 +19,9 @@ */ -#include <libIRDB-core.hpp> -#include <libIRDB-cfg.hpp> -#include <utils.hpp> +#include <irdb-core> +#include <irdb-cfg> +#include <algorithm> #include <iostream> #include <stdlib.h> #include <assert.h> @@ -33,9 +33,9 @@ #include "fill_in_indtargs.hpp" -using namespace libIRDB; using namespace std; using namespace EXEIO; +using namespace IRDB_SDK; // macros #define ALLOF(a) begin(a),end(a) @@ -44,7 +44,7 @@ using namespace EXEIO; // externs extern void read_ehframe(FileIR_t* firp, EXEIO::exeio* ); -class FixCalls_t : public libIRDB::Transform_SDK::TransformStep_t +class FixCalls_t : public TransformStep_t { public: @@ -52,32 +52,32 @@ public: class Range_t { public: - Range_t(virtual_offset_t p_s, virtual_offset_t p_e) : m_start(p_s), m_end(p_e) { } + Range_t(VirtualOffset_t p_s, VirtualOffset_t p_e) : m_start(p_s), m_end(p_e) { } Range_t() : m_start(0), m_end(0) { } - virtual virtual_offset_t GetStart() const { return m_start; } - virtual virtual_offset_t GetEnd() const { return m_end; } - virtual void SetStart(virtual_offset_t s) { m_start=s; } - virtual void SetEnd(virtual_offset_t e) { m_end=e; } + virtual VirtualOffset_t getStart() const { return m_start; } + virtual VirtualOffset_t getEnd() const { return m_end; } + virtual void setStart(VirtualOffset_t s) { m_start=s; } + virtual void setEnd(VirtualOffset_t e) { m_end=e; } protected: - virtual_offset_t m_start, m_end; + VirtualOffset_t m_start, m_end; }; struct Range_tCompare { bool operator() (const Range_t &first, const Range_t &second) const { - return first.GetEnd() < second.GetStart(); + return first.getEnd() < second.getStart(); } }; -using RangeSet_t = std::set<Range_t, Range_tCompare>; +using Rangeset_t = std::set<Range_t, Range_tCompare>; -RangeSet_t eh_frame_ranges; +Rangeset_t eh_frame_ranges; size_t no_target_insn=0; size_t no_fallthrough_insn=0; size_t target_not_in_function=0; @@ -98,40 +98,34 @@ bool opt_fix_safefn = true; bool check_entry(bool &found, ControlFlowGraph_t* cfg) { - BasicBlock_t *entry=cfg->GetEntry(); + auto entry=cfg->getEntry(); found=false; - for( - std::vector<Instruction_t*>::const_iterator it=entry->GetInstructions().begin(); - it!=entry->GetInstructions().end(); - ++it - ) + for(auto insn : entry->getInstructions()) { - Instruction_t* insn=*it; - //DISASM disasm; - //Disassemble(insn,disasm); - DecodedInstruction_t disasm(insn); + auto disasmp = DecodedInstruction_t::factory(insn); + auto &disasm = *disasmp; if(disasm.setsStackPointer()) { return false; } else { if(getenv("VERBOSE_FIX_CALLS")) { - virtual_offset_t addr = 0; - if (insn->GetAddress()) - addr = insn->GetAddress()->GetVirtualOffset(); + VirtualOffset_t addr = 0; + if (insn->getAddress()) + addr = insn->getAddress()->getVirtualOffset(); cout<<"check_entry: does not set stack pointer?"<< " address=" <<hex<<addr<<": "<<insn->getDisassembly()<<endl; } } - if(strstr(disasm.getDisassembly().c_str()/* disasm.CompleteInstr*/, "[esp]")) + if(strstr(disasm.getDisassembly().c_str(), "[esp]")) { found=true; if(getenv("VERBOSE_FIX_CALLS")) { - virtual_offset_t addr = 0; - if (insn->GetAddress()) - addr = insn->GetAddress()->GetVirtualOffset(); + VirtualOffset_t addr = 0; + if (insn->getAddress()) + addr = insn->getAddress()->getVirtualOffset(); cout<<"Needs fix (check_entry): [esp]"<< " address=" <<hex<<addr<<": "<<insn->getDisassembly()<<endl; } @@ -142,25 +136,20 @@ bool check_entry(bool &found, ControlFlowGraph_t* cfg) return false; } -using ControlFlowGraphMap_t = map<Function_t*, ControlFlowGraph_t*>; +using ControlFlowGraphMap_t = map<Function_t*, shared_ptr<ControlFlowGraph_t> >; ControlFlowGraphMap_t cfg_optimizer; bool call_needs_fix(Instruction_t* insn) { - for(set<Relocation_t*>::iterator it=insn->GetRelocations().begin(); - it!=insn->GetRelocations().end(); - ++it - ) + for(auto reloc : insn->getRelocations()) { - Relocation_t* reloc=*it; - if(string("safefr") == reloc->GetType()) + if(string("safefr") == reloc->getType()) return false; } - Instruction_t *target=insn->GetTarget(); - Instruction_t *fallthru=insn->GetFallthrough(); - //DISASM disasm; + auto target=insn->getTarget(); + auto fallthru=insn->getFallthrough(); string pattern; @@ -174,9 +163,9 @@ bool call_needs_fix(Instruction_t* insn) { if(getenv("VERBOSE_FIX_CALLS")) { - virtual_offset_t addr = 0; - if (insn->GetAddress()) - addr = insn->GetAddress()->GetVirtualOffset(); + VirtualOffset_t addr = 0; + if (insn->getAddress()) + addr = insn->getAddress()->getVirtualOffset(); cout<<"Needs fix: No fallthrough"<< " address=" <<hex<<addr<<": "<<insn->getDisassembly()<<endl; } @@ -184,15 +173,15 @@ bool call_needs_fix(Instruction_t* insn) return true; } - virtual_offset_t addr=fallthru->GetAddress()->GetVirtualOffset(); - RangeSet_t::iterator rangeiter=eh_frame_ranges.find(Range_t(addr,addr)); + auto addr=fallthru->getAddress()->getVirtualOffset(); + auto rangeiter=eh_frame_ranges.find(Range_t(addr,addr)); if(rangeiter != eh_frame_ranges.end()) // found an eh_frame addr entry for this call { in_ehframe++; return true; } - if (!opt_fix_icalls && insn->GetIBTargets() && insn->GetIBTargets()->size() > 0) + if (!opt_fix_icalls && insn->getIBTargets() && insn->getIBTargets()->size() > 0) { /* do not fix indirect calls */ no_fix_for_ib++; @@ -203,10 +192,8 @@ bool call_needs_fix(Instruction_t* insn) if(!target) { /* call 0's aren't to real locations */ - // Disassemble(insn,disasm); - DecodedInstruction_t disasm(insn); - // if(strcmp(disasm.getDisassembly().c_str()/*CompleteInstr*/, "call 0x00000000")==0) - if(disasm.getOperand(0).isConstant() && disasm.getAddress()==0) + auto disasm=DecodedInstruction_t::factory(insn); + if(disasm->getOperand(0)->isConstant() && disasm->getAddress()==0) { return false; } @@ -214,9 +201,9 @@ bool call_needs_fix(Instruction_t* insn) if(getenv("VERBOSE_FIX_CALLS")) { - virtual_offset_t addr = 0; - if (insn->GetAddress()) - addr = insn->GetAddress()->GetVirtualOffset(); + VirtualOffset_t addr = 0; + if (insn->getAddress()) + addr = insn->getAddress()->getVirtualOffset(); cout<<"Needs fix: No target instruction"<< " address=" <<hex<<addr<<": "<<insn->getDisassembly()<<endl; } @@ -230,16 +217,16 @@ bool call_needs_fix(Instruction_t* insn) */ - Function_t* func=target->GetFunction(); + auto func=target->getFunction(); /* if there's no function for this instruction */ if(!func) { if(getenv("VERBOSE_FIX_CALLS")) { - virtual_offset_t addr = 0; - if (insn->GetAddress()) - addr = insn->GetAddress()->GetVirtualOffset(); + VirtualOffset_t addr = 0; + if (insn->getAddress()) + addr = insn->getAddress()->getVirtualOffset(); cout<<"Needs fix: Target not in a function"<< " address=" <<hex<<addr<<": "<<insn->getDisassembly()<<endl; } @@ -255,16 +242,16 @@ bool call_needs_fix(Instruction_t* insn) if(!is_found) /* build a cfg for this function */ - cfg_optimizer[func]=new ControlFlowGraph_t(func); + cfg_optimizer[func]=shared_ptr<ControlFlowGraph_t>(move(ControlFlowGraph_t::factory(func))); - auto cfg=cfg_optimizer[func]; + auto cfg=cfg_optimizer[func].get(); - assert(cfg->GetEntry()); + assert(cfg->getEntry()); /* if the call instruction isn't to a function entry point */ - if(cfg->GetEntry()->GetInstructions()[0]!=target) + if(cfg->getEntry()->getInstructions()[0]!=target) { call_to_not_entry++; /* then we need to fix it */ @@ -273,7 +260,7 @@ bool call_needs_fix(Instruction_t* insn) /* check the entry block for thunks, etc. */ - bool found; + auto found=false; bool ret=check_entry(found,cfg); // delete cfg; if(found) @@ -282,9 +269,9 @@ bool call_needs_fix(Instruction_t* insn) { if(getenv("VERBOSE_FIX_CALLS")) { - virtual_offset_t addr = 0; - if (insn->GetAddress()) - addr = insn->GetAddress()->GetVirtualOffset(); + VirtualOffset_t addr = 0; + if (insn->getAddress()) + addr = insn->getAddress()->getVirtualOffset(); cout<<"Needs fix: (via check_entry) Thunk detected"<< " address=" <<hex<<addr<<": "<<insn->getDisassembly()<<endl; } @@ -430,17 +417,16 @@ string adjust_esp_offset(string newbits, int offset) */ void convert_to_jump(Instruction_t* insn, int offset) { - string newbits=insn->GetDataBits(); - //DISASM d; - //Disassemble(insn,d); - DecodedInstruction_t d(insn); + string newbits=insn->getDataBits(); + auto dp=DecodedInstruction_t::factory(insn); + auto &d=*dp; /* this case is odd, handle it specially (and more easily to understand) */ - if(strcmp(d.getDisassembly().c_str()/*.CompleteInstr*/, "call qword [rsp]")==0) + if(strcmp(d.getDisassembly().c_str(), "call qword [rsp]")==0) { char buf[100]; sprintf(buf,"jmp qword [rsp+%d]", offset); - insn->Assemble(buf); + insn->assemble(buf); return; } @@ -503,7 +489,7 @@ void convert_to_jump(Instruction_t* insn, int offset) } /* set the instruction's bits */ - insn->SetDataBits(newbits); + insn->setDataBits(newbits); return; } @@ -513,28 +499,32 @@ void convert_to_jump(Instruction_t* insn, int offset) */ void fix_call(Instruction_t* insn, FileIR_t *firp, bool can_unpin) { + if(firp->getArchitecture()->getMachineType()==admtAarch64) + return; + /* record the possibly new indirect branch target if this call gets fixed */ - Instruction_t* newindirtarg=insn->GetFallthrough(); + Instruction_t* newindirtarg=insn->getFallthrough(); /* Disassemble the instruction */ - DecodedInstruction_t disasm(insn); + auto disasmp=DecodedInstruction_t::factory (insn); + auto &disasm=*disasmp; /* if this instruction is an inserted call instruction than we don't need to * convert it for correctness' sake. */ - if(insn->GetAddress()->GetVirtualOffset()==0) + if(insn->getAddress()->getVirtualOffset()==0) return; /* if the first byte isn't a call opcode, there's some odd prefixing and we aren't handling it. * this comes up most frequently in a call gs:0x10 instruction where an override prefix specifes the gs: part. */ - if((insn->GetDataBits()[0]&0x40)==0x40) + if((insn->getDataBits()[0]&0x40)==0x40) { // ignore rex prefixes } - else if( (insn->GetDataBits()[0]!=(char)0xff) && - (insn->GetDataBits()[0]!=(char)0xe8) && - (insn->GetDataBits()[0]!=(char)0x9a) ) + else if( (insn->getDataBits()[0]!=(char)0xff) && + (insn->getDataBits()[0]!=(char)0xe8) && + (insn->getDataBits()[0]!=(char)0x9a) ) { cout<<"Found odd prefixing.\n Not handling **********************************************"<<endl; assert(0); @@ -543,55 +533,61 @@ void fix_call(Instruction_t* insn, FileIR_t *firp, bool can_unpin) if(getenv("VERBOSE_FIX_CALLS")) { - cout<<"Doing a fix_call on "<<std::hex<<insn->GetAddress()->GetVirtualOffset()<< " which is "<<disasm.getDisassembly() /*.CompleteInstr*/<<endl; + cout<<"Doing a fix_call on "<<std::hex<<insn->getAddress()->getVirtualOffset()<< " which is "<<disasm.getDisassembly() /*.CompleteInstr*/<<endl; } - virtual_offset_t next_addr=insn->GetAddress()->GetVirtualOffset() + insn->GetDataBits().length(); + VirtualOffset_t next_addr=insn->getAddress()->getVirtualOffset() + insn->getDataBits().length(); /* create a new instruction and a new addresss for it that do not correspond to any original program address */ - Instruction_t *callinsn=new Instruction_t(); - AddressID_t *calladdr=new AddressID_t; - calladdr->SetFileID(insn->GetAddress()->GetFileID()); + /* + Instruction_t *callinsn=new Instruction_t(); + firp->getInstructions().insert(callinsn); + */ + auto callinsn=firp->addNewInstruction(); + /* + AddressID_t *calladdr=new AddressID_t; + firp->getAddresses().insert(calladdr); + calladdr->setFileID(insn->getAddress()->getFileID()); + */ + auto calladdr=firp->addNewAddress(insn->getAddress()->getFileID(),0); /* set the fields in the new instruction */ - callinsn->SetAddress(calladdr); - callinsn->SetTarget(insn->GetTarget()); - callinsn->SetFallthrough(NULL); - callinsn->SetFunction(insn->GetFunction()); - callinsn->SetComment(insn->GetComment()+" Jump part"); + callinsn->setAddress(calladdr); + callinsn->setTarget(insn->getTarget()); + callinsn->setFallthrough(NULL); + callinsn->setFunction(insn->getFunction()); + callinsn->setComment(insn->getComment()+" Jump part"); /* handle ib targets */ - callinsn->SetIBTargets(insn->GetIBTargets()); - insn->SetIBTargets(NULL); + callinsn->setIBTargets(insn->getIBTargets()); + insn->setIBTargets(NULL); // We need the control transfer instruction to be from the orig program because // if for some reason it's fallthrough/target isn't in the DB, we need to correctly // emit fallthrough/target rules - callinsn->SetOriginalAddressID(insn->GetOriginalAddressID()); - insn->SetOriginalAddressID(BaseObj_t::NOT_IN_DATABASE); + callinsn->setOriginalAddressID(insn->getOriginalAddressID()); + insn->setOriginalAddressID(BaseObj_t::NOT_IN_DATABASE); /* set the new instruction's data bits to be a jmp instead of a call */ string newbits=""; /* add 4 (8) if it's an esp(rsp) indirect branch for x86-32 (-64) */ - callinsn->SetDataBits(insn->GetDataBits()); - convert_to_jump(callinsn,firp->GetArchitectureBitWidth()/8); + callinsn->setDataBits(insn->getDataBits()); + convert_to_jump(callinsn,firp->getArchitectureBitWidth()/8); /* the jump instruction should NOT be indirectly reachable. We should * land at the push */ - fix_other_pcrel(firp, callinsn, insn->GetAddress()->GetVirtualOffset()); - callinsn->SetIndirectBranchTargetAddress(NULL); + fix_other_pcrel(firp, callinsn, insn->getAddress()->getVirtualOffset()); + callinsn->setIndirectBranchTargetAddress(NULL); /* add the new insn and new address into the list of valid calls and addresses */ - firp->GetAddresses().insert(calladdr); - firp->GetInstructions().insert(callinsn); /* Convert the old call instruction into a push return_address instruction */ - insn->SetFallthrough(callinsn); - insn->SetTarget(NULL); + insn->setFallthrough(callinsn); + insn->setTarget(NULL); newbits=string(""); newbits.resize(5); newbits[0]=0x68; /* assemble an instruction push next_addr */ @@ -599,63 +595,73 @@ void fix_call(Instruction_t* insn, FileIR_t *firp, bool can_unpin) newbits[2]=(next_addr>>8) & 0xff; newbits[3]=(next_addr>>16) & 0xff; newbits[4]=(next_addr>>24) & 0xff; - insn->SetDataBits(newbits); - insn->SetComment(insn->GetComment()+" Push part"); + insn->setDataBits(newbits); + insn->setComment(insn->getComment()+" Push part"); /* create a relocation for this instruction */ + /* Relocation_t* reloc=new Relocation_t; - if(firp->GetArchitectureBitWidth()==32) - { - reloc->SetOffset(1); - reloc->SetType("32-bit"); - } - else - { - assert(firp->GetArchitectureBitWidth()==64); - reloc->SetOffset(0); - reloc->SetType("push64"); - } + insn->getRelocations().insert(reloc); + firp->getRelocations().insert(reloc); + */ + auto reloc= firp->getArchitectureBitWidth()==32 ? firp->addNewRelocation(insn, 1, "32-bit") : + /* + reloc->setOffset(1); + reloc->setType("32-bit"); + */ + firp->getArchitectureBitWidth()==64 ? firp->addNewRelocation(insn, 0, "push64") : + /* + reloc->setOffset(0); + reloc->setType("push64"); + */ + throw invalid_argument("odd bit width?"); - insn->GetRelocations().insert(reloc); - firp->GetRelocations().insert(reloc); /* If the fallthrough is not marked as indirectly branchable-to, then mark it so */ - if(newindirtarg && !newindirtarg->GetIndirectBranchTargetAddress()) + if(newindirtarg && !newindirtarg->getIndirectBranchTargetAddress()) { /* create a new address for the IBTA */ + /* AddressID_t* newaddr = new AddressID_t; assert(newaddr); - newaddr->SetFileID(newindirtarg->GetAddress()->GetFileID()); - newaddr->SetVirtualOffset(newindirtarg->GetAddress()->GetVirtualOffset()); + newaddr->setFileID(newindirtarg->getAddress()->getFileID()); + newaddr->setVirtualOffset(newindirtarg->getAddress()->getVirtualOffset()); + firp->getAddresses().insert(newaddr); + */ + auto newaddr=firp->addNewAddress(newindirtarg->getAddress()->getFileID(), newindirtarg->getAddress()->getVirtualOffset()); /* set the instruction and include this address in the list of addrs */ - newindirtarg->SetIndirectBranchTargetAddress(newaddr); - firp->GetAddresses().insert(newaddr); + newindirtarg->setIndirectBranchTargetAddress(newaddr); // if we're marking this as an IBTA, determine whether we can unpin it or not if(can_unpin) { if(getenv("VERBOSE_FIX_CALLS")) { - cout<<"Setting unpin for type="<< reloc->GetType()<< " address=" - <<hex<<insn->GetBaseID()<<":"<<insn->getDisassembly()<<endl; + cout<<"setting unpin for type="<< reloc->getType()<< " address=" + <<hex<<insn->getBaseID()<<":"<<insn->getDisassembly()<<endl; } // set newindirtarg as unpinned - newindirtarg->GetIndirectBranchTargetAddress()->SetVirtualOffset(0); - reloc->SetWRT(newindirtarg); + newindirtarg->getIndirectBranchTargetAddress()->setVirtualOffset(0); + reloc->setWRT(newindirtarg); } } // mark in the IR what the fallthrough of this insn is. + /* Relocation_t* fix_call_reloc=new Relocation_t(); - fix_call_reloc->SetOffset(0); - fix_call_reloc->SetType("fix_call_fallthrough"); - fix_call_reloc->SetWRT(newindirtarg); - callinsn->GetRelocations().insert(fix_call_reloc); - firp->GetRelocations().insert(fix_call_reloc); - + callinsn->getRelocations().insert(fix_call_reloc); + firp->getRelocations().insert(fix_call_reloc); + */ + auto fix_call_reloc=firp->addNewRelocation(callinsn, 0, "fix_call_fallthrough", newindirtarg); + (void)fix_call_reloc; // not used, just give to IR + /* + fix_call_reloc->setOffset(0); + fix_call_reloc->setType("fix_call_fallthrough"); + fix_call_reloc->setWRT(newindirtarg); + */ } @@ -664,13 +670,9 @@ void fix_call(Instruction_t* insn, FileIR_t *firp, bool can_unpin) // bool is_call(Instruction_t* insn) { - /* Disassemble the instruction */ - DecodedInstruction_t disasm(insn); - //int instr_len = disasm.length(); // Disassemble(insn,disasm); - - - return disasm.isCall(); // (disasm.Instruction.BranchType==CallType); + auto disasm=DecodedInstruction_t::factory (insn); + return disasm->isCall(); } bool can_skip_safe_function(Instruction_t *call_insn) @@ -679,31 +681,31 @@ bool can_skip_safe_function(Instruction_t *call_insn) return false; if (!is_call(call_insn)) return false; - Instruction_t *target=call_insn->GetTarget(); + Instruction_t *target=call_insn->getTarget(); if (!target) return false; - Function_t* func=target->GetFunction(); + auto func=target->getFunction(); if (!func) return false; /* if the call instruction isn't to a function entry point */ - if(func->GetEntryPoint()!=target) + if(func->getEntryPoint()!=target) { return false; } - if (func->IsSafe()) + if (func->isSafe()) { - cout << "Function " << func->GetName() << " is safe" << endl; + cout << "Function " << func->getName() << " is safe" << endl; } - return func->IsSafe(); + return func->isSafe(); } template <class T> struct insn_less : binary_function <T,T,bool> { bool operator() (const T& x, const T& y) const { - return x->GetBaseID() < y->GetBaseID() ;} + return x->getBaseID() < y->getBaseID() ;} }; @@ -713,15 +715,18 @@ template <class T> struct insn_less : binary_function <T,T,bool> { void mark_as_unpinned_ibt(FileIR_t* firp, Instruction_t* ret_point) { if( ret_point == NULL ) return; - if( ret_point->GetIndirectBranchTargetAddress() != NULL ) return; + if( ret_point->getIndirectBranchTargetAddress() != NULL ) return; + /* auto newaddr = new AddressID_t; assert(newaddr); - newaddr->SetFileID(ret_point->GetAddress()->GetFileID()); - newaddr->SetVirtualOffset(0); // unpinne + newaddr->setFileID(ret_point->getAddress()->getFileID()); + newaddr->setVirtualOffset(0); // unpinne - firp->GetAddresses().insert(newaddr); - ret_point->SetIndirectBranchTargetAddress(newaddr); + firp->getAddresses().insert(newaddr); + */ + auto newaddr=firp->addNewAddress(ret_point->getAddress()->getFileID(),0); + ret_point->setIndirectBranchTargetAddress(newaddr); } @@ -732,27 +737,10 @@ void mark_as_unpinned_ibt(FileIR_t* firp, Instruction_t* ret_point) void fix_all_calls(FileIR_t* firp, bool fix_all) { - set<Instruction_t*,insn_less<Instruction_t*> > sorted_insns; + auto sorted_insns = set<Instruction_t*,insn_less<Instruction_t*> >(ALLOF(firp->getInstructions())); - for( - set<Instruction_t*>::const_iterator it=firp->GetInstructions().begin(); - it!=firp->GetInstructions().end(); - ++it - ) - { - Instruction_t* insn=*it; - sorted_insns.insert(insn); - } - - - for( - set<Instruction_t*,insn_less<Instruction_t*> >::const_iterator it=sorted_insns.begin(); - it!=sorted_insns.end(); - ++it - ) + for(auto insn : sorted_insns) { - - Instruction_t* insn=*it; if(getenv("STOP_FIX_CALLS_AT") && fixed_calls>=(size_t)atoi(getenv("STOP_FIX_CALLS_AT"))) break; @@ -767,7 +755,7 @@ void fix_all_calls(FileIR_t* firp, bool fix_all) // (and a bit about debugging fix-calls that's not important for anyone but jdh. else if ( fix_all || (getenv("FIX_CALL_LIMIT") && not_fixed_calls>=(size_t)atoi(getenv("FIX_CALL_LIMIT")))) { - bool fix_me = true; + auto fix_me = true; if (!opt_fix_safefn && can_skip_safe_function(insn)) { fix_me = false; @@ -789,8 +777,8 @@ void fix_all_calls(FileIR_t* firp, bool fix_all) else { if(getenv("VERBOSE_FIX_CALLS")) - cout<<"No fix needed, marking ret site IBT, for "<<insn->GetAddress()->GetVirtualOffset()<<":"<<insn->getDisassembly()<<endl; - mark_as_unpinned_ibt(firp, insn->GetFallthrough()); + cout<<"No fix needed, marking ret site IBT, for "<<insn->getAddress()->getVirtualOffset()<<":"<<insn->getDisassembly()<<endl; + mark_as_unpinned_ibt(firp, insn->getFallthrough()); not_fixed_calls++; } } @@ -798,7 +786,7 @@ void fix_all_calls(FileIR_t* firp, bool fix_all) else { if(getenv("VERBOSE_FIX_CALLS")) - cout<<"Not a call "<<insn->GetAddress()->GetVirtualOffset()<<":"<<insn->getDisassembly()<<endl; + cout<<"Not a call "<<insn->getAddress()->getVirtualOffset()<<":"<<insn->getDisassembly()<<endl; not_calls++; } } @@ -826,12 +814,10 @@ void fix_all_calls(FileIR_t* firp, bool fix_all) // void fix_other_pcrel(FileIR_t* firp, Instruction_t *insn, uintptr_t virt_offset) { - //DISASM disasm; - //Disassemble(insn,disasm); - DecodedInstruction_t disasm(insn); - const auto &operands=disasm.getOperands(); - const auto relop_it=find_if(ALLOF(operands),[](const DecodedOperand_t& op) - { return op.isMemory() && op.isPcrel() ; } ); + auto disasm=DecodedInstruction_t::factory(insn); + const auto &operands=disasm->getOperands(); + const auto relop_it=find_if(ALLOF(operands),[](const shared_ptr<DecodedOperand_t>& op) + { return op->isPcrel() ; } ); const bool is_rel= relop_it!=operands.end(); /* if this has already been fixed, we can skip it */ @@ -840,71 +826,82 @@ void fix_other_pcrel(FileIR_t* firp, Instruction_t *insn, uintptr_t virt_offset) if(is_rel) { + const auto &the_arg=*(relop_it->get()); + const auto mt=firp->getArchitecture()->getMachineType(); + if(mt==admtAarch64) + { + // figure out how to rewrite pcrel arm insns, then change the virt addr + // insn->getAddress()->setVirtualOffset(0); + } + else if(mt==admtX86_64 || mt==admtI386) + { + assert(the_arg.isMemory()); + auto offset=disasm->getMemoryDisplacementOffset(&the_arg, insn); + assert(offset>=0 && offset <=15); + auto size=the_arg.getMemoryDisplacementEncodingSize(); + assert(size==1 || size==2 || size==4 || size==8); - const auto the_arg=*relop_it; + if(getenv("VERBOSE_FIX_CALLS")) + { + cout<<"Found insn with pcrel memory operand: "<<disasm->getDisassembly() + <<" Displacement="<<std::hex<<the_arg.getMemoryDisplacement() << dec + <<" size="<<the_arg.getMemoryDisplacementEncodingSize() <<" Offset="<<offset; + } - int offset=disasm.getMemoryDisplacementOffset(the_arg, insn); /*the_arg->Memory.DisplacementAddr-disasm.EIP*/; - assert(offset>=0 && offset <=15); - int size=the_arg.getMemoryDisplacementEncodingSize(); // the_arg->Memory.DisplacementSize; - assert(size==1 || size==2 || size==4 || size==8); + /* convert [rip_pc+displacement] addresssing mode into [rip_0+displacement] where rip_pc is the actual PC of the insn, + * and rip_0 is means that the PC=0. AKA, we are relocating this instruction to PC=0. Later we add a relocation to undo this transform at runtime + * when we know the actual address. + */ - if(getenv("VERBOSE_FIX_CALLS")) - { - cout<<"Found insn with pcrel memory operand: "<<disasm.getDisassembly()/*.CompleteInstr */ - <<" Displacement="<<std::hex<<the_arg.getMemoryDisplacement() /*the_arg->Memory.Displacement*/<<std::dec - <<" size="<<the_arg.getMemoryDisplacementEncodingSize() /*the_arg->Memory.DisplacementSize*/<<" Offset="<<offset; - } + /* get the data */ + string data=insn->getDataBits(); + char cstr[20]={}; + memcpy(cstr,data.c_str(), data.length()); + void *offsetptr=&cstr[offset]; - /* convert [rip_pc+displacement] addresssing mode into [rip_0+displacement] where rip_pc is the actual PC of the insn, - * and rip_0 is means that the PC=0. AKA, we are relocating this instruction to PC=0. Later we add a relocation to undo this transform at runtime - * when we know the actual address. - */ + uintptr_t disp=the_arg.getMemoryDisplacement(); + uintptr_t oldpc=virt_offset; + uintptr_t newdisp=disp+oldpc; - /* get the data */ - string data=insn->GetDataBits(); - char cstr[20]; - memcpy(cstr,data.c_str(), data.length()); - void *offsetptr=&cstr[offset]; + assert((uintptr_t)(offset+size)<=(uintptr_t)(data.length())); + + switch(size) + { + case 4: + assert( (uintptr_t)(int)newdisp == (uintptr_t)newdisp); + *(int*)offsetptr=newdisp; + break; + case 1: + case 2: + case 8: + default: + assert(0); + //assert(("Cannot handle offset of given size", 0)); + } - uintptr_t disp=the_arg.getMemoryDisplacement(); // ->Memory.Displacement; - uintptr_t oldpc=virt_offset; - uintptr_t newdisp=disp+oldpc; + /* put the data back into the insn */ + data.replace(0, data.length(), cstr, data.length()); + insn->setDataBits(data); - assert((uintptr_t)(offset+size)<=(uintptr_t)(data.length())); - - switch(size) - { - case 4: - assert( (uintptr_t)(int)newdisp == (uintptr_t)newdisp); - *(int*)offsetptr=newdisp; - break; - case 1: - case 2: - case 8: - default: - assert(0); - //assert(("Cannot handle offset of given size", 0)); - } + other_fixes++; - /* put the data back into the insn */ - data.replace(0, data.length(), cstr, data.length()); - insn->SetDataBits(data); + disasm=DecodedInstruction_t::factory(insn); + if(getenv("VERBOSE_FIX_CALLS")) + cout<<" Converted to: "<<disasm->getDisassembly() << endl; - // going to end up in the SPRI file anyhow after changing the data bits - // and it's important to set the VO to 0, so that the pcrel-ness is calculated correctly. - insn->GetAddress()->SetVirtualOffset(0); - - Relocation_t *reloc=new Relocation_t; - reloc->SetOffset(0); - reloc->SetType("pcrel"); - insn->GetRelocations().insert(reloc); - firp->GetRelocations().insert(reloc); + // and it's important to set the VO to 0, so that the pcrel-ness is calculated correctly. + insn->getAddress()->setVirtualOffset(0); + } - other_fixes++; + // now that we've done the rewriting, go ahead and add the reloc. + /* + auto reloc=new Relocation_t(BaseObj_t::NOT_IN_DATABASE, 0,"pcrel"); + insn->getRelocations().insert(reloc); + firp->getRelocations().insert(reloc); + */ + auto reloc=firp->addNewRelocation(insn,0,"pcrel"); + (void)reloc; // not used, only given to the IR - disasm=DecodedInstruction_t(insn); - if(getenv("VERBOSE_FIX_CALLS")) - cout<<" Converted to: "<<disasm.getDisassembly() /*CompleteInstr*/<<endl; } } @@ -914,18 +911,17 @@ void fix_safefr(FileIR_t* firp, Instruction_t *insn, uintptr_t virt_offset) if(virt_offset==0 || virt_offset==(uintptr_t)-1) return; - for(set<Relocation_t*>::iterator it=insn->GetRelocations().begin(); - it!=insn->GetRelocations().end(); - ++it) + for(auto reloc : insn->getRelocations()) { - Relocation_t* reloc=*it; assert(reloc); - if(string("safefr") == reloc->GetType()) + if( reloc->getType() == "safefr" ) { - AddressID_t* addr =new AddressID_t; - addr->SetFileID(insn->GetAddress()->GetFileID()); - firp->GetAddresses().insert(addr); - insn->SetAddress(addr); + /* + auto addr=new AddressID_t(BaseObj_t::NOT_IN_DATABASE, insn->getAddress()->getFileID(), 0); + firp->getAddresses().insert(addr); + */ + auto addr=firp->addNewAddress(insn->getAddress()->getFileID(), 0); + insn->setAddress(addr); } } } @@ -934,15 +930,10 @@ void fix_safefr(FileIR_t* firp, Instruction_t *insn, uintptr_t virt_offset) void fix_other_pcrel(FileIR_t* firp) { - for( - set<Instruction_t*>::const_iterator it=firp->GetInstructions().begin(); - it!=firp->GetInstructions().end(); - ++it - ) + for(auto insn : firp->getInstructions()) { - Instruction_t* insn=*it; - fix_other_pcrel(firp,insn, insn->GetAddress()->GetVirtualOffset()); - fix_safefr(firp,insn, insn->GetAddress()->GetVirtualOffset()); + fix_other_pcrel(firp,insn, insn->getAddress()->getVirtualOffset()); + fix_safefr(firp,insn, insn->getAddress()->getVirtualOffset()); } cout << "# ATTRIBUTE fix_calls::other_fixes="<<std::dec<<other_fixes<<endl; } @@ -1019,7 +1010,7 @@ int parseArgs(const vector<string> step_args) return 0; } -db_id_t variant_id=BaseObj_t::NOT_IN_DATABASE; +DatabaseID_t variant_id=BaseObj_t::NOT_IN_DATABASE; int executeStep(IRDBObjects_t *const irdb_objects) @@ -1030,26 +1021,26 @@ int executeStep(IRDBObjects_t *const irdb_objects) { /* setup the interface to the sql server */ const auto pqxx_interface=irdb_objects->getDBInterface(); - BaseObj_t::SetInterface(pqxx_interface); + BaseObj_t::setInterface(pqxx_interface); auto pidp = irdb_objects->addVariant(variant_id); cout<<"Fixing calls->push/jmp in variant "<<*pidp<< "." <<endl; - assert(pidp->IsRegistered()==true); + assert(pidp->isRegistered()==true); - for(const auto &this_file : pidp->GetFiles()) + for(const auto &this_file : pidp->getFiles()) { assert(this_file); // read the db - auto firp = irdb_objects->addFileIR(variant_id, this_file->GetBaseID()); + auto firp = irdb_objects->addFileIR(variant_id, this_file->getBaseID()); assert(firp && pidp); eh_frame_ranges.clear(); - int elfoid=firp->GetFile()->GetELFOID(); + int elfoid=firp->getFile()->getELFOID(); pqxx::largeobject lo(elfoid); - lo.to_file(pqxx_interface->GetTransaction(),"readeh_tmp_file.exe"); + lo.to_file(pqxx_interface->getTransaction(),"readeh_tmp_file.exe"); EXEIO::exeio* elfiop=new EXEIO::exeio; elfiop->load(string("readeh_tmp_file.exe")); EXEIO::dump::header(cout,*elfiop); @@ -1082,12 +1073,7 @@ int executeStep(IRDBObjects_t *const irdb_objects) return 0; } - - - - - -void range(virtual_offset_t a, virtual_offset_t b) +void range(VirtualOffset_t a, VirtualOffset_t b) { // we've found examples of ranges being 0 sized, and it's a bit weird what that means. // it applies to 0 instructions? @@ -1097,7 +1083,7 @@ void range(virtual_offset_t a, virtual_offset_t b) // non-zero sized fde assert(a<b); - RangeSet_t::iterator rangeiter=eh_frame_ranges.find(Range_t(a+1,a+1)); + const auto rangeiter=eh_frame_ranges.find(Range_t(a+1,a+1)); assert(rangeiter==eh_frame_ranges.end()); eh_frame_ranges.insert(Range_t(a+1,b)); // ranges are interpreted as (a,b] @@ -1117,22 +1103,22 @@ std::string getStepName(void) const override }; // end class FixCalls_t -shared_ptr<Transform_SDK::TransformStep_t> curInvocation; +shared_ptr<TransformStep_t> curInvocation; -bool possible_target(virtual_offset_t p, virtual_offset_t from_addr, ibt_provenance_t prov) +bool possible_target(VirtualOffset_t p, VirtualOffset_t from_addr, ibt_provenance_t prov) { assert(curInvocation); return (dynamic_cast<FixCalls_t*>(curInvocation.get()))->possible_target(p,from_addr,prov); } -void range(virtual_offset_t start, virtual_offset_t end) +void range(VirtualOffset_t start, VirtualOffset_t end) { assert(curInvocation); return (dynamic_cast<FixCalls_t*>(curInvocation.get()))->range(start,end); } extern "C" -shared_ptr<Transform_SDK::TransformStep_t> GetTransformStep(void) +shared_ptr<TransformStep_t> getTransformStep(void) { curInvocation.reset(new FixCalls_t()); return curInvocation; diff --git a/libIRDB/test/generate_spri.cpp b/ir_builders/generate_spri.cpp similarity index 100% rename from libIRDB/test/generate_spri.cpp rename to ir_builders/generate_spri.cpp diff --git a/libIRDB/test/ilr.cpp b/ir_builders/ilr.cpp similarity index 100% rename from libIRDB/test/ilr.cpp rename to ir_builders/ilr.cpp diff --git a/libIRDB/test/list_programs.cpp b/ir_builders/list_programs.cpp similarity index 100% rename from libIRDB/test/list_programs.cpp rename to ir_builders/list_programs.cpp diff --git a/libIRDB/test/mark_functions_safe.cpp b/ir_builders/mark_functions_safe.cpp similarity index 100% rename from libIRDB/test/mark_functions_safe.cpp rename to ir_builders/mark_functions_safe.cpp diff --git a/libIRDB/test/pin_address.cpp b/ir_builders/pin_address.cpp similarity index 100% rename from libIRDB/test/pin_address.cpp rename to ir_builders/pin_address.cpp diff --git a/libIRDB/test/print_variant.cpp b/ir_builders/print_variant.cpp similarity index 100% rename from libIRDB/test/print_variant.cpp rename to ir_builders/print_variant.cpp diff --git a/libIRDB/test/read_ehframe.cpp b/ir_builders/read_ehframe.cpp similarity index 95% rename from libIRDB/test/read_ehframe.cpp rename to ir_builders/read_ehframe.cpp index 5fef4dc7a5d1ea9df6354827d0ef66771f0c7234..17dd5f8c673ec71a17105a50bee17d77e7a79ce9 100644 --- a/libIRDB/test/read_ehframe.cpp +++ b/ir_builders/read_ehframe.cpp @@ -22,10 +22,9 @@ -#include <libIRDB-core.hpp> -#include <libIRDB-cfg.hpp> -#include <utils.hpp> +#include <irdb-core> #include <iostream> +#include <algorithm> #include <stdlib.h> #include <assert.h> #include <string.h> @@ -42,8 +41,8 @@ #include "fill_in_indtargs.hpp" -using namespace libIRDB; using namespace std; +using namespace IRDB_SDK; @@ -797,7 +796,7 @@ void linear_search_fdes (struct object *ob, fde *this_fde, int offset) cout<<"absptr pc_end 0x"<<std::hex<<(pc_begin+pc_range+offset)<<endl; } #ifndef TEST - extern void range(virtual_offset_t, virtual_offset_t); + extern void range(VirtualOffset_t, VirtualOffset_t); range(pc_begin,pc_begin+pc_range); #endif if (pc_begin == 0) @@ -819,7 +818,7 @@ void linear_search_fdes (struct object *ob, fde *this_fde, int offset) } #ifndef TEST - extern void range(virtual_offset_t, virtual_offset_t); + extern void range(VirtualOffset_t, VirtualOffset_t); range(pc_begin,pc_begin+pc_range); #endif @@ -847,7 +846,7 @@ void linear_search_fdes (struct object *ob, fde *this_fde, int offset) void read_ehframe(FileIR_t* virp, EXEIO::exeio* exeiop) { - ptrsize=virp->GetArchitectureBitWidth()/(8*sizeof(char)); + ptrsize=virp->getArchitectureBitWidth()/(8*sizeof(char)); // 64/8 = 8 // 32/8 = 4 @@ -856,18 +855,16 @@ void read_ehframe(FileIR_t* virp, EXEIO::exeio* exeiop) if(!elfiop) return; // skip entire analysis for non-elf files as eh-frame is way different. - const auto eh_frame_it=find_if(virp->GetDataScoops().begin(), virp->GetDataScoops().end(), - [](const DataScoop_t* scoop) { return scoop->GetName()==".eh_frame"; }); + const auto eh_frame_it=find_if(virp->getDataScoops().begin(), virp->getDataScoops().end(), + [](const DataScoop_t* scoop) { return scoop->getName()==".eh_frame"; }); // either no eh_frame in the elf file, or fill_in_indtargs removed it because // it was asked to import the EH IR. - if(eh_frame_it==virp->GetDataScoops().end()) + if(eh_frame_it==virp->getDataScoops().end()) return; int secndx=0; int secnum=elfiop->sections.size(); - //ELFIO::Elf_Half strndx = elfiop->get_section_name_str_index(); - //const char* strtab=elfiop->sections[strndx]->get_data(); /* Locate desired section */ bool found=false; @@ -895,9 +892,7 @@ void read_ehframe(FileIR_t* virp, EXEIO::exeio* exeiop) cout<<"Found .eh_frame section addr is "<<std::dec<<eh_frame_addr<<endl; int total_size=0; -// char *p=&strtab[ sechdrs[secndx+1].sh_name]; const char *p=elfiop->sections[secndx+1]->get_name().c_str(); -#if 1 if (strcmp(".gcc_except_table",p)!=0) { cout<<"Did not find .gcc_except_table immediately after .eh_frame\n"; @@ -909,32 +904,15 @@ void read_ehframe(FileIR_t* virp, EXEIO::exeio* exeiop) (elfiop->sections[eh_frame_index+1]->get_address()+ elfiop->sections[eh_frame_index+1]->get_size() ) - (uintptr_t)eh_frame_addr; } -#else - total_size=elfiop->sections[eh_frame_index]->get_size()+1; -#endif eh_frame_data_total_size=total_size; -#if 0 - // collect eh_frame and gcc_except_table into one memory region - eh_frame_data=(char*)calloc(1,total_size); - memcpy(eh_frame_data,elfiop->sections[eh_frame_index]->get_data(), - elfiop->sections[eh_frame_index]->get_size()); - - if (strcmp(".gcc_except_table",p)==0) - { - memcpy(eh_frame_data+elfiop->sections[eh_frame_index]->get_size(), - elfiop->sections[eh_frame_index+1]->get_data(), - elfiop->sections[eh_frame_index+1]->get_size()); - } -#else // calc the size needed to safely walk the EH frame data. apparently walking assumes a null value in memory // after the section is loaded (or properly using eh_frame_hdr, which we aren't doing) //eh_frame_data=(char*)elfiop->sections[eh_frame_index]->get_data(); int newsize=elfiop->sections[eh_frame_index]->get_size()+4; eh_frame_data=(char*)calloc(1,newsize); memcpy(eh_frame_data, (void*)elfiop->sections[eh_frame_index]->get_data(), elfiop->sections[eh_frame_index]->get_size()); -#endif uintptr_t offset; // careful with offset and eh_offset as it can only be used for eh_frame_data offsetting, not offsetting into other addrs. @@ -943,7 +921,6 @@ void read_ehframe(FileIR_t* virp, EXEIO::exeio* exeiop) struct object ob; register_frame_info( eh_frame_data, &ob); -//classify_object_over_fdes (struct object *ob, fde *this_fde) classify_object_over_fdes(&ob,ob.u.single); linear_search_fdes (&ob,ob.u.single,offset); diff --git a/libIRDB/test/read_variantir.cpp b/ir_builders/read_variantir.cpp similarity index 100% rename from libIRDB/test/read_variantir.cpp rename to ir_builders/read_variantir.cpp diff --git a/libIRDB/test/rename_function.cpp b/ir_builders/rename_function.cpp similarity index 100% rename from libIRDB/test/rename_function.cpp rename to ir_builders/rename_function.cpp diff --git a/libIRDB/test/split_eh_frame.cpp b/ir_builders/split_eh_frame.cpp similarity index 68% rename from libIRDB/test/split_eh_frame.cpp rename to ir_builders/split_eh_frame.cpp index 1da5b084de78b3948876e7bdbae411263802219e..b1c96c7e2d0a9350c6cea8e8f2008eae0a2b816b 100644 --- a/libIRDB/test/split_eh_frame.cpp +++ b/ir_builders/split_eh_frame.cpp @@ -1,4 +1,4 @@ -#include <libIRDB-core.hpp> +#include <irdb-core> #include <iostream> #include <iomanip> #include <fstream> @@ -20,16 +20,37 @@ using namespace std; using namespace EXEIO; -using namespace libIRDB; +using namespace IRDB_SDK; using namespace EHP; #define ALLOF(s) begin(s), end(s) + +struct EhProgramPlaceHolder_t +{ + uint8_t caf; + int8_t daf; + int8_t rr; + uint8_t ptrsize; // needed for interpreting programs + IRDB_SDK::EhProgramListing_t cie_program; + IRDB_SDK::EhProgramListing_t fde_program; + + //IRDB_SDK::EhProgramListing_t& getCIEProgram() { return cie_program; } + //IRDB_SDK::EhProgramListing_t& getFDEProgram() { return fde_program; } + const IRDB_SDK::EhProgramListing_t& getCIEProgram() const { return cie_program; } + const IRDB_SDK::EhProgramListing_t& getFDEProgram() const { return fde_program; } + uint8_t getCodeAlignmentFactor() const { return caf; } + int8_t getDataAlignmentFactor() const { return daf; } + int8_t getReturnRegNumber() const { return rr; } + uint8_t getPointerSize() const { return ptrsize; } + +}; + template <int ptrsize> bool split_eh_frame_impl_t<ptrsize>::lsda_call_site_appliesTo(const LSDACallSite_t& cs, const Instruction_t* insn) const { - assert(insn && insn->GetAddress()); - auto insn_addr=insn->GetAddress()->GetVirtualOffset(); + assert(insn && insn->getAddress()); + auto insn_addr=insn->getAddress()->getVirtualOffset(); const auto call_site_addr=cs.getCallSiteAddress(); const auto call_site_end_addr=cs.getCallSiteEndAddress(); @@ -54,20 +75,18 @@ void split_eh_frame_impl_t<ptrsize>::lsda_call_site_build_ir assert(lsda_call_site_appliesTo(cs,insn)); // find landing pad instruction. - auto lp_insn=(Instruction_t*)NULL; + auto lp_insn=(IRDB_SDK::Instruction_t*)NULL; auto lp_it=om.find(landing_pad_addr); if(lp_it!=om.end()) lp_insn=lp_it->second; // create the callsite. - auto new_ehcs = new EhCallSite_t(BaseObj_t::NOT_IN_DATABASE, tt_encoding, lp_insn); - firp->GetAllEhCallSites().insert(new_ehcs); - insn->SetEhCallSite(new_ehcs); + auto new_ehcs = firp->addEhCallSite_t(insn, tt_encoding, lp_insn); //cout<<"landing pad addr : 0x"<<hex<<landing_pad_addr<<endl; if(action_table.size() == 0 ) { - new_ehcs->SetHasCleanup(); + new_ehcs->setHasCleanup(); // cout<<"Destructors to call, but no exceptions to catch"<<endl; } else @@ -77,12 +96,17 @@ void split_eh_frame_impl_t<ptrsize>::lsda_call_site_build_ir const auto action=p->getAction(); if(action==0) { - new_ehcs->GetTTOrderVector().push_back(action); + auto new_ttov=new_ehcs->getTTOrderVector(); + new_ttov.push_back(action); + new_ehcs->setTTOrderVector(new_ttov); //cout<<"Cleanup only (no catches) ."<<endl; } else if(action>0) { - new_ehcs->GetTTOrderVector().push_back(action); + auto new_ttov=new_ehcs->getTTOrderVector(); + new_ttov.push_back(action); + new_ehcs->setTTOrderVector(new_ttov); + // new_ehcs->getTTOrderVector().push_back(action); const auto index=action - 1; //cout<<"Catch for type: "; // the type table reveral was done during parsing, type table is right-side-up now. @@ -90,21 +114,25 @@ void split_eh_frame_impl_t<ptrsize>::lsda_call_site_build_ir auto wrt=(DataScoop_t*)NULL; if(type_table.at(index)->getTypeInfoPointer()!=0) { - wrt=firp->FindScoop(type_table.at(index)->getTypeInfoPointer()); + wrt=firp->findScoop(type_table.at(index)->getTypeInfoPointer()); assert(wrt); } const auto offset=index*type_table.at(index)->getTTEncodingSize(); auto addend=0; if(wrt!=NULL) - addend=type_table.at(index)->getTypeInfoPointer()-wrt->GetStart()->GetVirtualOffset(); + addend=type_table.at(index)->getTypeInfoPointer()-wrt->getStart()->getVirtualOffset(); + /* auto newreloc=new Relocation_t(BaseObj_t::NOT_IN_DATABASE, offset, "type_table_entry", wrt, addend); - new_ehcs->GetRelocations().insert(newreloc); - firp->GetRelocations().insert(newreloc); + new_ehcs->getRelocations().insert(newreloc); + firp->getRelocations().insert(newreloc); + */ + auto newreloc=firp->addNewRelocation(new_ehcs,offset, "type_table_entry", wrt, addend); + (void)newreloc; // just give it to the ir //if(wrt==NULL) // cout<<"Catch all in type table"<<endl; //else - // cout<<"Catch for type at "<<wrt->GetName()<<"+0x"<<hex<<addend<<"."<<endl; + // cout<<"Catch for type at "<<wrt->getName()<<"+0x"<<hex<<addend<<"."<<endl; } else if(action<0) { @@ -117,7 +145,7 @@ void split_eh_frame_impl_t<ptrsize>::lsda_call_site_build_ir } // this isn't right at all, but pretend it's a cleanup! - new_ehcs->SetHasCleanup(); + new_ehcs->setHasCleanup(); //cout<<"Cleanup only (no catches) ."<<endl; } else @@ -156,8 +184,8 @@ void split_eh_frame_impl_t<ptrsize>::lsda_build_ir(const LSDA_t& lsda, Instructi template <int ptrsize> bool split_eh_frame_impl_t<ptrsize>::fde_contents_appliesTo(const FDEContents_t& fde, const Instruction_t* insn) const { - assert(insn && insn->GetAddress()); - auto insn_addr=insn->GetAddress()->GetVirtualOffset(); + assert(insn && insn->getAddress()); + auto insn_addr=insn->getAddress()->getVirtualOffset(); const auto fde_start_addr=fde.getStartAddress(); const auto fde_end_addr=fde.getEndAddress(); return ( fde_start_addr<=insn_addr && insn_addr<fde_end_addr ); @@ -173,7 +201,7 @@ void split_eh_frame_impl_t<ptrsize>::fde_contents_build_ir(const FDEContents_t& const auto lsda_addr=fde.getLSDAAddress(); // assert this is the right FDE. - assert( fde_start_addr<= insn->GetAddress()->GetVirtualOffset() && insn->GetAddress()->GetVirtualOffset() <= fde_end_addr); + assert( fde_start_addr<= insn->getAddress()->getVirtualOffset() && insn->getAddress()->getVirtualOffset() <= fde_end_addr); //eh_pgm.print(fde_start_addr); if(lsda_addr!=0) @@ -183,10 +211,9 @@ void split_eh_frame_impl_t<ptrsize>::fde_contents_build_ir(const FDEContents_t& template <int ptrsize> bool split_eh_frame_impl_t<ptrsize>::init_offset_map() { - //for_each(firp->GetInstructions().begin(), firp->GetInstructions().end(), [&](Instruction_t* i) - for(const auto i : firp->GetInstructions()) + for(const auto i : firp->getInstructions()) { - offset_to_insn_map[i->GetAddress()->GetVirtualOffset()]=i; + offset_to_insn_map[i->getAddress()->getVirtualOffset()]=i; }; return false; } @@ -198,27 +225,28 @@ void split_eh_frame_impl_t<ptrsize>::build_ir() const class whole_pgm_t { public: - whole_pgm_t(EhProgram_t* _pgm, uint64_t _personality) - : hashcode(hashPgm(_pgm)), pgm(_pgm), personality(_personality) + whole_pgm_t(EhProgramPlaceHolder_t& _pgm, EhProgram_t* cp, uint64_t _personality) + : hashcode(hashPgm(_pgm)), pgm(_pgm), cached_pgm(cp), personality(_personality) { } - EhProgram_t* getProgram() const { return pgm; } + void setCachedProgram(EhProgram_t* cp) { cached_pgm=cp; } + EhProgram_t* getCachedProgram() const { return cached_pgm; } uint64_t getPersonality() const { return personality; } private: - static uint64_t hashPgm(const EhProgram_t* vec) + static uint64_t hashPgm(const EhProgramPlaceHolder_t& vec) { - assert(vec); - auto seed = vec->GetCIEProgram().size() + vec->GetFDEProgram().size(); + auto seed = vec.getCIEProgram().size() + vec.getFDEProgram().size(); auto hash_fn=hash<string>(); - for(const auto& i : vec->GetCIEProgram()) + for(const auto& i : vec.getCIEProgram()) seed ^= hash_fn(i) + 0x9e3779b9 + (seed << 6) + (seed >> 2); - for(const auto& i : vec->GetFDEProgram()) + for(const auto& i : vec.getFDEProgram()) seed ^= hash_fn(i) + 0x9e3779b9 + (seed << 6) + (seed >> 2); return seed; }; uint64_t hashcode; - EhProgram_t* pgm; + EhProgramPlaceHolder_t pgm; + EhProgram_t* cached_pgm; uint64_t personality; friend struct EhProgramComparator_t; @@ -232,27 +260,27 @@ void split_eh_frame_impl_t<ptrsize>::build_ir() const { bool operator() (const whole_pgm_t& lhs, const whole_pgm_t& rhs) { - const auto &a=*(lhs.pgm); - const auto &b=*(rhs.pgm); + const auto &a=(lhs.pgm); + const auto &b=(rhs.pgm); if(lhs.hashcode == rhs.hashcode) return make_tuple( - a.GetCIEProgram(), - a.GetFDEProgram(), - a.GetCodeAlignmentFactor(), - a.GetDataAlignmentFactor(), - a.GetReturnRegNumber(), - a.GetPointerSize(), + a.getCIEProgram(), + a.getFDEProgram(), + a.getCodeAlignmentFactor(), + a.getDataAlignmentFactor(), + a.getReturnRegNumber(), + a.getPointerSize(), lhs.personality ) < make_tuple( - b.GetCIEProgram(), - b.GetFDEProgram(), - b.GetCodeAlignmentFactor(), - b.GetDataAlignmentFactor(), - b.GetReturnRegNumber(), - b.GetPointerSize(), + b.getCIEProgram(), + b.getFDEProgram(), + b.getCodeAlignmentFactor(), + b.getDataAlignmentFactor(), + b.getReturnRegNumber(), + b.getPointerSize(), rhs.personality ); else @@ -268,17 +296,7 @@ void split_eh_frame_impl_t<ptrsize>::build_ir() const // find the right cie and fde, and build the IR from those for this instruction. auto build_ir_insn=[&](Instruction_t* insn) -> void { - /* - const auto tofind=fde_contents_t<ptrsize>( insn->GetAddress()->GetVirtualOffset(), insn->GetAddress()->GetVirtualOffset()+1 ); - const auto fie_it=fdes.find(tofind); - */ - const auto find_addr=insn->GetAddress()->GetVirtualOffset(); - /* - too slow - const auto finder=[&](const shared_ptr<FDEContents_t>& fde) -> bool - { return fde->getStartAddress() <= find_addr && find_addr < fde->getEndAddress(); }; - const auto fie_ptr_it=find_if ( ALLOF(*fdes), finder); - */ + const auto find_addr=insn->getAddress()->getVirtualOffset(); static auto fie_ptr=shared_ptr<FDEContents_t>(); static auto cie_instructions=shared_ptr<EHProgramInstructionVector_t>(); static auto fde_instructions=shared_ptr<EHProgramInstructionVector_t>(); @@ -303,18 +321,17 @@ void split_eh_frame_impl_t<ptrsize>::build_ir() const if(getenv("EHIR_VERBOSE")!=NULL) { - cout<<hex<<insn->GetAddress()->GetVirtualOffset()<<":" - <<insn->GetBaseID()<<":"<<insn->getDisassembly()<<" -> "<<endl; - //fie_it->GetCIE().print(); + cout<<hex<<insn->getAddress()->getVirtualOffset()<<":" + <<insn->getBaseID()<<":"<<insn->getDisassembly()<<" -> "<<endl; fie_ptr->print(); } const auto fde_addr=fie_ptr->getStartAddress(); - const auto caf=fie_ptr->getCIE().getCAF(); - const auto daf=fie_ptr->getCIE().getDAF(); - const auto return_reg=fie_ptr->getCIE().getReturnRegister(); + const auto caf=(uint8_t)fie_ptr->getCIE().getCAF(); + const auto daf=(int8_t)fie_ptr->getCIE().getDAF(); + const auto return_reg=(int8_t)fie_ptr->getCIE().getReturnRegister(); const auto personality=fie_ptr->getCIE().getPersonality(); - const auto insn_addr=insn->GetAddress()->GetVirtualOffset(); + const auto insn_addr=insn->getAddress()->getVirtualOffset(); auto import_pgm = [&](EhProgramListing_t& out_pgm_final, const shared_ptr<EHProgramInstructionVector_t> &in_pgm_instructions_ptr) -> void { @@ -354,8 +371,6 @@ void split_eh_frame_impl_t<ptrsize>::build_ir() const } else { - // string to_push(insn.GetBytes().begin(),insn.GetBytes().end()); - // out_pgm.push_back(to_push); out_pgm.push_back(insn_ptr); } @@ -372,21 +387,22 @@ void split_eh_frame_impl_t<ptrsize>::build_ir() const ); }; - // build an eh program on the stack; - auto ehpgm=EhProgram_t(BaseObj_t::NOT_IN_DATABASE,caf,daf,return_reg, ptrsize); - import_pgm(ehpgm.GetCIEProgram(), cie_instructions); - import_pgm(ehpgm.GetFDEProgram(), fde_instructions); + // build an eh program on the stack; + // + auto ehpgm=EhProgramPlaceHolder_t({caf,daf,return_reg, ptrsize, {}, {}}); + import_pgm(ehpgm.cie_program, cie_instructions); + import_pgm(ehpgm.fde_program, fde_instructions); - if(getenv("EHIR_VERBOSE")!=NULL) - ehpgm.print(); + //if(getenv("EHIR_VERBOSE")!=NULL) + // ehpgm.print(); // see if we've already built this one. - auto ehpgm_it = eh_program_cache.find(whole_pgm_t(&ehpgm, personality)) ; + auto ehpgm_it = eh_program_cache.find(whole_pgm_t(ehpgm, nullptr, personality)) ; if(ehpgm_it != eh_program_cache.end()) { // yes, use the cached program. - insn->SetEhProgram(ehpgm_it->getProgram()); + insn->setEhProgram(ehpgm_it->getCachedProgram()); if(getenv("EHIR_VERBOSE")!=NULL) cout<<"Re-using existing Program!"<<endl; reusedpgms++; @@ -398,19 +414,21 @@ void split_eh_frame_impl_t<ptrsize>::build_ir() const cout<<"Allocating new Program!"<<endl; // allocate a new pgm in the heap so we can give it to the IR. + /* auto newehpgm=new EhProgram_t(ehpgm); // copy constructor assert(newehpgm); - firp->GetAllEhPrograms().insert(newehpgm); + firp->getAllEhPrograms().insert(newehpgm); + insn->setEhProgram(newehpgm); + */ + auto newehpgm=firp->addEhProgram(insn, ehpgm.caf, ehpgm.daf,ehpgm.rr, ehpgm.ptrsize, ehpgm.cie_program, ehpgm.fde_program); // allocate a relocation for the personality and give it to the IR. - auto personality_scoop=firp->FindScoop(personality); + auto personality_scoop=firp->findScoop(personality); auto personality_insn_it=offset_to_insn_map.find(personality); auto personality_insn=personality_insn_it==offset_to_insn_map.end() ? (Instruction_t*)NULL : personality_insn_it->second; auto personality_obj = personality_scoop ? (BaseObj_t*)personality_scoop : (BaseObj_t*)personality_insn; - auto addend= personality_scoop ? personality - personality_scoop->GetStart()->GetVirtualOffset() : 0; - auto newreloc=new Relocation_t(BaseObj_t::NOT_IN_DATABASE, 0, "personality", personality_obj, addend); + auto addend= personality_scoop ? personality - personality_scoop->getStart()->getVirtualOffset() : 0; assert(personality==0 || personality_obj!=NULL); - assert(newreloc); if(personality_obj==NULL) { @@ -421,26 +439,28 @@ void split_eh_frame_impl_t<ptrsize>::build_ir() const { if(getenv("EHIR_VERBOSE")!=NULL) cout<<"Found personality scoop: 0x"<<hex<<personality<<" -> " - <<personality_scoop->GetName()<<"+0x"<<hex<<addend<<endl; + <<personality_scoop->getName()<<"+0x"<<hex<<addend<<endl; } else if(personality_insn) { if(getenv("EHIR_VERBOSE")!=NULL) cout<<"Found personality insn: 0x"<<hex<<personality<<" -> " - <<personality_insn->GetBaseID()<<":"<<personality_insn->getDisassembly()<<endl; + <<personality_insn->getBaseID()<<":"<<personality_insn->getDisassembly()<<endl; } else assert(0); - newehpgm->GetRelocations().insert(newreloc); - firp->GetRelocations().insert(newreloc); - - - // record for this insn - insn->SetEhProgram(newehpgm); + /* + auto newreloc=new Relocation_t(BaseObj_t::NOT_IN_DATABASE, 0, "personality", personality_obj, addend); + assert(newreloc); + newehpgm->getRelocations().insert(newreloc); + firp->getRelocations().insert(newreloc); + */ + auto newreloc=firp->addNewRelocation(newehpgm,0, "personality", personality_obj, addend); + (void)newreloc; // not used, just give it to the IR // update cache. - eh_program_cache.insert(whole_pgm_t(newehpgm,personality)); + eh_program_cache.insert( whole_pgm_t(ehpgm,newehpgm,personality)); } // build the IR from the FDE. @@ -450,25 +470,25 @@ void split_eh_frame_impl_t<ptrsize>::build_ir() const { if(getenv("EHIR_VERBOSE")!=NULL) { - cout<<hex<<insn->GetAddress()->GetVirtualOffset()<<":" - <<insn->GetBaseID()<<":"<<insn->getDisassembly()<<" has no FDE "<<endl; + cout<<hex<<insn->getAddress()->getVirtualOffset()<<":" + <<insn->getBaseID()<<":"<<insn->getDisassembly()<<" has no FDE "<<endl; } } }; - +#if 0 auto remove_reloc=[&](Relocation_t* r) -> void { - firp->GetRelocations().erase(r); + firp->getRelocations().erase(r); delete r; }; auto remove_address=[&](AddressID_t* a) -> void { - firp->GetAddresses().erase(a); - for(auto &r : a->GetRelocations()) remove_reloc(r); - for(auto &r : firp->GetRelocations()) assert(r->GetWRT() != a); + firp->getAddresses().erase(a); + for(auto &r : a->getRelocations()) remove_reloc(r); + for(auto &r : firp->getRelocations()) assert(r->getWRT() != a); delete a; }; @@ -476,48 +496,40 @@ void split_eh_frame_impl_t<ptrsize>::build_ir() const { if(s==NULL) return; - firp->GetDataScoops().erase(s); - remove_address(s->GetStart()); - remove_address(s->GetEnd()); - for(auto &r : s->GetRelocations()) remove_reloc(r); - for(auto &r : firp->GetRelocations()) assert(r->GetWRT() != s); + firp->getDataScoops().erase(s); + remove_address(s->getStart()); + remove_address(s->getEnd()); + for(auto &r : s->getRelocations()) remove_reloc(r); + for(auto &r : firp->getRelocations()) assert(r->getWRT() != s); delete s; }; +#endif - for(Instruction_t* i : firp->GetInstructions()) + for(Instruction_t* i : firp->getInstructions()) { build_ir_insn(i); } - cout<<"# ATTRIBUTE Split_Exception_Handler::total_eh_programs_created="<<dec<<firp->GetAllEhPrograms().size()<<endl; + cout<<"# ATTRIBUTE Split_Exception_Handler::total_eh_programs_created="<<dec<<firp->getAllEhPrograms().size()<<endl; cout<<"# ATTRIBUTE Split_Exception_Handler::total_eh_programs_reused="<<dec<<reusedpgms<<endl; - cout<<"# ATTRIBUTE Split_Exception_Handler::total_eh_programs="<<dec<<firp->GetAllEhPrograms().size()+reusedpgms<<endl; + cout<<"# ATTRIBUTE Split_Exception_Handler::total_eh_programs="<<dec<<firp->getAllEhPrograms().size()+reusedpgms<<endl; cout<<"# ATTRIBUTE Split_Exception_Handler::pct_eh_programs="<<std::fixed - <<((float)firp->GetAllEhPrograms().size()/((float)firp->GetAllEhPrograms().size()+reusedpgms))*100.00 + <<((float)firp->getAllEhPrograms().size()/((float)firp->getAllEhPrograms().size()+reusedpgms))*100.00 <<"%" <<endl; cout<<"# ATTRIBUTE Split_Exception_Handler::pct_eh_programs_reused="<<std::fixed - <<((float)reusedpgms/((float)firp->GetAllEhPrograms().size()+reusedpgms))*100.00 + <<((float)reusedpgms/((float)firp->getAllEhPrograms().size()+reusedpgms))*100.00 <<"%"<<endl; - remove_scoop(eh_frame_scoop); - remove_scoop(eh_frame_hdr_scoop); - remove_scoop(gcc_except_table_scoop); + firp->removeScoop(eh_frame_scoop); + firp->removeScoop(eh_frame_hdr_scoop); + firp->removeScoop(gcc_except_table_scoop); } template <int ptrsize> -libIRDB::Instruction_t* split_eh_frame_impl_t<ptrsize>::find_lp(libIRDB::Instruction_t* i) const +Instruction_t* split_eh_frame_impl_t<ptrsize>::find_lp(Instruction_t* i) const { - const auto find_addr=i->GetAddress()->GetVirtualOffset(); - //const auto tofind=fde_contents_t<ptrsize>( i->GetAddress()->GetVirtualOffset(), i->GetAddress()->GetVirtualOffset()+1); - //const auto fde_it=fdes.find(tofind); - /* too slow - const auto fde_ptr_it=find_if - ( - ALLOF(*fdes), - [&](const shared_ptr<FDEContents_t>& fde) { return fde->getStartAddress() <= find_addr && find_addr < fde->getEndAddress(); } - ); - */ + const auto find_addr=i->getAddress()->getVirtualOffset(); const auto fde_ptr=eh_frame_parser->findFDE(find_addr); if(fde_ptr==nullptr) @@ -566,21 +578,20 @@ split_eh_frame_impl_t<ptrsize>::split_eh_frame_impl_t(FileIR_t* p_firp) // function to find a scoop by name. auto lookup_scoop_by_name=[&](const string &the_name) -> DataScoop_t* { - //auto scoop_it=find_if(ALLOF(firp->GetDataScoops()), [the_name](DataScoop_t* scoop) const auto scoop_it=find_if( - firp->GetDataScoops().begin(), - firp->GetDataScoops().end(), + firp->getDataScoops().begin(), + firp->getDataScoops().end(), [the_name](DataScoop_t* scoop) { - return scoop->GetName()==the_name; + return scoop->getName()==the_name; }); - if(scoop_it!=firp->GetDataScoops().end()) + if(scoop_it!=firp->getDataScoops().end()) return *scoop_it; return NULL; }; - auto scoop_address=[&](const DataScoop_t* p) -> uint64_t { return p==NULL ? 0 : p->GetStart()->GetVirtualOffset(); }; - auto scoop_contents=[&](const DataScoop_t* p) -> string { return p==NULL ? "" : p->GetContents(); }; + auto scoop_address=[&](const DataScoop_t* p) -> uint64_t { return p==NULL ? 0 : p->getStart()->getVirtualOffset(); }; + auto scoop_contents=[&](const DataScoop_t* p) -> string { return p==NULL ? "" : p->getContents(); }; eh_frame_scoop=lookup_scoop_by_name(".eh_frame"); eh_frame_hdr_scoop=lookup_scoop_by_name(".eh_frame_hdr"); @@ -602,7 +613,7 @@ split_eh_frame_impl_t<ptrsize>::split_eh_frame_impl_t(FileIR_t* p_firp) unique_ptr<split_eh_frame_t> split_eh_frame_t::factory(FileIR_t *firp) { - if( firp->GetArchitectureBitWidth()==64) + if( firp->getArchitectureBitWidth()==64) return unique_ptr<split_eh_frame_t>(new split_eh_frame_impl_t<8>(firp)); else return unique_ptr<split_eh_frame_t>(new split_eh_frame_impl_t<4>(firp)); diff --git a/libIRDB/test/split_eh_frame.hpp b/ir_builders/split_eh_frame.hpp similarity index 62% rename from libIRDB/test/split_eh_frame.hpp rename to ir_builders/split_eh_frame.hpp index 0e0d69063ea5a7b7d050fd0afe8a722d52f19de8..2e1a2b08eb507eb17a802009b8033e6cb31d887f 100644 --- a/libIRDB/test/split_eh_frame.hpp +++ b/ir_builders/split_eh_frame.hpp @@ -1,7 +1,7 @@ #ifndef eh_frame_hpp #define eh_frame_hpp -#include <libIRDB-core.hpp> +#include <irdb-core> #include <iostream> #include <iomanip> #include <fstream> @@ -20,7 +20,7 @@ -using OffsetMap_t = std::map<libIRDB::virtual_offset_t, libIRDB::Instruction_t*>; +using OffsetMap_t = std::map<IRDB_SDK::VirtualOffset_t, IRDB_SDK::Instruction_t*>; class split_eh_frame_t { @@ -28,9 +28,9 @@ class split_eh_frame_t virtual void build_ir() const =0; virtual void print() const=0; - virtual libIRDB::Instruction_t* find_lp(libIRDB::Instruction_t*) const =0; + virtual IRDB_SDK::Instruction_t* find_lp(IRDB_SDK::Instruction_t*) const =0; - static std::unique_ptr<split_eh_frame_t> factory(libIRDB::FileIR_t *firp); + static std::unique_ptr<split_eh_frame_t> factory(IRDB_SDK::FileIR_t *firp); }; @@ -39,10 +39,10 @@ class split_eh_frame_impl_t : public split_eh_frame_t { private: - libIRDB::FileIR_t* firp; - libIRDB::DataScoop_t* eh_frame_scoop; - libIRDB::DataScoop_t* eh_frame_hdr_scoop; - libIRDB::DataScoop_t* gcc_except_table_scoop; + IRDB_SDK::FileIR_t* firp; + IRDB_SDK::DataScoop_t* eh_frame_scoop; + IRDB_SDK::DataScoop_t* eh_frame_hdr_scoop; + IRDB_SDK::DataScoop_t* gcc_except_table_scoop; OffsetMap_t offset_to_insn_map; std::unique_ptr<const EHP::EHFrameParser_t> eh_frame_parser; @@ -53,43 +53,43 @@ class split_eh_frame_impl_t : public split_eh_frame_t bool lsda_call_site_appliesTo ( const EHP::LSDACallSite_t& cs, - const libIRDB::Instruction_t* insn + const IRDB_SDK::Instruction_t* insn ) const; void lsda_call_site_build_ir ( const EHP::LSDACallSite_t& cs, - libIRDB::Instruction_t* insn, + IRDB_SDK::Instruction_t* insn, /* const std::vector<lsda_type_table_entry_t <ptrsize> > &*/ std::shared_ptr<EHP::TypeTableVector_t> type_table_ptr, const uint8_t& tt_encoding ) const; void lsda_build_ir ( const EHP::LSDA_t& lsda, - libIRDB::Instruction_t* insn + IRDB_SDK::Instruction_t* insn ) const; bool fde_contents_appliesTo ( const EHP::FDEContents_t& fde, - const libIRDB::Instruction_t* insn + const IRDB_SDK::Instruction_t* insn ) const; void fde_contents_build_ir ( const EHP::FDEContents_t& fde, - libIRDB::Instruction_t* insn + IRDB_SDK::Instruction_t* insn ) const; public: - split_eh_frame_impl_t(libIRDB::FileIR_t* p_firp); + split_eh_frame_impl_t(IRDB_SDK::FileIR_t* p_firp); void print() const; void build_ir() const; - libIRDB::Instruction_t* find_lp(libIRDB::Instruction_t*) const ; + IRDB_SDK::Instruction_t* find_lp(IRDB_SDK::Instruction_t*) const ; }; -void split_eh_frame(libIRDB::FileIR_t* firp); +void split_eh_frame(IRDB_SDK::FileIR_t* firp); #endif diff --git a/libIRDB/test/tests/ibtarget/Makefile b/ir_builders/tests/ibtarget/Makefile similarity index 100% rename from libIRDB/test/tests/ibtarget/Makefile rename to ir_builders/tests/ibtarget/Makefile diff --git a/libIRDB/test/tests/ibtarget/README b/ir_builders/tests/ibtarget/README similarity index 100% rename from libIRDB/test/tests/ibtarget/README rename to ir_builders/tests/ibtarget/README diff --git a/libIRDB/test/tests/ibtarget/icall.cpp b/ir_builders/tests/ibtarget/icall.cpp similarity index 100% rename from libIRDB/test/tests/ibtarget/icall.cpp rename to ir_builders/tests/ibtarget/icall.cpp diff --git a/libIRDB/test/tests/ibtarget/jmp.main.cpp b/ir_builders/tests/ibtarget/jmp.main.cpp similarity index 100% rename from libIRDB/test/tests/ibtarget/jmp.main.cpp rename to ir_builders/tests/ibtarget/jmp.main.cpp diff --git a/libIRDB/test/tests/ibtarget/jmp.shared.cpp b/ir_builders/tests/ibtarget/jmp.shared.cpp similarity index 100% rename from libIRDB/test/tests/ibtarget/jmp.shared.cpp rename to ir_builders/tests/ibtarget/jmp.shared.cpp diff --git a/libIRDB/test/tests/ibtarget/jmp1.cpp b/ir_builders/tests/ibtarget/jmp1.cpp similarity index 100% rename from libIRDB/test/tests/ibtarget/jmp1.cpp rename to ir_builders/tests/ibtarget/jmp1.cpp diff --git a/libIRDB/test/tests/ibtarget/jmp2.cpp b/ir_builders/tests/ibtarget/jmp2.cpp similarity index 100% rename from libIRDB/test/tests/ibtarget/jmp2.cpp rename to ir_builders/tests/ibtarget/jmp2.cpp diff --git a/libIRDB/test/tests/ibtarget/jmp2.shared.cpp b/ir_builders/tests/ibtarget/jmp2.shared.cpp similarity index 100% rename from libIRDB/test/tests/ibtarget/jmp2.shared.cpp rename to ir_builders/tests/ibtarget/jmp2.shared.cpp diff --git a/libIRDB/test/tests/ibtarget/validate_ibts.sh b/ir_builders/tests/ibtarget/validate_ibts.sh similarity index 100% rename from libIRDB/test/tests/ibtarget/validate_ibts.sh rename to ir_builders/tests/ibtarget/validate_ibts.sh diff --git a/libIRDB/test/unfix_calls.cpp b/ir_builders/unfix_calls.cpp similarity index 100% rename from libIRDB/test/unfix_calls.cpp rename to ir_builders/unfix_calls.cpp diff --git a/libIRDB/test/unwind-pe.h b/ir_builders/unwind-pe.h similarity index 100% rename from libIRDB/test/unwind-pe.h rename to ir_builders/unwind-pe.h diff --git a/libEXEIO/include/exeio.h b/libEXEIO/include/exeio.h index 1380e42ffb7c18b7d2cac44b13631b0ade75f171..f27c8556d7af114c2759766074643f751156ea5d 100644 --- a/libEXEIO/include/exeio.h +++ b/libEXEIO/include/exeio.h @@ -13,6 +13,7 @@ namespace EXEIO class exeio_t; // forward decl typedef enum { ELF64, ELF32, PE32, PE64 } execlass_t; + typedef enum { mtX86_64, mtI386, mtArm32, mtAarch64 } MachineType_t; typedef uintptr_t virtual_offset_t; @@ -31,6 +32,7 @@ namespace EXEIO virtual const char* get_data() const =0; virtual std::string get_name() const =0; virtual int get_size() const =0; + virtual int get_type() const =0; virtual EXEIO::virtual_offset_t get_address() const =0; virtual bool mightContainStrings() const =0; }; @@ -46,6 +48,7 @@ namespace EXEIO virtual void dump_section_headers(std::ostream& stream) =0; virtual void load(exeio_t* main, const char* filename) =0; 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 bool isDLL() =0; @@ -116,6 +119,7 @@ namespace EXEIO virtual void dump_header(std::ostream& stream) { assert(backend); backend->dump_header(stream); } 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 bool isDLL() { assert(backend); return backend->isDLL(); } virtual bool isDynamicallyLinked() { assert(backend); return backend->isDynamicallyLinked(); } diff --git a/libEXEIO/src/SConscript b/libEXEIO/src/SConscript index 413aadb3a346d28327d1af0621ae11c140aa024a..3a81a1b36c99bf204a68e16461c9c9633d0dc950 100644 --- a/libEXEIO/src/SConscript +++ b/libEXEIO/src/SConscript @@ -21,7 +21,7 @@ cpppath=''' myenv=myenv.Clone(CPPPATH=Split(cpppath)) myenv.Append(CXXFLAGS=" -std=c++11 -Wall -Werror ") -lib=myenv.SharedLibrary(libname, Split(files), LIBS=Split("IRDB-core pebliss"), LIBPATH="$SECURITY_TRANSFORMS_HOME/lib" ) +lib=myenv.SharedLibrary(libname, Split(files), LIBS=Split("irdb-core pebliss"), LIBPATH="$SECURITY_TRANSFORMS_HOME/lib" ) install=myenv.Install("$SECURITY_TRANSFORMS_HOME/lib/", lib) Default(install) diff --git a/libEXEIO/include/exeio_elf.h b/libEXEIO/src/exeio_elf.h similarity index 89% rename from libEXEIO/include/exeio_elf.h rename to libEXEIO/src/exeio_elf.h index 0b3dd175acb3c8b9cd5dd6889868e46412ecc7ef..cd2230b757b674a77aff6ab723d9ccdd1327a76d 100644 --- a/libEXEIO/include/exeio_elf.h +++ b/libEXEIO/src/exeio_elf.h @@ -5,17 +5,15 @@ #include <vector> #include <assert.h> - -// #include "targ-config.h" #pragma GCC diagnostic ignored "-Wsign-compare" #include "elfio/elfio.hpp" #include "elfio/elfio_dump.hpp" +#include "elf.h" #pragma GCC diagnostic pop class exeio_backend; class exeio_section; - namespace EXEIO { class exeio_elf_section_t : public exeio_section_t @@ -33,6 +31,7 @@ namespace EXEIO const char* get_data() const { return s->get_data(); } std::string get_name() const { return s->get_name(); } int get_size() const { return s->get_size(); } + int get_type() const { return s->get_type(); } EXEIO::virtual_offset_t get_address() const { return s->get_address(); } bool mightContainStrings() const { assert(0); } @@ -94,6 +93,19 @@ namespace EXEIO default: assert(0); }; } + virtual MachineType_t getMachineType() const + { + assert(e); + switch(e->get_machine()) + { + case EM_ARM : return mtArm32; + case EM_AARCH64 : return mtAarch64; + case EM_386 : return mtI386; + case EM_X86_64 : return mtX86_64; + default: assert(0); + } + assert(0); + } // get entry point of function. virtual virtual_offset_t get_entry() diff --git a/libEXEIO/include/exeio_pe.h b/libEXEIO/src/exeio_pe.h similarity index 97% rename from libEXEIO/include/exeio_pe.h rename to libEXEIO/src/exeio_pe.h index 78f78d619cc488de5f2976534e89dfba06ece386..868ddeec9e26f2bd578b7e81b12130baa2394b3f 100644 --- a/libEXEIO/include/exeio_pe.h +++ b/libEXEIO/src/exeio_pe.h @@ -32,6 +32,7 @@ namespace EXEIO const char* get_data() const { return s->get_raw_data().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 EXEIO::virtual_offset_t get_address() const { EXEIO::virtual_offset_t base = b->get_image_base_64(); return base + s->get_virtual_address(); @@ -129,6 +130,11 @@ namespace EXEIO } } + virtual MachineType_t getMachineType() const + { + assert(0); + } + virtual execlass_t get_class() { assert(e); diff --git a/libIRDB-cfg/include/BasicBlock.hpp b/libIRDB-cfg/include/BasicBlock.hpp new file mode 100644 index 0000000000000000000000000000000000000000..d2059b22eca8bf27a7df1c8991de15116ede1822 --- /dev/null +++ b/libIRDB-cfg/include/BasicBlock.hpp @@ -0,0 +1,75 @@ +/* + * Copyright (c) 2014 - Zephyr Software LLC + * + * This file may be used and modified for non-commercial purposes as long as + * all copyright, permission, and nonwarranty notices are preserved. + * Redistribution is prohibited without prior written consent from Zephyr + * Software. + * + * Please contact the authors for restrictions applying to commercial use. + * + * THIS SOURCE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * Author: Zephyr Software + * e-mail: jwd@zephyr-software.com + * URL : http://www.zephyr-software.com/ + * + */ + + +namespace libIRDB +{ + using namespace std; + + class BasicBlock_t : public IRDB_SDK::BasicBlock_t + { + + public: + BasicBlock_t(); + virtual ~BasicBlock_t() { } + + bool getIsExitBlock() const { return is_exit_block; } + void setIsExitBlock(bool is_exit) { is_exit_block=is_exit; } + + IRDB_SDK::InstructionVector_t& GetInstructions() { return instructions; } + IRDB_SDK::BasicBlockSet_t& GetPredecessors() { return predecessors; } + IRDB_SDK::BasicBlockSet_t& GetSuccessors() { return successors; } + IRDB_SDK::BasicBlockSet_t& GetIndirectTargets() { return indirect_targets; } + + // for const correctness if you aren't modifying. + const IRDB_SDK::InstructionVector_t& getInstructions() const { return instructions; } + const IRDB_SDK::BasicBlockSet_t& getPredecessors() const { return predecessors; } + const IRDB_SDK::BasicBlockSet_t& getSuccessors() const { return successors; } + const IRDB_SDK::BasicBlockSet_t& getIndirectTargets() const { return indirect_targets; } +// IRDB_SDK::BasicBlock_t * getFallthrough() const ; +// IRDB_SDK::BasicBlock_t * getTarget() const ; + + bool endsInBranch() const; + bool endsInIndirectBranch() const; + bool endsInConditionalBranch() const; + IRDB_SDK::Instruction_t* getBranchInstruction() const; + void dump(ostream &os=cout) const ; + + protected: + + void BuildBlock( IRDB_SDK::Instruction_t* insn, + const map<IRDB_SDK::Instruction_t*,BasicBlock_t*> &insn2block_map + ); + + + private: + + IRDB_SDK::InstructionVector_t instructions; + IRDB_SDK::BasicBlockSet_t predecessors; + IRDB_SDK::BasicBlockSet_t successors; + IRDB_SDK::BasicBlockSet_t indirect_targets; + bool is_exit_block; + + friend ostream& operator<<(ostream& os, const BasicBlock_t& block); + friend class ControlFlowGraph_t; + }; + + +} diff --git a/libIRDB-cfg/include/CFG.hpp b/libIRDB-cfg/include/CFG.hpp new file mode 100644 index 0000000000000000000000000000000000000000..2499b994eea66f87fe85f49cd85dffaaa056489e --- /dev/null +++ b/libIRDB-cfg/include/CFG.hpp @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2014 - Zephyr Software LLC + * + * This file may be used and modified for non-commercial purposes as long as + * all copyright, permission, and nonwarranty notices are preserved. + * Redistribution is prohibited without prior written consent from Zephyr + * Software. + * + * Please contact the authors for restrictions applying to commercial use. + * + * THIS SOURCE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * Author: Zephyr Software + * e-mail: jwd@zephyr-software.com + * URL : http://www.zephyr-software.com/ + * + */ + +namespace libIRDB +{ + using namespace std; + + class ControlFlowGraph_t : public IRDB_SDK::ControlFlowGraph_t + { + public: + ControlFlowGraph_t(IRDB_SDK::Function_t* func); + virtual ~ControlFlowGraph_t() { } + IRDB_SDK::BasicBlock_t* getEntry() const { return entry; } + IRDB_SDK::Function_t* getFunction() const { return function; } + IRDB_SDK::BasicBlockSet_t& GetBlocks() { return blocks; } + const IRDB_SDK::BasicBlockSet_t& getBlocks() const { return blocks; } + void dump(ostream &os=cout) const; + bool hasEdge(IRDB_SDK::BasicBlock_t *p_src, IRDB_SDK::BasicBlock_t *p_tgt) const; + IRDB_SDK::CFGEdgeType_t getEdgeType(const IRDB_SDK::BasicBlock_t *p_src, const IRDB_SDK::BasicBlock_t *p_tgt) const; + + private: + // methods + void Build(IRDB_SDK::Function_t *func); + void alloc_blocks(const IRDB_SDK::InstructionSet_t &starts, map<IRDB_SDK::Instruction_t*,BasicBlock_t*>& insn2block_map); + void build_blocks(const map<IRDB_SDK::Instruction_t*,BasicBlock_t*>& insn2block_map); + void find_unblocked_instructions(InstructionSet_t &starts, IRDB_SDK::Function_t* func); + + // data + IRDB_SDK::BasicBlockSet_t blocks; + IRDB_SDK::BasicBlock_t* entry; + IRDB_SDK::Function_t* function; + + }; + +} diff --git a/libIRDB-cfg/include/callgraph.hpp b/libIRDB-cfg/include/callgraph.hpp new file mode 100644 index 0000000000000000000000000000000000000000..bc5f383923e2e686c9c08325aa175a7b008db8b4 --- /dev/null +++ b/libIRDB-cfg/include/callgraph.hpp @@ -0,0 +1,189 @@ +/* + * Copyright (c) 2014-2015 - Zephyr Software LLC + * + * This file may be used and modified for non-commercial purposes as long as + * all copyright, permission, and nonwarranty notices are preserved. + * Redistribution is prohibited without prior written consent from Zephyr + * Software. + * + * Please contact the authors for restrictions applying to commercial use. + * + * THIS SOURCE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * Author: Zephyr Software + * e-mail: jwd@zephyr-software.com + * URL : http://www.zephyr-software.com/ + * + */ + +#ifndef irdb_cfg_callgraph_h +#define irdb_cfg_callgraph_h + +namespace libIRDB +{ + + using namespace std; + + // only one type of hell node for now, but leave + // open the possibilty for multiple hell nodes + typedef enum { DEFAULT_HELL_NODE = 0 } HellNodeType; + + class CallGraphNode_t : public IRDB_SDK::CallGraphNode_t + { + public: + virtual ~CallGraphNode_t(){ } + CallGraphNode_t(IRDB_SDK::Function_t* f = NULL) { + if (f) { + SetFunction(f); + } else { + m_isHellNode = true; + m_node.hellNodeType = DEFAULT_HELL_NODE; + } + } + + bool isHellnode() const { return m_isHellNode; } + + IRDB_SDK::Function_t* getFunction() const { + assert(!m_isHellNode); + if (m_isHellNode) + return NULL; + else + return m_node.func; + } + + HellNodeType GetHellNodeType() const { + assert(m_isHellNode); + return m_node.hellNodeType; + } + + bool operator==(const CallGraphNode_t &other) const { + if (this == &other) return true; + if (m_isHellNode) + { + return m_node.hellNodeType == other.m_node.hellNodeType; + } + else + return m_node.func == other.m_node.func; + } + void dump(ostream& os=cout) const; + + private: + void SetFunction(IRDB_SDK::Function_t* const f) { + assert(f); + m_node.func = f; + m_isHellNode = false; + } + + private: + bool m_isHellNode; + union { + IRDB_SDK::Function_t* func; + HellNodeType hellNodeType; + } m_node; + }; + + + class Callgraph_t : public IRDB_SDK::CallGraph_t + { + public: + Callgraph_t(); + virtual ~Callgraph_t(); + void addFile(IRDB_SDK::FileIR_t* const firp); + + bool edgeExists(const IRDB_SDK::CallGraphEdge_t& edge) const + { + const auto from = dynamic_cast<CallGraphNode_t*>(edge.first); + const auto to = dynamic_cast<CallGraphNode_t*>(edge.second); + + const auto caller_it = callers.find(from); + if(caller_it==callers.end()) + return false; + + const auto &calleeSet = caller_it->second; + return calleeSet.find(to)!=calleeSet.end(); + } + bool edgeExists(IRDB_SDK::CallGraphNode_t& n1, IRDB_SDK::CallGraphNode_t& n2) const + { return edgeExists(IRDB_SDK::CallGraphEdge_t(&n1,&n2));} + + IRDB_SDK::CallGraphNodeSet_t& GetCallersOfNode(IRDB_SDK::CallGraphNode_t* const node) + { return callers[node]; } + IRDB_SDK::CallGraphNodeSet_t& GetCalleesOfNode(IRDB_SDK::CallGraphNode_t* const node) + { return callees[node]; } + + const IRDB_SDK::CallGraphNodeSet_t& getCallersOfNode(IRDB_SDK::CallGraphNode_t* const node) const + { + static const auto empty = IRDB_SDK::CallGraphNodeSet_t(); + const auto it=callers.find(node); + return (it==callers.end()) ? empty : it->second; + } + const IRDB_SDK::CallGraphNodeSet_t& getCalleesOfNode(IRDB_SDK::CallGraphNode_t* const node) const + { + static const auto empty = IRDB_SDK::CallGraphNodeSet_t(); + const auto it=callees.find(node); + return (it==callees.end()) ? empty : it->second; + } + + void GetAncestors(IRDB_SDK::Function_t* const fn, IRDB_SDK::CallGraphNodeSet_t& ancestors, bool skipHellNode = false) const; + void GetAncestors(IRDB_SDK::CallGraphNode_t* const node, IRDB_SDK::CallGraphNodeSet_t& ancestors, bool skipHellNode = false) const; + + const IRDB_SDK::CallSiteSet_t& GetCallSites(IRDB_SDK::CallGraphNode_t* const n1) const + { + static const auto empty = IRDB_SDK::CallSiteSet_t(); + const auto it=call_sites.find(n1); + return (it==call_sites.end()) ? empty : it->second; + } + + + IRDB_SDK::CallSiteSet_t& getCallSites(IRDB_SDK::CallGraphNode_t* const n1) + { return call_sites[n1]; } + + void dump(ostream& fout) const; + + string GetNodeName(const IRDB_SDK::CallGraphNode_t* const p_n1) const { + auto n1=dynamic_cast<CallGraphNode_t const*>(p_n1); + assert(n1); + if (n1->isHellnode()) { + ostringstream s; + s << "HELLNODE" << n1->GetHellNodeType(); + return s.str(); + } else { + assert(n1->getFunction()); + return n1->getFunction()->getName(); + } + } + + string GetCallsiteDisassembly(const IRDB_SDK::CallSite_t &c) const + { return c ? c->getDisassembly() : "NOFROMFUNC"; } + + bool isReachable(IRDB_SDK::CallGraphNode_t* const from, IRDB_SDK::CallGraphNode_t* const to, bool skipHellNode = false) const; + + CallGraphNode_t& GetDefaultHellNode() { return default_hellnode; } + const CallGraphNode_t& getDefaultHellNode() const { return default_hellnode; } + + IRDB_SDK::CallGraphNode_t* findNode(IRDB_SDK::Function_t* const fn) const; + + private: + // create nodes from functions + void CreateNodes(IRDB_SDK::FileIR_t *firp); + + // mark the given insn as a call site. + void MarkCallSite(IRDB_SDK::Instruction_t* const insn); + + // traverse graph to retrieve all ancestors + void _GetAncestors(IRDB_SDK::CallGraphNode_t* const node, IRDB_SDK::CallGraphNodeSet_t &ancestors, IRDB_SDK::CallGraphNodeSet_t &visited, bool skipHellNode) const; + + using CGNodeToCGNodeSetMap_t = map<IRDB_SDK::CallGraphNode_t*, IRDB_SDK::CallGraphNodeSet_t > ; + using NodeToCallSiteSetMap_t = map<IRDB_SDK::CallGraphNode_t*, IRDB_SDK::CallSiteSet_t > ; + using FunctionToCGNodeMap_t = map<IRDB_SDK::Function_t* , IRDB_SDK::CallGraphNode_t* > ; +; + CGNodeToCGNodeSetMap_t callers; // map a callee to its callees + CGNodeToCGNodeSetMap_t callees; // map a caller to its callers + NodeToCallSiteSetMap_t call_sites; + CallGraphNode_t default_hellnode; // default hell node + FunctionToCGNodeMap_t nodes; // maps functions to call graph nodes + }; + +} +#endif diff --git a/libIRDB/include/core/archdesc.hpp b/libIRDB-cfg/include/criticaledge.hpp similarity index 54% rename from libIRDB/include/core/archdesc.hpp rename to libIRDB-cfg/include/criticaledge.hpp index 89c2b40e1cffaf993d97682377516fd1640f1fe6..244e68347ab77f4e565bb300fc98e8a6b4e81911 100644 --- a/libIRDB/include/core/archdesc.hpp +++ b/libIRDB-cfg/include/criticaledge.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014 - Zephyr Software LLC + * Copyright (c) 2019 - Zephyr Software LLC * * This file may be used and modified for non-commercial purposes as long as * all copyright, permission, and nonwarranty notices are preserved. @@ -18,24 +18,22 @@ * */ - -enum AD_FileType_t { AD_ELF, AD_CGC, AD_PE }; - -class ArchitectureDescription_t +namespace libIRDB { - public: - - ArchitectureDescription_t() : bits(0) {} - - int GetBitWidth() { return bits; } - void SetBitWidth(int _bits) { bits=_bits; } - - AD_FileType_t GetFileType() { return ft; } - void SetFileType(AD_FileType_t t) { ft=t; } - - private: - - int bits; - AD_FileType_t ft; -}; - + using namespace std; + + class CriticalEdgeAnalyzer_t : public IRDB_SDK::CriticalEdges_t + { + public: + CriticalEdgeAnalyzer_t(const ControlFlowGraph_t *p_cfg, const bool p_conservative=true); + virtual ~CriticalEdgeAnalyzer_t() { } + const IRDB_SDK::BasicBlockEdgeSet_t& getAllCriticalEdges() const { return criticals; } + + private: + void init(); + const IRDB_SDK::ControlFlowGraph_t *m_cfg; + const bool m_conservative; + IRDB_SDK::BasicBlockEdgeSet_t criticals; + + }; +} diff --git a/libIRDB-cfg/include/domgraph.hpp b/libIRDB-cfg/include/domgraph.hpp new file mode 100644 index 0000000000000000000000000000000000000000..932a34475e59e7044cffb485dcca828bc87a6f43 --- /dev/null +++ b/libIRDB-cfg/include/domgraph.hpp @@ -0,0 +1,61 @@ +#include <ostream> +namespace libIRDB +{ + using namespace std; + + using DominatorMap_t = map<const IRDB_SDK::BasicBlock_t*, IRDB_SDK::BasicBlockSet_t>; + using BlockToBlockMap_t = map<const IRDB_SDK::BasicBlock_t*, IRDB_SDK::BasicBlock_t*>; + + + + + + class DominatorGraph_t : public IRDB_SDK::DominatorGraph_t + { + public: + DominatorGraph_t(const ControlFlowGraph_t* p_cfg, bool needs_postdoms=false, bool needs_idoms=false); + virtual ~DominatorGraph_t() { } + + + // get the (post) dominators for a node + IRDB_SDK::BasicBlockSet_t& GetDominators(const IRDB_SDK::BasicBlock_t* node) { return dom_graph[node]; } + IRDB_SDK::BasicBlockSet_t& GetPostDominators(const IRDB_SDK::BasicBlock_t* node) { return post_dom_graph[node]; } + + const IRDB_SDK::BasicBlockSet_t& getDominators(const IRDB_SDK::BasicBlock_t* node) const { return dom_graph.at(node); } + const IRDB_SDK::BasicBlockSet_t& getPostDominators(const IRDB_SDK::BasicBlock_t* node) const { return post_dom_graph.at(node); } + + bool hasWarnings() const { return warn; } + + + // get the immeidate (post) dominators for a node + const IRDB_SDK::BasicBlock_t* getImmediateDominator(const IRDB_SDK::BasicBlock_t* node) const + { auto it=idom_graph.find(node); return (it!=idom_graph.end()) ? it->second : NULL; } + const IRDB_SDK::BasicBlock_t* getImmediatePostDominators(const IRDB_SDK::BasicBlock_t* node) const + { auto it=post_idom_graph.find(node); return (it!=post_idom_graph.end()) ? it->second : NULL; } + + void dump(ostream& os=cout) const; + + + private: + + typedef const IRDB_SDK::BasicBlockSet_t& (*pred_func_ptr_t) (const IRDB_SDK::BasicBlock_t* node); + + DominatorMap_t Dom_Comp(const IRDB_SDK::BasicBlockSet_t& N, pred_func_ptr_t pred_func, IRDB_SDK::BasicBlock_t* r); + BlockToBlockMap_t Idom_Comp(const IRDB_SDK::BasicBlockSet_t& N, const DominatorMap_t &Domin, IRDB_SDK::BasicBlock_t* r); + + + DominatorMap_t dom_graph; + BlockToBlockMap_t idom_graph; + + DominatorMap_t post_dom_graph; + BlockToBlockMap_t post_idom_graph; + + const ControlFlowGraph_t& cfg; // a reference to our cfg. + + bool warn; + + }; + + + +} diff --git a/libIRDB/include/libIRDB-cfg.hpp b/libIRDB-cfg/include/libIRDB-cfg.hpp similarity index 86% rename from libIRDB/include/libIRDB-cfg.hpp rename to libIRDB-cfg/include/libIRDB-cfg.hpp index 1a720ec614c5b281ceaef0efe3230d37c8fda04e..003113796c76bed60fd626b097b7ad11b00bef7d 100644 --- a/libIRDB/include/libIRDB-cfg.hpp +++ b/libIRDB-cfg/include/libIRDB-cfg.hpp @@ -23,6 +23,7 @@ /* Building a CFG depends on core functionality */ +#include <irdb-cfg> #include <libIRDB-core.hpp> #include <vector> @@ -30,14 +31,11 @@ #include <map> #include <ostream> -namespace libIRDB -{ +#include <BasicBlock.hpp> +#include <CFG.hpp> +#include <callgraph.hpp> +#include <domgraph.hpp> +#include <criticaledge.hpp> -#include <cfg/BasicBlock.hpp> -#include <cfg/CFG.hpp> -#include <cfg/callgraph.hpp> -#include <cfg/domgraph.hpp> - -}; #endif diff --git a/libIRDB/src/cfg/BasicBlock.cpp b/libIRDB-cfg/src/BasicBlock.cpp similarity index 60% rename from libIRDB/src/cfg/BasicBlock.cpp rename to libIRDB-cfg/src/BasicBlock.cpp index ccba987cdb1d648e62a59bb932ec08c3341a094e..565d5b6607db07b1d0dcb166ab704f6a53f7b8d1 100644 --- a/libIRDB/src/cfg/BasicBlock.cpp +++ b/libIRDB-cfg/src/BasicBlock.cpp @@ -22,12 +22,44 @@ #include <map> #include <libIRDB-core.hpp> #include <libIRDB-cfg.hpp> -#include <utils.hpp> +#include <irdb-util> +#include <algorithm> using namespace libIRDB; using namespace std; +#define ALLOF(a) begin((a)), end((a)) + +/* + * is_in_container - a handle template function returning whether key S is contained in container T. + */ +template <class T, class S> +inline bool is_in_container(const T& container, const S& key) +{ + bool is_in=container.find(key) != container.end(); + return is_in; +} + +template <class S> +inline bool is_in_set(const std::set<S>& container, const S& key) +{ + return std::find(container.begin(), container.end(), key) != container.end(); +} +/* + * find_map_object - without modifying the object, return the element + */ +template <class T, class S> +inline S const& find_map_object( const std::map< T , S > &a_map, const T& key) +{ + const auto it=a_map.find(key); + assert(it!=a_map.end()); + + return (*it).second; +} + + + BasicBlock_t::BasicBlock_t() : is_exit_block(false) { @@ -37,11 +69,11 @@ BasicBlock_t::BasicBlock_t() void BasicBlock_t::BuildBlock ( - Instruction_t* insn, - const map<Instruction_t*,BasicBlock_t*> &insn2block_map + IRDB_SDK::Instruction_t* insn, + const map<IRDB_SDK::Instruction_t*,BasicBlock_t*> &insn2block_map ) { - const auto &func=insn->GetFunction(); + const auto &func=insn->getFunction(); assert(insn); /* loop through the instructions for this block */ while(insn) @@ -49,8 +81,8 @@ void BasicBlock_t::BuildBlock /* insert this instruction */ instructions.push_back(insn); - Instruction_t* target_insn=insn->GetTarget(); - Instruction_t* ft_insn=insn->GetFallthrough(); + auto target_insn=insn->getTarget(); + auto ft_insn=insn->getFallthrough(); /* determine if there's a target block */ BasicBlock_t* target_block=NULL; @@ -70,27 +102,27 @@ void BasicBlock_t::BuildBlock } /* This is also the end of the block if this is a function exit instruction */ - if(insn->IsFunctionExit()) + if(insn->isFunctionExit()) { is_exit_block=true; } // handle fixed-call fallthroughs. - for_each(insn->GetRelocations().begin(), insn->GetRelocations().end(), [this,&insn2block_map](Relocation_t* reloc) + for_each(ALLOF(insn->getRelocations()), [this,&insn2block_map](IRDB_SDK::Relocation_t* reloc) { // and has a reloc that's a pcrel with a WRT object // possible for a call to have a null fallthrouth (and consequently null WRT) // becauase the call may be the last insn in a section, etc. - if( reloc->GetType()==string("fix_call_fallthrough") && reloc->GetWRT()!=NULL) + if( reloc->getType()==string("fix_call_fallthrough") && reloc->getWRT()!=NULL) { - assert(reloc->GetWRT()!=NULL); - Instruction_t* fix_call_fallthrough_insn=dynamic_cast<Instruction_t*>(reloc->GetWRT()); + assert(reloc->getWRT()!=NULL); + auto fix_call_fallthrough_insn=dynamic_cast<Instruction_t*>(reloc->getWRT()); assert(fix_call_fallthrough_insn); // this block has a fallthrough to the return block. if(is_in_container(insn2block_map,fix_call_fallthrough_insn)) { - BasicBlock_t* fix_call_fallthrough_blk=find_map_object(insn2block_map,fix_call_fallthrough_insn); + BasicBlock_t* fix_call_fallthrough_blk=find_map_object(insn2block_map,static_cast<IRDB_SDK::Instruction_t*>(fix_call_fallthrough_insn)); successors.insert(fix_call_fallthrough_blk); fix_call_fallthrough_blk->GetPredecessors().insert(this); } @@ -116,7 +148,7 @@ void BasicBlock_t::BuildBlock break; /* check for a fallthrough out of the function */ - if(ft_insn && ft_insn->GetFunction() != func) // !is_in_container(func->GetInstructions(),ft_insn)) + if(ft_insn && ft_insn->getFunction() != func) break; @@ -128,11 +160,11 @@ void BasicBlock_t::BuildBlock insn=instructions[instructions.size()-1]; // get last instruction. assert(insn); - if(insn->GetIBTargets()) + if(insn->getIBTargets()) { - for_each(insn->GetIBTargets()->begin(), insn->GetIBTargets()->end(), [this,&insn2block_map,func](Instruction_t* target) + for_each(ALLOF(*insn->getIBTargets()), [this,&insn2block_map,func](IRDB_SDK::Instruction_t* target) { - if(is_in_container(insn2block_map,target) && target!=func->GetEntryPoint()) // don't link calls to the entry block. + if(is_in_container(insn2block_map,target) && target!=func->getEntryPoint()) // don't link calls to the entry block. { BasicBlock_t* target_block=find_map_object(insn2block_map,target); target_block->GetPredecessors().insert(this); @@ -144,44 +176,30 @@ void BasicBlock_t::BuildBlock } -std::ostream& libIRDB::operator<<(std::ostream& os, const BasicBlock_t& block) -{ - os<<block.is_exit_block; - os<<"\t ---- Starting block print -----" <<endl; - for(auto i=0U;i<block.instructions.size();i++) - { - const auto insn=block.instructions[i]; - os<<"\t Instruction "<<std::dec<<i<<" at " << std::hex << insn->GetAddress()->GetVirtualOffset() << " with id " << std::dec << insn->GetBaseID() << " " << insn->GetComment() << endl; - } - os<<"\t ---- done block print -----" <<endl; - os<<endl; - - return os; -} - -bool BasicBlock_t::EndsInBranch() +bool BasicBlock_t::endsInBranch() const { const auto branch=instructions[instructions.size()-1]; assert(branch); - const auto d=DecodedInstruction_t(branch); - return d.isBranch(); + const auto d=DecodedInstruction_t::factory(branch); + return d->isBranch(); } -bool BasicBlock_t::EndsInIndirectBranch() +bool BasicBlock_t::endsInIndirectBranch() const { const auto *branch=instructions[instructions.size()-1]; assert(branch); - const auto d=DecodedInstruction_t(branch); + const auto p_d=DecodedInstruction_t::factory(branch); + const auto &d =*p_d; if(d.isReturn()) return true; if(d.isUnconditionalBranch() || d.isCall()) { - if(!d.getOperand(0).isConstant()) + if(!d.getOperand(0)->isConstant()) /* not a constant type */ return true; return false; @@ -189,24 +207,43 @@ bool BasicBlock_t::EndsInIndirectBranch() } return false; } -bool BasicBlock_t::EndsInConditionalBranch() +bool BasicBlock_t::endsInConditionalBranch() const { - if(!EndsInBranch()) + if(!endsInBranch()) return false; const auto branch=instructions[instructions.size()-1]; assert(branch); - const auto d=DecodedInstruction_t(branch); + const auto d=DecodedInstruction_t::factory(branch); - return d.isConditionalBranch(); + return d->isConditionalBranch(); } -Instruction_t* BasicBlock_t::GetBranchInstruction() +IRDB_SDK::Instruction_t* BasicBlock_t::getBranchInstruction() const { - if(!EndsInBranch()) + if(!endsInBranch()) return NULL; auto branch=instructions[instructions.size()-1]; return branch; } + +std::ostream& IRDB_SDK::operator<<(std::ostream& os, const IRDB_SDK::BasicBlock_t& block) +{ + block.dump(os); + return os; +} +void BasicBlock_t::dump(std::ostream& os) const +{ + os<<getIsExitBlock(); + os<<"\t ---- Starting block print -----" <<endl; + for(auto i=0U;i<getInstructions().size();i++) + { + const auto insn=getInstructions()[i]; + os<<"\t Instruction "<<std::dec<<i<<" at " << std::hex << insn->getAddress()->getVirtualOffset() << " with id " << std::dec << insn->getBaseID() << " " << insn->getComment() << endl; + } + os<<"\t ---- done block print -----" <<endl; + os<<endl; +} + diff --git a/libIRDB-cfg/src/CFG.cpp b/libIRDB-cfg/src/CFG.cpp new file mode 100644 index 0000000000000000000000000000000000000000..096c2cee87061d8b551fd00ff34c262b96606758 --- /dev/null +++ b/libIRDB-cfg/src/CFG.cpp @@ -0,0 +1,283 @@ +/* + * Copyright (c) 2014 - Zephyr Software LLC + * + * This file may be used and modified for non-commercial purposes as long as + * all copyright, permission, and nonwarranty notices are preserved. + * Redistribution is prohibited without prior written consent from Zephyr + * Software. + * + * Please contact the authors for restrictions applying to commercial use. + * + * THIS SOURCE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * Author: Zephyr Software + * e-mail: jwd@zephyr-software.com + * URL : http://www.zephyr-software.com/ + * + */ + + +#include <libIRDB-cfg.hpp> +#include <irdb-util> +#include <algorithm> + +using namespace std; +using namespace libIRDB; + +#define ALLOF(a) begin((a)), end((a)) + +/* + * is_in_container - a handle template function returning whether key S is contained in container T. + */ +template <class T, class S> +inline bool is_in_container(const T& container, const S& key) +{ + bool is_in=container.find(key) != container.end(); + return is_in; +} + +template <class S> +inline bool is_in_set(const std::set<S>& container, const S& key) +{ + return std::find(container.begin(), container.end(), key) != container.end(); +} +/* + * find_map_object - without modifying the object, return the element + */ +template <class T, class S> +inline S const& find_map_object( const std::map< T , S > &a_map, const T& key) +{ + const auto it=a_map.find(key); + assert(it!=a_map.end()); + + return (*it).second; +} + + +/* + * FindTargets - locate all possible instructions that are the target of a jump instruction + */ +static InstructionSet_t FindBlockStarts(IRDB_SDK::Function_t* func) +{ + + InstructionSet_t targets; + InstructionSet_t found_fallthrough_to; + + if(func->getEntryPoint()) + /* the entry point of the function is a target instruction for this CFG */ + targets.insert(func->getEntryPoint()); + + /* for each instruction, decide if it's a block start based on whether or not + * it can be indirectly branched to. Also mark direct targets as block starts. + */ + for(auto it=func->getInstructions().begin(); + it!=func->getInstructions().end(); + ++it + ) + { + /* Get the instruction */ + auto insn=*it; + + /* If this instruction might be an indirect branch target, then mark it as a block start */ + if(insn->getIndirectBranchTargetAddress()) + { + targets.insert(insn); + } + + /* get target and fallthrough */ + auto target=insn->getTarget(); + auto ft=insn->getFallthrough(); + + /* if this instruction has a target, and the target is in this function, mark the target as a block start */ + if(target && is_in_container(func->getInstructions(), target)) + targets.insert(target); + + /* there is a target, and a failthrough, and the fallthrough is in this function */ + if(target && ft && is_in_container(func->getInstructions(), ft)) + targets.insert(ft); + + // we already found a fallthrough to ft, so we have 2+ fallthroughs to ft. mark it as a control flow merge. + if( ft && is_in_container(found_fallthrough_to, ft)) + targets.insert(ft); + + // if there is a ft, mark that we've seen it now. + if(ft) + found_fallthrough_to.insert(ft); + + } + + return targets; +} + +ControlFlowGraph_t::ControlFlowGraph_t(IRDB_SDK::Function_t* func) : + entry(NULL), function(dynamic_cast<Function_t*>(func)) +{ + Build(func); +} + + +void ControlFlowGraph_t::alloc_blocks(const IRDB_SDK::InstructionSet_t &starts, map<IRDB_SDK::Instruction_t*,BasicBlock_t*>& insn2block_map) +{ + /* create a basic block for each instruction that starts a block */ + for(const auto &insn : starts) + { + if(is_in_container(insn2block_map,insn)) // already allocated + continue; + + auto newblock=new BasicBlock_t; + + assert( insn && newblock ); + + blocks.insert(newblock); + insn2block_map[insn]=newblock; + } +} + +void ControlFlowGraph_t::build_blocks(const map<IRDB_SDK::Instruction_t*,BasicBlock_t*>& insn2block_map) +{ + + /* Ask the basic block to set the fields for each block that need to be set */ + for(const auto &it : insn2block_map) + { + const auto insn=it.first; + const auto block=it.second; + + if(block->getInstructions().size()>0) // already built + continue; + + assert(insn && block); + + block->BuildBlock(insn, insn2block_map); + + } + +} + +void ControlFlowGraph_t::find_unblocked_instructions(IRDB_SDK::InstructionSet_t &starts, IRDB_SDK::Function_t* func) +{ + auto mapped_instructions=InstructionSet_t(); + auto missed_instructions=InstructionSet_t(); + for(const auto block : GetBlocks()) + mapped_instructions.insert(ALLOF(block->getInstructions())); + + auto my_inserter=inserter(missed_instructions,missed_instructions.end()); + set_difference(ALLOF(func->getInstructions()), ALLOF(mapped_instructions), my_inserter); + starts.insert(ALLOF(missed_instructions)); +} + + + +void ControlFlowGraph_t::Build(IRDB_SDK::Function_t* func) +{ + auto starts=FindBlockStarts(func); + + auto insn2block_map=map<IRDB_SDK::Instruction_t*,BasicBlock_t*> (); + + alloc_blocks(starts, insn2block_map); + build_blocks(insn2block_map); + /* record the entry block */ + if(func->getEntryPoint()) + entry=insn2block_map[func->getEntryPoint()]; + + /* most functions are done now. */ + /* however, if a function has a (direct) side entrance, + * some code may appear unreachable and not be placed in + * a block -- here, we detect that code and create a + * new basic block for every instruction, as any may have a side entrance + */ + /* note: side entrances may miss a block start */ + /* in code that appears reachable from the entrance?! */ + find_unblocked_instructions(starts, func); + alloc_blocks(starts, insn2block_map); + build_blocks(insn2block_map); +} + +// returns true iff there's an edge from <p_src> to <p_tgt> in the CFG +bool ControlFlowGraph_t::hasEdge(IRDB_SDK::BasicBlock_t *p_src, IRDB_SDK::BasicBlock_t *p_tgt) const +{ + const auto src_exists = blocks.find(p_src) != blocks.end(); + const auto tgt_exists = blocks.find(p_tgt) != blocks.end(); + + if (!src_exists || !tgt_exists) return false; + + const auto successors = p_src->getSuccessors(); + return successors.find(p_tgt) != successors.end(); +} + +IRDB_SDK::CFGEdgeType_t ControlFlowGraph_t::getEdgeType(const IRDB_SDK::BasicBlock_t *p_src, const IRDB_SDK::BasicBlock_t *p_tgt) const +{ + const auto last_in_src = p_src->getInstructions()[p_src->getInstructions().size()-1]; + const auto first_in_tgt = p_tgt->getInstructions()[0]; + + auto edgeType = IRDB_SDK::CFGEdgeType_t(); + + if (last_in_src->getFallthrough() == first_in_tgt) + { + edgeType.insert(IRDB_SDK::cetFallthroughEdge); + } + + if (last_in_src->getTarget() == first_in_tgt) + { + edgeType.insert(IRDB_SDK::cetTargetEdge); + } + + if (edgeType.size() == 0) + { + edgeType.insert(IRDB_SDK::cetIndirectEdge); + } + + return edgeType; +} + +/* + * output operator + */ +ostream& IRDB_SDK::operator<<(ostream& os, const IRDB_SDK::ControlFlowGraph_t& cfg) +{ + cfg.dump(os); + return os; +} + +void ControlFlowGraph_t::dump(ostream& os) const +{ + int i=0; + + auto blk_numbers = map<IRDB_SDK::BasicBlock_t*,int>(); + for(auto blk : getBlocks() ) + { + blk_numbers[blk]=i++; + } + + + for(auto block : getBlocks()) + { + if(block==getEntry()) + os<<"**** Entry "; + else + os<<"---- NotEntry "; + os<<"block "<<std::dec<<blk_numbers[block]<<endl; + os<<"Successors: "; + for(auto succ : block->getSuccessors()) + { + os<<blk_numbers[succ]<<", "; + + }; + os<<endl; + os<<"Predecessors: "; + for(auto pred : block->getPredecessors()) + { + os<<blk_numbers[pred]<<", "; + }; + os<<endl; + os << *block; + } + +} + +unique_ptr<IRDB_SDK::ControlFlowGraph_t> IRDB_SDK::ControlFlowGraph_t::factory(IRDB_SDK::Function_t* func) +{ + return unique_ptr<IRDB_SDK::ControlFlowGraph_t>(new libIRDB::ControlFlowGraph_t(func)); +} + diff --git a/libIRDB/src/cfg/Makefile b/libIRDB-cfg/src/Makefile similarity index 100% rename from libIRDB/src/cfg/Makefile rename to libIRDB-cfg/src/Makefile diff --git a/libIRDB/src/cfg/SConscript b/libIRDB-cfg/src/SConscript similarity index 63% rename from libIRDB/src/cfg/SConscript rename to libIRDB-cfg/src/SConscript index c9e8e715cd9b968b23bf9134009c81d655192826..b09d70d762d99825fdab5b46b0f48e86eedcdefd 100644 --- a/libIRDB/src/cfg/SConscript +++ b/libIRDB-cfg/src/SConscript @@ -6,13 +6,15 @@ myenv=env.Clone() myenv.Replace(SECURITY_TRANSFORMS_HOME=os.environ['SECURITY_TRANSFORMS_HOME']) -libname="IRDB-cfg" +libname="irdb-cfg" files= ''' - BasicBlock.cpp callgraph.cpp CFG.cpp domgraph.cpp + BasicBlock.cpp callgraph.cpp CFG.cpp domgraph.cpp criticaledge.cpp ''' cpppath=''' + $IRDB_SDK/include/ $SECURITY_TRANSFORMS_HOME/include/ - $SECURITY_TRANSFORMS_HOME/libIRDB/include/ + $SECURITY_TRANSFORMS_HOME/libIRDB-core/include/ + $SECURITY_TRANSFORMS_HOME/libIRDB-cfg/include/ ''' libpath=''' $SECURITY_TRANSFORMS_HOME/lib @@ -21,7 +23,7 @@ libpath=''' myenv.Append(CCFLAGS=" -Wall -std=c++11") myenv=myenv.Clone(CPPPATH=Split(cpppath)) -lib=myenv.SharedLibrary(libname, Split(files), LIBS=Split("IRDB-core"), LIBPATH=Split(libpath)) +lib=myenv.SharedLibrary(libname, Split(files), LIBS=Split("irdb-core"), LIBPATH=Split(libpath)) install=myenv.Install("$SECURITY_TRANSFORMS_HOME/lib/", lib) Default(install) diff --git a/libIRDB/src/cfg/SConstruct b/libIRDB-cfg/src/SConstruct similarity index 100% rename from libIRDB/src/cfg/SConstruct rename to libIRDB-cfg/src/SConstruct diff --git a/libIRDB-cfg/src/callgraph.cpp b/libIRDB-cfg/src/callgraph.cpp new file mode 100644 index 0000000000000000000000000000000000000000..fe35a0105a294f1971f6003828827de5994f3c0a --- /dev/null +++ b/libIRDB-cfg/src/callgraph.cpp @@ -0,0 +1,297 @@ +/* + * Copyright (c) 2014-2015 - Zephyr Software LLC + * + * This file may be used and modified for non-commercial purposes as long as + * all copyright, permission, and nonwarranty notices are preserved. + * Redistribution is prohibited without prior written consent from Zephyr + * Software. + * + * Please contact the authors for restrictions applying to commercial use. + * + * THIS SOURCE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * Author: Zephyr Software + * e-mail: jwd@zephyr-software.com + * URL : http://www.zephyr-software.com/ + * + */ + + +#include <map> +#include <ostream> +#include <libIRDB-core.hpp> +#include <libIRDB-cfg.hpp> +#include <irdb-util> + +using namespace libIRDB; +using namespace std; + + +Callgraph_t::Callgraph_t() : + default_hellnode(NULL) +{ +} + +unique_ptr<IRDB_SDK::CallGraph_t> IRDB_SDK::CallGraph_t::factory(FileIR_t* const firp) +{ + auto ret=unique_ptr<IRDB_SDK::CallGraph_t>(new libIRDB::Callgraph_t()); + if(firp != nullptr) + ret->addFile(firp); + return ret; +} + + +Callgraph_t::~Callgraph_t() +{ + for (auto p : nodes) + { + delete p.second; + } + nodes.clear(); +} + +static bool IsCallSite(Instruction_t* insn) +{ + const auto d=DecodedInstruction_t::factory(insn); + return d->isCall(); +} + +static bool IsTailJmpSite(Instruction_t* insn) +{ + const auto d=DecodedInstruction_t::factory(insn); + if(d->isBranch()) + return false; + + if(insn->getTarget()==NULL) + return true; + + if(insn->getFunction() != insn->getTarget()->getFunction()) + return true; + return false; +} + +static bool IsPushJmpSite(Instruction_t* insn) +{ + const auto d=DecodedInstruction_t::factory(insn); + if(d->getMnemonic()!="push" || insn->getFallthrough()==NULL) + return false; + + if(insn->getRelocations().size()==0) + return false; + + const auto d2=DecodedInstruction_t::factory(insn->getFallthrough()); + if(!d2->isBranch()) + return false; + + return true; +} + +void Callgraph_t::MarkCallSite(IRDB_SDK::Instruction_t* insn) +{ + auto from_func=insn->getFunction(); + auto to_insn=insn->getTarget(); + auto to_func= to_insn==NULL? NULL : to_insn->getFunction(); + + auto from_node = findNode(from_func); + auto to_node = findNode(to_func); + + if (!from_node) + from_node = &GetDefaultHellNode(); + + if (!to_node) + to_node = &GetDefaultHellNode(); + + call_sites[from_node].insert(insn); + callees[from_node].insert(to_node); + callers[to_node].insert(from_node); +} + +void Callgraph_t::CreateNodes(IRDB_SDK::FileIR_t *firp) +{ + const FunctionSet_t &fns=firp->getFunctions(); + for(auto it=fns.begin(); fns.end() != it; ++it) + { + auto fn=*it; + if (fn) { + auto newnode = new CallGraphNode_t(fn); + nodes[fn] = newnode; +// cout << "Added CGNode: " << GetNodeName(newnode) << endl; + } + } +} + +void Callgraph_t::addFile(IRDB_SDK::FileIR_t* const firp) +{ + // Create CG Nodes from functions + CreateNodes(firp); + + // for each instruction + auto &insns=firp->getInstructions(); + + for(auto it=insns.begin(); insns.end() != it; ++it) + { + auto insn=dynamic_cast<Instruction_t*>(*it); + if(IsCallSite(insn) || IsTailJmpSite(insn)) + MarkCallSite(insn); + if(IsPushJmpSite(insn)) + MarkCallSite(dynamic_cast<Instruction_t*>(insn->getFallthrough())); + + if(insn->getFunction() && insn->getFunction()->getEntryPoint()==insn + && insn->getIndirectBranchTargetAddress()) + { + auto node = findNode(insn->getFunction()); + assert(node); + callees[&GetDefaultHellNode()].insert(node); + callers[node].insert(&GetDefaultHellNode()); + } + } +} + + +void Callgraph_t::_GetAncestors(IRDB_SDK::CallGraphNode_t* const node, IRDB_SDK::CallGraphNodeSet_t &ancestors, IRDB_SDK::CallGraphNodeSet_t &visited, bool skipHellNode) const +{ + if (!node || visited.count(node) > 0) + return; + + cerr << "visiting node: " << GetNodeName(node) << " visited(size):" << visited.size() << endl; + + // ancestor-traversal(node X) + // mark X visited + // get parents P of X + // if P[i] not visited: + // add P[i] to ancestors + // ancestor-traversal(P[i]) + + visited.insert(node); + + const auto &directPredecessors = getCallersOfNode(node); + for (const auto pred : directPredecessors ) // it = directPredecessors.begin(); it != directPredecessors.end(); ++it) + { + if (visited.count(pred) == 0) + { + assert(pred); + if (pred->isHellnode() && skipHellNode) continue; + + cerr << "adding " << GetNodeName(pred) << " to ancestor list " << hex << pred << dec << endl; + ancestors.insert(pred); + _GetAncestors(pred, ancestors, visited, skipHellNode); + } + } +} + +IRDB_SDK::CallGraphNode_t* Callgraph_t::findNode(IRDB_SDK::Function_t* const fn) const +{ + auto node_it=nodes.find(fn); + return (node_it==nodes.end()) ? nullptr : node_it->second; +} + +void Callgraph_t::GetAncestors(IRDB_SDK::Function_t* const fn, IRDB_SDK::CallGraphNodeSet_t &ancestors, bool skipHellNode) const +{ + auto node = findNode(fn); + if (node) + GetAncestors(node, ancestors, skipHellNode); +} + +void Callgraph_t::GetAncestors(IRDB_SDK::CallGraphNode_t* const node, IRDB_SDK::CallGraphNodeSet_t &ancestors, bool skipHellNode) const +{ + auto visited=IRDB_SDK::CallGraphNodeSet_t(); + _GetAncestors(node, ancestors, visited, skipHellNode); +} + +bool Callgraph_t::isReachable(IRDB_SDK::CallGraphNode_t* const from, IRDB_SDK::CallGraphNode_t* const to, bool skipHellNode) const +{ + auto ancestors=IRDB_SDK::CallGraphNodeSet_t(); + GetAncestors(to, ancestors, skipHellNode); + return (ancestors.count(from) > 0); +} + +void Callgraph_t::dump(std::ostream& fout) const +{ + + fout<<"Dumping callgraph ..."<<endl; + + fout<<"Mapping one way ..."<<endl; + for(const auto p : callees) // it=callees.begin(); callees.end()!=it; ++it) + { + // CallGraphNode_t* node = it->first; + // CallGraphNodeSet_t &node_callers=it->second; + const auto node =p.first; + const auto &node_callers=p.second; + + fout<<"Function "<<GetNodeName(node)<<" calls: "; + for(const auto &the_callee : node_callers) // auto it2=node_callers.begin(); node_callers.end()!=it2; ++it2) + { + // CallGraphNode_t* the_callee=*it2; + fout<<GetNodeName(the_callee)<<", "; + } + fout<<endl; + for(const auto the_call_site : GetCallSites(node)) // auto it2=GetCallSites(node).begin(); GetCallSites(node).end() != it2; ++it2) + { + // CallSite_t the_call_site=*it2; + fout<<"\t"<<GetCallsiteDisassembly(the_call_site)<<endl; + } + } + + fout<<"Mapping the other way ..."<<endl; + for(const auto p : callers) // auto it=callers.begin(); callers.end()!=it; ++it) + { + // CallGraphNode_t* n=it->first; + const auto n =p.first; + const auto &node_callees=p.second; + + fout<<"Function "<<GetNodeName(n)<<" called by: "; + for(auto the_caller : node_callees) // CallGraphNodeSet_t::iterator it2=node_callees.begin(); node_callees.end()!=it2; ++it2) + { + // CallGraphNode_t* the_caller=*it2; + fout<<GetNodeName(the_caller)<<", "; + + } + fout<<endl; + } + + + fout<<"Printing call sites..."<<endl; + for(const auto p : call_sites) // auto it=call_sites.begin(); call_sites.end()!=it; ++it) + { + const auto from_node=p.first; + const auto &call_sites_for_func=p.second; + + fout<<"Call Sites for "<<GetNodeName(from_node)<<": "; + + for(const auto the_call_site : call_sites_for_func) // auto it2=call_sites_for_func.begin(); call_sites_for_func.end() != it2; ++it2) + { + // auto the_call_site=*it2; + fout<<GetCallsiteDisassembly(the_call_site)<<", "; + } + fout<<endl; + } + + fout<<"Done!"<<endl; +} + +void CallGraphNode_t::dump(std::ostream& fout) const +{ + if (isHellnode()) + { + fout << "HELLNODE" << GetHellNodeType(); + } + else + { + assert(getFunction()); + fout << getFunction()->getName(); + } +} + +ostream& IRDB_SDK::operator<<(ostream& os, const IRDB_SDK::CallGraph_t& cg) +{ + cg.dump(os); + return os; +} +ostream& IRDB_SDK::operator<<(ostream& os, const IRDB_SDK::CallGraphNode_t& cgn) +{ + cgn.dump(os); + return os; +} + diff --git a/libIRDB-cfg/src/criticaledge.cpp b/libIRDB-cfg/src/criticaledge.cpp new file mode 100644 index 0000000000000000000000000000000000000000..82e5dd67edee08cfc8744ab42e7a57bc40dabbda --- /dev/null +++ b/libIRDB-cfg/src/criticaledge.cpp @@ -0,0 +1,100 @@ +/* + * Copyright (c) 2019 - Zephyr Software LLC + * + * This file may be used and modified for non-commercial purposes as long as + * all copyright, permission, and nonwarranty notices are preserved. + * Redistribution is prohibited without prior written consent from Zephyr + * Software. + * + * Please contact the authors for restrictions applying to commercial use. + * + * THIS SOURCE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * Author: Zephyr Software + * e-mail: jwd@zephyr-software.com + * URL : http://www.zephyr-software.com/ + * + */ + + +#include <libIRDB-cfg.hpp> +#include <irdb-util> +#include <algorithm> + +using namespace std; +using namespace libIRDB; + +#define ALLOF(a) begin(a),end(a) + +CriticalEdgeAnalyzer_t::CriticalEdgeAnalyzer_t(const ControlFlowGraph_t* p_cfg, const bool p_conservative) : + m_cfg(p_cfg), + m_conservative(p_conservative) +{ + init(); +} + +/* +* Critical edge between two nodes is where the source node has multiple successsors, +* and the target node has multiple predecessors +*/ +void CriticalEdgeAnalyzer_t::init() +{ + for (const auto &src : m_cfg->getBlocks()) + { + auto num_successors = src->getSuccessors().size(); + if (!m_conservative) + { + // in aggressive (non conservative) mode, ignore indirect edges + // when counting number of successors + num_successors = count_if + ( + ALLOF(src->getSuccessors()), + [&] (const IRDB_SDK::BasicBlock_t* bb_tgt) + { + auto myEdgeType = m_cfg->getEdgeType(src, bb_tgt); + return myEdgeType.find(IRDB_SDK::cetTargetEdge)!=myEdgeType.end() || + myEdgeType.find(IRDB_SDK::cetFallthroughEdge)!=myEdgeType.end(); + } + ); + } + + if (num_successors <= 1) continue; + + for (const auto &tgt : src->getSuccessors()) + { + auto num_predecessors = tgt->getPredecessors().size(); + if (!m_conservative) + { + // in aggressive (non conservative) mode, ignore indirect edges + // when counting number of predecessors + num_predecessors = count_if + ( + ALLOF(tgt->getPredecessors()), + [&] (const IRDB_SDK::BasicBlock_t* bb_pred) + { + auto myEdgeType = m_cfg->getEdgeType(bb_pred, tgt); + return myEdgeType.find(IRDB_SDK::cetTargetEdge)!=myEdgeType.end() || + myEdgeType.find(IRDB_SDK::cetFallthroughEdge)!=myEdgeType.end(); + } + ); + } + + if (num_predecessors > 1) + { + auto e=IRDB_SDK::BasicBlockEdge_t(src, tgt); + criticals.insert(e); + } + } + } +} + +unique_ptr<IRDB_SDK::CriticalEdges_t> IRDB_SDK::CriticalEdges_t::factory( + const IRDB_SDK::ControlFlowGraph_t &p_cfg, + const bool p_conservative) +{ + auto real_cfg = dynamic_cast<const libIRDB::ControlFlowGraph_t*>(&p_cfg); + return unique_ptr<IRDB_SDK::CriticalEdges_t>(new libIRDB::CriticalEdgeAnalyzer_t( + real_cfg, p_conservative)); +} diff --git a/libIRDB/src/cfg/domgraph.cpp b/libIRDB-cfg/src/domgraph.cpp similarity index 63% rename from libIRDB/src/cfg/domgraph.cpp rename to libIRDB-cfg/src/domgraph.cpp index e5fb3a6d1e9951d95741f970937a90d20ac2cc6c..ba865b9b68bf096c5f6e687fe71b9d3c74fa3ef0 100644 --- a/libIRDB/src/cfg/domgraph.cpp +++ b/libIRDB-cfg/src/domgraph.cpp @@ -1,13 +1,43 @@ #include <libIRDB-cfg.hpp> #include <algorithm> -#include <utils.hpp> +#include <irdb-util> using namespace std; using namespace libIRDB; +#define ALLOF(a) begin((a)), end((a)) + +/* + * is_in_container - a handle template function returning whether key S is contained in container T. + */ +template <class T, class S> +inline bool is_in_container(const T& container, const S& key) +{ + bool is_in=container.find(key) != container.end(); + return is_in; +} + +template <class S> +inline bool is_in_set(const std::set<S>& container, const S& key) +{ + return std::find(container.begin(), container.end(), key) != container.end(); +} +/* + * find_map_object - without modifying the object, return the element + */ +template <class T, class S> +inline S const& find_map_object( const std::map< T , S > &a_map, const T& key) +{ + const auto it=a_map.find(key); + assert(it!=a_map.end()); + + return (*it).second; +} + + // constructor DominatorGraph_t::DominatorGraph_t(const ControlFlowGraph_t* p_cfg, bool needs_postdoms, bool needs_idoms) @@ -20,13 +50,13 @@ DominatorGraph_t::DominatorGraph_t(const ControlFlowGraph_t* p_cfg, bool needs_p // typedef const BasicBlockSet_t& (*) (const BasicBlock_t* node) pred_func_ptr_t; - pred_func_ptr_t func_get_predecessors=[](const BasicBlock_t* node) -> const BasicBlockSet_t& + pred_func_ptr_t func_get_predecessors=[](const IRDB_SDK::BasicBlock_t* node) -> const IRDB_SDK::BasicBlockSet_t& { - return node->GetPredecessors(); + return node->getPredecessors(); }; - dom_graph=Dom_Comp(p_cfg->GetBlocks(), func_get_predecessors, p_cfg->GetEntry()); - idom_graph=Idom_Comp(p_cfg->GetBlocks(), dom_graph, p_cfg->GetEntry()); + dom_graph=Dom_Comp(p_cfg->getBlocks(), func_get_predecessors, p_cfg->getEntry()); + idom_graph=Idom_Comp(p_cfg->getBlocks(), dom_graph, p_cfg->getEntry()); // a func may have multiple exit nodes. how do we deal with that? // psuedo-block? invoke this for each exit block? @@ -78,7 +108,7 @@ end || Dom_Comp */ -DominatorMap_t DominatorGraph_t::Dom_Comp(const BasicBlockSet_t& N, pred_func_ptr_t get_preds, BasicBlock_t* r) +DominatorMap_t DominatorGraph_t::Dom_Comp(const IRDB_SDK::BasicBlockSet_t& N, pred_func_ptr_t get_preds, IRDB_SDK::BasicBlock_t* r) { /* D, T: set of Node @@ -87,12 +117,12 @@ DominatorMap_t DominatorGraph_t::Dom_Comp(const BasicBlockSet_t& N, pred_func_pt Domin: Node -> set of Node Domin(r) := { r } */ - BasicBlockSet_t D, T; + IRDB_SDK::BasicBlockSet_t D, T; bool change=true; DominatorMap_t Domin; Domin[r].insert(r); - BasicBlockSet_t NminusR=N; + IRDB_SDK::BasicBlockSet_t NminusR=N; NminusR.erase(r); /* @@ -100,10 +130,10 @@ DominatorMap_t DominatorGraph_t::Dom_Comp(const BasicBlockSet_t& N, pred_func_pt Domin(n)={N} od */ - for_each( NminusR.begin(), NminusR.end(), [&](BasicBlock_t* n) + for( auto n : NminusR) { Domin[n]=N; - }); + }; /* repeat @@ -114,7 +144,7 @@ DominatorMap_t DominatorGraph_t::Dom_Comp(const BasicBlockSet_t& N, pred_func_pt /* for each n \in N - {r} do */ - for_each(NminusR.begin(), NminusR.end(), [&](BasicBlock_t* n) + for( auto n : NminusR) { /* T := N */ T=N; @@ -124,13 +154,13 @@ DominatorMap_t DominatorGraph_t::Dom_Comp(const BasicBlockSet_t& N, pred_func_pt T = T intersect Domin(p) done */ - for_each(get_preds(n).begin(), get_preds(n).end(), [&](const BasicBlock_t* p) + for(auto p : get_preds(n) ) { - BasicBlockSet_t tmp; + IRDB_SDK::BasicBlockSet_t tmp; set_intersection(T.begin(), T.end(), Domin[p].begin(), Domin[p].end(), inserter(tmp,tmp.begin())); T=tmp; - }); + }; /* D = {n} union T */ @@ -148,7 +178,7 @@ DominatorMap_t DominatorGraph_t::Dom_Comp(const BasicBlockSet_t& N, pred_func_pt change=true; // keep trying Domin[n]=D; } - }); + }; /* done until ! change @@ -164,7 +194,7 @@ DominatorMap_t DominatorGraph_t::Dom_Comp(const BasicBlockSet_t& N, pred_func_pt { assert(blk); const BasicBlockSet_t& blk_dominates=Domin[blk]; - Instruction_t* first_insn=*(blk->GetInstructions().begin()); + Instruction_t* first_insn=*(blk->getInstructions().begin()); assert(first_insn); #if 1 cout<<"\tBlock " <<endl<<*blk<<endl; @@ -215,7 +245,7 @@ end || IDom_Comp -BlockToBlockMap_t DominatorGraph_t::Idom_Comp(const BasicBlockSet_t& N, const DominatorMap_t &Domin, BasicBlock_t* r) +BlockToBlockMap_t DominatorGraph_t::Idom_Comp(const IRDB_SDK::BasicBlockSet_t& N, const DominatorMap_t &Domin, IRDB_SDK::BasicBlock_t* r) { // n, s, t: Node //BasicBlock_t* n=NULL, *s=NULL, *t=NULL; @@ -228,30 +258,32 @@ BlockToBlockMap_t DominatorGraph_t::Idom_Comp(const BasicBlockSet_t& N, const Do // calculate this set as we use it several times - BasicBlockSet_t NminusR = N; + IRDB_SDK::BasicBlockSet_t NminusR = N; NminusR.erase(r); // for each n \in N do - for_each( N.begin(), N.end(), [&](BasicBlock_t* n) + for(auto n : N) { //Tmp(n) := Domin(n) - {n} Tmp[n] = Domin.at(n); Tmp[n].erase(n); // od - }); + }; //for each n \in N - {r} do - for_each( NminusR.begin(), NminusR.end(), [&]( BasicBlock_t* n) + for(auto n : NminusR) { // for each s \in Tmp(n) do auto Tmp_n=Tmp[n]; - for_each( Tmp_n.begin(), Tmp_n.end(), [&]( BasicBlock_t* s) + // for_each( Tmp_n.begin(), Tmp_n.end(), [&]( BasicBlock_t* s) + for (auto s : Tmp_n) { //for each t \in Tmp(n) - {s} do - for_each( Tmp_n.begin(), Tmp_n.end(), [&]( BasicBlock_t* t) + // for_each( Tmp_n.begin(), Tmp_n.end(), [&]( BasicBlock_t* t) + for (auto t : Tmp_n) { // quickly do Tmp(n)-s if(t != s) @@ -263,48 +295,54 @@ BlockToBlockMap_t DominatorGraph_t::Idom_Comp(const BasicBlockSet_t& N, const Do Tmp[n].erase(t); } } - }); - }); - }); + }; + }; + }; //for each n \in N-{r} do - for_each( NminusR.begin(), NminusR.end(), [&](BasicBlock_t* n) + for (auto n : NminusR) { //IDom(n) = <only element in>Tmp(n) IDom[n]= *(Tmp[n].begin()); if(Tmp[n].size()!=1) // should only be one idominator. warn=true; - }); + }; return IDom; } // IDom_Comp -ostream& libIRDB::operator<<(ostream& os, const DominatorGraph_t& dg) +ostream& IRDB_SDK::operator<<(ostream& os, const DominatorGraph_t& dg) { - for_each(dg.cfg.GetBlocks().begin(), dg.cfg.GetBlocks().end(), [&](const BasicBlock_t* blk) + dg.dump(os); + return os; +} + +void DominatorGraph_t::dump(ostream& os) const +{ + // for_each(dg.cfg.GetBlocks().begin(), dg.cfg.GetBlocks().end(), [&](const BasicBlock_t* blk) + for(auto blk : cfg.getBlocks()) { assert(blk); - const BasicBlockSet_t& blk_dominates=dg.GetDominators(blk); - Instruction_t* first_insn=*(blk->GetInstructions().begin()); + const auto& blk_dominates=getDominators(blk); + auto first_insn=*(blk->getInstructions().begin()); assert(first_insn); - os<<"\tBlock entry id:" <<blk->GetInstructions()[0]->GetBaseID()<<endl; + os<<"\tBlock entry id:" <<blk->getInstructions()[0]->getBaseID()<<endl; os<<"\t\tDominated by: "; - for_each(blk_dominates.begin(), blk_dominates.end(), [&os](const BasicBlock_t* dom) + for(auto dom : blk_dominates) { - os<<dom->GetInstructions()[0]->GetBaseID()<<", "; - }); + os<<dom->getInstructions()[0]->getBaseID()<<", "; + }; os<<endl; - const BasicBlock_t* idom=dg.GetImmediateDominator(blk); + const IRDB_SDK::BasicBlock_t* idom=getImmediateDominator(blk); if(idom) - os<<"\t\tImmediate Dominator: "<<hex<<idom->GetInstructions()[0]->GetBaseID()<<endl; + os<<"\t\tImmediate Dominator: "<<hex<<idom->getInstructions()[0]->getBaseID()<<endl; else os<<"\t\tNo Immed Dominator."<<endl; - }); + }; - return os; } diff --git a/libIRDB/include/core/IRDB_Objects.hpp b/libIRDB-core/include/IRDB_Objects.hpp similarity index 65% rename from libIRDB/include/core/IRDB_Objects.hpp rename to libIRDB-core/include/IRDB_Objects.hpp index 859d9177eeb36652af749fd363181df31a362874..aaa34b8abebcf01c0e43be4a2025c9122828aea4 100644 --- a/libIRDB/include/core/IRDB_Objects.hpp +++ b/libIRDB-core/include/IRDB_Objects.hpp @@ -1,48 +1,45 @@ #ifndef IRDB_Objects_h #define IRDB_Objects_h -#include <map> -#include <utility> -#include <memory> - +namespace libIRDB +{ // TODO: Should really use unordered maps but was getting build errors // *** A toolchain step should NOT delete pointers to any variant, file IR, or file object stored // in a IRFiles_t object. I have made pointers shared where possible to communicate this. *** -class IRDBObjects_t +class IRDBObjects_t : virtual public IRDB_SDK::IRDBObjects_t { public: - using FileSet_t = std::set<File_t*>; IRDBObjects_t() { pqxx_interface = std::unique_ptr<pqxxDB_t>(new pqxxDB_t()); // set up interface to the sql server - BaseObj_t::SetInterface(pqxx_interface.get()); + BaseObj_t::setInterface(pqxx_interface.get()); }; - ~IRDBObjects_t(); + virtual ~IRDBObjects_t(); // Add/delete file IRs for a variant. // Step does not have ownership of fileIR (can't make assumptions about its // lifetime!), and a call to DeleteFileIR will render any pointers to that fileIR dangling. // AddFileIR returns the added IR or the preexistent IR if it was already added. - FileIR_t* addFileIR(const db_id_t variant_id, const db_id_t file_id); // Returns NULL if no such file exists - void deleteFileIR(const db_id_t file_id); + IRDB_SDK::FileIR_t* addFileIR(const IRDB_SDK::DatabaseID_t variant_id, const IRDB_SDK::DatabaseID_t file_id); // Returns NULL if no such file exists + void deleteFileIR(const IRDB_SDK::DatabaseID_t file_id); // Add or delete a variant // Step does not have ownership of variant (can't make assumptions about its lifetime!), and a call to DeleteVariant will render any pointers to that variant dangling. // Deleting a variant does NOT write its files' IRs, but DOES delete them! // AddVariant returns the added variant or the preexistent variant if it was already added. - VariantID_t* addVariant(const db_id_t variant_id); - void deleteVariant(db_id_t variant_id); + IRDB_SDK::VariantID_t* addVariant(const IRDB_SDK::DatabaseID_t variant_id); + void deleteVariant(IRDB_SDK::DatabaseID_t variant_id); // Get DB interface - pqxxDB_t* getDBInterface() const; - pqxxDB_t* resetDBInterface(); + IRDB_SDK::pqxxDB_t* getDBInterface() const; + IRDB_SDK::pqxxDB_t* resetDBInterface(); // Write back variants and file IRs. Does NOT commit changes. - int writeBackFileIR(const db_id_t file_id, std::ostream *verbose_logging=nullptr); - int writeBackVariant(const db_id_t variant_id); // Does NOT write back its files' IRs + int writeBackFileIR(const IRDB_SDK::DatabaseID_t file_id, std::ostream *verbose_logging=nullptr); + int writeBackVariant(const IRDB_SDK::DatabaseID_t variant_id); // Does NOT write back its files' IRs int writeBackAll(std::ostream* verbose_logging=nullptr); // Returns -1 if any writes fail. void deleteAll(void); @@ -53,7 +50,7 @@ class IRDBObjects_t std::unique_ptr<pqxxDB_t> pqxx_interface; // type aliases of maps. maps allow speed of finding needed files, file IRs // and/or variants that have already been read from the DB - using IdToVariantMap_t = std::map<db_id_t, std::unique_ptr<VariantID_t>>; + using IdToVariantMap_t = std::map<IRDB_SDK::DatabaseID_t, std::unique_ptr<VariantID_t>>; struct FileIRInfo_t { File_t * file; @@ -64,15 +61,16 @@ class IRDBObjects_t } }; - using IdToFileIRInfoMap_t = std::map<db_id_t, FileIRInfo_t>; + using IdToFileIRInfoMap_t = std::map<IRDB_SDK::DatabaseID_t, FileIRInfo_t>; IdToVariantMap_t variant_map; IdToFileIRInfoMap_t file_IR_map; // minor helper - bool filesAlreadyPresent(const std::set<File_t*>&) const; + bool filesAlreadyPresent(const FileSet_t&) const; }; -#endif +} +#endif diff --git a/libIRDB/include/core/address.hpp b/libIRDB-core/include/address.hpp similarity index 74% rename from libIRDB/include/core/address.hpp rename to libIRDB-core/include/address.hpp index e0f7e17dff225861985c5293155f10a3f7874b93..f6b341b56c76e902a82f2a1a2a64e329e422d919 100644 --- a/libIRDB/include/core/address.hpp +++ b/libIRDB-core/include/address.hpp @@ -18,18 +18,22 @@ * */ +namespace libIRDB +{ + // // An address in a variant. // -typedef uintptr_t virtual_offset_t; -class AddressID_t : public BaseObj_t +using virtual_offset_t = IRDB_SDK::VirtualOffset_t; +class AddressID_t : virtual public IRDB_SDK::AddressID_t, public BaseObj_t { public: + virtual ~AddressID_t() {} AddressID_t() : BaseObj_t(NULL), fileID(NOT_IN_DATABASE), virtual_offset(0) - { SetBaseID(NOT_IN_DATABASE); } + { setBaseID(NOT_IN_DATABASE); } AddressID_t(db_id_t myid, db_id_t myfileID, virtual_offset_t voff) : BaseObj_t(NULL), fileID(myfileID), virtual_offset(voff) - { SetBaseID(myid); } + { setBaseID(myid); } AddressID_t& operator=(const AddressID_t &rhs) { if (this != &rhs) @@ -41,18 +45,18 @@ class AddressID_t : public BaseObj_t return *this; } - db_id_t GetFileID() const { return fileID; } - void SetFileID(db_id_t thefileID) { fileID=thefileID; } + db_id_t getFileID() const { return fileID; } + void setFileID(db_id_t thefileID) { fileID=thefileID; } - virtual_offset_t GetVirtualOffset() { return virtual_offset; } - void SetVirtualOffset(virtual_offset_t voff) { virtual_offset=voff; } + virtual_offset_t getVirtualOffset() const { return virtual_offset; } + void setVirtualOffset(virtual_offset_t voff) { virtual_offset=voff; } std::vector<std::string> WriteToDB(File_t *vid, db_id_t newid, bool p_withHeader); - inline bool operator<(const AddressID_t& cmp) const + bool operator<(const AddressID_t& cmp) const { return fileID < cmp.fileID || (fileID == cmp.fileID && virtual_offset < cmp.virtual_offset);} - inline bool operator!=(const AddressID_t& cmp) const + bool operator!=(const AddressID_t& cmp) const { return fileID != cmp.fileID || virtual_offset != cmp.virtual_offset; } @@ -65,3 +69,4 @@ class AddressID_t : public BaseObj_t void Register(VariantID_t *vid); }; +} diff --git a/libIRDB-core/include/archdesc.hpp b/libIRDB-core/include/archdesc.hpp new file mode 100644 index 0000000000000000000000000000000000000000..e7299d450190a189b6929b41a957db00170aba93 --- /dev/null +++ b/libIRDB-core/include/archdesc.hpp @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2014 - Zephyr Software LLC + * + * This file may be used and modified for non-commercial purposes as long as + * all copyright, permission, and nonwarranty notices are preserved. + * Redistribution is prohibited without prior written consent from Zephyr + * Software. + * + * Please contact the authors for restrictions applying to commercial use. + * + * THIS SOURCE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * Author: Zephyr Software + * e-mail: jwd@zephyr-software.com + * URL : http://www.zephyr-software.com/ + * + */ + +namespace libIRDB +{ + + +using ADFileType_t = IRDB_SDK::ADFileType_t; +using ADMachineType_t = IRDB_SDK::ADMachineType_t; + +class ArchitectureDescription_t : virtual public IRDB_SDK::ArchitectureDescription_t +{ + public: + + virtual ~ArchitectureDescription_t() {} + ArchitectureDescription_t() : bits(0), ft(IRDB_SDK::adftNone), mt(IRDB_SDK::admtNone) {} + + int getBitWidth() const { return bits; } + void setBitWidth(const int _bits) { bits=_bits; } + + ADFileType_t getFileType() const { return ft; } + void setFileType(const ADFileType_t t) { ft=t; } + + ADMachineType_t getMachineType() const { return mt; } + void setMachineType(const ADMachineType_t t) { mt=t; } + + private: + + size_t bits; + ADFileType_t ft; + ADMachineType_t mt; +}; + +} diff --git a/libIRDB/include/core/baseobj.hpp b/libIRDB-core/include/baseobj.hpp similarity index 61% rename from libIRDB/include/core/baseobj.hpp rename to libIRDB-core/include/baseobj.hpp index 05f690020fe95b0a6395900bfd73399e1c961ad6..00abd21a166fbd056a3dd73b026e90be7a24d4da 100644 --- a/libIRDB/include/core/baseobj.hpp +++ b/libIRDB-core/include/baseobj.hpp @@ -19,37 +19,34 @@ */ -typedef uintptr_t virtual_offset_t; -typedef int db_id_t; - - -class Relocation_t; -typedef std::set<Relocation_t*> RelocationSet_t; +namespace libIRDB +{ +using virtual_offset_t = IRDB_SDK::VirtualOffset_t; +using db_id_t = IRDB_SDK::DatabaseID_t; +using RelocationSet_t = IRDB_SDK::RelocationSet_t; // A base class for something that all objects have, for now just a DOIP. // see .cpp file for method descriptions. -class BaseObj_t +class BaseObj_t : virtual public IRDB_SDK::BaseObj_t { public: + virtual ~BaseObj_t() {} BaseObj_t(doip_t* doip); - virtual ~BaseObj_t() { /* management of doips is explicit */ } - - static void SetInterface(DBinterface_t *dbintr); + // static void SetInterface(DBinterface_t *dbintr); static DBinterface_t* GetInterface() {return dbintr;} // get and set the ID - db_id_t GetBaseID() const {return base_id; } - db_id_t GetDoipID() const { return doip ? doip->GetBaseID() : NOT_IN_DATABASE; } - void SetDoipID(doip_t *dp) { doip=dp; } - void SetBaseID(db_id_t id) {base_id=id; } - - static const db_id_t NOT_IN_DATABASE; + db_id_t getBaseID() const {return base_id; } + db_id_t getDoipID() const { return doip ? doip->GetBaseID() : NOT_IN_DATABASE; } + void setDoipID(IRDB_SDK::Doip_t *dp) { doip=dynamic_cast<doip_t*>(dp); if(dp) assert(doip); } + void setBaseID(db_id_t id) {base_id=id; } virtual RelocationSet_t& GetRelocations() { return relocs; } - virtual const RelocationSet_t& GetRelocations() const { return relocs; } + virtual const RelocationSet_t& getRelocations() const { return relocs; } + virtual void setRelocations(const RelocationSet_t& rels) { relocs=rels; } protected: @@ -59,5 +56,8 @@ class BaseObj_t doip_t* doip; db_id_t base_id; // -1 means not yet in the DB. RelocationSet_t relocs; + + friend class IRDB_SDK::BaseObj_t; }; +} diff --git a/libIRDB-core/include/basetypes.hpp b/libIRDB-core/include/basetypes.hpp new file mode 100644 index 0000000000000000000000000000000000000000..16cd27493835113a7569bd0514fd22da7f8f8860 --- /dev/null +++ b/libIRDB-core/include/basetypes.hpp @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2014 - Zephyr Software LLC + * + * This file may be used and modified for non-commercial purposes as long as + * all copyright, permission, and nonwarranty notices are preserved. + * Redistribution is prohibited without prior written consent from Zephyr + * Software. + * + * Please contact the authors for restrictions applying to commercial use. + * + * THIS SOURCE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * Author: Zephyr Software + * e-mail: jwd@zephyr-software.com + * URL : http://www.zephyr-software.com/ + * + */ + + +namespace libIRDB +{ + using virtual_offset_t = IRDB_SDK::VirtualOffset_t; + using db_id_t = IRDB_SDK::DatabaseID_t; + using schema_version_t = IRDB_SDK::SchemaVersionID_t; + + // forward decls + class AddressID_t; + class ArchitectureDescription_t; + class BaseObj_t; + class DatabaseError_t; + class DBinterface_t; + class Doip_t; + class EhProgram_t; + class EhCallSite_t; + class File_t; + class FileIR_t; + class Function_t; + class ICFS_t; + class Instruction_t; + class IRDBObjects_t; + class pqxxDB_t; + class Relocation_t; + class DataScoop_t; + class Type_t; + class BasicType_t; + class PointerType_t; + class AggregateType_t; + class FuncType_t; + class VariantID_t; + class DecodedInstructionDispatcher_t; + class DecodedOperandDispatcher_t; + +} diff --git a/libIRDB/include/core/dbinterface.hpp b/libIRDB-core/include/dbinterface.hpp similarity index 68% rename from libIRDB/include/core/dbinterface.hpp rename to libIRDB-core/include/dbinterface.hpp index 96954be9e3e60d2cb254df905fa778ed055ca368..fb4836ab16fc3cc460de37d18ae189d90ef55d92 100644 --- a/libIRDB/include/core/dbinterface.hpp +++ b/libIRDB-core/include/dbinterface.hpp @@ -18,11 +18,14 @@ * */ +namespace libIRDB +{ +using DatabaseErrorType_t = IRDB_SDK::DatabaseErrorType_t; -class DatabaseError_t +class DatabaseError_t : virtual public IRDB_SDK::DatabaseError_t { public: - enum DatabaseErrorType_t {VariantNotInDatabase, VariantTableNotRegistered}; + virtual ~DatabaseError_t() { } DatabaseError_t(DatabaseErrorType_t the_err) : err(the_err) {} DatabaseErrorType_t GetErrorCode() const { return err; } private: @@ -33,16 +36,17 @@ std::ostream& operator<<(std::ostream& output, const DatabaseError_t& p); // an interface to a database -class DBinterface_t +class DBinterface_t : virtual public IRDB_SDK::DBinterface_t { public: DBinterface_t() {}; virtual ~DBinterface_t() {}; - virtual void IssueQuery(std::string query)=0; - virtual void MoveToNextRow()=0; - virtual std::string GetResultColumn(std::string colname)=0; - virtual bool IsDone()=0; - virtual void Commit()=0; + virtual void issueQuery(std::string query)=0; + virtual void moveToNextRow()=0; + virtual std::string getResultColumn(std::string colname)=0; + virtual bool isDone()=0; + virtual void commit()=0; }; +} diff --git a/libIRDB-core/include/decode.hpp b/libIRDB-core/include/decode.hpp new file mode 100644 index 0000000000000000000000000000000000000000..79bd8617f47f14d06db59b03894423b09e31c651 --- /dev/null +++ b/libIRDB-core/include/decode.hpp @@ -0,0 +1,10 @@ + +namespace libIRDB +{ + +using DecodedInstruction_t = IRDB_SDK::DecodedInstruction_t; +using DecodedOperand_t = IRDB_SDK::DecodedOperand_t; +using DecodedOperandVector_t = IRDB_SDK::DecodedOperandVector_t; + +} + diff --git a/libIRDB-core/include/decode_base.hpp b/libIRDB-core/include/decode_base.hpp new file mode 100644 index 0000000000000000000000000000000000000000..5cbbcee821ef04a9cd55e5784b3e512eeb5d27c6 --- /dev/null +++ b/libIRDB-core/include/decode_base.hpp @@ -0,0 +1,50 @@ +#if 0 +namespace libIRDB +{ + +using namespace libIRDB; +using namespace std; + +class DecodedOperandCapstone_t; + +class DecodedInstructionCapstone_t : virtual public IRDB_SDK::DecodedInstruction_t +{ + public: + virtual ~DecodedInstructionCapstone_t(){} + virtual string getDisassembly() const =0; + virtual bool valid() const =0; + virtual uint32_t length() const =0; + virtual bool isBranch() const =0; + virtual bool isCall() const =0; + virtual bool isUnconditionalBranch() const =0; + virtual bool isConditionalBranch() const =0; + virtual bool isReturn() const =0; + virtual string getMnemonic() const =0; + virtual int64_t getImmediate() const =0; + virtual virtual_offset_t getAddress() const =0; + virtual bool setsStackPointer() const =0; + virtual uint32_t getPrefixCount() const =0; + virtual bool hasRelevantRepPrefix() const =0; + virtual bool hasRelevantRepnePrefix() const =0; + virtual bool hasRelevantOperandSizePrefix() const =0; + virtual bool hasRexWPrefix() const =0; + virtual bool hasImplicitlyModifiedRegs() const =0; + virtual virtual_offset_t getMemoryDisplacementOffset(const IRDB_SDK::DecodedOperand_t& t, const Instruction_t* insn) const =0; + + // 0-based. first operand is numbered 0. + virtual bool hasOperand(const int op_num) const =0; + virtual shared_ptr<IRDB_SDK::DecodedOperand_t> getOperand(const int op_num) const =0; + virtual DecodedOperandVector_t getOperands() const =0; + + private: + + // static unique_ptr<DecodedInstructionCapstone_t> factory(const Instruction_t* i); + // static unique_ptr<DecodedInstructionCapstone_t> factory(const IRDB_SDK::VirtualOffset_t start_addr, const void *data, uint32_t max_len); + // static unique_ptr<DecodedInstructionCapstone_t> factory(const IRDB_SDK::VirtualOffset_t start_addr, const void *data, const void* endptr); + // friend class DecodedInstructionDispatcher_t; + +}; + +} + +#endif diff --git a/libIRDB-core/include/decode_csarm.hpp b/libIRDB-core/include/decode_csarm.hpp new file mode 100644 index 0000000000000000000000000000000000000000..b517d7d04b0708e317ee4a3809680866ff67bfff --- /dev/null +++ b/libIRDB-core/include/decode_csarm.hpp @@ -0,0 +1,72 @@ + +namespace libIRDB +{ + +using namespace libIRDB; +using namespace std; + +class DecodedOperandCapstoneARM64_t; +class DecodedInstructionCapstoneARM64_t : virtual public IRDB_SDK::DecodedInstruction_t +{ + public: + DecodedInstructionCapstoneARM64_t()=delete; + DecodedInstructionCapstoneARM64_t& operator=(const DecodedInstructionCapstoneARM64_t& copy); + + virtual ~DecodedInstructionCapstoneARM64_t(); + + virtual string getDisassembly() const override; + virtual bool valid() const override; + virtual uint32_t length() const override; + virtual bool isBranch() const override; + virtual bool isCall() const override; + virtual bool isUnconditionalBranch() const override; + virtual bool isConditionalBranch() const override; + virtual bool isReturn() const override; + virtual string getMnemonic() const override; + virtual int64_t getImmediate() const override; + virtual virtual_offset_t getAddress() const override; + virtual bool setsStackPointer() const override; + virtual uint32_t getPrefixCount() const override; + virtual bool hasRelevantRepPrefix() const override; + virtual bool hasRelevantRepnePrefix() const override; + virtual bool hasRelevantOperandSizePrefix() const override; + virtual bool hasRexWPrefix() const override; + virtual bool hasImplicitlyModifiedRegs() const override; + virtual IRDB_SDK::VirtualOffset_t getMemoryDisplacementOffset(const DecodedOperand_t* t, const IRDB_SDK::Instruction_t* insn) const override; + + // 0-based. first operand is numbered 0. + virtual bool hasOperand(const int op_num) const override; + virtual std::shared_ptr<DecodedOperand_t> getOperand(const int op_num) const override; + virtual DecodedOperandVector_t getOperands() const override; + + private: + + void Disassemble(const virtual_offset_t start_addr, const void *data, const uint32_t max_len); + + shared_ptr<void> my_insn; + + class CapstoneHandle_t + { + public: + CapstoneHandle_t(FileIR_t* firp=NULL); + inline unsigned long getHandle() { return handle; } + + private: + // csh handle; // this is the real type, but it's an alias and I don't want to export capstone values. + unsigned long handle; + }; + static CapstoneHandle_t *cs_handle; + + + friend class IRDB_SDK::DecodedInstruction_t; + friend class DecodedOperandCapstoneARM64_t; + + DecodedInstructionCapstoneARM64_t(const shared_ptr<void> &my_insn); + DecodedInstructionCapstoneARM64_t(const Instruction_t*); + DecodedInstructionCapstoneARM64_t(const virtual_offset_t start_addr, const void *data, uint32_t max_len); + DecodedInstructionCapstoneARM64_t(const virtual_offset_t start_addr, const void *data, const void* endptr); + DecodedInstructionCapstoneARM64_t(const DecodedInstructionCapstoneARM64_t& copy); +}; + +} + diff --git a/libIRDB-core/include/decode_csx86.hpp b/libIRDB-core/include/decode_csx86.hpp new file mode 100644 index 0000000000000000000000000000000000000000..c7e85d91bb308db2b3d637c5a1d5cc28dcff73ee --- /dev/null +++ b/libIRDB-core/include/decode_csx86.hpp @@ -0,0 +1,72 @@ + +namespace libIRDB +{ + +using namespace libIRDB; +using namespace std; + +class DecodedOperandCapstoneX86_t; +class DecodedInstructionCapstoneX86_t : virtual public DecodedInstruction_t +{ + public: + DecodedInstructionCapstoneX86_t()=delete; + DecodedInstructionCapstoneX86_t& operator=(const DecodedInstructionCapstoneX86_t& copy); + + virtual ~DecodedInstructionCapstoneX86_t(); + + virtual string getDisassembly() const override; + virtual bool valid() const override; + virtual uint32_t length() const override; + virtual bool isBranch() const override; + virtual bool isCall() const override; + virtual bool isUnconditionalBranch() const override; + virtual bool isConditionalBranch() const override; + virtual bool isReturn() const override; + virtual string getMnemonic() const override; + virtual int64_t getImmediate() const override; + virtual virtual_offset_t getAddress() const override; + virtual bool setsStackPointer() const override; + virtual uint32_t getPrefixCount() const override; + virtual bool hasRelevantRepPrefix() const override; + virtual bool hasRelevantRepnePrefix() const override; + virtual bool hasRelevantOperandSizePrefix() const override; + virtual bool hasRexWPrefix() const override; + virtual bool hasImplicitlyModifiedRegs() const override; + virtual IRDB_SDK::VirtualOffset_t getMemoryDisplacementOffset(const DecodedOperand_t* t, const IRDB_SDK::Instruction_t* insn) const override; + + // 0-based. first operand is numbered 0. + virtual bool hasOperand(const int op_num) const override; + virtual std::shared_ptr<DecodedOperand_t> getOperand(const int op_num) const override; + virtual DecodedOperandVector_t getOperands() const override; + + private: + + void Disassemble(const virtual_offset_t start_addr, const void *data, const uint32_t max_len); + + shared_ptr<void> my_insn; + + class CapstoneHandle_t + { + public: + CapstoneHandle_t(FileIR_t* firp=NULL); + inline unsigned long getHandle() { return handle; } + + private: + // csh handle; // this is the real type, but it's an alias and I don't want to export capstone values. + unsigned long handle; + }; + static CapstoneHandle_t *cs_handle; + + + friend class DecodedInstruction_t; + friend class DecodedOperandCapstoneX86_t; + + DecodedInstructionCapstoneX86_t(const shared_ptr<void> &my_insn); + DecodedInstructionCapstoneX86_t(const Instruction_t*); + DecodedInstructionCapstoneX86_t(const virtual_offset_t start_addr, const void *data, uint32_t max_len); + DecodedInstructionCapstoneX86_t(const virtual_offset_t start_addr, const void *data, const void* endptr); + DecodedInstructionCapstoneX86_t(const DecodedInstructionCapstoneX86_t& copy); +}; + +} + diff --git a/libIRDB-core/include/decode_dispatch.hpp b/libIRDB-core/include/decode_dispatch.hpp new file mode 100644 index 0000000000000000000000000000000000000000..491df5ca2ce2ff7daff7069a1a62cd23dee4f339 --- /dev/null +++ b/libIRDB-core/include/decode_dispatch.hpp @@ -0,0 +1,55 @@ + +namespace libIRDB +{ + +using namespace libIRDB; +using namespace std; + +class DecodedOperandDispatcher_t; +typedef std::vector<DecodedOperandDispatcher_t> DecodedOperandMetaVector_t; + +class DecodedInstructionDispatcher_t : virtual public IRDB_SDK::DecodedInstruction_t +{ + public: + DecodedInstructionDispatcher_t()=delete; + DecodedInstructionDispatcher_t(const Instruction_t*); + DecodedInstructionDispatcher_t(const virtual_offset_t start_addr, const void *data, uint32_t max_len); + DecodedInstructionDispatcher_t(const virtual_offset_t start_addr, const void *data, const void* endptr); + DecodedInstructionDispatcher_t(const DecodedInstructionDispatcher_t& copy); + DecodedInstructionDispatcher_t& operator=(const DecodedInstructionDispatcher_t& copy); + + virtual ~DecodedInstructionDispatcher_t(); + + string getDisassembly() const; + bool valid() const; + uint32_t length() const; + bool isBranch() const; + bool isCall() const; + bool isUnconditionalBranch() const; + bool isConditionalBranch() const; + bool isReturn() const; + string getMnemonic() const; + int64_t getImmediate() const; + virtual_offset_t getAddress() const; + bool setsStackPointer() const; + uint32_t getPrefixCount() const; + bool hasRelevantRepPrefix() const; + bool hasRelevantRepnePrefix() const; + bool hasRelevantOperandSizePrefix() const; + bool hasRexWPrefix() const; + bool hasImplicitlyModifiedRegs() const; + IRDB_SDK::VirtualOffset_t getMemoryDisplacementOffset(const IRDB_SDK::DecodedOperand_t* t, const IRDB_SDK::Instruction_t* insn) const; + + // 0-based. first operand is numbered 0. + bool hasOperand(const int op_num) const; + shared_ptr<IRDB_SDK::DecodedOperand_t> getOperand(const int op_num) const; + IRDB_SDK::DecodedOperandVector_t getOperands() const; + + private: + + std::shared_ptr<DecodedInstructionCapstone_t> cs; + +}; + +} + diff --git a/libIRDB/include/core/doip.hpp b/libIRDB-core/include/doip.hpp similarity index 82% rename from libIRDB/include/core/doip.hpp rename to libIRDB-core/include/doip.hpp index 7a491b35ca54d47558e24ef42a8aee0658fd23e5..e379150cd7f9e00507714c5bab40f4166bf2a36b 100644 --- a/libIRDB/include/core/doip.hpp +++ b/libIRDB-core/include/doip.hpp @@ -18,21 +18,18 @@ * */ +namespace libIRDB +{ + // The Digital Object Identifier for Peasoup. -class doip_t +class doip_t : virtual public IRDB_SDK::Doip_t { public: + virtual ~doip_t(){} doip_t(db_id_t did, int conf, std::string tool_name , std::string comment); db_id_t GetBaseID() const { return did; } - -#if 0 - operator<<(); // output - operator==(); // comparison operators - // compare confidence levels of two datum - operator<(); -#endif private: db_id_t did; @@ -40,3 +37,4 @@ class doip_t std::string tool_name; std::string comment; }; +} diff --git a/libIRDB/include/core/eh.hpp b/libIRDB-core/include/eh.hpp similarity index 51% rename from libIRDB/include/core/eh.hpp rename to libIRDB-core/include/eh.hpp index 6c3da494cb6278f0a36cdb981b29eb167436236f..77082ae522f1dcafd68ba4080ec539266f9f1f17 100644 --- a/libIRDB/include/core/eh.hpp +++ b/libIRDB-core/include/eh.hpp @@ -18,14 +18,19 @@ * */ +namespace libIRDB +{ +using EhProgramInstruction_t = IRDB_SDK::EhProgramInstruction_t; +using EhProgramListing_t = IRDB_SDK::EhProgramListing_t; +using EhProgramSet_t = IRDB_SDK::EhProgramSet_t; +using TTOrderVector_t = IRDB_SDK::TTOrderVector_t; +using EhCallSiteSet_t = IRDB_SDK::EhCallSiteSet_t; -typedef std::string EhProgramInstruction_t; -typedef std::vector<EhProgramInstruction_t> EhProgramListing_t; - -class EhProgram_t : public BaseObj_t +class EhProgram_t : public BaseObj_t, virtual public IRDB_SDK::EhProgram_t { public: + virtual ~EhProgram_t(){} EhProgram_t(const EhProgram_t& orig) : BaseObj_t(NULL) @@ -36,50 +41,54 @@ class EhProgram_t : public BaseObj_t data_alignment_factor=orig.data_alignment_factor; return_register=orig.return_register; ptrsize=orig.ptrsize; - SetBaseID(BaseObj_t::NOT_IN_DATABASE); - GetRelocations()=orig.GetRelocations(); + setBaseID(BaseObj_t::NOT_IN_DATABASE); + GetRelocations()=orig.getRelocations(); } - EhProgram_t(db_id_t id, const uint64_t caf, const int64_t daf, const uint8_t rr, const uint8_t p_ptrsize) + EhProgram_t(db_id_t id, const uint64_t caf, const int64_t daf, const uint8_t rr, const uint8_t p_ptrsize, + const EhProgramListing_t& ciep, const EhProgramListing_t& fdep) : BaseObj_t(NULL), - code_alignment_factor(0), - data_alignment_factor(0), + code_alignment_factor(caf), + data_alignment_factor(daf), return_register(rr), - ptrsize(p_ptrsize) + ptrsize(p_ptrsize) , + cie_program(ciep), + fde_program(fdep) { - SetDataAlignmentFactor(daf); - SetCodeAlignmentFactor(caf); - SetBaseID(id); + setBaseID(id); } EhProgramListing_t& GetCIEProgram() { return cie_program; } - const EhProgramListing_t& GetCIEProgram() const { return cie_program; } + const EhProgramListing_t& getCIEProgram() const { return cie_program; } EhProgramListing_t& GetFDEProgram() { return fde_program; } - const EhProgramListing_t& GetFDEProgram() const { return fde_program; } + const EhProgramListing_t& getFDEProgram() const { return fde_program; } + void setCIEProgram(const EhProgramListing_t& p) { cie_program=p; } + void setFDEProgram(const EhProgramListing_t& p) { fde_program=p; } - uint64_t GetCodeAlignmentFactor() const { return code_alignment_factor; } - void SetCodeAlignmentFactor(const uint64_t caf) + + uint64_t getCodeAlignmentFactor() const { return code_alignment_factor; } + void setCodeAlignmentFactor(const uint64_t caf) { if ( ((uint8_t)caf) != caf ) throw std::logic_error(std::string()+"Invalid code alignment factor in call to "+__FUNCTION__); code_alignment_factor=(uint8_t)caf; } - int64_t GetDataAlignmentFactor() const { return data_alignment_factor; } - void SetDataAlignmentFactor(const int64_t daf) + int64_t getDataAlignmentFactor() const { return data_alignment_factor; } + void setDataAlignmentFactor(const int64_t daf) { if ( (( int8_t)daf) != daf ) throw std::logic_error(std::string()+"Invalid datat alignment factor in call to "+__FUNCTION__); data_alignment_factor=(int8_t)daf; } - int64_t GetReturnRegNumber() const { return return_register; } - void SetReturnRegNumber(const uint8_t rr) { return_register=rr; } + int64_t getReturnRegNumber() const { return return_register; } + void setReturnRegNumber(const uint8_t rr) { return_register=rr; } std::vector<std::string> WriteToDB(File_t* fid); // writes to DB, ID is not -1. - uint8_t GetPointerSize() const { return ptrsize; } + uint8_t getPointerSize() const { return ptrsize; } friend bool operator<(const EhProgram_t&a, const EhProgram_t&b); @@ -88,48 +97,49 @@ class EhProgram_t : public BaseObj_t private: - EhProgramListing_t cie_program; - EhProgramListing_t fde_program; uint8_t code_alignment_factor; int8_t data_alignment_factor; int8_t return_register; uint8_t ptrsize; // needed for interpreting programs + EhProgramListing_t cie_program; + EhProgramListing_t fde_program; }; bool operator<(const EhProgram_t&a, const EhProgram_t&b); -typedef std::set<EhProgram_t*> EhProgramSet_t; -typedef std::vector<int> TTOrderVector_t; -class EhCallSite_t : public BaseObj_t +class EhCallSite_t : public BaseObj_t, virtual public IRDB_SDK::EhCallSite_t { public: - EhCallSite_t(const db_id_t id, const uint64_t enc=0, Instruction_t* lp=NULL) : + virtual ~EhCallSite_t(){} + EhCallSite_t(const db_id_t id, const uint64_t enc=0, IRDB_SDK::Instruction_t* lp=NULL) : BaseObj_t(NULL), tt_encoding(enc), landing_pad(lp) - { SetBaseID(id); } + { setBaseID(id); } - uint64_t GetTTEncoding() const { return tt_encoding; } - void SetTTEncoding(const uint64_t p_tt) { tt_encoding=p_tt; } + uint64_t getTTEncoding() const { return tt_encoding; } + void setTTEncoding(const uint64_t p_tt) { tt_encoding=p_tt; } - Instruction_t* GetLandingPad() const { return landing_pad; } - void SetLandingPad(Instruction_t* lp) { landing_pad=lp; } + IRDB_SDK::Instruction_t* getLandingPad() const { return landing_pad; } + void setLandingPad(IRDB_SDK::Instruction_t* lp) { landing_pad=dynamic_cast<Instruction_t*>(lp); if(lp) assert(landing_pad); } - bool GetHasCleanup() const ; - void SetHasCleanup(bool p_has_cleanup=true) ; + bool getHasCleanup() const ; + void setHasCleanup(bool p_has_cleanup=true) ; TTOrderVector_t& GetTTOrderVector() { return ttov; } - const TTOrderVector_t& GetTTOrderVector() const { return ttov; } + const TTOrderVector_t& getTTOrderVector() const { return ttov; } + void setTTOrderVector(const TTOrderVector_t& p_ttov) { ttov=p_ttov; } std::string WriteToDB(File_t* fid); // writes to DB, ID is not -1. + private: uint64_t tt_encoding; - Instruction_t* landing_pad; + IRDB_SDK::Instruction_t* landing_pad; TTOrderVector_t ttov; }; -typedef std::set<EhCallSite_t*> EhCallSiteSet_t; +} diff --git a/libIRDB/include/core/file.hpp b/libIRDB-core/include/file.hpp similarity index 74% rename from libIRDB/include/core/file.hpp rename to libIRDB-core/include/file.hpp index 8c30dc9a74fcb2cd496f553e4045b768d6e96ec9..da3db353a3bdd86e4a1d49ca3da90c1ed38fd2ca 100644 --- a/libIRDB/include/core/file.hpp +++ b/libIRDB-core/include/file.hpp @@ -18,10 +18,13 @@ * */ +namespace libIRDB +{ // An ELF file as represented by the DB -class File_t : public BaseObj_t +class File_t : public BaseObj_t, virtual public IRDB_SDK::File_t { public: + virtual ~File_t(){} // create new item. File_t( const db_id_t &file_id, const db_id_t &orig_fid, const std::string &url, const std::string &hash, const std::string &arch, const int &elfoid, @@ -34,22 +37,22 @@ class File_t : public BaseObj_t File_t(db_id_t file_id) : BaseObj_t(NULL) { (void)file_id; assert(0);} // read from DB void WriteToDB() { assert(0); } // writes to DB ID is not -1. - std::string GetAddressTableName() const { return address_table_name; } - std::string GetFunctionTableName() const { return function_table_name; } - std::string GetInstructionTableName() const { return instruction_table_name; } - std::string GetICFSTableName() const { return icfs_table_name; } - std::string GetICFSMapTableName() const { return icfs_map_table_name; } - std::string GetRelocationsTableName() const { return relocs_table_name; } - std::string GetTypesTableName() const { return types_table_name; } - std::string GetScoopTableName() const { return scoop_table_name; } - std::string GetEhProgramTableName() const { return ehpgm_table_name; } - std::string GetEhCallSiteTableName() const { return ehcss_table_name; } - std::string GetURL() const { return url; } + std::string getAddressTableName() const { return address_table_name; } + std::string getFunctionTableName() const { return function_table_name; } + std::string getInstructionTableName() const { return instruction_table_name; } + std::string getICFSTableName() const { return icfs_table_name; } + std::string getICFSMapTableName() const { return icfs_map_table_name; } + std::string getRelocationsTableName() const { return relocs_table_name; } + std::string getTypesTableName() const { return types_table_name; } + std::string getScoopTableName() const { return scoop_table_name; } + std::string getEhProgramTableName() const { return ehpgm_table_name; } + std::string getEhCallSiteTableName() const { return ehcss_table_name; } + std::string getURL() const { return url; } void CreateTables(); - int GetELFOID() const { return elfoid; }; - db_id_t GetFileID() const {return orig_fid; }; + int getELFOID() const { return elfoid; }; + db_id_t getFileID() const {return orig_fid; }; friend class FileIR_t; friend class Function_t; @@ -83,3 +86,4 @@ class File_t : public BaseObj_t std::string ehcss_table_name; int elfoid; }; +} diff --git a/libIRDB-core/include/fileir.hpp b/libIRDB-core/include/fileir.hpp new file mode 100644 index 0000000000000000000000000000000000000000..17b9a9c5fb4d0c753cbbcd1881ac26da57fd8e02 --- /dev/null +++ b/libIRDB-core/include/fileir.hpp @@ -0,0 +1,235 @@ +/* + * Copyright (c) 2014 - Zephyr Software LLC + * + * This file may be used and modified for non-commercial purposes as long as + * all copyright, permission, and nonwarranty notices are preserved. + * Redistribution is prohibited without prior written consent from Zephyr + * Software. + * + * Please contact the authors for restrictions applying to commercial use. + * + * THIS SOURCE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * Author: Zephyr Software + * e-mail: jwd@zephyr-software.com + * URL : http://www.zephyr-software.com/ + * + */ + +namespace libIRDB +{ + +using namespace std; +using FunctionSet_t = IRDB_SDK::FunctionSet_t; +using AddressSet_t = IRDB_SDK::AddressSet_t ; + +// A variant of a problem, this +// may be an original variant +// (i.e., and unmodified Variant) or a modified variant. +class FileIR_t : public BaseObj_t, virtual public IRDB_SDK::FileIR_t +{ + public: + + // Create a Variant from the database + FileIR_t(const VariantID_t &newprogid, File_t* fid=NULL); + virtual ~FileIR_t(); + + // DB operations + void writeToDB(std::ostream *verbose_logging=&std::cerr); + + // accessors and mutators in one + FunctionSet_t& GetFunctions() { return funcs; } + const FunctionSet_t& getFunctions() const { return funcs; } + + InstructionSet_t& GetInstructions() { return insns; } + const InstructionSet_t& getInstructions() const { return insns; } + + AddressSet_t& GetAddresses() { return addrs; } + const AddressSet_t& getAddresses() const { return addrs; } + + RelocationSet_t& GetRelocations() { return relocs; } + const RelocationSet_t& getRelocations() const { return relocs; } + + DataScoopSet_t& GetDataScoops() { return scoops; } + const DataScoopSet_t& getDataScoops() const { return scoops; } + + ICFSSet_t& GetAllICFS() { return icfs_set; } + const ICFSSet_t& getAllICFS() const { return icfs_set; } + + EhProgramSet_t& GetAllEhPrograms() { return eh_pgms; } + const EhProgramSet_t& getAllEhPrograms() const { return eh_pgms; } + + EhCallSiteSet_t& GetAllEhCallSites() { return eh_css; } + const EhCallSiteSet_t& getAllEhCallSites() const { return eh_css; } + + // generate the spri rules into the output file, fout. + void GenerateSPRI(std::ostream &fout, bool with_ilr=false); + + // generate spri, assume that orig_varirp is the original variant. + void GenerateSPRI(FileIR_t *orig_varirp, std::ostream &fout, bool with_ilr=false); + + void setBaseIDS(); + IRDB_SDK::DatabaseID_t getMaxBaseID() const; + + File_t* getFile() const { return fileptr; } + + // Used for modifying a large number of instructions. AssembleRegistry + // assembles the assembly isntructions for each registered instruction + // and clears the registry. RegisterAssembly registers the instruction + // to be assembled later. + void assembleRegistry(); + void registerAssembly(IRDB_SDK::Instruction_t *instr, string assembly); + void unregisterAssembly(IRDB_SDK::Instruction_t *instr); + string lookupAssembly(IRDB_SDK::Instruction_t *instr); + + //Needed for inserting assembly before an instruction. + //if orig is not registered, the function returns, otherwise + //the instruction/assembly mapping of orig->assembly is altered to + //updated->assembly + //removes the mapping for orig->assembly from the map. + void changeRegistryKey(IRDB_SDK::Instruction_t* orig, IRDB_SDK::Instruction_t* updated); + + void setArchitecture(); + + static void setArchitecture(const int width, const IRDB_SDK::ADMachineType_t mt); + // static const IRDB_SDK::ArchitectureDescription_t* getArchitecture() { return archdesc; } + + // Lookup a scoop by address + IRDB_SDK::DataScoop_t* findScoop(const IRDB_SDK::VirtualOffset_t &addr) const; + + void splitScoop(IRDB_SDK::DataScoop_t *tosplit, const IRDB_SDK::VirtualOffset_t &addr, size_t size, + IRDB_SDK::DataScoop_t* &before, IRDB_SDK::DataScoop_t* &containing, IRDB_SDK::DataScoop_t* &after, IRDB_SDK::DatabaseID_t *max_id=NULL); + + virtual IRDB_SDK::EhCallSite_t* addEhCallSite_t(IRDB_SDK::Instruction_t* for_insn, const uint64_t enc=0, IRDB_SDK::Instruction_t* lp=nullptr) ; + + virtual IRDB_SDK::Relocation_t* addNewRelocation( + IRDB_SDK::BaseObj_t* from_obj, + int32_t _offset, + string _type, + IRDB_SDK::BaseObj_t* p_wrt_obj=nullptr, + int32_t p_addend=0) ; + virtual EhProgram_t* addEhProgram( + IRDB_SDK::Instruction_t* insn=nullptr, + const uint64_t caf=1, + const int64_t daf=1, + const uint8_t rr=1, + const uint8_t p_ptrsize=8, + const EhProgramListing_t& p_cie_program={}, + const EhProgramListing_t& p_fde_program={} + ) ; + virtual IRDB_SDK::AddressID_t* addNewAddress(const IRDB_SDK::DatabaseID_t& myfileID, const IRDB_SDK::VirtualOffset_t& voff=0) ; + virtual IRDB_SDK::ICFS_t* addNewICFS ( + IRDB_SDK::Instruction_t* insn=nullptr, + const IRDB_SDK::InstructionSet_t& targets={}, + const IRDB_SDK::ICFSAnalysisStatus_t& status=IRDB_SDK::iasAnalysisIncomplete); + virtual IRDB_SDK::Instruction_t* addNewInstruction( + IRDB_SDK::AddressID_t* addr=nullptr, + IRDB_SDK::Function_t* func=nullptr, + const string& bits="", + const string& comment="user-added", + IRDB_SDK::AddressID_t* indTarg=nullptr); + + virtual IRDB_SDK::DataScoop_t* addNewDataScoop( + const string& p_name="user-added", + IRDB_SDK::AddressID_t* p_start=nullptr, + IRDB_SDK::AddressID_t* p_end=nullptr, + IRDB_SDK::Type_t* p_type=nullptr, + uint8_t p_permissions=0, + bool p_is_relro=false, + const string &p_contents="", + IRDB_SDK::DatabaseID_t id=BaseObj_t::NOT_IN_DATABASE); + + virtual void removeScoop(IRDB_SDK::DataScoop_t* s) ; + virtual void moveRelocation(IRDB_SDK::Relocation_t* reloc, IRDB_SDK::Instruction_t* from, IRDB_SDK::Instruction_t* to) ; + virtual IRDB_SDK::EhProgram_t* copyEhProgram(const IRDB_SDK::EhProgram_t& orig); + + virtual void setAllEhPrograms(const EhProgramSet_t& new_pgms) { eh_pgms=new_pgms; } + + + + + + + + private: + + static ArchitectureDescription_t *archdesc; + + #define ASM_REG_MAX_SIZE 500000 + + typedef std::map<Instruction_t*,string> registry_type; + + // a pointer to the original variants IR, NULL means not yet loaded. + FileIR_t* orig_variant_ir_p; + + registry_type assembly_registry; + + void ReadFromDB(); //accesses DB + + FunctionSet_t funcs; + InstructionSet_t insns; + AddressSet_t addrs; + RelocationSet_t relocs; + TypeSet_t types; + DataScoopSet_t scoops; + VariantID_t& progid; // Not owned by fileIR + ICFSSet_t icfs_set; + File_t* fileptr; // Owned by variant, not fileIR + EhProgramSet_t eh_pgms; + EhCallSiteSet_t eh_css; + + map<db_id_t,AddressID_t*> ReadAddrsFromDB(); + map<db_id_t,EhProgram_t*> ReadEhPgmsFromDB(); + + map<db_id_t,EhCallSite_t*> ReadEhCallSitesFromDB + ( + map<EhCallSite_t*,db_id_t> &unresolvedEhCssLandingPads + ); + + map<db_id_t,Function_t*> ReadFuncsFromDB + ( + map<db_id_t,AddressID_t*> &addrMap, + map<db_id_t,Type_t*> &typeMap, + map<Function_t*,db_id_t> &entry_points + ); + + map<db_id_t,DataScoop_t*> ReadScoopsFromDB + ( + map<db_id_t,AddressID_t*> &addrMap, + map<db_id_t,Type_t*> &typeMap + ); + + map<db_id_t,Instruction_t*> ReadInsnsFromDB + ( + const map<db_id_t,Function_t*> &funcMap, + const map<db_id_t,AddressID_t*> &addrMap, + const map<db_id_t,EhProgram_t*> &ehpgmMap, + const map<db_id_t,EhCallSite_t*> &ehcsMap, + map<db_id_t,Instruction_t*> &addressToInstructionMap, + map<Instruction_t*, db_id_t> &unresolvedICFS + ); + + void ReadRelocsFromDB + ( + map<db_id_t,BaseObj_t*> &insnMap + ); + + map<db_id_t, Type_t*> ReadTypesFromDB(TypeSet_t& types); + void ReadAllICFSFromDB(map<db_id_t,Instruction_t*> &addr2insnMap, + map<Instruction_t*, db_id_t> &unresolvedICFS); + + void CleanupICFS(ostream *verbose_logging=&cerr); + void GarbageCollectICFS(ostream *verbose_logging=&cerr); + void DedupICFS(ostream *verbose_logging=&cerr); + + + clock_t ReadIRDB_start; + clock_t ReadIRDB_end; + + friend IRDB_SDK::FileIR_t; + +}; + +} diff --git a/libIRDB/include/core/function.hpp b/libIRDB-core/include/function.hpp similarity index 50% rename from libIRDB/include/core/function.hpp rename to libIRDB-core/include/function.hpp index a4d80aaa63789619764fcec387b0e14499e7790e..50731fd873e70a9d116a535d0d108ec92299155a 100644 --- a/libIRDB/include/core/function.hpp +++ b/libIRDB-core/include/function.hpp @@ -18,44 +18,45 @@ * */ -#include "core/type.hpp" - +namespace libIRDB +{ // The basic Function of a variant. -class Function_t : public BaseObj_t +class Function_t : public BaseObj_t, virtual public IRDB_SDK::Function_t { public: + virtual ~Function_t() {} Function_t() : BaseObj_t(NULL) {} // create a new function not in the db // create a function that's already in the DB - Function_t(db_id_t id, std::string name, int size, int oa_size, bool use_fp, bool is_safe, FuncType_t *, Instruction_t *entry); + Function_t(db_id_t id, std::string name, int size, int oa_size, bool use_fp, bool is_safe, IRDB_SDK::FuncType_t *, IRDB_SDK::Instruction_t *entry); InstructionSet_t& GetInstructions() { return my_insns; } - const InstructionSet_t& GetInstructions() const { return my_insns; } + const InstructionSet_t& getInstructions() const { return my_insns; } - int GetStackFrameSize() const { return stack_frame_size; } - const std::string& GetName() const { return name; } - uint32_t GetOutArgsRegionSize() const { return out_args_region_size; } + const int getStackFrameSize() const { return stack_frame_size; } + const std::string& getName() const { return name; } + uint32_t getOutArgsRegionSize() const { return out_args_region_size; } - void SetStackFrameSize(int size) { stack_frame_size=size; } - void SetName(std::string newname) { name=newname; } - void SetOutArgsRegionSize(uint32_t oa_size) {out_args_region_size=oa_size;} + void setStackFrameSize(int size) { stack_frame_size=size; } + void setName(std::string newname) { name=newname; } + void setOutArgsRegionSize(uint32_t oa_size) {out_args_region_size=oa_size;} - void SetEntryPoint(Instruction_t *insn) {entry_point=insn;} - Instruction_t* GetEntryPoint() const { return entry_point;} + void setEntryPoint(IRDB_SDK::Instruction_t *insn) { entry_point=dynamic_cast<Instruction_t*>(insn); if(insn) assert(entry_point); } + IRDB_SDK::Instruction_t* getEntryPoint() const { return entry_point;} std::string WriteToDB(File_t *fid, db_id_t newid); - bool GetUseFramePointer() const { return use_fp; } - void SetUseFramePointer(bool useFP) { use_fp = useFP; } + bool getUseFramePointer() const { return use_fp; } + void setUseFramePointer(bool useFP) { use_fp = useFP; } - void SetSafe(bool safe) { is_safe = safe; } - bool IsSafe() const { return is_safe; } + void setSafe(bool safe) { is_safe = safe; } + bool isSafe() const { return is_safe; } - void SetType(FuncType_t *t) { function_type = t; } - FuncType_t* GetType() const { return function_type; } + void setType(IRDB_SDK::FuncType_t *t) ; // { function_type = dynamic_cast<FuncType_t*>(t); if(t) assert(function_type); } + IRDB_SDK::FuncType_t* getType() const ; // { return function_type; } - int GetNumArguments() const; + int getNumArguments() const; private: Instruction_t *entry_point; @@ -68,3 +69,4 @@ class Function_t : public BaseObj_t FuncType_t *function_type; }; +} diff --git a/libIRDB/include/core/icfs.hpp b/libIRDB-core/include/icfs.hpp similarity index 62% rename from libIRDB/include/core/icfs.hpp rename to libIRDB-core/include/icfs.hpp index f74bb02c720a0c2704e5b177378e692cee8c41a1..c18efe782582386561d1a9b17df9156599367773 100644 --- a/libIRDB/include/core/icfs.hpp +++ b/libIRDB-core/include/icfs.hpp @@ -18,10 +18,11 @@ * */ -class Instruction_t; -typedef std::set<Instruction_t*> InstructionSet_t; - -typedef enum ICFS_Analysis_Status_t { ICFS_Analysis_Incomplete, ICFS_Analysis_Module_Complete, ICFS_Analysis_Complete } ICFS_Analysis_Status_t; +namespace libIRDB +{ +using InstructionSet_t = IRDB_SDK::InstructionSet_t; +using ICFS_Analysis_Status_t = IRDB_SDK::ICFSAnalysisStatus_t; +using ICFSSet_t = IRDB_SDK::ICFSSet_t; // these must match the allowed values for type icfs_analysis_result in Postgres DB #define ICFS_ANALYSIS_INCOMPLETE_STR "icfs_analysis_incomplete" @@ -29,44 +30,45 @@ typedef enum ICFS_Analysis_Status_t { ICFS_Analysis_Incomplete, ICFS_Analysis_Mo #define ICFS_ANALYSIS_COMPLETE_STR "icfs_analysis_complete" // Keep track of instruction control flow sets -class ICFS_t : public InstructionSet_t, public BaseObj_t +class ICFS_t : virtual public InstructionSet_t, public BaseObj_t, virtual public IRDB_SDK::ICFS_t { public: - ICFS_t(): BaseObj_t(NULL), m_icfs_analysis_status(ICFS_Analysis_Incomplete) {} + virtual ~ICFS_t(){} + ICFS_t(): BaseObj_t(NULL), m_icfs_analysis_status(IRDB_SDK::iasAnalysisIncomplete) {} ICFS_t(const ICFS_Analysis_Status_t p_status) : BaseObj_t(NULL), m_icfs_analysis_status(p_status) {} - ICFS_t(db_id_t p_set_id, const ICFS_Analysis_Status_t p_status = ICFS_Analysis_Incomplete); + ICFS_t(db_id_t p_set_id, const ICFS_Analysis_Status_t p_status = IRDB_SDK::iasAnalysisIncomplete); ICFS_t(db_id_t p_set_id, const std::string); std::string WriteToDB(File_t *fid); // this is bad -- you loose data with this operator=. - void SetTargets(const InstructionSet_t &other) + void setTargets(const InstructionSet_t &other) { InstructionSet_t::operator=(other); } - void AddTargets(const InstructionSet_t &other) + void addTargets(const InstructionSet_t &other) { insert(std::begin(other), std::end(other)); } - bool IsIncomplete() const { - return GetAnalysisStatus() == ICFS_Analysis_Incomplete; + bool isIncomplete() const { + return getAnalysisStatus() == IRDB_SDK::iasAnalysisIncomplete; } - bool IsComplete() const { - return GetAnalysisStatus() == ICFS_Analysis_Complete; + bool isComplete() const { + return getAnalysisStatus() == IRDB_SDK::iasAnalysisComplete; } - bool IsModuleComplete() const { - return GetAnalysisStatus() == ICFS_Analysis_Module_Complete; + bool isModuleComplete() const { + return getAnalysisStatus() == IRDB_SDK::iasAnalysisModuleComplete; } - void SetAnalysisStatus(const ICFS_Analysis_Status_t p_status) { + void setAnalysisStatus(const ICFS_Analysis_Status_t p_status) { m_icfs_analysis_status = p_status; } - ICFS_Analysis_Status_t GetAnalysisStatus() const { + ICFS_Analysis_Status_t getAnalysisStatus() const { return m_icfs_analysis_status; } @@ -74,4 +76,4 @@ class ICFS_t : public InstructionSet_t, public BaseObj_t ICFS_Analysis_Status_t m_icfs_analysis_status; }; -typedef std::set<ICFS_t*> ICFSSet_t; +} diff --git a/libIRDB-core/include/instruction.hpp b/libIRDB-core/include/instruction.hpp new file mode 100644 index 0000000000000000000000000000000000000000..0a332983d156da80f52f9f2774dfe4a57a0a0b0b --- /dev/null +++ b/libIRDB-core/include/instruction.hpp @@ -0,0 +1,91 @@ +/* + * Copyright (c) 2014 - Zephyr Software LLC + * + * This file may be used and modified for non-commercial purposes as long as + * all copyright, permission, and nonwarranty notices are preserved. + * Redistribution is prohibited without prior written consent from Zephyr + * Software. + * + * Please contact the authors for restrictions applying to commercial use. + * + * THIS SOURCE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * Author: Zephyr Software + * e-mail: jwd@zephyr-software.com + * URL : http://www.zephyr-software.com/ + * + */ + +namespace libIRDB +{ + +using RelocationSet_t = IRDB_SDK::RelocationSet_t; + +// The basic instruction of a variant. +class Instruction_t : public BaseObj_t, virtual public IRDB_SDK::Instruction_t +{ + public: + virtual ~Instruction_t(){} + Instruction_t(); + Instruction_t(db_id_t id, AddressID_t *addr, Function_t *func, db_id_t orig_id, + std::string data, std::string callback, std::string comment, AddressID_t *my_indTarg, db_id_t doip_id); + + IRDB_SDK::AddressID_t* getAddress() const { return my_address; } + IRDB_SDK::Function_t* getFunction() const ; // { return my_function; } + db_id_t getOriginalAddressID() const { return orig_address_id; } + IRDB_SDK::Instruction_t* getFallthrough() const { return fallthrough; } + IRDB_SDK::Instruction_t* getTarget() const { return target; } + IRDB_SDK::ICFS_t* getIBTargets() const { return icfs; } + + std::string getDataBits() const { return data; } + std::string getCallback() const { return callback; } + std::string getComment() const { return comment; } + IRDB_SDK::EhProgram_t* getEhProgram() const ; // { return eh_pgm; } + IRDB_SDK::EhCallSite_t* getEhCallSite() const ; // { return eh_cs; } + + + void setAddress(IRDB_SDK::AddressID_t* newaddr) ; // { my_address=newaddr; } + void setFunction(IRDB_SDK::Function_t* func ) ; // { my_function=func;} + void setOriginalAddressID(db_id_t origid) { orig_address_id=origid; /* you shouldn't do this, unless you know what you're doing! */} + void setFallthrough(IRDB_SDK::Instruction_t* i) ; // { fallthrough=i; } + void setTarget(IRDB_SDK::Instruction_t* i) ; // { target=i; } + void setIBTargets(IRDB_SDK::ICFS_t *p_icfs) ; // { icfs=p_icfs; } + void setDataBits(std::string orig) { data=orig; } + void setCallback(std::string orig) { callback=orig; } + void setComment(std::string orig) { comment=orig; } + void setEhProgram(IRDB_SDK::EhProgram_t* orig) ; // { eh_pgm=orig; } + void setEhCallSite(IRDB_SDK::EhCallSite_t* orig); // { eh_cs=orig; } + + IRDB_SDK::AddressID_t* getIndirectBranchTargetAddress() const; // { return indTarg; } + void setIndirectBranchTargetAddress(IRDB_SDK::AddressID_t* myIndTarg) ; // { indTarg=myIndTarg; } + + void WriteToDB() { assert(0); } + std::vector<std::string> WriteToDB(File_t *fid, db_id_t newid); + // int Disassemble(DISASM &d) const; + std::string getDisassembly() const; + bool assemble(std::string assembly); + + bool isFunctionExit() const; + + //static bool SetsStackPointer(DISASM *disasm); + //static bool SetsStackPointer(ARGTYPE* arg); + + bool IsSyscall() { return getDisassembly().find("int 0x80") != std::string::npos; } + + private: + AddressID_t* my_address; + Function_t* my_function; + db_id_t orig_address_id; // const, should not change. + Instruction_t* fallthrough; + Instruction_t* target; + std::string data; + std::string callback; // name of callback handler (if any) + std::string comment; + AddressID_t* indTarg; + ICFS_t* icfs; + EhProgram_t* eh_pgm; + EhCallSite_t* eh_cs; +}; +} diff --git a/libIRDB/include/libIRDB-core.hpp b/libIRDB-core/include/libIRDB-core.hpp similarity index 53% rename from libIRDB/include/libIRDB-core.hpp rename to libIRDB-core/include/libIRDB-core.hpp index 96d47e3053cbafb5bcbb0cebfd4b46e5039ea684..681d93a330914a1953761dee21fb246b913d08b4 100644 --- a/libIRDB/include/libIRDB-core.hpp +++ b/libIRDB-core/include/libIRDB-core.hpp @@ -31,36 +31,31 @@ #include <ctime> #include <stdint.h> -namespace libIRDB -{ +// include SDK +#include <irdb-core> + +#include <basetypes.hpp> +#include <dbinterface.hpp> +#include <doip.hpp> +#include <baseobj.hpp> +#include <reloc.hpp> +#include <address.hpp> +#include <icfs.hpp> +#include <instruction.hpp> +#include <file.hpp> +#include <function.hpp> +#include <variantid.hpp> +#include <archdesc.hpp> +#include <type.hpp> +#include <scoop.hpp> +#include <eh.hpp> +#include <fileir.hpp> +#include <pqxxdb.hpp> +#include <IRDB_Objects.hpp> +#include <transform_step.h> +#include <decode.hpp> + +int command_to_stream(const std::string& command, std::ostream& stream); -class VariantID_t; // forward decl for many classes -class File_t; // forward decl for many classes -class Instruction_t; // forward decl for many classes - -#include <core/basetypes.hpp> -#include <core/dbinterface.hpp> -#include <core/doip.hpp> -#include <core/baseobj.hpp> -#include <core/reloc.hpp> -#include <core/address.hpp> -// xxx #include <core/instructioncfg.hpp> -#include <core/icfs.hpp> -#include <core/instruction.hpp> -#include <core/file.hpp> -#include <core/function.hpp> -#include <core/variantid.hpp> -#include <core/archdesc.hpp> -#include <core/type.hpp> -#include <core/scoop.hpp> -#include <core/eh.hpp> -#include <core/fileir.hpp> -#include <core/pqxxdb.hpp> -#include <core/IRDB_Objects.hpp> -#include <core/transform_step.h> - -}; - -#include <core/decode.hpp> #endif diff --git a/libIRDB-core/include/operand_base.hpp b/libIRDB-core/include/operand_base.hpp new file mode 100644 index 0000000000000000000000000000000000000000..7c408fc3f96a55cac0e295a15a6ecbe4a564fa57 --- /dev/null +++ b/libIRDB-core/include/operand_base.hpp @@ -0,0 +1,45 @@ +#if 0 +namespace libIRDB +{ + +using namespace std; +using namespace libIRDB; + + +class DecodedOperandCapstone_t : virtual public IRDB_SDK::DecodedOperand_t +{ + public: + virtual bool isConstant() const=0; + virtual uint64_t getConstant() const=0; + virtual string getString() const=0; + virtual bool isRegister() const=0; + virtual bool isGeneralPurposeRegister() const=0; + virtual bool isMmxRegister() const=0; + virtual bool isFpuRegister() const=0; + virtual bool isSseRegister() const=0; + virtual bool isAvxRegister() const=0; + virtual bool isZmmRegister() const=0; + virtual bool isSpecialRegister() const=0; + virtual bool isSegmentRegister() const=0; + virtual uint32_t getRegNumber() const=0; + virtual bool isMemory() const=0; + virtual bool hasSegmentRegister() const=0; + virtual uint32_t getSegmentRegister() const=0; + virtual bool hasBaseRegister() const=0; + virtual bool hasIndexRegister() const=0; + virtual uint32_t getBaseRegister() const=0; + virtual uint32_t getIndexRegister() const=0; + virtual bool hasMemoryDisplacement() const=0; + virtual virtual_offset_t getMemoryDisplacement() const=0; + virtual bool isPcrel() const=0; + virtual uint32_t getScaleValue() const=0; + virtual uint32_t getMemoryDisplacementEncodingSize() const=0; + virtual uint32_t getArgumentSizeInBytes() const=0; + virtual uint32_t getArgumentSizeInBits() const=0; + virtual bool isRead() const=0; + virtual bool isWritten() const=0; + +}; + +} +#endif diff --git a/libIRDB-core/include/operand_csarm.hpp b/libIRDB-core/include/operand_csarm.hpp new file mode 100644 index 0000000000000000000000000000000000000000..da26a2105ca45719f9262f9e0a9912939195e7fa --- /dev/null +++ b/libIRDB-core/include/operand_csarm.hpp @@ -0,0 +1,57 @@ + +namespace libIRDB +{ + +using namespace std; +using namespace libIRDB; + +class DecodedOperandCapstoneARM64_t; + +class DecodedOperandCapstoneARM64_t : virtual public IRDB_SDK::DecodedOperand_t +{ + public: + DecodedOperandCapstoneARM64_t() =delete; + virtual ~DecodedOperandCapstoneARM64_t(); + + virtual bool isConstant() const override; + virtual uint64_t getConstant() const override; + virtual string getString() const override; + virtual bool isRegister() const override; + virtual bool isGeneralPurposeRegister() const override; + virtual bool isMmxRegister() const override; + virtual bool isFpuRegister() const override; + virtual bool isSseRegister() const override; + virtual bool isAvxRegister() const override; + virtual bool isZmmRegister() const override; + virtual bool isSpecialRegister() const override; + virtual bool isSegmentRegister() const override; + virtual uint32_t getRegNumber() const override; + virtual bool isMemory() const override; + virtual bool hasSegmentRegister() const override; + virtual uint32_t getSegmentRegister() const override; + virtual bool hasBaseRegister() const override; + virtual bool hasIndexRegister() const override; + virtual uint32_t getBaseRegister() const override; + virtual uint32_t getIndexRegister() const override; + virtual bool hasMemoryDisplacement() const override; + virtual virtual_offset_t getMemoryDisplacement() const override; + virtual bool isPcrel() const override; + virtual uint32_t getScaleValue() const override; + virtual uint32_t getMemoryDisplacementEncodingSize() const override; + virtual uint32_t getArgumentSizeInBytes() const override; + virtual uint32_t getArgumentSizeInBits() const override; + virtual bool isRead() const override; + virtual bool isWritten() const override; + + + private: + + DecodedOperandCapstoneARM64_t( const shared_ptr<void> &my_insn, uint8_t op_num); + + shared_ptr<void> my_insn; + uint8_t op_num; + + friend class DecodedInstructionCapstoneARM64_t; +}; + +} diff --git a/libIRDB-core/include/operand_csx86.hpp b/libIRDB-core/include/operand_csx86.hpp new file mode 100644 index 0000000000000000000000000000000000000000..2c2a250824843b0c151162d2bb330d070143cf74 --- /dev/null +++ b/libIRDB-core/include/operand_csx86.hpp @@ -0,0 +1,58 @@ + +namespace libIRDB +{ + +using namespace std; +using namespace libIRDB; + +class DecodedInstructionCapstoneX86_t; + +class DecodedOperandCapstoneX86_t : virtual public IRDB_SDK::DecodedOperand_t +{ + public: + DecodedOperandCapstoneX86_t() =delete; + virtual ~DecodedOperandCapstoneX86_t(); + + virtual bool isConstant() const override; + virtual uint64_t getConstant() const override; + virtual string getString() const override; + virtual bool isRegister() const override; + virtual bool isGeneralPurposeRegister() const override; + virtual bool isMmxRegister() const override; + virtual bool isFpuRegister() const override; + virtual bool isSseRegister() const override; + virtual bool isAvxRegister() const override; + virtual bool isZmmRegister() const override; + virtual bool isSpecialRegister() const override; + virtual bool isSegmentRegister() const override; + virtual uint32_t getRegNumber() const override; + virtual bool isMemory() const override; + virtual bool hasSegmentRegister() const override; + virtual uint32_t getSegmentRegister() const override; + virtual bool hasBaseRegister() const override; + virtual bool hasIndexRegister() const override; + virtual uint32_t getBaseRegister() const override; + virtual uint32_t getIndexRegister() const override; + virtual bool hasMemoryDisplacement() const override; + virtual virtual_offset_t getMemoryDisplacement() const override; + virtual bool isPcrel() const override; + virtual uint32_t getScaleValue() const override; + virtual uint32_t getMemoryDisplacementEncodingSize() const override; + virtual uint32_t getArgumentSizeInBytes() const override; + virtual uint32_t getArgumentSizeInBits() const override; + virtual bool isRead() const override; + virtual bool isWritten() const override; + + + private: + + DecodedOperandCapstoneX86_t( const shared_ptr<void> &my_insn, uint8_t op_num); + + shared_ptr<void> my_insn; + uint8_t op_num; + + friend class DecodedInstructionCapstoneX86_t; + +}; + +} diff --git a/libIRDB/include/core/operand_meta.hpp b/libIRDB-core/include/operand_dispatch.hpp similarity index 66% rename from libIRDB/include/core/operand_meta.hpp rename to libIRDB-core/include/operand_dispatch.hpp index 38080e08f1ee0c13014c3c3a169e357801843b8e..7d7087668047338a912eb5ea7239fd15dfb05d0c 100644 --- a/libIRDB/include/core/operand_meta.hpp +++ b/libIRDB-core/include/operand_dispatch.hpp @@ -1,8 +1,3 @@ -#ifndef libRIDB_decodedoperandmeta_hpp -#define libRIDB_decodedoperandmeta_hpp - -#include <core/decode_bea.hpp> -#include <core/operand_bea.hpp> namespace libIRDB { @@ -10,15 +5,16 @@ using namespace std; using namespace libIRDB; -class DecodedOperandMeta_t +class DecodedOperandDispatcher_t : virtual public IRDB_SDK::DecodedOperand_t { public: - DecodedOperandMeta_t() =delete; - DecodedOperandMeta_t& operator=(const DecodedOperandMeta_t& copy); - DecodedOperandMeta_t(const DecodedOperandMeta_t& copy); - virtual ~DecodedOperandMeta_t(); + DecodedOperandDispatcher_t() =delete; + DecodedOperandDispatcher_t& operator=(const DecodedOperandDispatcher_t& copy); + DecodedOperandDispatcher_t(const DecodedOperandDispatcher_t& copy); + virtual ~DecodedOperandDispatcher_t(); bool isConstant() const; + uint64_t getConstant() const; string getString() const; bool isRegister() const; bool isGeneralPurposeRegister() const; @@ -48,13 +44,12 @@ class DecodedOperandMeta_t private: - DecodedOperandMeta_t(const DecodedOperandCapstone_t& in); + DecodedOperandDispatcher_t(const shared_ptr<DecodedOperandCapstone_t> in); - DecodedOperandCapstone_t cs; + std::shared_ptr<DecodedOperandCapstone_t> cs; - friend class DecodedInstructionMeta_t; + friend class DecodedInstructionDispatcher_t; }; } -#endif diff --git a/libIRDB/include/core/pqxxdb.hpp b/libIRDB-core/include/pqxxdb.hpp similarity index 67% rename from libIRDB/include/core/pqxxdb.hpp rename to libIRDB-core/include/pqxxdb.hpp index 9b2f3c1a4c023bab96110bbe79ad1a1ef53e56c4..031bd635313ae1a7e1c950ea74387cd9e4d6ebbb 100644 --- a/libIRDB/include/core/pqxxdb.hpp +++ b/libIRDB-core/include/pqxxdb.hpp @@ -18,25 +18,27 @@ * */ +namespace libIRDB +{ -class pqxxDB_t : public DBinterface_t +class pqxxDB_t : public DBinterface_t, virtual public IRDB_SDK::pqxxDB_t { public: pqxxDB_t(); - ~pqxxDB_t() override + virtual ~pqxxDB_t() override { // do nothing }; - void IssueQuery(std::string query); - void IssueQuery(std::stringstream & query); - void MoveToNextRow(); - std::string GetResultColumn(std::string colname); - bool IsDone(); - void Commit(); + void issueQuery(std::string query); + void issueQuery(std::stringstream & query); + void moveToNextRow(); + std::string getResultColumn(std::string colname); + bool isDone(); + void commit(); - pqxx::connection& GetConnection() { return conn; } - pqxx::work& GetTransaction() { return txn; } + pqxx::connection& getConnection() { return conn; } + pqxx::work& getTransaction() { return txn; } private: pqxx::connection conn; @@ -45,3 +47,4 @@ class pqxxDB_t : public DBinterface_t pqxx::result::const_iterator results_iter; }; +} diff --git a/libIRDB/include/core/reloc.hpp b/libIRDB-core/include/reloc.hpp similarity index 69% rename from libIRDB/include/core/reloc.hpp rename to libIRDB-core/include/reloc.hpp index 0f352c19aba25aef65e9a278fe63af54b2a462fe..bcd911010fee1e4309eb273fd797966c8fd1a537 100644 --- a/libIRDB/include/core/reloc.hpp +++ b/libIRDB-core/include/reloc.hpp @@ -18,34 +18,37 @@ * */ +namespace libIRDB +{ + // An ELF file as represented by the DB -class Relocation_t : public BaseObj_t +class Relocation_t : public BaseObj_t, virtual public IRDB_SDK::Relocation_t { public: // create new item. + virtual ~Relocation_t() {} Relocation_t() : BaseObj_t(NULL), offset(0), wrt_obj(NULL), addend(0) {} // new reloc w/no data // a reloc read from the DB - Relocation_t(db_id_t reloc_id, int _offset, std::string _type, BaseObj_t* p_wrt_obj=NULL, int32_t p_addend=0) : - BaseObj_t(NULL), offset(_offset), type(_type), wrt_obj(p_wrt_obj), addend(p_addend) { SetBaseID(reloc_id); } + Relocation_t(db_id_t reloc_id, int _offset, std::string _type, IRDB_SDK::BaseObj_t* p_wrt_obj=NULL, int32_t p_addend=0) : + BaseObj_t(NULL), offset(_offset), type(_type), wrt_obj(p_wrt_obj), addend(p_addend) { setBaseID(reloc_id); } -// Relocation_t(db_id_t reloc_id) : BaseObj_t(NULL), type(""), wrt_obj(NULL), addend(0) { assert(0);} // read from DB void WriteToDB() { assert(0); } // writes to DB ID is not -1. std::vector<std::string> WriteToDB(File_t* fid, BaseObj_t* insn); // writes to DB, ID is not -1. - void SetOffset(int off) { offset=off;} - int GetOffset() const { return offset; } - void SetType(std::string ty) { type=ty;} - std::string GetType() const { return type; } + void setOffset(int off) { offset=off;} + int getOffset() const { return offset; } + void setType(std::string ty) { type=ty;} + std::string getType() const { return type; } - void SetAddend(uint32_t p_addend) { addend=p_addend;} - uint32_t GetAddend() const { return addend; } + void setAddend(uint32_t p_addend) { addend=p_addend;} + uint32_t getAddend() const { return addend; } /* get and set "with respect to" field */ - void SetWRT(libIRDB::BaseObj_t* WRT) { wrt_obj=WRT;} - libIRDB::BaseObj_t* GetWRT() const { return wrt_obj; } + void setWRT(IRDB_SDK::BaseObj_t* WRT) { wrt_obj=dynamic_cast<BaseObj_t*>(WRT); if(WRT) assert(wrt_obj); } + IRDB_SDK::BaseObj_t* getWRT() const { return wrt_obj; } friend class FileIR_t; friend class Function_t; @@ -58,6 +61,7 @@ class Relocation_t : public BaseObj_t std::string type; // a string that describes the relocation type. // possible values: 32-bit, pcrel - BaseObj_t* wrt_obj; + IRDB_SDK::BaseObj_t* wrt_obj; int32_t addend; }; +} diff --git a/libIRDB/include/core/scoop.hpp b/libIRDB-core/include/scoop.hpp similarity index 57% rename from libIRDB/include/core/scoop.hpp rename to libIRDB-core/include/scoop.hpp index 6dc37fd3a33462f93584a1abf3a946e7235c9557..1985de0c01a347e195b36d605fc9dde0620e7045 100644 --- a/libIRDB/include/core/scoop.hpp +++ b/libIRDB-core/include/scoop.hpp @@ -18,12 +18,13 @@ * */ -#ifndef libirdb_data_scoop_hpp -#define libirdb_data_scoop_hpp + +namespace libIRDB +{ class DataScoopByAddressComp_t; -class DataScoop_t : public BaseObj_t +class DataScoop_t : public BaseObj_t, virtual public IRDB_SDK::DataScoop_t { public: @@ -58,40 +59,40 @@ class DataScoop_t : public BaseObj_t contents(p_contents) { assert(start && end); - SetBaseID(id); + setBaseID(id); } virtual ~DataScoop_t() { /* management of addresses and types is explicit */ } - const std::string GetName() const { return name; } - const std::string& GetContents() const { return contents; } - std::string &GetContents() { return contents; } - libIRDB::AddressID_t* GetStart() const { return start; } - libIRDB::AddressID_t* GetEnd() const { return end; } - libIRDB::Type_t* GetType() const { return type; } - libIRDB::virtual_offset_t GetSize() { assert(start && end); return end->GetVirtualOffset() - start->GetVirtualOffset() + 1 ; } + const std::string getName() const { return name; } + const std::string& getContents() const { return contents; } + std::string &getContents() { return contents; } + IRDB_SDK::AddressID_t* getStart() const { return start; } + IRDB_SDK::AddressID_t* getEnd() const { return end; } + IRDB_SDK::Type_t* getType() const { return type; } + IRDB_SDK::VirtualOffset_t getSize() const { assert(start && end); return end->getVirtualOffset() - start->getVirtualOffset() + 1 ; } bool isReadable() const { return (permissions & permissions_r) == permissions_r; } bool isWriteable() const { return (permissions & permissions_w) == permissions_w; }; bool isExecuteable() const { return (permissions & permissions_x) == permissions_x; }; bool isRelRo() const { return is_relro; }; - int getRawPerms() const { return permissions; } + uint8_t getRawPerms() const { return permissions; } void setRawPerms(int newperms) { permissions=newperms; } - void SetName(const std::string &n) { name=n; } - void SetContents(const std::string &n) { contents=n; } - void SetStart( libIRDB::AddressID_t* addr) { assert(addr); start=addr; } - void SetEnd( libIRDB::AddressID_t* addr ) { assert(addr); end=addr; } - void SetType( libIRDB::Type_t* t) { type=t; } + void setName(const std::string &n) { name=n; } + void setContents(const std::string &n) { contents=n; } + void setStart( IRDB_SDK::AddressID_t* addr) { assert(addr); start=dynamic_cast<AddressID_t*>(addr); assert(start); } + void setEnd ( IRDB_SDK::AddressID_t* addr) { assert(addr); end =dynamic_cast<AddressID_t*>(addr); assert(end ); } + void setType( IRDB_SDK::Type_t* t) { type=dynamic_cast<Type_t*>(t); } - void SetReadable() { permissions |= permissions_r; } - void SetWriteable() { permissions |= permissions_w; } - void SetExecuteable() { permissions |= permissions_x; } - void SetRelRo() { is_relro = true; } + void setReadable() { permissions |= permissions_r; } + void setWriteable() { permissions |= permissions_w; } + void setExecuteable() { permissions |= permissions_x; } + void setRelRo() { is_relro = true; } - void ClearReadable() { permissions &= ~permissions_r; } - void ClearWriteable() { permissions &= ~permissions_w; } - void ClearExecuteable() { permissions &= ~permissions_x; } - void ClearRelRo() { is_relro=false; } + void clearReadable() { permissions &= ~permissions_r; } + void clearWriteable() { permissions &= ~permissions_w; } + void clearExecuteable() { permissions &= ~permissions_x; } + void clearRelRo() { is_relro=false; } std::string WriteToDB(File_t *fid, db_id_t newid); std::string WriteToDBRange(File_t *fid, db_id_t newid, int start, int end, std::string table_name); @@ -104,9 +105,9 @@ class DataScoop_t : public BaseObj_t const static int permissions_x=1; std::string name; - libIRDB::AddressID_t* start; - libIRDB::AddressID_t* end; - libIRDB::Type_t* type; + AddressID_t* start; + AddressID_t* end; + Type_t* type; int permissions; bool is_relro; std::string contents; @@ -125,12 +126,12 @@ class DataScoopByAddressComp_t { ) throw std::logic_error("Cannot order scoops that have null elements."); - return std::make_tuple(lhs->start->GetVirtualOffset(), lhs) < - std::make_tuple(rhs->start->GetVirtualOffset(), rhs); + return std::make_tuple(lhs->start->getVirtualOffset(), lhs) < + std::make_tuple(rhs->start->getVirtualOffset(), rhs); } }; -typedef std::set<DataScoop_t*> DataScoopSet_t; -typedef std::set<DataScoop_t*, DataScoopByAddressComp_t> DataScoopByAddressSet_t; +using DataScoopSet_t = IRDB_SDK::DataScoopSet_t; +using DataScoopByAddressSet_t = std::set<DataScoop_t*, DataScoopByAddressComp_t>; -#endif +} diff --git a/libIRDB/include/core/transform_step.h b/libIRDB-core/include/transform_step.h similarity index 65% rename from libIRDB/include/core/transform_step.h rename to libIRDB-core/include/transform_step.h index 4069c60f51e4d49c1d502e79645c18c2cb9213c7..7e6d40926b5d577d2fc61001834dde4a669c7424 100644 --- a/libIRDB/include/core/transform_step.h +++ b/libIRDB-core/include/transform_step.h @@ -1,10 +1,8 @@ -#ifndef TransformStep_h -#define TransformStep_h -namespace Transform_SDK +namespace libIRDB { - class TransformStep_t + class TransformStep_t : virtual public IRDB_SDK::TransformStep_t { public: // Step names must be unique, allows arguments to @@ -17,7 +15,7 @@ namespace Transform_SDK return 0; // success } - virtual int executeStep(libIRDB::IRDBObjects_t *const irdb_objects) + virtual int executeStep(IRDB_SDK::IRDBObjects_t *const irdb_objects) { return 0; // success } @@ -30,6 +28,5 @@ namespace Transform_SDK } extern "C" -std::shared_ptr<Transform_SDK::TransformStep_t> GetTransformStep(void); +std::shared_ptr<IRDB_SDK::TransformStep_t> GetTransformStep(void); -#endif diff --git a/libIRDB-core/include/type.hpp b/libIRDB-core/include/type.hpp new file mode 100644 index 0000000000000000000000000000000000000000..da04eb8b8a8cc94e2a1f472ca484a47342c6fb2a --- /dev/null +++ b/libIRDB-core/include/type.hpp @@ -0,0 +1,143 @@ +/* + * Copyright (c) 2014 - Zephyr Software LLC + * + * This file may be used and modified for non-commercial purposes as long as + * all copyright, permission, and nonwarranty notices are preserved. + * Redistribution is prohibited without prior written consent from Zephyr + * Software. + * + * Please contact the authors for restrictions applying to commercial use. + * + * THIS SOURCE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * Author: Zephyr Software + * e-mail: jwd@zephyr-software.com + * URL : http://www.zephyr-software.com/ + * + */ + +namespace libIRDB +{ +using IRDB_Type = IRDB_SDK::IRDBType_t; +using TypeSet_t = IRDB_SDK::TypeSet_t; +using TypeVector_t = IRDB_SDK::TypeVector_t; + +class Type_t : public BaseObj_t, virtual public IRDB_SDK::Type_t +{ + public: + Type_t() : BaseObj_t(NULL) { + typeID = IRDB_SDK::itUnknown; + } + Type_t(db_id_t dbid, IRDB_Type t, std::string n) : BaseObj_t(NULL) { + setBaseID(dbid); + typeID = t; + name = n; + } + virtual ~Type_t() {} + + virtual std::string WriteToDB(File_t *fid, db_id_t newid) = 0; + + std::string getName() const { return name; } + void setName(const std::string& newname) { name=newname; } + IRDB_Type getTypeID() const { return typeID; } + void setTypeID(IRDB_Type t) { typeID = t; } + + virtual bool isUnknownType() const { return typeID == IRDB_SDK::itUnknown; } + virtual bool isVariadicType() const { return typeID == IRDB_SDK::itVariadic; } + virtual bool isAggregateType() const { return typeID == IRDB_SDK::itAggregate; } + virtual bool isFuncType() const { return typeID == IRDB_SDK::itFunc; } + virtual bool isBasicType() const { return false; } + virtual bool isPointerType() const { return false; } + virtual bool isNumericType() const { return false; } + + private: + std::string name; + IRDB_Type typeID; +}; + +class BasicType_t : public Type_t, virtual public IRDB_SDK::BasicType_t +{ + public: + BasicType_t() : Type_t() {} + BasicType_t(db_id_t id, IRDB_Type type, std::string p_name) : Type_t(id, type, p_name) {} + virtual ~BasicType_t() {} + + virtual bool isBasicType() const { return true; } + virtual bool isNumericType() const; + + std::string WriteToDB(File_t *fid, db_id_t newid); +}; + +class PointerType_t : public Type_t, virtual public IRDB_SDK::PointerType_t +{ + public: + PointerType_t() : Type_t() { setTypeID(IRDB_SDK::itPointer); referentType = NULL; } + PointerType_t(db_id_t id, Type_t* ref, std::string p_name) : Type_t(id, IRDB_SDK::itPointer, p_name) { + setReferentType(ref); + } + virtual ~PointerType_t() {} + virtual bool isPointerType() const { return true; } + + IRDB_SDK::Type_t* getReferentType() const { return referentType; } + void setReferentType(IRDB_SDK::Type_t* r) { referentType = dynamic_cast<Type_t*>(r); if(r) assert(referentType); } + + std::string WriteToDB(File_t *fid, db_id_t newid); + + private: + Type_t* referentType; +}; + +class AggregateType_t : public Type_t, virtual public IRDB_SDK::AggregateType_t +{ + public: + AggregateType_t() : Type_t() { setTypeID(IRDB_SDK::itAggregate); } + AggregateType_t(db_id_t id, std::string p_name) : Type_t(id, IRDB_SDK::itAggregate, p_name) {} + virtual ~AggregateType_t() {} + virtual bool isAggregateType() const { return true; } + + void addAggregatedType(IRDB_SDK::Type_t *t, int pos); + virtual size_t getNumAggregatedTypes() const { return refTypes.size(); } + IRDB_SDK::Type_t* getAggregatedType(unsigned int pos) const { + return (pos < (unsigned int)refTypes.size()) ? refTypes.at(pos) : NULL; + } + + std::string toString() { + return getName(); + } + + std::string WriteToDB(File_t *fid, db_id_t newid); + + private: + TypeVector_t refTypes; +}; + +class FuncType_t : public Type_t, virtual public IRDB_SDK::FuncType_t +{ + public: + FuncType_t() : Type_t() { setTypeID(IRDB_SDK::itFunc); _init(); } + FuncType_t(db_id_t id, std::string p_name) : Type_t(id, IRDB_SDK::itFunc, p_name) { _init(); } + virtual ~FuncType_t() {} + + virtual bool isFuncType() const { return true; } + + std::string WriteToDB(File_t *fid, db_id_t newid); + + IRDB_SDK::Type_t* getReturnType() const { return returnType; } + void setReturnType(IRDB_SDK::Type_t *t) { returnType = dynamic_cast<Type_t*>(t); if(t) assert(returnType); } + IRDB_SDK::AggregateType_t* getArgumentsType() const { return argsType; } + void setArgumentsType(IRDB_SDK::AggregateType_t *t) { argsType = dynamic_cast<AggregateType_t*>(t); if(t) assert(argsType); } + + private: + void _init() { + returnType = NULL; + argsType = NULL; + } + + private: + Type_t* returnType; + AggregateType_t* argsType; +}; + +} diff --git a/libIRDB/include/core/variantid.hpp b/libIRDB-core/include/variantid.hpp similarity index 64% rename from libIRDB/include/core/variantid.hpp rename to libIRDB-core/include/variantid.hpp index ce17a1f3683961122cbdf10e4ce2603a07dc5214..578ff647efbc08183a6677b00c8af65cc217a165 100644 --- a/libIRDB/include/core/variantid.hpp +++ b/libIRDB-core/include/variantid.hpp @@ -18,46 +18,38 @@ * */ +namespace libIRDB +{ #define CURRENT_SCHEMA 2 -class VariantID_t; - -std::ostream& operator<<(std::ostream& out, const libIRDB::VariantID_t& pid); +using FileSet_t = IRDB_SDK::FileSet_t; -using FileSet_t = std::set<File_t*>; - -class VariantID_t : public BaseObj_t +class VariantID_t : public BaseObj_t, virtual public IRDB_SDK::VariantID_t { public: VariantID_t(); // create a Variant ID not in the database VariantID_t(db_id_t pid); // read from the DB ~VariantID_t(); // Deletes the File_t objects -- beware dangling File_t* in FileIR_t objects! - bool IsRegistered(); - bool Register(); // accesses DB + bool isRegistered() const; + bool registerID(); // accesses DB - VariantID_t* Clone(bool deep=true); // accesses DB + IRDB_SDK::VariantID_t* clone(bool deep=true); // accesses DB void WriteToDB(); void DropFromDB(); - FileSet_t& GetFiles() { return files; } - const FileSet_t& GetFiles() const { return files; } + const FileSet_t& getFiles() const { return files; } - std::string GetName() { return name; } - void SetName(std::string newname) { name=newname;} + std::string getName() const { return name; } + void setName(std::string newname) { name=newname;} - File_t* GetMainFile() const; + IRDB_SDK::File_t* getMainFile() const; - friend std::ostream& libIRDB::operator<<(std::ostream& out, const VariantID_t& pid); - //friend class FileIR_T; - //friend class Function_t; - //friend class AddressID_t; - //friend class Instruction_t; - db_id_t GetOriginalVariantID() const { return orig_pid;} + db_id_t getOriginalVariantID() const { return orig_pid;} void CloneFiles(FileSet_t& files); File_t* CloneFile(File_t* fptr); @@ -77,3 +69,8 @@ class VariantID_t : public BaseObj_t }; + + + +} + diff --git a/libIRDB/src/core/IRDB_Objects.cpp b/libIRDB-core/src/IRDB_Objects.cpp similarity index 67% rename from libIRDB/src/core/IRDB_Objects.cpp rename to libIRDB-core/src/IRDB_Objects.cpp index 34c05f812b444211e05a0564381411a9888845fb..f61feee43be90c3164841e9ac71232492526bd08 100644 --- a/libIRDB/src/core/IRDB_Objects.cpp +++ b/libIRDB-core/src/IRDB_Objects.cpp @@ -1,8 +1,9 @@ #include <map> #include <libIRDB-core.hpp> -#include <utils.hpp> +#include <irdb-util> #include <utility> #include <memory> +#include <algorithm> #include <assert.h> @@ -19,7 +20,7 @@ IRDBObjects_t::~IRDBObjects_t() // explicitly deleted. } -FileIR_t* IRDBObjects_t::addFileIR(const db_id_t variant_id, const db_id_t file_id) +IRDB_SDK::FileIR_t* IRDBObjects_t::addFileIR(const IRDB_SDK::DatabaseID_t variant_id, const IRDB_SDK::DatabaseID_t file_id) { const auto it = file_IR_map.find(file_id); @@ -44,12 +45,12 @@ FileIR_t* IRDBObjects_t::addFileIR(const db_id_t variant_id, const db_id_t file_ } // make sure static variable is set in the calling module -- IMPORTANT - the_fileIR->SetArchitecture(); + the_fileIR->setArchitecture(); return the_fileIR.get(); } } -int IRDBObjects_t::writeBackFileIR(const db_id_t file_id, ostream *verbose_logging) +int IRDBObjects_t::writeBackFileIR(const IRDB_SDK::DatabaseID_t file_id, ostream *verbose_logging) { const auto it = file_IR_map.find(file_id); @@ -61,28 +62,28 @@ int IRDBObjects_t::writeBackFileIR(const db_id_t file_id, ostream *verbose_loggi try { - // cout<<"Writing changes for "<<the_file->GetURL()<<endl; + // cout<<"Writing changes for "<<the_file->getURL()<<endl; // make sure static variable is set in the calling module -- IMPORTANT const auto & the_fileIR = (it->second).fileIR; - the_fileIR->SetArchitecture(); - the_fileIR->WriteToDB(verbose_logging); + the_fileIR->setArchitecture(); + the_fileIR->writeToDB(verbose_logging); return 0; } catch (DatabaseError_t pnide) { - cerr << "Unexpected database error: " << pnide << "file url: " << the_file->GetURL() << endl; + cerr << "Unexpected database error: " << pnide << "file url: " << the_file->getURL() << endl; return -1; } catch (...) { - cerr << "Unexpected error file url: " << the_file->GetURL() << endl; + cerr << "Unexpected error file url: " << the_file->getURL() << endl; return -1; } assert(0); // should not reach } -void IRDBObjects_t::deleteFileIR(const db_id_t file_id) +void IRDBObjects_t::deleteFileIR(const IRDB_SDK::DatabaseID_t file_id) { const auto it = file_IR_map.find(file_id); @@ -96,19 +97,19 @@ void IRDBObjects_t::deleteFileIR(const db_id_t file_id) } } -bool IRDBObjects_t::filesAlreadyPresent(const set<File_t*>& the_files) const +bool IRDBObjects_t::filesAlreadyPresent(const FileSet_t& the_files) const { // look for a missing file - const auto missing_file_it=find_if(ALLOF(the_files), [&](const File_t* const f) + const auto missing_file_it=find_if(ALLOF(the_files), [&](const IRDB_SDK::File_t* const f) { - return (file_IR_map.find(f->GetBaseID()) == file_IR_map.end()); + return (file_IR_map.find(f->getBaseID()) == file_IR_map.end()); }); // return true if no files missing return missing_file_it==the_files.end(); } -VariantID_t* IRDBObjects_t::addVariant(const db_id_t variant_id) +IRDB_SDK::VariantID_t* IRDBObjects_t::addVariant(const IRDB_SDK::DatabaseID_t variant_id) { const auto var_it = variant_map.find(variant_id); @@ -120,23 +121,23 @@ VariantID_t* IRDBObjects_t::addVariant(const db_id_t variant_id) variant_map[variant_id].reset(new VariantID_t(variant_id)); auto the_variant = variant_map[variant_id].get(); - assert(the_variant->IsRegistered()==true); + assert(the_variant->isRegistered()==true); // disallow variants that share shallow copies to both be read in // to prevent desynchronization. - assert(!filesAlreadyPresent(the_variant->GetFiles())); + assert(!filesAlreadyPresent(the_variant->getFiles())); // add files - for(auto &curr_file : the_variant->GetFiles()) + for(auto &curr_file : the_variant->getFiles()) { - file_IR_map[curr_file->GetBaseID()]=FileIRInfo_t(); - file_IR_map[curr_file->GetBaseID()].file = curr_file; + file_IR_map[curr_file->getBaseID()]=FileIRInfo_t(); + file_IR_map[curr_file->getBaseID()].file = dynamic_cast<File_t*>(curr_file); } return the_variant; } -int IRDBObjects_t::writeBackVariant(const db_id_t variant_id) +int IRDBObjects_t::writeBackVariant(const IRDB_SDK::DatabaseID_t variant_id) { const auto it = variant_map.find(variant_id); @@ -163,7 +164,7 @@ int IRDBObjects_t::writeBackVariant(const db_id_t variant_id) } -void IRDBObjects_t::deleteVariant(const db_id_t variant_id) +void IRDBObjects_t::deleteVariant(const IRDB_SDK::DatabaseID_t variant_id) { const auto var_it = variant_map.find(variant_id); @@ -171,9 +172,9 @@ void IRDBObjects_t::deleteVariant(const db_id_t variant_id) return; // remove files and file IRs - for(const auto file : var_it->second->GetFiles()) + for(const auto file : var_it->second->getFiles()) { - file_IR_map.erase(file->GetBaseID()); + file_IR_map.erase(file->getBaseID()); } // remove variant @@ -187,7 +188,7 @@ int IRDBObjects_t::writeBackAll(ostream *verbose_logging) // Write back FileIRs for(auto &file_pair : file_IR_map) { - const int result = IRDBObjects_t::writeBackFileIR((file_pair.second.file)->GetBaseID(), verbose_logging); + const int result = IRDBObjects_t::writeBackFileIR((file_pair.second.file)->getBaseID(), verbose_logging); if(result != 0) { ret_status = -1; @@ -197,7 +198,7 @@ int IRDBObjects_t::writeBackAll(ostream *verbose_logging) // Write back Variants for(auto & variant_pair : variant_map) { - const int result = IRDBObjects_t::writeBackVariant((variant_pair.second)->GetBaseID()); + const int result = IRDBObjects_t::writeBackVariant((variant_pair.second)->getBaseID()); if(result != 0) { ret_status = -1; @@ -211,19 +212,19 @@ void IRDBObjects_t::deleteAll(void) // Delete Variants (also deletes all files) for( auto &variant_pair : variant_map) { - IRDBObjects_t::deleteVariant((variant_pair.second)->GetBaseID()); + IRDBObjects_t::deleteVariant((variant_pair.second)->getBaseID()); } } -pqxxDB_t* IRDBObjects_t::getDBInterface() const +IRDB_SDK::pqxxDB_t* IRDBObjects_t::getDBInterface() const { return pqxx_interface.get(); } -pqxxDB_t* IRDBObjects_t::resetDBInterface() +IRDB_SDK::pqxxDB_t* IRDBObjects_t::resetDBInterface() { pqxx_interface.reset(new pqxxDB_t()); // Aborts if Commit() has not been called - BaseObj_t::SetInterface(pqxx_interface.get()); + BaseObj_t::setInterface(pqxx_interface.get()); return pqxx_interface.get(); } @@ -235,7 +236,20 @@ void IRDBObjects_t::tidyIR(void) { const auto &file_ir_info = variant_pair.second; auto fileIR=file_ir_info.fileIR.get(); - fileIR->AssembleRegistry(); - fileIR->SetBaseIDS(); + fileIR->assembleRegistry(); + fileIR->setBaseIDS(); } } + +void FileIR_t::moveRelocation(IRDB_SDK::Relocation_t* reloc, IRDB_SDK::Instruction_t* from, IRDB_SDK::Instruction_t* to) +{ + auto irdb_from=dynamic_cast<libIRDB::Instruction_t*>(from); + auto irdb_to =dynamic_cast<libIRDB::Instruction_t*>(to); + + irdb_to ->GetRelocations().insert(reloc); + irdb_from->GetRelocations().erase (reloc); + + + +} + diff --git a/libIRDB/src/core/SConscript b/libIRDB-core/src/SConscript similarity index 80% rename from libIRDB/src/core/SConscript rename to libIRDB-core/src/SConscript index b538b5836f21a88d19043920906a184377752fa9..a98b3d156e385fe8ccc4ceeb536ca852bcd7969f 100644 --- a/libIRDB/src/core/SConscript +++ b/libIRDB-core/src/SConscript @@ -6,7 +6,7 @@ myenv=env.Clone() myenv.Replace(SECURITY_TRANSFORMS_HOME=os.environ['SECURITY_TRANSFORMS_HOME']) -libname="IRDB-core" +libname="irdb-core" files= ''' address.cpp baseobj.cpp @@ -23,23 +23,25 @@ files= ''' variantid.cpp eh.cpp reloc.cpp - decode_cs.cpp - operand_cs.cpp + decode_csx86.cpp + operand_csx86.cpp + decode_csarm.cpp + operand_csarm.cpp IRDB_Objects.cpp + decode_base.cpp ''' unused_files=''' decode_bea.cpp operand_bea.cpp - decode_meta.cpp - operand_meta.cpp ''' # bea engine listed for core components. cpppath=''' . + $IRDB_SDK/include/ $SECURITY_TRANSFORMS_HOME/include/ - $SECURITY_TRANSFORMS_HOME/libIRDB/include/ + $SECURITY_TRANSFORMS_HOME/libIRDB-core/include/ $SECURITY_TRANSFORMS_HOME/libcapstone/include/capstone/ ''' libpath=''' @@ -48,7 +50,7 @@ libpath=''' #globs=glob.glob(os.environ['SECURITY_TRANSFORMS_HOME']+'/libcapstone/zipr_unpack/*.o') -myenv.Append(CCFLAGS=" -Wall -std=c++11 ") +myenv.Append(CCFLAGS=" -Wall -std=c++11 -fmax-errors=2 ") myenv.Append(LIBPATH=libpath) myenv=myenv.Clone(CPPPATH=Split(cpppath)) diff --git a/libIRDB/src/core/SConstruct b/libIRDB-core/src/SConstruct similarity index 100% rename from libIRDB/src/core/SConstruct rename to libIRDB-core/src/SConstruct diff --git a/libIRDB/src/core/address.cpp b/libIRDB-core/src/address.cpp similarity index 90% rename from libIRDB/src/core/address.cpp rename to libIRDB-core/src/address.cpp index f06a0783a0aff1a79f45fa3386bf907a1171a6f2..cb5bb7ebb755a51270bf2145f2b894aff2c1207d 100644 --- a/libIRDB/src/core/address.cpp +++ b/libIRDB-core/src/address.cpp @@ -20,7 +20,7 @@ #include <all.hpp> -#include <utils.hpp> +#include <irdb-util> #include <stdlib.h> using namespace libIRDB; @@ -31,8 +31,8 @@ vector<string> AddressID_t::WriteToDB(File_t *fid, db_id_t newid, bool p_withHea { assert(fid); - if(GetBaseID()==NOT_IN_DATABASE) - SetBaseID(newid); + if(getBaseID()==NOT_IN_DATABASE) + setBaseID(newid); /* string q; @@ -46,10 +46,10 @@ vector<string> AddressID_t::WriteToDB(File_t *fid, db_id_t newid, bool p_withHea q += */ return { - to_string(GetBaseID()), + to_string(getBaseID()), to_string(fileID), to_string(virtual_offset), - to_string(GetDoipID()) + to_string(getDoipID()) }; } diff --git a/libIRDB/src/core/all.hpp b/libIRDB-core/src/all.hpp similarity index 100% rename from libIRDB/src/core/all.hpp rename to libIRDB-core/src/all.hpp diff --git a/libIRDB/src/core/baseobj.cpp b/libIRDB-core/src/baseobj.cpp similarity index 77% rename from libIRDB/src/core/baseobj.cpp rename to libIRDB-core/src/baseobj.cpp index 900303f9f8e52f732c1dc710442a361d9d3e74b6..90cef65fdb8e19e1a20240f196cea48ca6633050 100644 --- a/libIRDB/src/core/baseobj.cpp +++ b/libIRDB-core/src/baseobj.cpp @@ -25,8 +25,8 @@ /* * initialize the DB interface */ -DBinterface_t* BaseObj_t::dbintr=NULL; -const db_id_t BaseObj_t::NOT_IN_DATABASE=-1; +DBinterface_t* BaseObj_t::dbintr=nullptr; +const db_id_t IRDB_SDK::BaseObj_t::NOT_IN_DATABASE=-1; /* * BaseObj_t constructor @@ -39,8 +39,9 @@ BaseObj_t::BaseObj_t(doip_t* _doip) : doip(_doip), base_id(BaseObj_t::NOT_IN_DAT /* * Set the database interface to be used for the base object class. */ -void BaseObj_t::SetInterface(DBinterface_t *dbi) +void IRDB_SDK::BaseObj_t::setInterface(IRDB_SDK::DBinterface_t *dbi) { - dbintr=dbi; + ::libIRDB::BaseObj_t::dbintr=dynamic_cast<libIRDB::DBinterface_t*>(dbi); + assert(::libIRDB::BaseObj_t::dbintr); } diff --git a/libIRDB/src/core/dbinterface.cpp b/libIRDB-core/src/dbinterface.cpp similarity index 71% rename from libIRDB/src/core/dbinterface.cpp rename to libIRDB-core/src/dbinterface.cpp index 742c76bc6916e70028a566de4490a93bafa6e6f3..f408adb289669812df763c1ea5bdb82eebef7acf 100644 --- a/libIRDB/src/core/dbinterface.cpp +++ b/libIRDB-core/src/dbinterface.cpp @@ -23,9 +23,9 @@ #include <iostream> #include <stdlib.h> -using namespace libIRDB; +using namespace std; -std::ostream& libIRDB::operator<<(std::ostream& output, const DatabaseError_t& p) +ostream& libIRDB::operator<<(ostream& output, const libIRDB::DatabaseError_t& p) { switch(p.GetErrorCode()) { @@ -36,10 +36,18 @@ std::ostream& libIRDB::operator<<(std::ostream& output, const DatabaseError_t& p output<<"Variant not detected in database"; break; default: - std::cerr<<"Cannot print database error code, aborting program...\n"; - exit(-100); + output<<"Cannot print database error code."; + break; } + return output; +} +ostream& IRDB_SDK::operator<<(ostream& output, const IRDB_SDK::DatabaseError_t& p) +{ + const auto p_p = &p; + const auto real_p=dynamic_cast<const libIRDB::DatabaseError_t* const>(p_p); + assert(real_p); + output << *real_p; return output; } diff --git a/libIRDB-core/src/decode_base.cpp b/libIRDB-core/src/decode_base.cpp new file mode 100644 index 0000000000000000000000000000000000000000..25e996b556c895ec1755e67804667818d5d279c3 --- /dev/null +++ b/libIRDB-core/src/decode_base.cpp @@ -0,0 +1,43 @@ + +#include <libIRDB-core.hpp> +#include <decode_base.hpp> +#include <operand_base.hpp> +#include <decode_csx86.hpp> +#include <operand_csx86.hpp> +#include <decode_csarm.hpp> +#include <operand_csarm.hpp> +#include <exception> + +using namespace std; +using namespace libIRDB; + + +unique_ptr<IRDB_SDK::DecodedInstruction_t> IRDB_SDK::DecodedInstruction_t::factory(const IRDB_SDK::Instruction_t* p_i) +{ + const auto i=dynamic_cast<const libIRDB::Instruction_t*>(p_i); + assert(i); + auto op=IRDB_SDK::FileIR_t::getArchitecture()->getMachineType()==IRDB_SDK::admtAarch64 ? (IRDB_SDK::DecodedInstruction_t*)new DecodedInstructionCapstoneARM64_t(i) : + IRDB_SDK::FileIR_t::getArchitecture()->getMachineType()==IRDB_SDK::admtX86_64 ? (IRDB_SDK::DecodedInstruction_t*)new DecodedInstructionCapstoneX86_t (i) : + IRDB_SDK::FileIR_t::getArchitecture()->getMachineType()==IRDB_SDK::admtI386 ? (IRDB_SDK::DecodedInstruction_t*)new DecodedInstructionCapstoneX86_t (i) : + throw invalid_argument("Unknown machine type"); + return unique_ptr<DecodedInstruction_t>(op); +} + +unique_ptr<IRDB_SDK::DecodedInstruction_t> IRDB_SDK::DecodedInstruction_t::factory(const IRDB_SDK::VirtualOffset_t start_addr, const void *data, uint32_t max_len) +{ + auto op=IRDB_SDK::FileIR_t::getArchitecture()->getMachineType()==IRDB_SDK::admtAarch64 ? (IRDB_SDK::DecodedInstruction_t*)new DecodedInstructionCapstoneARM64_t(start_addr,data,max_len) : + IRDB_SDK::FileIR_t::getArchitecture()->getMachineType()==IRDB_SDK::admtX86_64 ? (IRDB_SDK::DecodedInstruction_t*)new DecodedInstructionCapstoneX86_t (start_addr,data,max_len) : + IRDB_SDK::FileIR_t::getArchitecture()->getMachineType()==IRDB_SDK::admtI386 ? (IRDB_SDK::DecodedInstruction_t*)new DecodedInstructionCapstoneX86_t (start_addr,data,max_len) : + throw invalid_argument("Unknown machine type"); + return unique_ptr<DecodedInstruction_t>(op); +} + +unique_ptr<IRDB_SDK::DecodedInstruction_t> IRDB_SDK::DecodedInstruction_t::factory(const IRDB_SDK::VirtualOffset_t start_addr, const void *data, const void* endptr) +{ + auto op=IRDB_SDK::FileIR_t::getArchitecture()->getMachineType()==IRDB_SDK::admtAarch64 ? (IRDB_SDK::DecodedInstruction_t*)new DecodedInstructionCapstoneARM64_t(start_addr,data,endptr) : + IRDB_SDK::FileIR_t::getArchitecture()->getMachineType()==IRDB_SDK::admtX86_64 ? (IRDB_SDK::DecodedInstruction_t*)new DecodedInstructionCapstoneX86_t (start_addr,data,endptr) : + IRDB_SDK::FileIR_t::getArchitecture()->getMachineType()==IRDB_SDK::admtI386 ? (IRDB_SDK::DecodedInstruction_t*)new DecodedInstructionCapstoneX86_t (start_addr,data,endptr) : + throw invalid_argument("Unknown machine type"); + return unique_ptr<DecodedInstruction_t>(op); +} + diff --git a/libIRDB-core/src/decode_csarm.cpp b/libIRDB-core/src/decode_csarm.cpp new file mode 100644 index 0000000000000000000000000000000000000000..497d92b2abdfc0f5d903baac223fc2e388b1253a --- /dev/null +++ b/libIRDB-core/src/decode_csarm.cpp @@ -0,0 +1,364 @@ + +#include <libIRDB-core.hpp> +#include <decode_base.hpp> +#include <decode_csarm.hpp> +#include <operand_base.hpp> +#include <operand_csarm.hpp> + + +#include <capstone.h> +#include <arm64.h> +#include <string> +#include <functional> +#include <set> +#include <algorithm> +#include <stdexcept> + +using namespace libIRDB; +using namespace std; + +#define ALLOF(a) begin(a),end(a) +static const auto ARM64_REG_PC=(arm64_reg)(ARM64_REG_ENDING+1); + + +DecodedInstructionCapstoneARM64_t::CapstoneHandle_t* DecodedInstructionCapstoneARM64_t::cs_handle=NULL ; + +DecodedInstructionCapstoneARM64_t::CapstoneHandle_t::CapstoneHandle_t(FileIR_t* firp) +{ + const auto mode = CS_MODE_LITTLE_ENDIAN; + static_assert(sizeof(csh)==sizeof(handle), "Capstone handle size is unexpected. Has CS changed?"); + auto err = cs_open(CS_ARCH_ARM64, mode, (csh*)&handle); + + if (err) + { + const auto s=string("Failed on cs_open() with error returned: ")+to_string(err)+"\n"; + throw std::runtime_error(s); + } + cs_option(handle, CS_OPT_DETAIL, CS_OPT_ON); + cs_option(handle, CS_OPT_SYNTAX, CS_OPT_SYNTAX_INTEL); + + +} + + + + +static bool isPartOfGroup(const cs_insn* the_insn, const arm64_insn_group the_grp) +{ + const auto grp_it=find(ALLOF(the_insn->detail->groups), the_grp); + return grp_it!=end(the_insn->detail->groups); + +} + +static bool isJmp(cs_insn* the_insn) +{ + return isPartOfGroup(the_insn,ARM64_GRP_JUMP); +} + + +template<class type> +static inline type insnToImmedHelper(cs_insn* the_insn, csh handle) +{ + const auto count = cs_op_count(handle, the_insn, ARM64_OP_IMM); + const auto arm = &(the_insn->detail->arm64); + + if (count==0) + return 0; /* no immediate is the same as an immediate of 0, i guess? */ + else if (count==1) + { + const auto index = cs_op_index(handle, the_insn, ARM64_OP_IMM, 1); + return arm->operands[index].imm; + } + else + throw std::logic_error(string("Called ")+__FUNCTION__+" with number of immedaites not equal 1"); +} + + + +// shared code +// constructors, destructors, operators. + +void DecodedInstructionCapstoneARM64_t::Disassemble(const virtual_offset_t start_addr, const void *data, const uint32_t max_len) +{ + using namespace std::placeholders; + auto insn=cs_malloc(cs_handle->getHandle()); + auto address=(uint64_t)start_addr; + auto size=(size_t)max_len; + const uint8_t* code=(uint8_t*)data; + const auto ok = cs_disasm_iter(cs_handle->getHandle(), &code, &size, &address, insn); + if(!ok) + insn->size=0; + + auto &op0 = (insn->detail->arm64.operands[0]); // might change these. + auto &op1 = (insn->detail->arm64.operands[1]); + + const auto mnemonic=string(insn->mnemonic); + const auto is_ldr_type = mnemonic=="ldr" || mnemonic=="ldrsw" ; + if(is_ldr_type && op1.type==ARM64_OP_IMM) + { + // no, this is a pcrel load. + const auto imm=op1.imm; + op1.type=ARM64_OP_MEM; + op1.mem.base=ARM64_REG_PC; + op1.mem.index=ARM64_REG_INVALID; + op1.mem.disp=imm; + } + if(mnemonic=="prfm" && op0.type==ARM64_OP_IMM) + { + // no, this is a pcrel load. + const auto imm=op0.imm; + op0.type=ARM64_OP_MEM; + op0.mem.base=ARM64_REG_PC; + op0.mem.index=ARM64_REG_INVALID; + op0.mem.disp=imm; + } + + + const auto cs_freer=[](cs_insn * insn) -> void + { + cs_free(insn,1); + } ; + my_insn.reset(insn,cs_freer); +} + +DecodedInstructionCapstoneARM64_t::DecodedInstructionCapstoneARM64_t(const Instruction_t* i) +{ + if(!cs_handle) cs_handle=new CapstoneHandle_t(NULL); + if(!i) throw std::invalid_argument("No instruction given to DecodedInstruction_t(Instruction_t*)"); + + const auto length=i->getDataBits().size(); + const auto &databits=i->getDataBits(); + const auto data=databits.data(); + const auto address=i->getAddress()->getVirtualOffset(); + Disassemble(address,data,length); + + if(!valid()) throw std::invalid_argument("The Instruction_t::getDataBits field is not a valid instruction."); +} + +DecodedInstructionCapstoneARM64_t::DecodedInstructionCapstoneARM64_t(const virtual_offset_t start_addr, const void *data, uint32_t max_len) +{ + if(!cs_handle) cs_handle=new CapstoneHandle_t(NULL); + Disassemble(start_addr, data, max_len); +} + +DecodedInstructionCapstoneARM64_t::DecodedInstructionCapstoneARM64_t(const virtual_offset_t start_addr, const void *data, const void* endptr) +{ + if(!cs_handle) cs_handle=new CapstoneHandle_t(NULL); + const auto length=(char*)endptr-(char*)data; + Disassemble(start_addr,data,length); +} + +DecodedInstructionCapstoneARM64_t::DecodedInstructionCapstoneARM64_t(const DecodedInstructionCapstoneARM64_t& copy) +{ + *this=copy; +} + +DecodedInstructionCapstoneARM64_t::DecodedInstructionCapstoneARM64_t(const shared_ptr<void> &p_my_insn) + : my_insn(p_my_insn) +{ +} + +DecodedInstructionCapstoneARM64_t::~DecodedInstructionCapstoneARM64_t() +{ + // no need to cs_free(my_insn) because shared pointer will do that for us! +} + +DecodedInstructionCapstoneARM64_t& DecodedInstructionCapstoneARM64_t::operator=(const DecodedInstructionCapstoneARM64_t& copy) +{ + my_insn=copy.my_insn; + return *this; +} + +// public methods + +string DecodedInstructionCapstoneARM64_t::getDisassembly() const +{ + + if(!valid()) throw std::logic_error(string("Called ")+__FUNCTION__+" on invalid instruction"); + const auto the_insn=static_cast<cs_insn*>(my_insn.get()); + auto full_str=getMnemonic()+" "+the_insn->op_str; + + return full_str; +} + +bool DecodedInstructionCapstoneARM64_t::valid() const +{ + const auto the_insn=static_cast<cs_insn*>(my_insn.get()); + return the_insn->size!=0; +} + +uint32_t DecodedInstructionCapstoneARM64_t::length() const +{ + if(!valid()) throw std::logic_error(string("Called ")+__FUNCTION__+" on invalid instruction"); + const auto the_insn=static_cast<cs_insn*>(my_insn.get()); + return the_insn->size; +} + +bool DecodedInstructionCapstoneARM64_t::isBranch() const +{ + if(!valid()) throw std::logic_error(string("Called ")+__FUNCTION__+" on invalid instruction"); + const auto the_insn=static_cast<cs_insn*>(my_insn.get()); + return isCall() || isReturn() || isJmp(the_insn); +} + +bool DecodedInstructionCapstoneARM64_t::isCall() const +{ + if(!valid()) throw std::logic_error(string("Called ")+__FUNCTION__+" on invalid instruction"); + + const auto mnemonic=getMnemonic(); + return mnemonic=="bl" || mnemonic=="blr"; +} + +bool DecodedInstructionCapstoneARM64_t::isUnconditionalBranch() const +{ + if(!valid()) throw std::logic_error(string("Called ")+__FUNCTION__+" on invalid instruction"); + const auto the_insn=static_cast<cs_insn*>(my_insn.get()); + + return isJmp(the_insn) && + (getMnemonic()=="b" || getMnemonic()=="br"); +} + +bool DecodedInstructionCapstoneARM64_t::isConditionalBranch() const +{ + if(!valid()) throw std::logic_error(string("Called ")+__FUNCTION__+" on invalid instruction"); + const auto the_insn=static_cast<cs_insn*>(my_insn.get()); + return isJmp(the_insn) && !isUnconditionalBranch(); +} + +bool DecodedInstructionCapstoneARM64_t::isReturn() const +{ + if(!valid()) throw std::logic_error(string("Called ")+__FUNCTION__+" on invalid instruction"); + const auto the_insn=static_cast<cs_insn*>(my_insn.get()); + return isPartOfGroup(the_insn,ARM64_GRP_RET); +} + +bool DecodedInstructionCapstoneARM64_t::hasOperand(const int op_num) const +{ + if(op_num<0) throw std::logic_error(string("Called ")+ __FUNCTION__+" with opnum="+to_string(op_num)); + const auto the_insn=static_cast<cs_insn*>(my_insn.get()); + const auto &arm = (the_insn->detail->arm64); + return 0 <= op_num && op_num < arm.op_count; +} + +// 0-based. first operand is numbered 0. +shared_ptr<DecodedOperand_t> DecodedInstructionCapstoneARM64_t::getOperand(const int op_num) const +{ + if(!valid()) throw std::logic_error(string("Called ")+__FUNCTION__+" on invalid instruction"); + if(!hasOperand(op_num)) throw std::logic_error(string("Called ")+__FUNCTION__+" on without hasOperand()==true"); + + return shared_ptr<DecodedOperand_t>(new DecodedOperandCapstoneARM64_t(my_insn,(uint8_t)op_num)); + +} + +DecodedOperandVector_t DecodedInstructionCapstoneARM64_t::getOperands() const +{ + if(!valid()) throw std::logic_error(string("Called ")+__FUNCTION__+" on invalid instruction"); + const auto the_insn=static_cast<cs_insn*>(my_insn.get()); + const auto &arm = (the_insn->detail->arm64); + const auto opcount=arm.op_count; + + auto ret_val=DecodedOperandVector_t(); + + for(auto i=0;i<opcount;i++) + ret_val.push_back(getOperand(i)); + + return ret_val; +} + +string DecodedInstructionCapstoneARM64_t::getMnemonic() const +{ + if(!valid()) throw std::logic_error(string("Called ")+__FUNCTION__+" on invalid instruction"); + + // return the new string. + const auto the_insn=static_cast<cs_insn*>(my_insn.get()); + return the_insn->mnemonic; + + +} + + +int64_t DecodedInstructionCapstoneARM64_t::getImmediate() const +{ + if(!valid()) throw std::logic_error(string("Called ")+__FUNCTION__+" on invalid instruction"); + + const auto the_insn=static_cast<cs_insn*>(my_insn.get()); + + // direct calls and jumps have a "immediate" which is really an address" those are returned by getAddress + if(isCall() || isJmp(the_insn)) + return 0; + + return insnToImmedHelper<int64_t>(the_insn, cs_handle->getHandle()); +} + + +virtual_offset_t DecodedInstructionCapstoneARM64_t::getAddress() const +{ + if(!valid()) throw std::logic_error(string("Called ")+__FUNCTION__+" on invalid instruction"); + const auto the_insn=static_cast<cs_insn*>(my_insn.get()); + if(isCall() || isJmp(the_insn)) + { + const auto mnemonic=getMnemonic(); + if( mnemonic=="tbnz" || mnemonic=="tbz") + return getOperand(2)->getConstant(); + return insnToImmedHelper<int64_t>(the_insn, cs_handle->getHandle()); + } + assert(0); + +} + + +bool DecodedInstructionCapstoneARM64_t::setsStackPointer() const +{ + if(!valid()) throw std::logic_error(string("Called ")+__FUNCTION__+" on invalid instruction"); + + if(!hasOperand(0)) return false; + + const auto the_insn=static_cast<cs_insn*>(my_insn.get()); + const auto &arm = (the_insn->detail->arm64); + return (arm.operands[0].type==ARM64_OP_REG && arm.operands[0].reg==ARM64_REG_SP); +} + +uint32_t DecodedInstructionCapstoneARM64_t::getPrefixCount() const +{ + if(!valid()) throw std::logic_error(string("Called ")+__FUNCTION__+" on invalid instruction"); + return 0; +} + +IRDB_SDK::VirtualOffset_t DecodedInstructionCapstoneARM64_t::getMemoryDisplacementOffset(const IRDB_SDK::DecodedOperand_t* t, const IRDB_SDK::Instruction_t* insn) const +{ + if(!valid()) throw std::logic_error(string("Called ")+__FUNCTION__+" on invalid instruction"); + assert(0); +} + + + +bool DecodedInstructionCapstoneARM64_t::hasRelevantRepPrefix() const +{ + if(!valid()) throw std::logic_error(string("Called ")+__FUNCTION__+" on invalid instruction"); + return false; +} + +bool DecodedInstructionCapstoneARM64_t::hasRelevantRepnePrefix() const +{ + if(!valid()) throw std::logic_error(string("Called ")+__FUNCTION__+" on invalid instruction"); + return false; +} + +bool DecodedInstructionCapstoneARM64_t::hasRelevantOperandSizePrefix() const +{ + if(!valid()) throw std::logic_error(string("Called ")+__FUNCTION__+" on invalid instruction"); + return false; +} + +bool DecodedInstructionCapstoneARM64_t::hasRexWPrefix() const +{ + if(!valid()) throw std::logic_error(string("Called ")+__FUNCTION__+" on invalid instruction"); + return false; +} + +bool DecodedInstructionCapstoneARM64_t::hasImplicitlyModifiedRegs() const +{ + if(!valid()) throw std::logic_error(string("Called ")+__FUNCTION__+" on invalid instruction"); + return false; +} + diff --git a/libIRDB/src/core/decode_cs.cpp b/libIRDB-core/src/decode_csx86.cpp similarity index 83% rename from libIRDB/src/core/decode_cs.cpp rename to libIRDB-core/src/decode_csx86.cpp index ec824293540cf94c45ef18ac51ce895a61167310..c261c069e16dfca79dc32f723d2b53337adb4f31 100644 --- a/libIRDB/src/core/decode_cs.cpp +++ b/libIRDB-core/src/decode_csx86.cpp @@ -1,5 +1,9 @@ #include <libIRDB-core.hpp> +#include <decode_base.hpp> +#include <decode_csx86.hpp> +#include <operand_base.hpp> +#include <operand_csx86.hpp> #include <capstone.h> #include <x86.h> @@ -14,11 +18,13 @@ using namespace std; #define ALLOF(a) begin(a),end(a) -DecodedInstructionCapstone_t::CapstoneHandle_t* DecodedInstructionCapstone_t::cs_handle=NULL ; -DecodedInstructionCapstone_t::CapstoneHandle_t::CapstoneHandle_t(FileIR_t* firp) + +DecodedInstructionCapstoneX86_t::CapstoneHandle_t* DecodedInstructionCapstoneX86_t::cs_handle=NULL ; + +DecodedInstructionCapstoneX86_t::CapstoneHandle_t::CapstoneHandle_t(FileIR_t* firp) { - const auto width=FileIR_t::GetArchitectureBitWidth(); + const auto width=FileIR_t::getArchitectureBitWidth(); const auto mode = (width==64) ? CS_MODE_64: CS_MODE_32; static_assert(sizeof(csh)==sizeof(handle), "Capstone handle size is unexpected. Has CS changed?"); auto err = cs_open(CS_ARCH_X86, mode, (csh*)&handle); @@ -76,7 +82,7 @@ class CapstoneHandle_t CapstoneHandle_t(FileIR_t* firp=NULL) { - const auto width=FileIR_t::GetArchitectureBitWidth(); + const auto width=FileIR_t::getArchitectureBitWidth(); const auto mode = (width==64) ? CS_MODE_64: CS_MODE_32; auto err = cs_open(CS_ARCH_X86, mode, &handle); @@ -120,7 +126,7 @@ static inline type insnToImmedHelper(cs_insn* the_insn, csh handle) // shared code // constructors, destructors, operators. -void DecodedInstructionCapstone_t::Disassemble(const virtual_offset_t start_addr, const void *data, const uint32_t max_len) +void DecodedInstructionCapstoneX86_t::Disassemble(const virtual_offset_t start_addr, const void *data, const uint32_t max_len) { using namespace std::placeholders; auto insn=cs_malloc(cs_handle->getHandle()); @@ -192,49 +198,49 @@ void DecodedInstructionCapstone_t::Disassemble(const virtual_offset_t start_addr my_insn.reset(insn,cs_freer); } -DecodedInstructionCapstone_t::DecodedInstructionCapstone_t(const Instruction_t* i) +DecodedInstructionCapstoneX86_t::DecodedInstructionCapstoneX86_t(const Instruction_t* i) { if(!cs_handle) cs_handle=new CapstoneHandle_t(NULL); if(!i) throw std::invalid_argument("No instruction given to DecodedInstruction_t(Instruction_t*)"); - const auto length=i->GetDataBits().size(); - const auto &databits=i->GetDataBits(); + const auto length=i->getDataBits().size(); + const auto &databits=i->getDataBits(); const auto data=databits.data(); - const auto address=i->GetAddress()->GetVirtualOffset(); + const auto address=i->getAddress()->getVirtualOffset(); Disassemble(address,data,length); - if(!valid()) throw std::invalid_argument("The Instruction_t::GetDataBits field is not a valid instruction."); + if(!valid()) throw std::invalid_argument("The Instruction_t::getDataBits field is not a valid instruction."); } -DecodedInstructionCapstone_t::DecodedInstructionCapstone_t(const virtual_offset_t start_addr, const void *data, uint32_t max_len) +DecodedInstructionCapstoneX86_t::DecodedInstructionCapstoneX86_t(const virtual_offset_t start_addr, const void *data, uint32_t max_len) { if(!cs_handle) cs_handle=new CapstoneHandle_t(NULL); Disassemble(start_addr, data, max_len); } -DecodedInstructionCapstone_t::DecodedInstructionCapstone_t(const virtual_offset_t start_addr, const void *data, const void* endptr) +DecodedInstructionCapstoneX86_t::DecodedInstructionCapstoneX86_t(const virtual_offset_t start_addr, const void *data, const void* endptr) { if(!cs_handle) cs_handle=new CapstoneHandle_t(NULL); const auto length=(char*)endptr-(char*)data; Disassemble(start_addr,data,length); } -DecodedInstructionCapstone_t::DecodedInstructionCapstone_t(const DecodedInstructionCapstone_t& copy) +DecodedInstructionCapstoneX86_t::DecodedInstructionCapstoneX86_t(const DecodedInstructionCapstoneX86_t& copy) { *this=copy; } -DecodedInstructionCapstone_t::DecodedInstructionCapstone_t(const shared_ptr<void> &p_my_insn) +DecodedInstructionCapstoneX86_t::DecodedInstructionCapstoneX86_t(const shared_ptr<void> &p_my_insn) : my_insn(p_my_insn) { } -DecodedInstructionCapstone_t::~DecodedInstructionCapstone_t() +DecodedInstructionCapstoneX86_t::~DecodedInstructionCapstoneX86_t() { // no need to cs_free(my_insn) because shared pointer will do that for us! } -DecodedInstructionCapstone_t& DecodedInstructionCapstone_t::operator=(const DecodedInstructionCapstone_t& copy) +DecodedInstructionCapstoneX86_t& DecodedInstructionCapstoneX86_t::operator=(const DecodedInstructionCapstoneX86_t& copy) { my_insn=copy.my_insn; return *this; @@ -242,7 +248,7 @@ DecodedInstructionCapstone_t& DecodedInstructionCapstone_t::operator=(const Deco // public methods -string DecodedInstructionCapstone_t::getDisassembly() const +string DecodedInstructionCapstoneX86_t::getDisassembly() const { const auto myReplace=[](std::string &str, const std::string& oldStr, @@ -338,27 +344,27 @@ string DecodedInstructionCapstone_t::getDisassembly() const return full_str; } -bool DecodedInstructionCapstone_t::valid() const +bool DecodedInstructionCapstoneX86_t::valid() const { const auto the_insn=static_cast<cs_insn*>(my_insn.get()); return the_insn->size!=0; } -uint32_t DecodedInstructionCapstone_t::length() const +uint32_t DecodedInstructionCapstoneX86_t::length() const { if(!valid()) throw std::logic_error(string("Called ")+__FUNCTION__+" on invalid instruction"); const auto the_insn=static_cast<cs_insn*>(my_insn.get()); return the_insn->size; } -bool DecodedInstructionCapstone_t::isBranch() const +bool DecodedInstructionCapstoneX86_t::isBranch() const { if(!valid()) throw std::logic_error(string("Called ")+__FUNCTION__+" on invalid instruction"); const auto the_insn=static_cast<cs_insn*>(my_insn.get()); return isCall() || isReturn() || isJmp(the_insn); } -bool DecodedInstructionCapstone_t::isCall() const +bool DecodedInstructionCapstoneX86_t::isCall() const { if(!valid()) throw std::logic_error(string("Called ")+__FUNCTION__+" on invalid instruction"); @@ -366,7 +372,7 @@ bool DecodedInstructionCapstone_t::isCall() const return isPartOfGroup(the_insn,X86_GRP_CALL); } -bool DecodedInstructionCapstone_t::isUnconditionalBranch() const +bool DecodedInstructionCapstoneX86_t::isUnconditionalBranch() const { if(!valid()) throw std::logic_error(string("Called ")+__FUNCTION__+" on invalid instruction"); const auto the_insn=static_cast<cs_insn*>(my_insn.get()); @@ -374,21 +380,21 @@ bool DecodedInstructionCapstone_t::isUnconditionalBranch() const return isJmp(the_insn) && !isConditionalBranch(); } -bool DecodedInstructionCapstone_t::isConditionalBranch() const +bool DecodedInstructionCapstoneX86_t::isConditionalBranch() const { if(!valid()) throw std::logic_error(string("Called ")+__FUNCTION__+" on invalid instruction"); const auto the_insn=static_cast<cs_insn*>(my_insn.get()); return isJmp(the_insn) && getMnemonic()!="jmp"; } -bool DecodedInstructionCapstone_t::isReturn() const +bool DecodedInstructionCapstoneX86_t::isReturn() const { if(!valid()) throw std::logic_error(string("Called ")+__FUNCTION__+" on invalid instruction"); const auto the_insn=static_cast<cs_insn*>(my_insn.get()); return isPartOfGroup(the_insn,X86_GRP_RET); } -bool DecodedInstructionCapstone_t::hasOperand(const int op_num) const +bool DecodedInstructionCapstoneX86_t::hasOperand(const int op_num) const { if(op_num<0) throw std::logic_error(string("Called ")+ __FUNCTION__+" with opnum="+to_string(op_num)); const auto the_insn=static_cast<cs_insn*>(my_insn.get()); @@ -397,23 +403,23 @@ bool DecodedInstructionCapstone_t::hasOperand(const int op_num) const } // 0-based. first operand is numbered 0. -DecodedOperandCapstone_t DecodedInstructionCapstone_t::getOperand(const int op_num) const +shared_ptr<DecodedOperand_t> DecodedInstructionCapstoneX86_t::getOperand(const int op_num) const { if(!valid()) throw std::logic_error(string("Called ")+__FUNCTION__+" on invalid instruction"); if(!hasOperand(op_num)) throw std::logic_error(string("Called ")+__FUNCTION__+" on without hasOperand()==true"); - return DecodedOperandCapstone_t(my_insn,(uint8_t)op_num); + return shared_ptr<DecodedOperand_t>(new DecodedOperandCapstoneX86_t(my_insn,(uint8_t)op_num)); } -DecodedOperandCapstoneVector_t DecodedInstructionCapstone_t::getOperands() const +IRDB_SDK::DecodedOperandVector_t DecodedInstructionCapstoneX86_t::getOperands() const { if(!valid()) throw std::logic_error(string("Called ")+__FUNCTION__+" on invalid instruction"); const auto the_insn=static_cast<cs_insn*>(my_insn.get()); const auto &x86 = (the_insn->detail->x86); const auto opcount=x86.op_count; - auto ret_val=DecodedOperandCapstoneVector_t(); + auto ret_val=IRDB_SDK::DecodedOperandVector_t(); for(auto i=0;i<opcount;i++) ret_val.push_back(getOperand(i)); @@ -421,7 +427,7 @@ DecodedOperandCapstoneVector_t DecodedInstructionCapstone_t::getOperands() const return ret_val; } -string DecodedInstructionCapstone_t::getMnemonic() const +string DecodedInstructionCapstoneX86_t::getMnemonic() const { if(!valid()) throw std::logic_error(string("Called ")+__FUNCTION__+" on invalid instruction"); @@ -471,7 +477,7 @@ string DecodedInstructionCapstone_t::getMnemonic() const } -int64_t DecodedInstructionCapstone_t::getImmediate() const +int64_t DecodedInstructionCapstoneX86_t::getImmediate() const { if(!valid()) throw std::logic_error(string("Called ")+__FUNCTION__+" on invalid instruction"); @@ -485,7 +491,7 @@ int64_t DecodedInstructionCapstone_t::getImmediate() const } -virtual_offset_t DecodedInstructionCapstone_t::getAddress() const +virtual_offset_t DecodedInstructionCapstoneX86_t::getAddress() const { if(!valid()) throw std::logic_error(string("Called ")+__FUNCTION__+" on invalid instruction"); @@ -514,7 +520,7 @@ virtual_offset_t DecodedInstructionCapstone_t::getAddress() const } -bool DecodedInstructionCapstone_t::setsStackPointer() const +bool DecodedInstructionCapstoneX86_t::setsStackPointer() const { if(!valid()) throw std::logic_error(string("Called ")+__FUNCTION__+" on invalid instruction"); @@ -577,7 +583,7 @@ bool DecodedInstructionCapstone_t::setsStackPointer() const return is_op0; } -uint32_t DecodedInstructionCapstone_t::getPrefixCount() const +uint32_t DecodedInstructionCapstoneX86_t::getPrefixCount() const { if(!valid()) throw std::logic_error(string("Called ")+__FUNCTION__+" on invalid instruction"); @@ -588,8 +594,9 @@ uint32_t DecodedInstructionCapstone_t::getPrefixCount() const return count_with_rex; } -virtual_offset_t DecodedInstructionCapstone_t::getMemoryDisplacementOffset(const DecodedOperandCapstone_t& t, const Instruction_t* insn) const +IRDB_SDK::VirtualOffset_t DecodedInstructionCapstoneX86_t::getMemoryDisplacementOffset(const IRDB_SDK::DecodedOperand_t* p_t, const IRDB_SDK::Instruction_t* insn) const { + auto &t = *p_t; if(!valid()) throw std::logic_error(string("Called ")+__FUNCTION__+" on invalid instruction"); const auto the_insn=static_cast<cs_insn*>(my_insn.get()); @@ -633,14 +640,14 @@ virtual_offset_t DecodedInstructionCapstone_t::getMemoryDisplacementOffset(const const auto disp_start=the_insn->size-imm_size-disp_size; const auto imm_start=the_insn->size-imm_size; - const auto candidate_disp_eq = disp_size==4 ? *(int32_t*)(&insn->GetDataBits().c_str()[disp_start])==(int32_t)disp : - disp_size==2 ? *(int16_t*)(&insn->GetDataBits().c_str()[disp_start])==(int16_t)disp : - disp_size==1 ? *(int8_t *)(&insn->GetDataBits().c_str()[disp_start])==(int8_t )disp : (assert(0),false); + const auto candidate_disp_eq = disp_size==4 ? *(int32_t*)(&insn->getDataBits().c_str()[disp_start])==(int32_t)disp : + disp_size==2 ? *(int16_t*)(&insn->getDataBits().c_str()[disp_start])==(int16_t)disp : + disp_size==1 ? *(int8_t *)(&insn->getDataBits().c_str()[disp_start])==(int8_t )disp : (assert(0),false); - const auto candidate_imm_eq = imm_size==8 ? *(int64_t*)(&insn->GetDataBits().c_str()[imm_start])==(int64_t)imm : - imm_size==4 ? *(int32_t*)(&insn->GetDataBits().c_str()[imm_start])==(int32_t)imm : - imm_size==2 ? *(int16_t*)(&insn->GetDataBits().c_str()[imm_start])==(int16_t)imm : - imm_size==1 ? *(int8_t *)(&insn->GetDataBits().c_str()[imm_start])==(int8_t )imm : (int64_t)(assert(0),false); + const auto candidate_imm_eq = imm_size==8 ? *(int64_t*)(&insn->getDataBits().c_str()[imm_start])==(int64_t)imm : + imm_size==4 ? *(int32_t*)(&insn->getDataBits().c_str()[imm_start])==(int32_t)imm : + imm_size==2 ? *(int16_t*)(&insn->getDataBits().c_str()[imm_start])==(int16_t)imm : + imm_size==1 ? *(int8_t *)(&insn->getDataBits().c_str()[imm_start])==(int8_t )imm : (int64_t)(assert(0),false); if(candidate_disp_eq && candidate_imm_eq) return disp_start; @@ -654,35 +661,35 @@ virtual_offset_t DecodedInstructionCapstone_t::getMemoryDisplacementOffset(const -bool DecodedInstructionCapstone_t::hasRelevantRepPrefix() const +bool DecodedInstructionCapstoneX86_t::hasRelevantRepPrefix() const { if(!valid()) throw std::logic_error(string("Called ")+__FUNCTION__+" on invalid instruction"); const auto the_insn=static_cast<cs_insn*>(my_insn.get()); return hasPrefix(the_insn,X86_PREFIX_REP); } -bool DecodedInstructionCapstone_t::hasRelevantRepnePrefix() const +bool DecodedInstructionCapstoneX86_t::hasRelevantRepnePrefix() const { if(!valid()) throw std::logic_error(string("Called ")+__FUNCTION__+" on invalid instruction"); const auto the_insn=static_cast<cs_insn*>(my_insn.get()); return hasPrefix(the_insn,X86_PREFIX_REPNE); } -bool DecodedInstructionCapstone_t::hasRelevantOperandSizePrefix() const +bool DecodedInstructionCapstoneX86_t::hasRelevantOperandSizePrefix() const { if(!valid()) throw std::logic_error(string("Called ")+__FUNCTION__+" on invalid instruction"); const auto the_insn=static_cast<cs_insn*>(my_insn.get()); return hasPrefix(the_insn,X86_PREFIX_OPSIZE); } -bool DecodedInstructionCapstone_t::hasRexWPrefix() const +bool DecodedInstructionCapstoneX86_t::hasRexWPrefix() const { if(!valid()) throw std::logic_error(string("Called ")+__FUNCTION__+" on invalid instruction"); const auto the_insn=static_cast<cs_insn*>(my_insn.get()); return (the_insn->detail->x86.rex & 0x8) == 0x8; } -bool DecodedInstructionCapstone_t::hasImplicitlyModifiedRegs() const +bool DecodedInstructionCapstoneX86_t::hasImplicitlyModifiedRegs() const { if(!valid()) throw std::logic_error(string("Called ")+__FUNCTION__+" on invalid instruction"); diff --git a/libIRDB-core/src/decode_dispatch.cpp b/libIRDB-core/src/decode_dispatch.cpp new file mode 100644 index 0000000000000000000000000000000000000000..97631d5cbad1dacf76a3a569b157251ee08f4c68 --- /dev/null +++ b/libIRDB-core/src/decode_dispatch.cpp @@ -0,0 +1,115 @@ + +#include <libIRDB-core.hpp> +#include <decode_base.hpp> +#include <decode_csx86.hpp> +#include <decode_csarm.hpp> + +#include <operand_base.hpp> +#include <operand_csx86.hpp> +#include <operand_csarm.hpp> + +#include <decode_dispatch.hpp> +#include <operand_dispatch.hpp> + + +using namespace libIRDB; +using namespace std; + +// constructors, destructors, operators. + +DecodedInstructionDispatcher_t::DecodedInstructionDispatcher_t(const Instruction_t* i) +{ + cs=DecodedInstructionCapstone_t::factory(i); +} + +DecodedInstructionDispatcher_t::DecodedInstructionDispatcher_t(const virtual_offset_t start_addr, const void *data, uint32_t max_len) +{ + cs=DecodedInstructionCapstone_t::factory(start_addr,data,max_len); +} + +DecodedInstructionDispatcher_t::DecodedInstructionDispatcher_t(const virtual_offset_t start_addr, const void *data, const void* endptr) +{ + cs=DecodedInstructionCapstone_t::factory(start_addr,data,endptr); +} + +DecodedInstructionDispatcher_t::DecodedInstructionDispatcher_t(const DecodedInstructionDispatcher_t& copy) +{ + cs=copy.cs; +} + +DecodedInstructionDispatcher_t::~DecodedInstructionDispatcher_t() +{ +} + +DecodedInstructionDispatcher_t& DecodedInstructionDispatcher_t::operator=(const DecodedInstructionDispatcher_t& copy) +{ + cs=copy.cs; + return *this; +} + + + +#define passthrough_to_cs(ret_type, method_name) \ + ret_type DecodedInstructionDispatcher_t::method_name() const \ + { \ + return cs->method_name(); \ + } + +// public methods + +/* demonstrating things are the same */ +passthrough_to_cs(bool, valid); +passthrough_to_cs(uint32_t, length); +passthrough_to_cs(bool, isBranch); +passthrough_to_cs(bool, isCall); +passthrough_to_cs(bool, isUnconditionalBranch); +passthrough_to_cs(bool, isConditionalBranch); +passthrough_to_cs(bool, isReturn); +passthrough_to_cs(uint32_t, getPrefixCount); +passthrough_to_cs(bool, hasRexWPrefix); +passthrough_to_cs(bool, setsStackPointer); +passthrough_to_cs(bool, hasRelevantRepPrefix); // rep ret disagreement. +passthrough_to_cs(bool, hasRelevantRepnePrefix); +passthrough_to_cs(bool, hasRelevantOperandSizePrefix); + +/* demonstrating when capstone is better */ +passthrough_to_cs(string, getMnemonic); +passthrough_to_cs(string,getDisassembly); +passthrough_to_cs(virtual_offset_t, getAddress); +passthrough_to_cs(int64_t, getImmediate); + +// demonstrating they different and trying to determine which is better. +passthrough_to_cs(bool, hasImplicitlyModifiedRegs); + +// not yet completed +// needs more complicated impl. + + +bool DecodedInstructionDispatcher_t::hasOperand(const int op_num) const +{ + const auto cs_res = cs->hasOperand(op_num); + return cs_res; +} + +// 0-based. first operand is numbered 0. +unique_ptr<DecodedOperand_t> DecodedInstructionDispatcher_t::getOperand(const int op_num) const +{ + return unique_ptr<DecodedOperand_t>(new DecodedOperandDispatcher_t(cs->getOperand(op_num))); +} + +DecodedOperandMetaVector_t DecodedInstructionDispatcher_t::getOperands() const +{ + auto ret_val=DecodedOperandMetaVector_t(); + auto cs_operands=cs->getOperands(); + for(const auto &op : cs_operands ) + ret_val.push_back(DecodedOperandDispatcher_t(op)); + return ret_val; +} + +virtual_offset_t DecodedInstructionDispatcher_t::getMemoryDisplacementOffset(const DecodedOperandDispatcher_t& t, const Instruction_t* insn) const +{ + return cs->getMemoryDisplacementOffset(*t.cs, insn); +} + + + diff --git a/libIRDB/src/core/eh.cpp b/libIRDB-core/src/eh.cpp similarity index 86% rename from libIRDB/src/core/eh.cpp rename to libIRDB-core/src/eh.cpp index 664ad880532303351b31181b9b1a4b853a40003c..fea5ca337dbd240bac597e77a55383a0a40cfcd3 100644 --- a/libIRDB/src/core/eh.cpp +++ b/libIRDB-core/src/eh.cpp @@ -19,22 +19,23 @@ */ #include <all.hpp> -#include <utils.hpp> +#include <irdb-util> #include <tuple> #include <functional> #include <assert.h> #include <sstream> #include <iostream> #include <iomanip> +#include <algorithm> using namespace libIRDB; using namespace std; bool libIRDB::operator<(const EhProgram_t&a, const EhProgram_t&b) { - return tie(a.cie_program,a.fde_program,a.code_alignment_factor,a.data_alignment_factor,a.return_register, a.ptrsize, a.GetRelocations()) + return tie(a.cie_program,a.fde_program,a.code_alignment_factor,a.data_alignment_factor,a.return_register, a.ptrsize, a.getRelocations()) < - tie(b.cie_program,b.fde_program,b.code_alignment_factor,b.data_alignment_factor,b.return_register, b.ptrsize, b.GetRelocations()); + tie(b.cie_program,b.fde_program,b.code_alignment_factor,b.data_alignment_factor,b.return_register, b.ptrsize, b.getRelocations()); } namespace std @@ -92,15 +93,9 @@ vector<std::string> EhProgram_t::WriteToDB(File_t* fid) // writes to DB, ID i string encoded_cie_program=vec_to_encoded_string(cie_program); string encoded_fde_program=vec_to_encoded_string(fde_program); -/* - string q; - q ="insert into " + fid->GetEhProgramTableName(); - q+="(eh_pgm_id,caf,daf,return_register,ptrsize,cie_program,fde_program) "+ - string(" VALUES (") + -*/ return { - to_string(GetBaseID()), + to_string(getBaseID()), to_string(+code_alignment_factor), to_string(+data_alignment_factor), to_string(+return_register), @@ -129,36 +124,36 @@ std::string EhCallSite_t::WriteToDB(File_t* fid) // writes to DB, ID is not - auto landing_pad_id=BaseObj_t::NOT_IN_DATABASE; if(landing_pad != NULL) - landing_pad_id=landing_pad->GetBaseID(); + landing_pad_id=landing_pad->getBaseID(); const auto ttov_str=vec_to_string(ttov); - q ="insert into " + fid->GetEhCallSiteTableName(); + q ="insert into " + fid->getEhCallSiteTableName(); q+="(ehcs_id,tt_encoding,ttov,lp_insn_id) "+ string(" VALUES (") + - string("'") + to_string(GetBaseID()) + string("', ") + + string("'") + to_string(getBaseID()) + string("', ") + string("'") + to_string(+tt_encoding) + string("', ") + string("'") + ttov_str + string("', ") + string("'") + to_string(landing_pad_id) + string("') ;"); return q; } -bool EhCallSite_t::GetHasCleanup() const +bool EhCallSite_t::getHasCleanup() const { const auto ttov_it=find(ttov.begin(), ttov.end(), 0); return ttov_it!=ttov.end(); } -void EhCallSite_t::SetHasCleanup(bool p_has_cleanup) +void EhCallSite_t::setHasCleanup(bool p_has_cleanup) { if(p_has_cleanup) { - if(!GetHasCleanup()) + if(!getHasCleanup()) ttov.push_back(0); } else { - if(GetHasCleanup()) + if(getHasCleanup()) { const auto ttov_it=find(ttov.begin(), ttov.end(), 0); ttov.erase(ttov_it); diff --git a/libIRDB/src/core/file.cpp b/libIRDB-core/src/file.cpp similarity index 95% rename from libIRDB/src/core/file.cpp rename to libIRDB-core/src/file.cpp index 7aa10476f6a13748430cde33781069b76d51e6f4..87a55124bb4324f7d4859786c08ce2e1256cf363 100644 --- a/libIRDB/src/core/file.cpp +++ b/libIRDB-core/src/file.cpp @@ -20,13 +20,13 @@ #include <all.hpp> -#include <utils.hpp> +#include <irdb-util> #include <stdlib.h> #include <unistd.h> #include <fstream> #include <iostream> -#include <utils.hpp> +#include <irdb-util> using namespace libIRDB; using namespace std; @@ -56,7 +56,7 @@ File_t::File_t(const db_id_t &myfile_id, const db_id_t &my_orig_fid, const std:: ehcss_table_name(ehcss), elfoid(myoid) { - SetBaseID(myfile_id); + setBaseID(myfile_id); } @@ -90,6 +90,6 @@ void File_t::CreateTables() buffer << t.rdbuf(); - dbintr->IssueQuery(buffer.str().c_str()); + dbintr->issueQuery(buffer.str().c_str()); } diff --git a/libIRDB/src/core/fileir.cpp b/libIRDB-core/src/fileir.cpp similarity index 52% rename from libIRDB/src/core/fileir.cpp rename to libIRDB-core/src/fileir.cpp index 59ec13bcf49ea7734f7ec3b913527b09373e90a2..73442e61e260d3df04e694f2a53bce321b81e215 100644 --- a/libIRDB/src/core/fileir.cpp +++ b/libIRDB-core/src/fileir.cpp @@ -20,14 +20,16 @@ */ #include <all.hpp> -#include <utils.hpp> +#include <irdb-util> #include <cstdlib> #include <map> #include <fstream> #include <elf.h> #include <stdlib.h> +#include <algorithm> #include <sys/wait.h> #include <iomanip> +#include <irdb-util> using namespace libIRDB; using namespace std; @@ -77,8 +79,8 @@ static void UpdateEntryPoints( db_id_t func_entry_id=(*it).second; assert(func_entry_id==-1 || insnMap.at(func_entry_id)); - func->SetEntryPoint(insnMap.at(func_entry_id)); -// cout<<"Function named "<<func->GetName()<< " getting entry point set to "<<insnMap[func_entry_id]->GetComment()<<"."<<endl; + func->setEntryPoint(insnMap.at(func_entry_id)); +// cout<<"Function named "<<func->getName()<< " getting entry point set to "<<insnMap[func_entry_id]->getComment()<<"."<<endl; } } @@ -93,13 +95,13 @@ static void UpdateUnresolvedEhCallSites( const auto& insnid=i.second; const auto& insn=insnMap.at(insnid); assert(insn); - ehcs->SetLandingPad(insn); + ehcs->setLandingPad(insn); } } static virtual_offset_t strtovo(std::string s) { - return strtoint<virtual_offset_t>(s); + return IRDB_SDK::strtoint<virtual_offset_t>(s); } // Create a Variant from the database @@ -110,45 +112,25 @@ FileIR_t::FileIR_t(const VariantID_t &newprogid, File_t* fid) orig_variant_ir_p=NULL; if(fid==NULL) - fileptr=newprogid.GetMainFile(); + fileptr=dynamic_cast<File_t*>(newprogid.getMainFile()); else fileptr=fid; - if(progid.IsRegistered()) + if(progid.isRegistered()) { ReadFromDB(); - SetArchitecture(); + setArchitecture(); } } FileIR_t::~FileIR_t() { - for(std::set<Function_t*>::const_iterator i=funcs.begin(); i!=funcs.end(); ++i) - { - delete *i; - } - - - for(std::set<Instruction_t*>::const_iterator i=insns.begin(); i!=insns.end(); ++i) - { - delete *i; - } - - for(std::set<AddressID_t*>::const_iterator i=addrs.begin(); i!=addrs.end(); ++i) - { - delete *i; - } - - for(std::set<Relocation_t*>::const_iterator i=relocs.begin(); i!=relocs.end(); ++i) - { - delete *i; - } - - for(std::set<Type_t*>::const_iterator i=types.begin(); i!=types.end(); ++i) - { - delete *i; - } + for(auto i : funcs ) delete i; + for(auto i : insns ) delete i; + for(auto i : addrs ) delete i; + for(auto i : relocs) delete i; + for(auto i : types ) delete i; // @todo: clear icfs_t } @@ -193,8 +175,11 @@ void FileIR_t::ReadFromDB() } -void FileIR_t::ChangeRegistryKey(Instruction_t *orig, Instruction_t *updated) +void FileIR_t::changeRegistryKey(IRDB_SDK::Instruction_t *p_orig, IRDB_SDK::Instruction_t *p_updated) { + auto orig=dynamic_cast<libIRDB::Instruction_t*>(p_orig); + auto updated=dynamic_cast<libIRDB::Instruction_t*>(p_updated); + if(assembly_registry.find(orig) != assembly_registry.end()) { assembly_registry[updated] = assembly_registry[orig]; @@ -203,7 +188,7 @@ void FileIR_t::ChangeRegistryKey(Instruction_t *orig, Instruction_t *updated) } } -void FileIR_t::AssembleRegistry() +void FileIR_t::assembleRegistry() { if(assembly_registry.size() == 0) return; @@ -221,14 +206,11 @@ void FileIR_t::AssembleRegistry() if(!asmFile.is_open()) assert(false); - asmFile<<"BITS "<<std::dec<<GetArchitectureBitWidth()<<endl; + asmFile<<"BITS "<<std::dec<<getArchitectureBitWidth()<<endl; - for(registry_type::iterator it = assembly_registry.begin(); - it != assembly_registry.end(); - it++ - ) + for(auto it : assembly_registry) { - asmFile<<it->second<<endl; + asmFile<<it.second<<endl; } asmFile.close(); @@ -236,11 +218,6 @@ void FileIR_t::AssembleRegistry() actual_exit = command_to_stream(command,cout); // system(command.c_str()); assert(actual_exit == 0); - - //DISASM disasm; - //memset(&disasm, 0, sizeof(DISASM)); - //disasm.Archi=GetArchitectureBitWidth(); - ifstream binreader; unsigned int filesize; binreader.open(binaryOutputFile.c_str(),ifstream::in|ifstream::binary); @@ -256,8 +233,6 @@ void FileIR_t::AssembleRegistry() binreader.read((char*)binary_stream,filesize); binreader.close(); - //unsigned int instr_index = 0; - //for(unsigned int index=0; index < filesize; instr_index++) unsigned int index = 0; registry_type::iterator reg_val = assembly_registry.begin(); @@ -271,12 +246,13 @@ void FileIR_t::AssembleRegistry() // disasm.EIP = (UIntPtr)&binary_stream[index]; // int instr_len = Disasm(&disasm); - const auto disasm=DecodedInstruction_t + const auto p_disasm=DecodedInstruction_t::factory ( /* fake start addr doesn't matter */0x1000, (void*)&binary_stream[index], (void*)&binary_stream[filesize] ); + const auto& disasm=*p_disasm; assert(disasm.valid()); const auto instr_len=disasm.length(); @@ -288,8 +264,8 @@ void FileIR_t::AssembleRegistry() rawBits[i] = binary_stream[index]; } - instr->SetDataBits(rawBits); -// *verbose_logging << "doing instruction:" << ((Instruction_t*)instr)->getDisassembly() << " comment: " << ((Instruction_t*)instr)->GetComment() << endl; + instr->setDataBits(rawBits); +// *verbose_logging << "doing instruction:" << ((Instruction_t*)instr)->getDisassembly() << " comment: " << ((Instruction_t*)instr)->getComment() << endl; reg_val++; } @@ -300,18 +276,24 @@ void FileIR_t::AssembleRegistry() } -void FileIR_t::RegisterAssembly(Instruction_t *instr, string assembly) +void FileIR_t::registerAssembly(IRDB_SDK::Instruction_t *p_instr, string assembly) { + auto instr=dynamic_cast<Instruction_t*>(p_instr); + assert(instr); assembly_registry[instr] = assembly; } -void FileIR_t::UnregisterAssembly(Instruction_t *instr) +void FileIR_t::unregisterAssembly(IRDB_SDK::Instruction_t *p_instr) { + auto instr=dynamic_cast<Instruction_t*>(p_instr); + assert(instr); assembly_registry.erase(instr); } -std::string FileIR_t::LookupAssembly(Instruction_t *instr) +std::string FileIR_t::lookupAssembly(IRDB_SDK::Instruction_t *p_instr) { + auto instr=dynamic_cast<Instruction_t*>(p_instr); + assert(instr); if (assembly_registry.find(instr) != assembly_registry.end()) return assembly_registry[instr]; else @@ -329,23 +311,23 @@ std::map<db_id_t,Function_t*> FileIR_t::ReadFuncsFromDB auto q=std::string("select * from ") + fileptr->function_table_name + " ; "; - dbintr->IssueQuery(q); + dbintr->issueQuery(q); - while(!dbintr->IsDone()) + while(!dbintr->isDone()) { // function_id | file_id | name | stack_frame_size | out_args_region_size | use_frame_pointer | is_safe | doip_id - db_id_t fid=atoi(dbintr->GetResultColumn("function_id").c_str()); - db_id_t entry_point_id=atoi(dbintr->GetResultColumn("entry_point_id").c_str()); - std::string name=dbintr->GetResultColumn("name"); - int sfsize=atoi(dbintr->GetResultColumn("stack_frame_size").c_str()); - int oasize=atoi(dbintr->GetResultColumn("out_args_region_size").c_str()); - db_id_t function_type_id=atoi(dbintr->GetResultColumn("type_id").c_str()); + db_id_t fid=atoi(dbintr->getResultColumn("function_id").c_str()); + db_id_t entry_point_id=atoi(dbintr->getResultColumn("entry_point_id").c_str()); + std::string name=dbintr->getResultColumn("name"); + int sfsize=atoi(dbintr->getResultColumn("stack_frame_size").c_str()); + int oasize=atoi(dbintr->getResultColumn("out_args_region_size").c_str()); + db_id_t function_type_id=atoi(dbintr->getResultColumn("type_id").c_str()); // postgresql encoding of boolean can be 'true', '1', 'T', 'y' bool useFP=false; bool isSafe=false; - string useFPString=dbintr->GetResultColumn("use_frame_pointer"); - string isSafeString=dbintr->GetResultColumn("is_safe"); + string useFPString=dbintr->getResultColumn("use_frame_pointer"); + string isSafeString=dbintr->getResultColumn("is_safe"); const char *useFPstr=useFPString.c_str(); const char *isSafestr=isSafeString.c_str(); if (strlen(useFPstr) > 0) @@ -361,7 +343,7 @@ std::map<db_id_t,Function_t*> FileIR_t::ReadFuncsFromDB } // handle later? - //db_id_t doipid=atoi(dbintr->GetResultColumn("doip_id").c_str()); + //db_id_t doipid=atoi(dbintr->getResultColumn("doip_id").c_str()); FuncType_t* fnType = NULL; if (typesMap.count(function_type_id) > 0) @@ -376,7 +358,7 @@ std::map<db_id_t,Function_t*> FileIR_t::ReadFuncsFromDB funcs.insert(newfunc); - dbintr->MoveToNextRow(); + dbintr->moveToNextRow(); } return idMap; @@ -390,9 +372,9 @@ std::map<db_id_t,EhCallSite_t*> FileIR_t::ReadEhCallSitesFromDB { auto ehcsMap=std::map<db_id_t,EhCallSite_t*>(); - std::string q= "select * from " + fileptr->GetEhCallSiteTableName() + " ; "; + std::string q= "select * from " + fileptr->getEhCallSiteTableName() + " ; "; - for(dbintr->IssueQuery(q); !dbintr->IsDone(); dbintr->MoveToNextRow()) + for(dbintr->issueQuery(q); !dbintr->isDone(); dbintr->moveToNextRow()) { const auto string_to_vec=[&](const string& str ) -> vector<int> { @@ -410,10 +392,10 @@ std::map<db_id_t,EhCallSite_t*> FileIR_t::ReadEhCallSitesFromDB */ - const auto eh_cs_id=atoi(dbintr->GetResultColumn("ehcs_id").c_str()); - const auto tt_encoding=atoi(dbintr->GetResultColumn("tt_encoding").c_str()); - const auto &ttov=string(dbintr->GetResultColumn("ttov").c_str()); - const auto lp_insn_id=atoi(dbintr->GetResultColumn("lp_insn_id").c_str()); + const auto eh_cs_id=atoi(dbintr->getResultColumn("ehcs_id").c_str()); + const auto tt_encoding=atoi(dbintr->getResultColumn("tt_encoding").c_str()); + const auto &ttov=string(dbintr->getResultColumn("ttov").c_str()); + const auto lp_insn_id=atoi(dbintr->getResultColumn("lp_insn_id").c_str()); auto newEhCs=new EhCallSite_t(eh_cs_id,tt_encoding,NULL); // create the call site with an unresolved LP newEhCs->GetTTOrderVector()=string_to_vec(ttov); @@ -431,7 +413,7 @@ std::map<db_id_t,EhProgram_t*> FileIR_t::ReadEhPgmsFromDB() auto idMap = std::map<db_id_t,EhProgram_t*>(); auto q=std::string("select * from ") + fileptr->ehpgm_table_name + " ; "; - dbintr->IssueQuery(q); + dbintr->issueQuery(q); auto decode_pgm=[](const string& encoded_pgm, EhProgramListing_t& decoded_pgm) { @@ -484,7 +466,7 @@ std::map<db_id_t,EhProgram_t*> FileIR_t::ReadEhPgmsFromDB() }; - while(!dbintr->IsDone()) + while(!dbintr->isDone()) { /* * eh_pgm_id integer, @@ -496,21 +478,21 @@ std::map<db_id_t,EhProgram_t*> FileIR_t::ReadEhPgmsFromDB() */ - const auto eh_pgm_id=atoi(dbintr->GetResultColumn("eh_pgm_id").c_str()); - const auto caf=atoi(dbintr->GetResultColumn("caf").c_str()); - const auto daf=atoi(dbintr->GetResultColumn("daf").c_str()); - const auto rr=atoi(dbintr->GetResultColumn("return_register").c_str()); - const auto ptrsize=atoi(dbintr->GetResultColumn("ptrsize").c_str()); - const auto& encoded_cie_program = dbintr->GetResultColumn("cie_program"); - const auto& encoded_fde_program = dbintr->GetResultColumn("fde_program"); + const auto eh_pgm_id=atoi(dbintr->getResultColumn("eh_pgm_id").c_str()); + const auto caf=atoi(dbintr->getResultColumn("caf").c_str()); + const auto daf=atoi(dbintr->getResultColumn("daf").c_str()); + const auto rr=atoi(dbintr->getResultColumn("return_register").c_str()); + const auto ptrsize=atoi(dbintr->getResultColumn("ptrsize").c_str()); + const auto& encoded_cie_program = dbintr->getResultColumn("cie_program"); + const auto& encoded_fde_program = dbintr->getResultColumn("fde_program"); - auto new_ehpgm=new EhProgram_t(eh_pgm_id, caf, daf, rr, ptrsize); + auto new_ehpgm=new EhProgram_t(eh_pgm_id, caf, daf, rr, ptrsize, {}, {}); decode_pgm(encoded_cie_program, new_ehpgm->GetCIEProgram()); decode_pgm(encoded_fde_program, new_ehpgm->GetFDEProgram()); idMap[eh_pgm_id]=new_ehpgm; eh_pgms.insert(new_ehpgm); - dbintr->MoveToNextRow(); + dbintr->moveToNextRow(); } return idMap; @@ -525,9 +507,9 @@ std::map<db_id_t,AddressID_t*> FileIR_t::ReadAddrsFromDB std::string q= "select * from " + fileptr->address_table_name + " ; "; - dbintr->IssueQuery(q); + dbintr->issueQuery(q); - while(!dbintr->IsDone()) + while(!dbintr->isDone()) { // address_id integer PRIMARY KEY, // file_id integer REFERENCES file_info, @@ -535,12 +517,12 @@ std::map<db_id_t,AddressID_t*> FileIR_t::ReadAddrsFromDB // doip_id integer DEFAULT -1 - db_id_t aid=atoi(dbintr->GetResultColumn("address_id").c_str()); - db_id_t file_id=atoi(dbintr->GetResultColumn("file_id").c_str()); - virtual_offset_t vaddr=strtovo(dbintr->GetResultColumn("vaddress_offset")); + db_id_t aid=atoi(dbintr->getResultColumn("address_id").c_str()); + db_id_t file_id=atoi(dbintr->getResultColumn("file_id").c_str()); + virtual_offset_t vaddr=strtovo(dbintr->getResultColumn("vaddress_offset")); // handle later? - //db_id_t doipid=atoi(dbintr->GetResultColumn("doip_id").c_str()); + //db_id_t doipid=atoi(dbintr->getResultColumn("doip_id").c_str()); AddressID_t *newaddr=new AddressID_t(aid,file_id,vaddr); @@ -550,7 +532,7 @@ std::map<db_id_t,AddressID_t*> FileIR_t::ReadAddrsFromDB addrs.insert(newaddr); - dbintr->MoveToNextRow(); + dbintr->moveToNextRow(); } return idMap; @@ -587,9 +569,9 @@ std::map<db_id_t,Instruction_t*> FileIR_t::ReadInsnsFromDB std::string q= "select * from " + fileptr->instruction_table_name + " ; "; - dbintr->IssueQuery(q); + dbintr->issueQuery(q); - while(!dbintr->IsDone()) + while(!dbintr->isDone()) { // address_id integer REFERENCES #PROGNAME#_address, @@ -604,23 +586,23 @@ std::map<db_id_t,Instruction_t*> FileIR_t::ReadInsnsFromDB // doip_id integer DEFAULT -1 - db_id_t instruction_id=atoi(dbintr->GetResultColumn("instruction_id").c_str()); - db_id_t aid=atoi(dbintr->GetResultColumn("address_id").c_str()); - db_id_t parent_func_id=atoi(dbintr->GetResultColumn("parent_function_id").c_str()); - db_id_t orig_address_id=atoi(dbintr->GetResultColumn("orig_address_id").c_str()); - db_id_t fallthrough_address_id=atoi(dbintr->GetResultColumn("fallthrough_address_id").c_str()); - db_id_t targ_address_id=atoi(dbintr->GetResultColumn("target_address_id").c_str()); - db_id_t icfs_id=atoi(dbintr->GetResultColumn("icfs_id").c_str()); - db_id_t eh_pgm_id=atoi(dbintr->GetResultColumn("ehpgm_id").c_str()); - db_id_t eh_cs_id=atoi(dbintr->GetResultColumn("ehcss_id").c_str()); - std::string encoded_data=(dbintr->GetResultColumn("data")); + db_id_t instruction_id=atoi(dbintr->getResultColumn("instruction_id").c_str()); + db_id_t aid=atoi(dbintr->getResultColumn("address_id").c_str()); + db_id_t parent_func_id=atoi(dbintr->getResultColumn("parent_function_id").c_str()); + db_id_t orig_address_id=atoi(dbintr->getResultColumn("orig_address_id").c_str()); + db_id_t fallthrough_address_id=atoi(dbintr->getResultColumn("fallthrough_address_id").c_str()); + db_id_t targ_address_id=atoi(dbintr->getResultColumn("target_address_id").c_str()); + db_id_t icfs_id=atoi(dbintr->getResultColumn("icfs_id").c_str()); + db_id_t eh_pgm_id=atoi(dbintr->getResultColumn("ehpgm_id").c_str()); + db_id_t eh_cs_id=atoi(dbintr->getResultColumn("ehcss_id").c_str()); + std::string encoded_data=(dbintr->getResultColumn("data")); std::string data=encoded_to_raw_string(encoded_data); - std::string callback=(dbintr->GetResultColumn("callback")); - std::string comment=(dbintr->GetResultColumn("comment")); - db_id_t indirect_branch_target_address_id = atoi(dbintr->GetResultColumn("ind_target_address_id").c_str()); - db_id_t doipid=atoi(dbintr->GetResultColumn("doip_id").c_str()); + std::string callback=(dbintr->getResultColumn("callback")); + std::string comment=(dbintr->getResultColumn("comment")); + db_id_t indirect_branch_target_address_id = atoi(dbintr->getResultColumn("ind_target_address_id").c_str()); + db_id_t doipid=atoi(dbintr->getResultColumn("doip_id").c_str()); - std::string isIndStr=(dbintr->GetResultColumn("ind_target_address_id")); + std::string isIndStr=(dbintr->getResultColumn("ind_target_address_id")); auto indTarg=(AddressID_t*)NULL; if (indirect_branch_target_address_id != NOT_IN_DATABASE) @@ -635,13 +617,13 @@ std::map<db_id_t,Instruction_t*> FileIR_t::ReadInsnsFromDB orig_address_id, data, callback, comment, indTarg, doipid); - if(eh_pgm_id != NOT_IN_DATABASE) newinsn->SetEhProgram(ehpgmMap.at(eh_pgm_id)); - if(eh_cs_id != NOT_IN_DATABASE) newinsn->SetEhCallSite(ehcsMap.at(eh_cs_id)); + if(eh_pgm_id != NOT_IN_DATABASE) newinsn->setEhProgram(ehpgmMap.at(eh_pgm_id)); + if(eh_cs_id != NOT_IN_DATABASE) newinsn->setEhCallSite(ehcsMap.at(eh_cs_id)); if(parent_func) { parent_func->GetInstructions().insert(newinsn); - newinsn->SetFunction(funcMap.at(parent_func_id)); + newinsn->setFunction(funcMap.at(parent_func_id)); } //std::cout<<"Found address "<<aid<<"."<<std::endl; @@ -655,7 +637,7 @@ std::map<db_id_t,Instruction_t*> FileIR_t::ReadInsnsFromDB if (icfs_id == NOT_IN_DATABASE) { - newinsn->SetIBTargets(NULL); + newinsn->setIBTargets(NULL); } else { @@ -664,18 +646,18 @@ std::map<db_id_t,Instruction_t*> FileIR_t::ReadInsnsFromDB unresolvedICFS[newinsn] = icfs_id; } - dbintr->MoveToNextRow(); + dbintr->moveToNextRow(); } for(std::map<db_id_t,Instruction_t*>::const_iterator i=idMap.begin(); i!=idMap.end(); ++i) { Instruction_t *instr=(*i).second; - db_id_t fallthroughid=fallthroughs[instr->GetBaseID()]; + db_id_t fallthroughid=fallthroughs[instr->getBaseID()]; if(idMap[fallthroughid]) - instr->SetFallthrough(idMap[fallthroughid]); - db_id_t targetid=targets[instr->GetBaseID()]; + instr->setFallthrough(idMap[fallthroughid]); + db_id_t targetid=targets[instr->getBaseID()]; if(idMap[targetid]) - instr->SetTarget(idMap[targetid]); + instr->setTarget(idMap[targetid]); } @@ -688,19 +670,19 @@ void FileIR_t::ReadRelocsFromDB ) { std::string q= "select * from " + fileptr->relocs_table_name + " ; "; - dbintr->IssueQuery(q); + dbintr->issueQuery(q); - while(!dbintr->IsDone()) + while(!dbintr->isDone()) { - db_id_t reloc_id=atoi(dbintr->GetResultColumn("reloc_id").c_str()); - int reloc_offset=atoi(dbintr->GetResultColumn("reloc_offset").c_str()); - std::string reloc_type=(dbintr->GetResultColumn("reloc_type")); - db_id_t instruction_id=atoi(dbintr->GetResultColumn("instruction_id").c_str()); + db_id_t reloc_id=atoi(dbintr->getResultColumn("reloc_id").c_str()); + int reloc_offset=atoi(dbintr->getResultColumn("reloc_offset").c_str()); + std::string reloc_type=(dbintr->getResultColumn("reloc_type")); + db_id_t instruction_id=atoi(dbintr->getResultColumn("instruction_id").c_str()); // handle later? - //db_id_t doipid=atoi(dbintr->GetResultColumn("doip_id").c_str()); - db_id_t wrt_id=atoi(dbintr->GetResultColumn("wrt_id").c_str()); - uint32_t addend=atoi(dbintr->GetResultColumn("addend").c_str()); + //db_id_t doipid=atoi(dbintr->getResultColumn("doip_id").c_str()); + db_id_t wrt_id=atoi(dbintr->getResultColumn("wrt_id").c_str()); + uint32_t addend=atoi(dbintr->getResultColumn("addend").c_str()); BaseObj_t* wrt_obj=objMap[wrt_id]; // might be null. @@ -711,13 +693,13 @@ void FileIR_t::ReadRelocsFromDB objMap[instruction_id]->GetRelocations().insert(reloc); relocs.insert(reloc); - dbintr->MoveToNextRow(); + dbintr->moveToNextRow(); } } -void FileIR_t::WriteToDB(ostream *verbose_logging) +void FileIR_t::writeToDB(ostream *verbose_logging) { // const auto WriteIRDB_start = clock(); @@ -725,113 +707,120 @@ void FileIR_t::WriteToDB(ostream *verbose_logging) assert(pqIntr); //Resolve (assemble) any instructions in the registry. - AssembleRegistry(); + assembleRegistry(); /* assign each item a unique ID */ - SetBaseIDS(); + setBaseIDS(); CleanupICFS(verbose_logging); db_id_t j=-1; - dbintr->IssueQuery(string("TRUNCATE TABLE ")+ fileptr->instruction_table_name + string(" cascade;")); - dbintr->IssueQuery(string("TRUNCATE TABLE ")+ fileptr->icfs_table_name + string(" cascade;")); - dbintr->IssueQuery(string("TRUNCATE TABLE ")+ fileptr->icfs_map_table_name + string(" cascade;")); - dbintr->IssueQuery(string("TRUNCATE TABLE ")+ fileptr->function_table_name + string(" cascade;")); - dbintr->IssueQuery(string("TRUNCATE TABLE ")+ fileptr->address_table_name + string(" cascade;")); - dbintr->IssueQuery(string("TRUNCATE TABLE ")+ fileptr->relocs_table_name + string(" cascade;")); - dbintr->IssueQuery(string("TRUNCATE TABLE ")+ fileptr->types_table_name + string(" cascade;")); - dbintr->IssueQuery(string("TRUNCATE TABLE ")+ fileptr->scoop_table_name + string(" cascade;")); - dbintr->IssueQuery(string("TRUNCATE TABLE ")+ fileptr->scoop_table_name+"_part2"+ string(" cascade;")); - dbintr->IssueQuery(string("TRUNCATE TABLE ")+ fileptr->ehpgm_table_name + string(" cascade;")); - dbintr->IssueQuery(string("TRUNCATE TABLE ")+ fileptr->ehcss_table_name + string(" cascade;")); + dbintr->issueQuery(string("TRUNCATE TABLE ")+ fileptr->instruction_table_name + string(" cascade;")); + dbintr->issueQuery(string("TRUNCATE TABLE ")+ fileptr->icfs_table_name + string(" cascade;")); + dbintr->issueQuery(string("TRUNCATE TABLE ")+ fileptr->icfs_map_table_name + string(" cascade;")); + dbintr->issueQuery(string("TRUNCATE TABLE ")+ fileptr->function_table_name + string(" cascade;")); + dbintr->issueQuery(string("TRUNCATE TABLE ")+ fileptr->address_table_name + string(" cascade;")); + dbintr->issueQuery(string("TRUNCATE TABLE ")+ fileptr->relocs_table_name + string(" cascade;")); + dbintr->issueQuery(string("TRUNCATE TABLE ")+ fileptr->types_table_name + string(" cascade;")); + dbintr->issueQuery(string("TRUNCATE TABLE ")+ fileptr->scoop_table_name + string(" cascade;")); + dbintr->issueQuery(string("TRUNCATE TABLE ")+ fileptr->scoop_table_name+"_part2"+ string(" cascade;")); + dbintr->issueQuery(string("TRUNCATE TABLE ")+ fileptr->ehpgm_table_name + string(" cascade;")); + dbintr->issueQuery(string("TRUNCATE TABLE ")+ fileptr->ehcss_table_name + string(" cascade;")); /* and now that everything has an ID, let's write to the DB */ // write out the types string q=string(""); - for(std::set<Type_t*>::const_iterator t=types.begin(); t!=types.end(); ++t) + for(auto t=types.begin(); t!=types.end(); ++t) { - q+=(*t)->WriteToDB(fileptr,j); // @TODO: wtf is j? + auto real_t=dynamic_cast<Type_t*>(*t); + assert(real_t); + q+=real_t->WriteToDB(fileptr,j); // @TODO: wtf is j? if(q.size()>1024*1024) { - dbintr->IssueQuery(q); + dbintr->issueQuery(q); q=string(""); } } - dbintr->IssueQuery(q); + dbintr->issueQuery(q); // write out functions auto withHeader=true; q=string(""); - for(std::set<Function_t*>::const_iterator f=funcs.begin(); f!=funcs.end(); ++f) + for(auto f=funcs.begin(); f!=funcs.end(); ++f) { - q+=(*f)->WriteToDB(fileptr,j); + auto real_f=dynamic_cast<Function_t*>(*f); + assert(real_f); + q+=real_f->WriteToDB(fileptr,j); if(q.size()>1024*1024) { - dbintr->IssueQuery(q); + dbintr->issueQuery(q); q=string(""); } } - dbintr->IssueQuery(q); + dbintr->issueQuery(q); // write out addresses - pqxx::tablewriter W_addrs(pqIntr->GetTransaction(),fileptr->address_table_name); + pqxx::tablewriter W_addrs(pqIntr->getTransaction(),fileptr->address_table_name); for(const auto &a : addrs) { - W_addrs << a->WriteToDB(fileptr,j,withHeader); + auto real_a=dynamic_cast<AddressID_t*>(a); + assert(real_a); + W_addrs << real_a->WriteToDB(fileptr,j,withHeader); } W_addrs.complete(); // write out instructions - pqxx::tablewriter W(pqIntr->GetTransaction(),fileptr->instruction_table_name); - for(std::set<Instruction_t*>::const_iterator i=insns.begin(); i!=insns.end(); ++i) + pqxx::tablewriter W(pqIntr->getTransaction(),fileptr->instruction_table_name); + for(auto i=insns.begin(); i!=insns.end(); ++i) { - Instruction_t const * const insnp=*i; + auto insnp=dynamic_cast<Instruction_t*>(*i); //DISASM disasm; //Disassemble(insnp,disasm); - const auto disasm=DecodedInstruction_t(insnp); + const auto p_disasm=DecodedInstruction_t::factory(insnp); + const auto& disasm=*p_disasm; - if(insnp->GetOriginalAddressID() == NOT_IN_DATABASE) + if(insnp->getOriginalAddressID() == NOT_IN_DATABASE) { - // if(insnp->GetFallthrough()==NULL && disasm.Instruction.BranchType!=RetType && disasm.Instruction.BranchType!=JmpType ) - if(insnp->GetFallthrough()==NULL && !disasm.isReturn() && !disasm.isUnconditionalBranch()) + // if(insnp->getFallthrough()==NULL && disasm.Instruction.BranchType!=RetType && disasm.Instruction.BranchType!=JmpType ) + if(insnp->getFallthrough()==NULL && !disasm.isReturn() && !disasm.isUnconditionalBranch()) { // instructions that fall through are required to either specify a fallthrough that's // in the IRDB, or have an associated "old" instruction. // without these bits of information, the new instruction can't possibly execute correctly. // and we won't have the information necessary to emit spri. - *verbose_logging << "NULL fallthrough: offending instruction:" << ((Instruction_t*)insnp)->getDisassembly() << " comment: " << ((Instruction_t*)insnp)->GetComment() << endl; + *verbose_logging << "NULL fallthrough: offending instruction:" << ((Instruction_t*)insnp)->getDisassembly() << " comment: " << ((Instruction_t*)insnp)->getComment() << endl; assert(0); abort(); } - //if(insnp->GetTarget()==NULL && disasm.Instruction.BranchType!=0 && + //if(insnp->getTarget()==NULL && disasm.Instruction.BranchType!=0 && // disasm.Instruction.BranchType!=RetType && // // not an indirect branch // ((disasm.Instruction.BranchType!=JmpType && disasm.Instruction.BranchType!=CallType) || // disasm.Argument1.ArgType&CONSTANT_TYPE)) - if(insnp->GetTarget()==NULL && disasm.isBranch() && !disasm.isReturn() && + if(insnp->getTarget()==NULL && disasm.isBranch() && !disasm.isReturn() && // not an indirect branch - ( (!disasm.isUnconditionalBranch() && !disasm.isCall()) || disasm.getOperand(0).isConstant()) + ( (!disasm.isUnconditionalBranch() && !disasm.isCall()) || disasm.getOperand(0)->isConstant()) ) { // direct branches are required to either specify a target that's // in the IRDB, or have an associated "old" instruction. // without these bits of information, the new instruction can't possibly execute correctly. // and we won't have the information necessary to emit spri. - *verbose_logging << "Call must have a target; offending instruction:" << ((Instruction_t*)insnp)->getDisassembly() << " comment: " << ((Instruction_t*)insnp)->GetComment() << endl; + *verbose_logging << "Call must have a target; offending instruction:" << ((Instruction_t*)insnp)->getDisassembly() << " comment: " << ((Instruction_t*)insnp)->getComment() << endl; assert(0); abort(); } } - const auto &insn_values=(*i)->WriteToDB(fileptr,j); + const auto &insn_values=insnp->WriteToDB(fileptr,j); W << insn_values; } @@ -839,199 +828,199 @@ void FileIR_t::WriteToDB(ostream *verbose_logging) // icfs - for (ICFSSet_t::iterator it = GetAllICFS().begin(); it != GetAllICFS().end(); ++it) + for (auto it = GetAllICFS().begin(); it != GetAllICFS().end(); ++it) { - ICFS_t* icfs = *it; + ICFS_t* icfs = dynamic_cast<ICFS_t*>(*it); assert(icfs); string q = icfs->WriteToDB(fileptr); - dbintr->IssueQuery(q); + dbintr->issueQuery(q); } // scoops - for(DataScoopSet_t::const_iterator it=scoops.begin(); it!=scoops.end(); ++it) + for(auto it=scoops.begin(); it!=scoops.end(); ++it) { - DataScoop_t* scoop = *it; + DataScoop_t* scoop = dynamic_cast<DataScoop_t*>(*it); assert(scoop); string q = scoop->WriteToDB(fileptr,j); - dbintr->IssueQuery(q); + dbintr->issueQuery(q); } // ehpgms - pqxx::tablewriter W_eh(pqIntr->GetTransaction(),fileptr->ehpgm_table_name); + pqxx::tablewriter W_eh(pqIntr->getTransaction(),fileptr->ehpgm_table_name); for(const auto& i : eh_pgms) { - W_eh << i->WriteToDB(fileptr); + W_eh << dynamic_cast<EhProgram_t*>(i)->WriteToDB(fileptr); } W_eh.complete(); // eh css for(const auto& i : eh_css) { - string q = i->WriteToDB(fileptr); - dbintr->IssueQuery(q); + string q = dynamic_cast<EhCallSite_t*>(i)->WriteToDB(fileptr); + dbintr->issueQuery(q); } // all relocs - pqxx::tablewriter W_reloc(pqIntr->GetTransaction(),fileptr->relocs_table_name); + pqxx::tablewriter W_reloc(pqIntr->getTransaction(),fileptr->relocs_table_name); // eh css relocs for(const auto& i : eh_css) { - const auto &relocs=i->GetRelocations(); + const auto &relocs=i->getRelocations(); for(auto& reloc : relocs) - W_reloc << reloc->WriteToDB(fileptr,i); + W_reloc << dynamic_cast<Relocation_t*>(reloc)->WriteToDB(fileptr,dynamic_cast<BaseObj_t*>(i)); } // eh pgms relocs for(const auto& i : eh_pgms) { - const auto &relocs=i->GetRelocations(); + const auto &relocs=i->getRelocations(); for(auto& reloc : relocs) - W_reloc << reloc->WriteToDB(fileptr,i); + W_reloc << dynamic_cast<Relocation_t*>(reloc)->WriteToDB(fileptr,dynamic_cast<BaseObj_t*>(i)); } // scoops relocs for(const auto& i : scoops) { - const auto &relocs=i->GetRelocations(); + const auto &relocs=i->getRelocations(); for(auto& reloc : relocs) - W_reloc << reloc->WriteToDB(fileptr,i); + W_reloc << dynamic_cast<Relocation_t*>(reloc)->WriteToDB(fileptr,dynamic_cast<BaseObj_t*>(i)); } // write out instruction's relocs for(const auto& i : insns) { - const auto &relocs=i->GetRelocations(); + const auto &relocs=i->getRelocations(); for(auto& reloc : relocs) - W_reloc << reloc->WriteToDB(fileptr,i); + W_reloc << dynamic_cast<Relocation_t*>(reloc)->WriteToDB(fileptr,dynamic_cast<BaseObj_t*>(i)); } W_reloc.complete(); -/* std::cout << std::dec; - - const auto WriteIRDB_end = clock(); - const auto read_time = (double)(ReadIRDB_end-ReadIRDB_start)/ CLOCKS_PER_SEC; - const auto write_time = (double)(WriteIRDB_end-WriteIRDB_start)/ CLOCKS_PER_SEC; - const auto wall_time = (double)(WriteIRDB_end-ReadIRDB_start)/ CLOCKS_PER_SEC; - const auto transform_time=wall_time - read_time - write_time; - std::cout << std::fixed << std::setprecision(2) << "#ATTRIBUTE ReadIRDB_WallClock=" << read_time <<endl; - std::cout << std::fixed << std::setprecision(2) << "#ATTRIBUTE WriteIRDB_WallClock=" << write_time << endl; - std::cout << std::fixed << std::setprecision(2) << "#ATTRIBUTE TotalIRDB_WallClock=" << wall_time << endl; - std::cout << std::fixed << std::setprecision(2) << "#ATTRIBUTE TransformIRDB_WallClock=" << transform_time << endl; -*/ - } -db_id_t FileIR_t::GetMaxBaseID() +db_id_t FileIR_t::getMaxBaseID() const { #define MAX(a,b) (((a)>(b)) ? (a) : (b)) /* find the highest database ID */ db_id_t j=0; for(auto i=funcs.begin(); i!=funcs.end(); ++i) - j=MAX(j,(*i)->GetBaseID()); + j=MAX(j,(*i)->getBaseID()); for(auto i=addrs.begin(); i!=addrs.end(); ++i) - j=MAX(j,(*i)->GetBaseID()); + j=MAX(j,(*i)->getBaseID()); for(auto i=insns.begin(); i!=insns.end(); ++i) - j=MAX(j,(*i)->GetBaseID()); + j=MAX(j,(*i)->getBaseID()); for(auto i=relocs.begin(); i!=relocs.end(); ++i) - j=MAX(j,(*i)->GetBaseID()); + j=MAX(j,(*i)->getBaseID()); for(auto i=types.begin(); i!=types.end(); ++i) - j=MAX(j,(*i)->GetBaseID()); + j=MAX(j,(*i)->getBaseID()); for(auto i=scoops.begin(); i!=scoops.end(); ++i) - j=MAX(j,(*i)->GetBaseID()); + j=MAX(j,(*i)->getBaseID()); for(auto i=icfs_set.begin(); i!=icfs_set.end(); ++i) - j=MAX(j,(*i)->GetBaseID()); + j=MAX(j,(*i)->getBaseID()); for(auto i=eh_pgms.begin(); i!=eh_pgms.end(); ++i) - j=MAX(j,(*i)->GetBaseID()); + j=MAX(j,(*i)->getBaseID()); for(auto i=eh_css.begin(); i!=eh_css.end(); ++i) - j=MAX(j,(*i)->GetBaseID()); + j=MAX(j,(*i)->getBaseID()); return j+1; // easy to off-by-one this so we do it for a user just in case. } -void FileIR_t::SetBaseIDS() +void FileIR_t::setBaseIDS() { - auto j=GetMaxBaseID(); + auto j=getMaxBaseID(); /* increment past the max ID so we don't duplicate */ j++; /* for anything that's not yet in the DB, assign an ID to it */ for(auto i=funcs.begin(); i!=funcs.end(); ++i) - if((*i)->GetBaseID()==NOT_IN_DATABASE) - (*i)->SetBaseID(j++); + if((*i)->getBaseID()==NOT_IN_DATABASE) + (*i)->setBaseID(j++); for(auto i=addrs.begin(); i!=addrs.end(); ++i) - if((*i)->GetBaseID()==NOT_IN_DATABASE) - (*i)->SetBaseID(j++); + if((*i)->getBaseID()==NOT_IN_DATABASE) + (*i)->setBaseID(j++); for(auto i=insns.begin(); i!=insns.end(); ++i) - if((*i)->GetBaseID()==NOT_IN_DATABASE) - (*i)->SetBaseID(j++); + if((*i)->getBaseID()==NOT_IN_DATABASE) + (*i)->setBaseID(j++); for(auto i=relocs.begin(); i!=relocs.end(); ++i) - if((*i)->GetBaseID()==NOT_IN_DATABASE) - (*i)->SetBaseID(j++); + if((*i)->getBaseID()==NOT_IN_DATABASE) + (*i)->setBaseID(j++); for(auto i=types.begin(); i!=types.end(); ++i) - if((*i)->GetBaseID()==NOT_IN_DATABASE) - (*i)->SetBaseID(j++); + if((*i)->getBaseID()==NOT_IN_DATABASE) + (*i)->setBaseID(j++); for(auto i=scoops.begin(); i!=scoops.end(); ++i) - if((*i)->GetBaseID()==NOT_IN_DATABASE) - (*i)->SetBaseID(j++); + if((*i)->getBaseID()==NOT_IN_DATABASE) + (*i)->setBaseID(j++); for(auto i=icfs_set.begin(); i!=icfs_set.end(); ++i) - if((*i)->GetBaseID()==NOT_IN_DATABASE) - (*i)->SetBaseID(j++); + if((*i)->getBaseID()==NOT_IN_DATABASE) + (*i)->setBaseID(j++); for(auto i=eh_pgms.begin(); i!=eh_pgms.end(); ++i) - if((*i)->GetBaseID()==NOT_IN_DATABASE) - (*i)->SetBaseID(j++); + if((*i)->getBaseID()==NOT_IN_DATABASE) + (*i)->setBaseID(j++); for(auto i=eh_css.begin(); i!=eh_css.end(); ++i) - if((*i)->GetBaseID()==NOT_IN_DATABASE) - (*i)->SetBaseID(j++); + if((*i)->getBaseID()==NOT_IN_DATABASE) + (*i)->setBaseID(j++); +} + +const IRDB_SDK::ArchitectureDescription_t* IRDB_SDK::FileIR_t::getArchitecture() +{ + return libIRDB::FileIR_t::archdesc; } -int FileIR_t::GetArchitectureBitWidth() +uint32_t IRDB_SDK::FileIR_t::getArchitectureBitWidth() { - return archdesc->GetBitWidth(); + return libIRDB::FileIR_t::archdesc->getBitWidth(); } -void FileIR_t::SetArchitectureBitWidth(int width) +void FileIR_t::setArchitecture(const int width, const ADMachineType_t mt) { if(archdesc==NULL) archdesc=new ArchitectureDescription_t; - archdesc->SetBitWidth(width); + archdesc->setBitWidth(width); + archdesc->setMachineType(mt); } -void FileIR_t::SetArchitecture() +void FileIR_t::setArchitecture() { /* the first 16 bytes of an ELF file define the magic number and ELF Class. */ - unsigned char e_ident[16]; + // unsigned char e_ident[16]; + union + { + Elf32_Ehdr ehdr32; + Elf64_Ehdr ehdr64; + } hdr_union; + + auto myinter=BaseObj_t::GetInterface(); + auto *mypqxxintr=dynamic_cast<pqxxDB_t*>(myinter); - DBinterface_t* myinter=BaseObj_t::GetInterface(); - pqxxDB_t *mypqxxintr=dynamic_cast<pqxxDB_t*>(myinter); + const auto elfoid=getFile()->getELFOID(); + pqxx::largeobjectaccess loa(mypqxxintr->getTransaction(), elfoid, PGSTD::ios::in); - int elfoid=GetFile()->GetELFOID(); - pqxx::largeobjectaccess loa(mypqxxintr->GetTransaction(), elfoid, PGSTD::ios::in); + loa.cread((char*)&hdr_union, sizeof(hdr_union)); - loa.cread((char*)&e_ident, sizeof(e_ident)); + const auto e_ident=hdr_union.ehdr32.e_ident; - archdesc=new ArchitectureDescription_t; + libIRDB::FileIR_t::archdesc=new ArchitectureDescription_t; if((e_ident[EI_MAG0]==ELFMAG0) && (e_ident[EI_MAG1]==ELFMAG1) && (e_ident[EI_MAG2]==ELFMAG2) && (e_ident[EI_MAG3]==ELFMAG3)) { - archdesc->SetFileType(AD_ELF); + libIRDB::FileIR_t::archdesc->setFileType(IRDB_SDK::adftELF); } else if((e_ident[EI_MAG0]==ELFMAG0) && (e_ident[EI_MAG1]=='C') && (e_ident[EI_MAG2]=='G') && (e_ident[EI_MAG3]=='C')) { - archdesc->SetFileType(AD_ELF); + libIRDB::FileIR_t::archdesc->setFileType(IRDB_SDK::adftELF); } else if((e_ident[EI_MAG0]=='M') && (e_ident[EI_MAG1]=='Z')) { - archdesc->SetFileType(AD_PE); + libIRDB::FileIR_t::archdesc->setFileType(IRDB_SDK::adftPE); } else { @@ -1040,22 +1029,34 @@ void FileIR_t::SetArchitecture() } - if (archdesc->GetFileType() == AD_PE) + if (libIRDB::FileIR_t::archdesc->getFileType() == IRDB_SDK::adftPE) { - // just assume 64 bit for Windows, o/w could also extract from file - archdesc->SetBitWidth(64); + // just assume x86-64 bit for Windows, o/w could also extract from file + libIRDB::FileIR_t::archdesc->setBitWidth(64); + libIRDB::FileIR_t::archdesc->setMachineType(IRDB_SDK::admtX86_64); } else { switch(e_ident[4]) { case ELFCLASS32: - archdesc->SetBitWidth(32); + { + libIRDB::FileIR_t::archdesc->setBitWidth(32); + if(hdr_union.ehdr32.e_machine!=EM_386) + throw std::invalid_argument("Arch not supported. 32-bit archs supported: I386"); + libIRDB::FileIR_t::archdesc->setMachineType(IRDB_SDK::admtI386); break; + } case ELFCLASS64: - archdesc->SetBitWidth(64); + { + libIRDB::FileIR_t::archdesc->setBitWidth(64); + const auto mt= + hdr_union.ehdr64.e_machine==EM_AARCH64 ? IRDB_SDK::admtAarch64 : + hdr_union.ehdr64.e_machine==EM_X86_64 ? IRDB_SDK::admtX86_64 : + throw std::invalid_argument("Arch not supported. 64-bit archs supported: Aarch64, X86-64"); + libIRDB::FileIR_t::archdesc->setMachineType(mt); break; - case ELFCLASSNONE: + } default: cerr << "Unknown ELF class " <<endl; exit(-1); @@ -1085,9 +1086,9 @@ std::map<db_id_t, Type_t*> FileIR_t::ReadTypesFromDB (TypeSet_t& types) // cout << "pass1: query: " << q; - dbintr->IssueQuery(q); + dbintr->issueQuery(q); - while(!dbintr->IsDone()) + while(!dbintr->isDone()) { // type_id integer, // type integer DEFAULT 0, -- possible types (0: UNKNOWN) @@ -1097,160 +1098,163 @@ std::map<db_id_t, Type_t*> FileIR_t::ReadTypesFromDB (TypeSet_t& types) // ref_type_id2 integer DEFAULT -1, -- for func types // doip_id integer DEFAULT -1 -- the DOIP - db_id_t tid=atoi(dbintr->GetResultColumn("type_id").c_str()); - IRDB_Type type=(IRDB_Type)atoi(dbintr->GetResultColumn("type").c_str()); - std::string name=dbintr->GetResultColumn("name"); + db_id_t tid=atoi(dbintr->getResultColumn("type_id").c_str()); + IRDB_Type type=(IRDB_Type)atoi(dbintr->getResultColumn("type").c_str()); + std::string name=dbintr->getResultColumn("name"); BasicType_t *t = NULL; // cout << "fileir::ReadFromDB(): pass1: " << name << endl; - switch(type) { - case T_UNKNOWN: - case T_VOID: - case T_NUMERIC: - case T_VARIADIC: - case T_INT: - case T_CHAR: - case T_FLOAT: - case T_DOUBLE: - t = new BasicType_t(tid, type, name); - types.insert(t); - tMap[tid] = t; - break; - - case T_POINTER: - // do nothing for pointers - break; - - default: - cerr << "ReadTypesFromDB(): ERROR: pass 1 should only see basic types or pointer" << endl; - assert(0); - break; + switch(type) + { + case IRDB_SDK::itUnknown: + case IRDB_SDK::itVoid: + case IRDB_SDK::itNumeric: + case IRDB_SDK::itVariadic: + case IRDB_SDK::itInt: + case IRDB_SDK::itChar: + case IRDB_SDK::itFloat: + case IRDB_SDK::itDouble: + t = new BasicType_t(tid, type, name); + types.insert(t); + tMap[tid] = t; + break; + + case IRDB_SDK::itPointer: + // do nothing for pointers + break; + + default: + cerr << "ReadTypesFromDB(): ERROR: pass 1 should only see basic types or pointer" << endl; + assert(0); + break; } - dbintr->MoveToNextRow(); + dbintr->moveToNextRow(); } // end pass1 char query[2048]; // pass2 get pointers - sprintf(query,"select * from %s WHERE type = %d;", fileptr->types_table_name.c_str(), T_POINTER); - dbintr->IssueQuery(query); + sprintf(query,"select * from %s WHERE type = %d;", fileptr->types_table_name.c_str(), IRDB_SDK::itPointer); + dbintr->issueQuery(query); - while(!dbintr->IsDone()) + while(!dbintr->isDone()) { - db_id_t tid=atoi(dbintr->GetResultColumn("type_id").c_str()); - IRDB_Type type=(IRDB_Type)atoi(dbintr->GetResultColumn("type").c_str()); - std::string name=dbintr->GetResultColumn("name"); - db_id_t ref1=atoi(dbintr->GetResultColumn("ref_type_id").c_str()); + db_id_t tid=atoi(dbintr->getResultColumn("type_id").c_str()); + IRDB_Type type=(IRDB_Type)atoi(dbintr->getResultColumn("type").c_str()); + std::string name=dbintr->getResultColumn("name"); + db_id_t ref1=atoi(dbintr->getResultColumn("ref_type_id").c_str()); // cout << "fileir::ReadFromDB(): pass2 (pointers): " << name << endl; - switch(type) { - case T_POINTER: - { + switch(type) + { + case IRDB_SDK::itPointer: + { // cout << " pointer type: ref1: " << ref1 << endl; - Type_t *referentType = NULL; - if (ref1 >= 0) - { - assert(tMap.count(ref1) > 0); - referentType = tMap[ref1]; - } - PointerType_t *ptr = new PointerType_t(tid, referentType, name); - types.insert(ptr); - tMap[tid] = ptr; - } - break; - - default: - cerr << "ReadTypesFromDB(): ERROR: pass3: unhandled type id = " << type << endl; - assert(0); // not yet handled - break; + Type_t *referentType = NULL; + if (ref1 >= 0) + { + assert(tMap.count(ref1) > 0); + referentType = tMap[ref1]; + } + PointerType_t *ptr = new PointerType_t(tid, referentType, name); + types.insert(ptr); + tMap[tid] = ptr; + } + break; + + default: + cerr << "ReadTypesFromDB(): ERROR: pass3: unhandled type id = " << type << endl; + assert(0); // not yet handled + break; } - dbintr->MoveToNextRow(); + dbintr->moveToNextRow(); } // end pass3 // pass3 get all aggregates - sprintf(query,"select * from %s WHERE type = %d order by type_id, pos;", fileptr->types_table_name.c_str(), T_AGGREGATE); - dbintr->IssueQuery(query); + sprintf(query,"select * from %s WHERE type = %d order by type_id, pos;", fileptr->types_table_name.c_str(), IRDB_SDK::itAggregate); + dbintr->issueQuery(query); - while(!dbintr->IsDone()) + while(!dbintr->isDone()) { - db_id_t tid=atoi(dbintr->GetResultColumn("type_id").c_str()); - IRDB_Type type=(IRDB_Type)atoi(dbintr->GetResultColumn("type").c_str()); - std::string name=dbintr->GetResultColumn("name"); - db_id_t ref1=atoi(dbintr->GetResultColumn("ref_type_id").c_str()); - int pos=atoi(dbintr->GetResultColumn("pos").c_str()); + db_id_t tid=atoi(dbintr->getResultColumn("type_id").c_str()); + IRDB_Type type=(IRDB_Type)atoi(dbintr->getResultColumn("type").c_str()); + std::string name=dbintr->getResultColumn("name"); + db_id_t ref1=atoi(dbintr->getResultColumn("ref_type_id").c_str()); + int pos=atoi(dbintr->getResultColumn("pos").c_str()); AggregateType_t *agg = NULL; // cout << "fileir::ReadFromDB(): pass3 (aggregates): " << name << endl; - switch(type) { - case T_AGGREGATE: - { - if (tMap.count(tid) == 0) // new aggregate - { + switch(type) + { + case IRDB_SDK::itAggregate: + { + if (tMap.count(tid) == 0) // new aggregate + { // cout << "fileir::ReadFromDB(): pass3: new aggregate type: typeid: " << tid << " name: " << name << endl; - agg = new AggregateType_t(tid, name); - types.insert(agg); - tMap[tid] = agg; - } - else - agg = dynamic_cast<AggregateType_t*>(tMap[tid]); - - assert(agg); - // ref1 has the id of a basic type, look it up - Type_t *ref = tMap[ref1]; - assert(ref); - agg->AddAggregatedType(ref, pos); - } - break; - - default: - cerr << "ReadTypesFromDB(): ERROR: pass2: unhandled type id = " << type << endl; - assert(0); // not yet handled - break; + agg = new AggregateType_t(tid, name); + types.insert(agg); + tMap[tid] = agg; + } + else + agg = dynamic_cast<AggregateType_t*>(tMap[tid]); + + assert(agg); + // ref1 has the id of a basic type, look it up + Type_t *ref = tMap[ref1]; + assert(ref); + agg->addAggregatedType(ref, pos); + } + break; + + default: + cerr << "ReadTypesFromDB(): ERROR: pass2: unhandled type id = " << type << endl; + assert(0); // not yet handled + break; } - dbintr->MoveToNextRow(); + dbintr->moveToNextRow(); } // end pass3 // pass4 get all functions - sprintf(query,"select * from %s WHERE type = %d;", fileptr->types_table_name.c_str(), T_FUNC); - dbintr->IssueQuery(query); + sprintf(query,"select * from %s WHERE type = %d;", fileptr->types_table_name.c_str(), IRDB_SDK::itFunc); + dbintr->issueQuery(query); - while(!dbintr->IsDone()) + while(!dbintr->isDone()) { - db_id_t tid=atoi(dbintr->GetResultColumn("type_id").c_str()); - IRDB_Type type=(IRDB_Type)atoi(dbintr->GetResultColumn("type").c_str()); - std::string name=dbintr->GetResultColumn("name"); - db_id_t ref1=atoi(dbintr->GetResultColumn("ref_type_id").c_str()); - db_id_t ref2=atoi(dbintr->GetResultColumn("ref_type_id2").c_str()); + db_id_t tid=atoi(dbintr->getResultColumn("type_id").c_str()); + IRDB_Type type=(IRDB_Type)atoi(dbintr->getResultColumn("type").c_str()); + std::string name=dbintr->getResultColumn("name"); + db_id_t ref1=atoi(dbintr->getResultColumn("ref_type_id").c_str()); + db_id_t ref2=atoi(dbintr->getResultColumn("ref_type_id2").c_str()); FuncType_t *fn = NULL; - switch(type) { - case T_FUNC: - { - assert(tMap.count(tid) == 0); - - fn = new FuncType_t(tid, name); - types.insert(fn); - tMap[tid] = fn; - assert(tMap[ref1]); // return type - assert(tMap[ref2]); // argument type (which is an aggregate) - fn->SetReturnType(tMap[ref1]); - AggregateType_t *args = dynamic_cast<AggregateType_t*>(tMap[ref2]); - assert(args); - fn->SetArgumentsType(args); - } - break; - - default: - cerr << "ReadTypesFromDB(): ERROR: pass4: unhandled type id = " << type << endl; - assert(0); // not yet handled - break; + switch(type) + { + case IRDB_SDK::itFunc: + { + assert(tMap.count(tid) == 0); + + fn = new FuncType_t(tid, name); + types.insert(fn); + tMap[tid] = fn; + assert(tMap[ref1]); // return type + assert(tMap[ref2]); // argument type (which is an aggregate) + fn->setReturnType(tMap[ref1]); + AggregateType_t *args = dynamic_cast<AggregateType_t*>(tMap[ref2]); + assert(args); + fn->setArgumentsType(args); + break; + } + default: + cerr << "ReadTypesFromDB(): ERROR: pass4: unhandled type id = " << type << endl; + assert(0); // not yet handled + break; } - dbintr->MoveToNextRow(); + dbintr->moveToNextRow(); } // end pass4 return tMap; @@ -1263,34 +1267,34 @@ void FileIR_t::ReadAllICFSFromDB(std::map<db_id_t,Instruction_t*> &addr2instMap, // retrieve all sets std::string q= "select * from " + fileptr->icfs_table_name + " ; "; - dbintr->IssueQuery(q); + dbintr->issueQuery(q); - while(!dbintr->IsDone()) + while(!dbintr->isDone()) { - db_id_t icfs_id = atoi(dbintr->GetResultColumn("icfs_id").c_str()); - string statusString=dbintr->GetResultColumn("icfs_status"); + db_id_t icfs_id = atoi(dbintr->getResultColumn("icfs_id").c_str()); + string statusString=dbintr->getResultColumn("icfs_status"); ICFS_t* icfs = new ICFS_t(icfs_id, statusString); GetAllICFS().insert(icfs); icfsMap[icfs_id] = icfs; - dbintr->MoveToNextRow(); + dbintr->moveToNextRow(); } ICFSSet_t all_icfs = GetAllICFS(); // for each set, populate its members - for (ICFSSet_t::iterator it = all_icfs.begin(); it != all_icfs.end(); ++it) + for (auto it = all_icfs.begin(); it != all_icfs.end(); ++it) { char query2[2048]; - ICFS_t *icfs = *it; + auto icfs = dynamic_cast<ICFS_t*>(*it); assert(icfs); - int icfsid = icfs->GetBaseID(); + int icfsid = icfs->getBaseID(); sprintf(query2,"select * from %s WHERE icfs_id = %d;", fileptr->icfs_map_table_name.c_str(), icfsid); - dbintr->IssueQuery(query2); - while(!dbintr->IsDone()) + dbintr->issueQuery(query2); + while(!dbintr->isDone()) { - db_id_t address_id = atoi(dbintr->GetResultColumn("address_id").c_str()); + db_id_t address_id = atoi(dbintr->getResultColumn("address_id").c_str()); Instruction_t* instruction = addr2instMap[address_id]; if (instruction) { @@ -1302,15 +1306,15 @@ void FileIR_t::ReadAllICFSFromDB(std::map<db_id_t,Instruction_t*> &addr2instMap, // if we encounter an unresolved address, we should mark the ICFS // as unresolved - dbintr->MoveToNextRow(); + dbintr->moveToNextRow(); } } // backpatch all unresolved instruction -> ICFS std::map<Instruction_t*, db_id_t>::iterator uit; - for (std::map<Instruction_t*, db_id_t>::iterator uit = unresolvedICFS.begin(); uit != unresolvedICFS.end(); ++uit) + for (auto uit = unresolvedICFS.begin(); uit != unresolvedICFS.end(); ++uit) { - Instruction_t* unresolved = uit->first; + auto unresolved = dynamic_cast<Instruction_t*>(uit->first); db_id_t icfs_id = uit->second; assert(unresolved); @@ -1318,7 +1322,7 @@ void FileIR_t::ReadAllICFSFromDB(std::map<db_id_t,Instruction_t*> &addr2instMap, ICFS_t *icfs = icfsMap[icfs_id]; assert(icfs); - unresolved->SetIBTargets(icfs); + unresolved->setIBTargets(icfs); } } @@ -1327,7 +1331,7 @@ void FileIR_t::GarbageCollectICFS(ostream* verbose_logging) auto used_icfs= ICFSSet_t(); // get the IBTarget of each instruction into used_icfs transform( ALLOF(insns), inserter(used_icfs, begin(used_icfs)), - [](const Instruction_t* insn) -> ICFS_t* { return insn->GetIBTargets(); } + [](const IRDB_SDK::Instruction_t* insn) -> IRDB_SDK::ICFS_t* { return insn->getIBTargets(); } ); // we likely inserted null into the set, which we just will remove as a special ase. used_icfs.erase(nullptr); @@ -1338,18 +1342,17 @@ void FileIR_t::GarbageCollectICFS(ostream* verbose_logging) void FileIR_t::DedupICFS(ostream *verbose_logging) { - std::set<ICFS_t> unique_icfs; + std::set<InstructionSet_t> unique_icfs; - ICFSSet_t& all_icfs=this->GetAllICFS(); + auto& all_icfs=this->GetAllICFS(); // detect duplicate icfs ICFSSet_t duplicates; - std::pair<std::set<ICFS_t>::iterator,bool> ret; - for(ICFSSet_t::iterator it=all_icfs.begin(); it!=all_icfs.end(); ++it) + for(auto it=all_icfs.begin(); it!=all_icfs.end(); ++it) { - ICFS_t* p=*it; + auto p=dynamic_cast<ICFS_t*>(*it); assert(p); - ret = unique_icfs.insert( *p ); + auto ret = unique_icfs.insert( *p ); if (!ret.second) { duplicates.insert(p); } @@ -1362,40 +1365,40 @@ void FileIR_t::DedupICFS(ostream *verbose_logging) } // remove duplicate icfs - for(ICFSSet_t::const_iterator it=duplicates.begin(); it!=duplicates.end(); ++it) + for(auto it=duplicates.begin(); it!=duplicates.end(); ++it) { - ICFS_t* icfs = *it; + auto icfs=*it; all_icfs.erase(icfs); } // build duplicate icfs map - std::map<ICFS_t*, ICFS_t*> duplicate_map; - for(ICFSSet_t::const_iterator it=duplicates.begin(); it!=duplicates.end(); ++it) + std::map<IRDB_SDK::ICFS_t*, IRDB_SDK::ICFS_t*> duplicate_map; + for(auto it=duplicates.begin(); it!=duplicates.end(); ++it) { - ICFS_t* icfs = *it; - for(ICFSSet_t::iterator it=all_icfs.begin(); it!=all_icfs.end(); ++it) + auto icfs = *it; + for(auto it=all_icfs.begin(); it!=all_icfs.end(); ++it) { - ICFS_t* t = *it; + auto t = *it; assert(t); if (*icfs == *t) { duplicate_map[icfs] = t; - *verbose_logging << "FileIR_t::DedupICFS(): remap: icfs id " << icfs->GetBaseID() << " --> icsf id " << t->GetBaseID() << endl; + *verbose_logging << "FileIR_t::DedupICFS(): remap: icfs id " << icfs->getBaseID() << " --> icsf id " << t->getBaseID() << endl; break; } } } // reassign ibtargets - for(set<Instruction_t*>::const_iterator it=this->GetInstructions().begin(); + for(auto it=this->GetInstructions().begin(); it!=this->GetInstructions().end(); ++it) { - Instruction_t* instr=*it; - if(instr->GetIBTargets() && duplicate_map[instr->GetIBTargets()]) + auto instr=*it; + if(instr->getIBTargets() && duplicate_map[instr->getIBTargets()]) { - instr->SetIBTargets(duplicate_map[instr->GetIBTargets()]); + instr->setIBTargets(duplicate_map[instr->getIBTargets()]); } } } @@ -1428,12 +1431,12 @@ std::map<db_id_t,DataScoop_t*> FileIR_t::ReadScoopsFromDB // // read part 2 of the scoops. //std::string q= "select * from " + fileptr->scoop_table_name + "_part2 ; "; - //dbintr->IssueQuery(q); - //while(!dbintr->IsDone()) + //dbintr->issueQuery(q); + //while(!dbintr->isDone()) //{ - // db_id_t sid=atoi(dbintr->GetResultColumn("scoop_id").c_str()); - // bonus_contents[sid]=dbintr->GetResultColumn("data"); - // dbintr->MoveToNextRow(); + // db_id_t sid=atoi(dbintr->getResultColumn("scoop_id").c_str()); + // bonus_contents[sid]=dbintr->getResultColumn("data"); + // dbintr->moveToNextRow(); //} @@ -1449,78 +1452,75 @@ std::map<db_id_t,DataScoop_t*> FileIR_t::ReadScoopsFromDB // data bytea -- the actual bytes of the scoop string q= "select scoop_id,name,type_id,start_address_id,end_address_id,permissions,relro from " + fileptr->scoop_table_name + " ; "; - dbintr->IssueQuery(q); - while(!dbintr->IsDone()) + dbintr->issueQuery(q); + while(!dbintr->isDone()) { - db_id_t sid=atoi(dbintr->GetResultColumn("scoop_id").c_str()); - std::string name=dbintr->GetResultColumn("name"); - db_id_t type_id=atoi(dbintr->GetResultColumn("type_id").c_str()); + db_id_t sid=atoi(dbintr->getResultColumn("scoop_id").c_str()); + std::string name=dbintr->getResultColumn("name"); + db_id_t type_id=atoi(dbintr->getResultColumn("type_id").c_str()); Type_t *type=typeMap[type_id]; - db_id_t start_id=atoi(dbintr->GetResultColumn("start_address_id").c_str()); + db_id_t start_id=atoi(dbintr->getResultColumn("start_address_id").c_str()); AddressID_t* start_addr=addrMap[start_id]; - db_id_t end_id=atoi(dbintr->GetResultColumn("end_address_id").c_str()); + db_id_t end_id=atoi(dbintr->getResultColumn("end_address_id").c_str()); AddressID_t* end_addr=addrMap[end_id]; - int permissions=atoi(dbintr->GetResultColumn("permissions").c_str()); - bool is_relro=atoi(dbintr->GetResultColumn("relro").c_str()) != 0 ; + int permissions=atoi(dbintr->getResultColumn("permissions").c_str()); + bool is_relro=atoi(dbintr->getResultColumn("relro").c_str()) != 0 ; DataScoop_t* newscoop=new DataScoop_t(sid,name,start_addr,end_addr,type,permissions,is_relro,""); assert(newscoop); GetDataScoops().insert(newscoop); - dbintr->MoveToNextRow(); + dbintr->moveToNextRow(); scoopMap[sid]=newscoop; } - for(DataScoopSet_t::iterator it=GetDataScoops().begin(); it!=GetDataScoops().end(); ++it) + for(auto it=getDataScoops().begin(); it!=getDataScoops().end(); ++it) { - DataScoop_t* scoop=*it; + DataScoop_t* scoop=dynamic_cast<DataScoop_t*>(*it); - q= "select length(data) from " + fileptr->scoop_table_name + " where scoop_id='"+to_string(scoop->GetBaseID())+"'; "; - dbintr->IssueQuery(q); - if(!dbintr->IsDone()) + q= "select length(data) from " + fileptr->scoop_table_name + " where scoop_id='"+to_string(scoop->getBaseID())+"'; "; + dbintr->issueQuery(q); + if(!dbintr->isDone()) { - int data_len=atoi(dbintr->GetResultColumn("length").c_str()); + int data_len=atoi(dbintr->getResultColumn("length").c_str()); for(int i=0;i<data_len;i+=SCOOP_CHUNK_SIZE) { string start_pos=to_string(i); string len_to_get=to_string(SCOOP_CHUNK_SIZE); string field="substr(data,"+start_pos+","+len_to_get+")"; - q= "select "+field+" from " + fileptr->scoop_table_name + " where scoop_id='"+to_string(scoop->GetBaseID())+"'; "; - dbintr->IssueQuery(q); + q= "select "+field+" from " + fileptr->scoop_table_name + " where scoop_id='"+to_string(scoop->getBaseID())+"'; "; + dbintr->issueQuery(q); - scoop->GetContents()+=dbintr->GetResultColumn("substr"); + scoop->getContents()+=dbintr->getResultColumn("substr"); } } // read part 2 from db - q= "select length(data) from " + fileptr->scoop_table_name + "_part2 where scoop_id='"+to_string(scoop->GetBaseID())+"'; "; - dbintr->IssueQuery(q); - if(!dbintr->IsDone()) + q= "select length(data) from " + fileptr->scoop_table_name + "_part2 where scoop_id='"+to_string(scoop->getBaseID())+"'; "; + dbintr->issueQuery(q); + if(!dbintr->isDone()) { - int part2_len=atoi(dbintr->GetResultColumn("length").c_str()); + int part2_len=atoi(dbintr->getResultColumn("length").c_str()); for(int i=0;i<part2_len; i+=SCOOP_CHUNK_SIZE) { string start_pos=to_string(i); string len_to_get=to_string(SCOOP_CHUNK_SIZE); string field="substr(data,"+start_pos+","+len_to_get+")"; - q= "select "+field+" from " + fileptr->scoop_table_name + "_part2 where scoop_id='"+to_string(scoop->GetBaseID())+"'; "; - dbintr->IssueQuery(q); + q= "select "+field+" from " + fileptr->scoop_table_name + "_part2 where scoop_id='"+to_string(scoop->getBaseID())+"'; "; + dbintr->issueQuery(q); - scoop->GetContents()+=dbintr->GetResultColumn("substr"); + scoop->getContents()+=dbintr->getResultColumn("substr"); } } } - for( DataScoopSet_t::const_iterator it=GetDataScoops().begin(); - it!=GetDataScoops().end(); - ++it - ) + for(auto s : getDataScoops()) { - DataScoop_t* scoop=*it; - assert(scoop->GetContents().size() == scoop->GetSize()); + auto scoop=dynamic_cast<DataScoop_t*>(s); + assert(scoop->getContents().size() == scoop->getSize()); } @@ -1529,46 +1529,51 @@ std::map<db_id_t,DataScoop_t*> FileIR_t::ReadScoopsFromDB // Lookup a scoop by address -DataScoop_t* FileIR_t::FindScoop(const libIRDB::virtual_offset_t &addr) +IRDB_SDK::DataScoop_t* FileIR_t::findScoop(const IRDB_SDK::VirtualOffset_t &addr) const { - for(DataScoopSet_t::iterator it=scoops.begin(); it!=scoops.end(); ++it) + for(auto it=scoops.begin(); it!=scoops.end(); ++it) { + auto s=dynamic_cast<DataScoop_t*>(*it); // we're doing <= in both comparisons here intentionally. // scoop addresses are the start/end address are inclusive // so that start+size-1 == end. - if( (*it)->GetStart()->GetVirtualOffset() <= addr && addr <= (*it)->GetEnd()->GetVirtualOffset() ) + if( s->getStart()->getVirtualOffset() <= addr && addr <= s->getEnd()->getVirtualOffset() ) return *it; } return NULL; } -void FileIR_t::SplitScoop( - DataScoop_t *tosplit, - const libIRDB::virtual_offset_t &addr, +void FileIR_t::splitScoop( + IRDB_SDK::DataScoop_t *p_tosplit, + const IRDB_SDK::VirtualOffset_t &addr, size_t size, - DataScoop_t* &before, - DataScoop_t* &containing, - DataScoop_t* &after, - db_id_t *max_id_ptr /* in and out param */ + IRDB_SDK::DataScoop_t* &p_before, + IRDB_SDK::DataScoop_t* &p_containing, + IRDB_SDK::DataScoop_t* &p_after, + IRDB_SDK::DatabaseID_t *max_id_ptr /* in and out param */ ) { - + auto tosplit = dynamic_cast<DataScoop_t*>(p_tosplit); + auto before = dynamic_cast<DataScoop_t*>(p_before); + auto containing = dynamic_cast<DataScoop_t*>(p_containing); + auto after = dynamic_cast<DataScoop_t*>(p_after); + // init output params. before=containing=after=NULL; - if(tosplit->GetStart()->GetVirtualOffset() == addr && - tosplit->GetEnd()->GetVirtualOffset() == addr+size-1) + if(tosplit->getStart()->getVirtualOffset() == addr && + tosplit->getEnd()->getVirtualOffset() == addr+size-1) { // no split necessary - containing=tosplit; + p_containing=tosplit; return; } auto calcd_max_id=db_id_t(0); if(max_id_ptr==NULL) - calcd_max_id = GetMaxBaseID(); + calcd_max_id = getMaxBaseID(); auto &max_id = max_id_ptr == NULL ? calcd_max_id : *max_id_ptr ; @@ -1582,8 +1587,8 @@ void FileIR_t::SplitScoop( max_id=rounded_max + multiple; // and skip forward so we're passed the highest. - const bool needs_before = addr!=tosplit->GetStart()->GetVirtualOffset(); - const bool needs_after = addr+size-1 != tosplit->GetEnd()->GetVirtualOffset(); + const bool needs_before = addr!=tosplit->getStart()->getVirtualOffset(); + const bool needs_after = addr+size-1 != tosplit->getEnd()->getVirtualOffset(); if(needs_before) @@ -1592,27 +1597,27 @@ void FileIR_t::SplitScoop( // const AddressID_t* before_start=NULL; const auto before_start=new AddressID_t; - before_start->SetBaseID(max_id++); - before_start->SetFileID(tosplit->GetStart()->GetFileID()); - before_start->SetVirtualOffset(tosplit->GetStart()->GetVirtualOffset()); + before_start->setBaseID(max_id++); + before_start->setFileID(tosplit->getStart()->getFileID()); + before_start->setVirtualOffset(tosplit->getStart()->getVirtualOffset()); // const AddressID_t* before_end=new AddressID_t; const auto before_end=new AddressID_t; - before_end->SetBaseID(max_id++); - before_end->SetFileID(tosplit->GetStart()->GetFileID()); - before_end->SetVirtualOffset(addr-1); + before_end->setBaseID(max_id++); + before_end->setFileID(tosplit->getStart()->getFileID()); + before_end->setVirtualOffset(addr-1); before=new DataScoop_t; - before->SetBaseID(max_id++); - before->SetName(tosplit->GetName()+"3"); - before->SetStart(before_start); - before->SetEnd(before_end); + before->setBaseID(max_id++); + before->setName(tosplit->getName()+"3"); + before->setStart(before_start); + before->setEnd(before_end); before->setRawPerms(tosplit->getRawPerms()); - before->GetContents().resize(before_end->GetVirtualOffset() - before_start->GetVirtualOffset()+1); + before->getContents().resize(before_end->getVirtualOffset() - before_start->getVirtualOffset()+1); // copy bytes - for(virtual_offset_t i=before_start->GetVirtualOffset() ; i <= before_end->GetVirtualOffset(); i++) - before->GetContents()[i-before_start->GetVirtualOffset()] = tosplit->GetContents()[i-tosplit->GetStart()->GetVirtualOffset()]; + for(virtual_offset_t i=before_start->getVirtualOffset() ; i <= before_end->getVirtualOffset(); i++) + before->getContents()[i-before_start->getVirtualOffset()] = tosplit->getContents()[i-tosplit->getStart()->getVirtualOffset()]; GetAddresses().insert(before_start); @@ -1623,26 +1628,26 @@ void FileIR_t::SplitScoop( // setup containing // AddressID_t* containing_start=new AddressID_t; const auto containing_start=new AddressID_t; - containing_start->SetBaseID(max_id++); - containing_start->SetFileID(tosplit->GetStart()->GetFileID()); - containing_start->SetVirtualOffset(addr); + containing_start->setBaseID(max_id++); + containing_start->setFileID(tosplit->getStart()->getFileID()); + containing_start->setVirtualOffset(addr); //AddressID_t* containing_end=new AddressID_t; const auto containing_end=new AddressID_t; - containing_end->SetBaseID(max_id++); - containing_end->SetFileID(tosplit->GetStart()->GetFileID()); - containing_end->SetVirtualOffset(addr+size-1); + containing_end->setBaseID(max_id++); + containing_end->setFileID(tosplit->getStart()->getFileID()); + containing_end->setVirtualOffset(addr+size-1); containing=new DataScoop_t; - containing->SetBaseID(max_id++); - containing->SetName(tosplit->GetName()+"3"); - containing->SetStart(containing_start); - containing->SetEnd(containing_end); + containing->setBaseID(max_id++); + containing->setName(tosplit->getName()+"3"); + containing->setStart(containing_start); + containing->setEnd(containing_end); containing->setRawPerms(tosplit->getRawPerms()); - containing->GetContents().resize(containing_end->GetVirtualOffset() - containing_start->GetVirtualOffset()+1); + containing->getContents().resize(containing_end->getVirtualOffset() - containing_start->getVirtualOffset()+1); // copy bytes - for(virtual_offset_t i=containing_start->GetVirtualOffset() ; i <= containing_end->GetVirtualOffset(); i++) - containing->GetContents()[i-containing_start->GetVirtualOffset()] = tosplit->GetContents()[i-tosplit->GetStart()->GetVirtualOffset()]; + for(virtual_offset_t i=containing_start->getVirtualOffset() ; i <= containing_end->getVirtualOffset(); i++) + containing->getContents()[i-containing_start->getVirtualOffset()] = tosplit->getContents()[i-tosplit->getStart()->getVirtualOffset()]; GetAddresses().insert(containing_start); GetAddresses().insert(containing_end); @@ -1654,26 +1659,26 @@ void FileIR_t::SplitScoop( // setup after // AddressID_t* after_start=new AddressID_t; const auto after_start=new AddressID_t; - after_start->SetBaseID(max_id++); - after_start->SetFileID(tosplit->GetStart()->GetFileID()); - after_start->SetVirtualOffset(addr+size); + after_start->setBaseID(max_id++); + after_start->setFileID(tosplit->getStart()->getFileID()); + after_start->setVirtualOffset(addr+size); // AddressID_t* after_end=new AddressID_t; const auto after_end=new AddressID_t; - after_end->SetBaseID(max_id++); - after_end->SetFileID(tosplit->GetStart()->GetFileID()); - after_end->SetVirtualOffset(tosplit->GetEnd()->GetVirtualOffset()); + after_end->setBaseID(max_id++); + after_end->setFileID(tosplit->getStart()->getFileID()); + after_end->setVirtualOffset(tosplit->getEnd()->getVirtualOffset()); after=new DataScoop_t; - after->SetBaseID(max_id++); - after->SetName(tosplit->GetName()+"3"); - after->SetStart(after_start); - after->SetEnd(after_end); + after->setBaseID(max_id++); + after->setName(tosplit->getName()+"3"); + after->setStart(after_start); + after->setEnd(after_end); after->setRawPerms(tosplit->getRawPerms()); - after->GetContents().resize(after_end->GetVirtualOffset() - after_start->GetVirtualOffset()+1); + after->getContents().resize(after_end->getVirtualOffset() - after_start->getVirtualOffset()+1); // copy bytes - for(virtual_offset_t i=after_start->GetVirtualOffset() ; i <= after_end->GetVirtualOffset(); i++) - after->GetContents()[i-after_start->GetVirtualOffset()] = tosplit->GetContents()[i-tosplit->GetStart()->GetVirtualOffset()]; + for(virtual_offset_t i=after_start->getVirtualOffset() ; i <= after_end->getVirtualOffset(); i++) + after->getContents()[i-after_start->getVirtualOffset()] = tosplit->getContents()[i-tosplit->getStart()->getVirtualOffset()]; GetAddresses().insert(after_start); GetAddresses().insert(after_end); @@ -1686,23 +1691,23 @@ void FileIR_t::SplitScoop( // adjust the reloc's offset accordingly before inserting into the correct scoop's reloc set. while(!tosplit->GetRelocations().empty()) { - Relocation_t* reloc=*(tosplit->GetRelocations().begin()); - tosplit->GetRelocations().erase(tosplit->GetRelocations().begin()); + auto reloc=dynamic_cast<Relocation_t*>(*(tosplit->getRelocations().begin())); + tosplit->GetRelocations().erase(tosplit->getRelocations().begin()); - virtual_offset_t reloc_start=reloc->GetOffset()+tosplit->GetStart()->GetVirtualOffset(); + virtual_offset_t reloc_start=reloc->getOffset()+tosplit->getStart()->getVirtualOffset(); - if(reloc_start < containing->GetStart()->GetVirtualOffset() ) + if(reloc_start < containing->getStart()->getVirtualOffset() ) { before->GetRelocations().insert(reloc); } - else if(reloc_start > containing->GetEnd()->GetVirtualOffset() ) + else if(reloc_start > containing->getEnd()->getVirtualOffset() ) { - reloc->SetOffset(reloc_start-after->GetStart()->GetVirtualOffset()); + reloc->setOffset(reloc_start-after->getStart()->getVirtualOffset()); after->GetRelocations().insert(reloc); } else { - reloc->SetOffset(reloc_start-containing->GetStart()->GetVirtualOffset()); + reloc->setOffset(reloc_start-containing->getStart()->getVirtualOffset()); containing->GetRelocations().insert(reloc); } @@ -1711,41 +1716,197 @@ void FileIR_t::SplitScoop( /* look at each relocation in the IR */ for(auto & r : GetRelocations()) { - if(r->GetWRT()==tosplit) + if(r->getWRT()==tosplit) { - const auto &addend=r->GetAddend(); - const auto containing_start_offset=(containing -> GetStart()->GetVirtualOffset() - - tosplit->GetStart()->GetVirtualOffset()); - const auto containing_end_offset=containing_start_offset+containing->GetSize(); - if(needs_before && addend<before->GetSize()) + const auto &addend=r->getAddend(); + const auto containing_start_offset=(containing -> getStart()->getVirtualOffset() - + tosplit->getStart()->getVirtualOffset()); + const auto containing_end_offset=containing_start_offset+containing->getSize(); + if(needs_before && addend<before->getSize()) { - r->SetWRT(before); + r->setWRT(before); } else if( addend < containing_end_offset) { - r->SetWRT(containing); - r->SetAddend(addend-containing_start_offset); + r->setWRT(containing); + r->setAddend(addend-containing_start_offset); } else { assert(needs_after); - const auto after_start_offset=(after -> GetStart()->GetVirtualOffset() - - tosplit->GetStart()->GetVirtualOffset()); - r->SetWRT(after); - r->SetAddend(addend-after_start_offset); + const auto after_start_offset=(after -> getStart()->getVirtualOffset() - + tosplit->getStart()->getVirtualOffset()); + r->setWRT(after); + r->setAddend(addend-after_start_offset); } } } - GetAddresses().erase(tosplit->GetStart()); - GetAddresses().erase(tosplit->GetEnd()); + GetAddresses().erase(tosplit->getStart()); + GetAddresses().erase(tosplit->getEnd()); GetDataScoops().erase(tosplit); - delete tosplit->GetStart(); - delete tosplit->GetEnd(); + delete tosplit->getStart(); + delete tosplit->getEnd(); delete tosplit; + // set output parameters before returning. + p_before = before; + p_containing= containing; + p_after = after; + return; } + +IRDB_SDK::EhCallSite_t* FileIR_t::addEhCallSite_t(IRDB_SDK::Instruction_t* for_insn, const uint64_t enc, IRDB_SDK::Instruction_t* lp) +{ + auto new_ehcs = new libIRDB::EhCallSite_t(BaseObj_t::NOT_IN_DATABASE, enc, lp); + GetAllEhCallSites().insert(new_ehcs); + for_insn->setEhCallSite(new_ehcs); + return new_ehcs; + +} + +IRDB_SDK::Relocation_t* FileIR_t::addNewRelocation( + IRDB_SDK::BaseObj_t* p_from_obj, + int32_t p_offset, + string p_type, + IRDB_SDK::BaseObj_t* p_wrt_obj, + int32_t p_addend) +{ + const auto from_obj=dynamic_cast<libIRDB::BaseObj_t*>(p_from_obj); + auto newreloc=new libIRDB::Relocation_t(BaseObj_t::NOT_IN_DATABASE, p_offset, p_type, p_wrt_obj, p_addend); + from_obj->GetRelocations().insert(newreloc); + GetRelocations().insert(newreloc); + + return newreloc; +} + +EhProgram_t* FileIR_t::addEhProgram( + IRDB_SDK::Instruction_t* insn, + const uint64_t caf, + const int64_t daf, + const uint8_t rr, + const uint8_t p_ptrsize, + const EhProgramListing_t& p_cie_program, + const EhProgramListing_t& p_fde_program) +{ + auto newehpgm=new EhProgram_t(BaseObj_t::NOT_IN_DATABASE, caf,daf,rr,p_ptrsize, p_cie_program, p_fde_program); + assert(newehpgm); + GetAllEhPrograms().insert(newehpgm); + if(insn) + insn->setEhProgram(newehpgm); + return newehpgm; +} + + + +void FileIR_t::removeScoop(IRDB_SDK::DataScoop_t* s) +{ + auto remove_reloc=[&](IRDB_SDK::Relocation_t* r) -> void + { + GetRelocations().erase(r); + delete r; + }; + + auto remove_address=[&](IRDB_SDK::AddressID_t* a) -> void + { + GetAddresses().erase(a); + for(auto &r : a->getRelocations()) remove_reloc(r); + for(auto &r : getRelocations()) assert(r->getWRT() != a); + delete a; + }; + + auto remove_scoop=[&] (IRDB_SDK::DataScoop_t* s) -> void + { + if(s==NULL) + return; + GetDataScoops().erase(s); + remove_address(s->getStart()); + remove_address(s->getEnd()); + for(auto &r : s->getRelocations()) remove_reloc(r); + for(auto &r : GetRelocations()) assert(r->getWRT() != s); + delete s; + }; + + remove_scoop(s); +} + +IRDB_SDK::AddressID_t* FileIR_t::addNewAddress(const IRDB_SDK::DatabaseID_t& myfileID, const IRDB_SDK::VirtualOffset_t& voff) +{ + auto newaddr = new libIRDB::AddressID_t(BaseObj_t::NOT_IN_DATABASE, myfileID, voff); + GetAddresses().insert(newaddr); + return newaddr; +} + + +IRDB_SDK::ICFS_t* FileIR_t::addNewICFS( + IRDB_SDK::Instruction_t* insn, + const IRDB_SDK::InstructionSet_t& targets, + const IRDB_SDK::ICFSAnalysisStatus_t& status) +{ + auto newicfs=new libIRDB::ICFS_t(BaseObj_t::NOT_IN_DATABASE, status); + newicfs->setTargets(targets); + if(insn) + insn->setIBTargets(newicfs); + GetAllICFS().insert(newicfs); + return newicfs; +} + +IRDB_SDK::Instruction_t* FileIR_t::addNewInstruction( + IRDB_SDK::AddressID_t* addr, + IRDB_SDK::Function_t* func, + const string& bits, + const string& comment, + IRDB_SDK::AddressID_t* indTarg) +{ + auto irdb_func = dynamic_cast<libIRDB::Function_t* >(func); + auto irdb_addr = dynamic_cast<libIRDB::AddressID_t*>(addr); + auto irdb_indTarg = dynamic_cast<libIRDB::AddressID_t*>(indTarg); + + if(irdb_addr==nullptr) + { + irdb_addr=dynamic_cast<libIRDB::AddressID_t*>(addNewAddress(getFile()->getBaseID(), 0)); + } + + auto newinsn=new libIRDB::Instruction_t(BaseObj_t::NOT_IN_DATABASE, irdb_addr, irdb_func, BaseObj_t::NOT_IN_DATABASE, bits, "", comment, irdb_indTarg, BaseObj_t::NOT_IN_DATABASE); + + GetInstructions().insert(newinsn); + + if(irdb_func) + irdb_func->GetInstructions().insert(newinsn); + return newinsn; +} + +IRDB_SDK::DataScoop_t* FileIR_t::addNewDataScoop( + const string& p_name, + IRDB_SDK::AddressID_t* p_start, + IRDB_SDK::AddressID_t* p_end, + IRDB_SDK::Type_t* p_type, + uint8_t p_permissions, + bool p_is_relro, + const string& p_contents, + IRDB_SDK::DatabaseID_t id) +{ + auto irdb_start = dynamic_cast<libIRDB::AddressID_t*>(p_start); + auto irdb_end = dynamic_cast<libIRDB::AddressID_t*>(p_end); + auto irdb_type = dynamic_cast<libIRDB::Type_t*> (p_type); + + auto newscoop=new libIRDB::DataScoop_t(id, p_name,irdb_start,irdb_end,irdb_type,p_permissions, p_is_relro, p_contents); + GetDataScoops().insert(newscoop); + return newscoop; +} + +IRDB_SDK::EhProgram_t* FileIR_t::copyEhProgram(const IRDB_SDK::EhProgram_t& orig) +{ + const auto ehpgm=dynamic_cast<const libIRDB::EhProgram_t*>(&orig); + assert(ehpgm); + auto new_eh_pgm=new libIRDB::EhProgram_t(*ehpgm); + GetAllEhPrograms().insert(new_eh_pgm); + return new_eh_pgm; +} + + + diff --git a/libIRDB/src/core/function.cpp b/libIRDB-core/src/function.cpp similarity index 64% rename from libIRDB/src/core/function.cpp rename to libIRDB-core/src/function.cpp index 44e1c5c5be1ae32c6ba37918b05bc75d672fb379..0be6aa95b661e68a9c3a8e004b0e7c287e79662a 100644 --- a/libIRDB/src/core/function.cpp +++ b/libIRDB-core/src/function.cpp @@ -19,22 +19,24 @@ */ #include <all.hpp> -#include <utils.hpp> +#include <irdb-util> #include <stdlib.h> using namespace libIRDB; using namespace std; -Function_t::Function_t(db_id_t id, std::string myname, int size, int oa_size, bool useFP, bool isSafe, FuncType_t *fn_type, Instruction_t* entry) - : BaseObj_t(NULL), entry_point(entry) +Function_t::Function_t(db_id_t id, std::string myname, int size, int oa_size, bool useFP, bool isSafe, IRDB_SDK::FuncType_t *fn_type, IRDB_SDK::Instruction_t* entry) + : BaseObj_t(NULL), entry_point(dynamic_cast<Instruction_t*>(entry)) { - SetBaseID(id); + setBaseID(id); name=myname; stack_frame_size=size; out_args_region_size=oa_size; - use_fp = useFP; - SetSafe(isSafe); - function_type = fn_type; + use_fp = useFP; + setSafe(isSafe); + function_type = dynamic_cast<FuncType_t*>(fn_type); + if(entry) assert(entry_point); + if(fn_type) assert(function_type); } string Function_t::WriteToDB(File_t *fid, db_id_t newid) @@ -43,19 +45,19 @@ string Function_t::WriteToDB(File_t *fid, db_id_t newid) int entryid=NOT_IN_DATABASE; if(entry_point) - entryid=entry_point->GetBaseID(); + entryid=entry_point->getBaseID(); - if(GetBaseID()==NOT_IN_DATABASE) - SetBaseID(newid); + if(getBaseID()==NOT_IN_DATABASE) + setBaseID(newid); int function_type_id = NOT_IN_DATABASE; - if (GetType()) - function_type_id = GetType()->GetBaseID(); + if (getType()) + function_type_id = getType()->getBaseID(); string q=string("insert into ")+fid->function_table_name + string(" (function_id, entry_point_id, name, stack_frame_size, out_args_region_size, use_frame_pointer, is_safe, type_id, doip_id) ")+ string(" VALUES (") + - string("'") + to_string(GetBaseID()) + string("', ") + + string("'") + to_string(getBaseID()) + string("', ") + string("'") + to_string(entryid) + string("', ") + string("'") + name + string("', ") + string("'") + to_string(stack_frame_size) + string("', ") + @@ -63,17 +65,30 @@ string Function_t::WriteToDB(File_t *fid, db_id_t newid) string("'") + to_string(use_fp) + string("', ") + string("'") + to_string(is_safe) + string("', ") + string("'") + to_string(function_type_id) + string("', ") + - string("'") + to_string(GetDoipID()) + string("') ; ") ; + string("'") + to_string(getDoipID()) + string("') ; ") ; return q; } -int Function_t::GetNumArguments() const +int Function_t::getNumArguments() const { if (!function_type) return -1; - AggregateType_t *argtype = function_type->GetArgumentsType(); + auto argtype = function_type->getArgumentsType(); if (argtype) - return argtype->GetNumAggregatedTypes(); + return argtype->getNumAggregatedTypes(); else return -1; } + +void Function_t::setType(IRDB_SDK::FuncType_t *t) +{ + function_type = dynamic_cast<FuncType_t*>(t); + if(t) + assert(function_type); +} + +IRDB_SDK::FuncType_t* Function_t::getType() const +{ + return function_type; +} + diff --git a/libIRDB/src/core/generate_spri.cpp b/libIRDB-core/src/generate_spri.cpp similarity index 81% rename from libIRDB/src/core/generate_spri.cpp rename to libIRDB-core/src/generate_spri.cpp index c70a735171424d8ae2d8f4a0c1c4b62f0cf85411..d9754e9d27f9763aadefb38ec83e733db91b8ab6 100644 --- a/libIRDB/src/core/generate_spri.cpp +++ b/libIRDB-core/src/generate_spri.cpp @@ -21,23 +21,24 @@ #include <all.hpp> -#include <utils.hpp> // to_string function from libIRDB +#include <irdb-util> // to_string function from libIRDB #include <iostream> #include <fstream> #include <stdlib.h> #include <map> #include <string.h> #include <assert.h> -//#include <bea_deprecated.hpp> #undef EIP using namespace libIRDB; using namespace std; +#if 0 + // forward decls for this file static string qualified_addressify(FileIR_t* fileIRp, Instruction_t *insn); -static string labelfy(Instruction_t* insn); +static string labelfy(IRDB_SDK::Instruction_t* insn); // @@ -82,7 +83,7 @@ static bool needs_short_branch_rewrite(Instruction_t* newinsn, const DecodedInst /* 64-bit has more needs than this */ // if(disasm.Archi==32) - if(FileIR_t::GetArchitectureBitWidth()==32) + if(FileIR_t::getArchitectureBitWidth()==32) return false; // if(disasm.Instruction.BranchType==0) /* non-branches, jumps, calls and returns don't need this rewrite */ @@ -99,9 +100,9 @@ static bool needs_short_branch_rewrite(Instruction_t* newinsn, const DecodedInst return false; /* all other branches (on x86-64) need further checking */ - if(!newinsn->GetTarget()) /* no specified target, no need to modify it */ + if(!newinsn->getTarget()) /* no specified target, no need to modify it */ return false; - string new_target=labelfy(newinsn->GetTarget()); + string new_target=labelfy(newinsn->getTarget()); if (new_target.c_str()[0]=='0') /* if we're jumping back to the base instruction */ return true; return false; @@ -111,8 +112,9 @@ static bool needs_short_branch_rewrite(Instruction_t* newinsn, const DecodedInst // // create a label for the given instruction // -static string qualified_labelfy(FileIR_t* fileIRp, Instruction_t* insn) +static string qualified_labelfy(FileIR_t* fileIRp, IRDB_SDK::Instruction_t* p_insn) { + auto insn=dynamic_cast<Instruction_t*>(p_insn); if(!needs_spri_rule(insn, insnMap[insn])) return qualified_addressify(fileIRp, insn); @@ -124,13 +126,10 @@ static long long int label_offset=0; static void update_label_offset(FileIR_t *firp) { int max=0; - for(set<Instruction_t*>::iterator it=firp->GetInstructions().begin(); - it!=firp->GetInstructions().end(); - ++it) + for(auto insn : firp->GetInstructions()) { - Instruction_t *insn=*it; - if(insn->GetBaseID()>max) - max=insn->GetBaseID(); + if(insn->getBaseID()>max) + max=insn->getBaseID(); } label_offset+=max+1; } @@ -140,12 +139,14 @@ static long long int IDToSPRIID(int id) return id+label_offset; } -static string labelfy(Instruction_t* insn) +static string labelfy(IRDB_SDK::Instruction_t* p_insn) { + auto insn=dynamic_cast<Instruction_t*>(p_insn); + if(!needs_spri_rule(insn, insnMap[insn])) return addressify(insn); - return string("LI_") + to_string(IDToSPRIID(insn->GetBaseID())); + return string("LI_") + to_string(IDToSPRIID(insn->getBaseID())); } @@ -160,7 +161,7 @@ static string addressify(Instruction_t* insn) if(!old_insn) return labelfy(insn); - s<<"0x"<<std::hex<<old_insn->GetAddress()->GetVirtualOffset(); + s<<"0x"<<std::hex<<old_insn->getAddress()->getVirtualOffset(); return s.str(); @@ -185,7 +186,7 @@ static string URLToFile(string url) static string qualify(FileIR_t* fileIRp) { - return URLToFile(fileIRp->GetFile()->GetURL()) + "+" ; + return URLToFile(fileIRp->getFile()->GetURL()) + "+" ; } @@ -196,10 +197,10 @@ static string qualify_address(FileIR_t* fileIRp, int addr) return ss.str(); } -static string better_qualify_address(FileIR_t* fileIRp, AddressID_t* addr) +static string better_qualify_address(FileIR_t* fileIRp, IRDB_SDK::AddressID_t* addr) { - db_id_t fileID=addr->GetFileID(); - virtual_offset_t off=addr->GetVirtualOffset(); + db_id_t fileID=addr->getFileID(); + virtual_offset_t off=addr->getVirtualOffset(); /* in theory, we could have an address from any file.. * but this appears to be broken. NOT_IN_DATABASE means we're in the spri address space, @@ -253,7 +254,7 @@ static string getPostCallbackLabel(Instruction_t *newinsn) static string get_relocation_string(FileIR_t* fileIRp, ostream& fout, int offset, string type, Instruction_t* insn) { stringstream ss; - ss<<labelfy(insn)<<" rl " << offset << " " << type << " " << URLToFile(fileIRp->GetFile()->GetURL()) << endl; + ss<<labelfy(insn)<<" rl " << offset << " " << type << " " << URLToFile(fileIRp->getFile()->GetURL()) << endl; return ss.str(); } @@ -288,26 +289,26 @@ void emit_jump(FileIR_t* fileIRp, ostream& fout, const DecodedInstruction_t& dis string label=labelfy(newinsn); string complete_instr=disasm.getDisassembly(); - string address_string=disasm.getOperand(0).getString(); + string address_string=disasm.getOperand(0)->getString(); /* if we have a target instruction in the database */ - if(newinsn->GetTarget() || needs_short_branch_rewrite(newinsn,disasm)) + if(newinsn->getTarget() || needs_short_branch_rewrite(newinsn,disasm)) { /* change the target to be symbolic */ /* first get the new target */ string new_target; - if(newinsn->GetTarget()) - new_target=labelfy(newinsn->GetTarget()); + if(newinsn->getTarget()) + new_target=labelfy(newinsn->getTarget()); /* if this is a short branch, write this branch to jump to the next insn */ if(needs_short_branch_rewrite(newinsn,disasm)) { new_target=get_short_branch_label(newinsn); /* also get the real target if it's a short branch */ - if(newinsn->GetTarget()) - original_target=labelfy(newinsn->GetTarget()); + if(newinsn->getTarget()) + original_target=labelfy(newinsn->getTarget()); else original_target=address_string; } @@ -323,7 +324,7 @@ void emit_jump(FileIR_t* fileIRp, ostream& fout, const DecodedInstruction_t& dis //assert(disasm.Argument1.SegmentReg==0); // if(disasm.Archi==64) - if(FileIR_t::GetArchitectureBitWidth()==64) + if(FileIR_t::getArchitectureBitWidth()==64) { auto converted=convert_jump_for_64bit(newinsn,final, emit_later,new_target); (void)converted; // unused? @@ -388,7 +389,7 @@ this will never work again? else { // assert this is the "main" file and no relocation is necessary. - assert(strstr(fileIRp->GetFile()->GetURL().c_str(),"a.ncexe")!=0); + assert(strstr(fileIRp->getFile()->GetURL().c_str(),"a.ncexe")!=0); } } #endif @@ -410,43 +411,17 @@ static string emit_spri_instruction(FileIR_t* fileIRp, Instruction_t *newinsn, o /* Disassemble the instruction */ //int instr_len = Disassemble(newinsn,disasm); - const auto disasm=DecodedInstruction_t(newinsn); - - -// not needed after library fix. -#if 0 - /* if this instruction has a prefix, re-disassemble it showing the segment regs */ - if( - disasm.Prefix.FSPrefix || - disasm.Prefix.SSPrefix || - disasm.Prefix.GSPrefix || - disasm.Prefix.ESPrefix || - disasm.Prefix.CSPrefix || - disasm.Prefix.DSPrefix - ) - - { - memset(&disasm, 0, sizeof(DISASM)); - - disasm.Options = NasmSyntax + PrefixedNumeral + ShowSegmentRegs; - disasm.Archi = fileIRp->GetArchitectureBitWidth(); - disasm.EIP = (UIntPtr)newinsn->GetDataBits().c_str(); - disasm.VirtualAddr = old_insn ? old_insn->GetAddress()->GetVirtualOffset() : 0; - - /* Disassemble the instruction */ - int instr_len = Disasm(&disasm); - } -#endif - + const auto p_disasm=DecodedInstruction_t::factory(newinsn); + const auto &disasm=*p_disasm; string label=labelfy(newinsn); - string complete_instr=disasm.getDisassembly(); //string(disasm.CompleteInstr); - string address_string=disasm.getOperand(0).getString(); // string(disasm.Argument1.ArgMnemonic); + string complete_instr=disasm.getDisassembly(); + string address_string=disasm.getOperand(0)->getString(); /* Emit any callback functions */ - if (!newinsn->GetCallback().empty()) + if (!newinsn->getCallback().empty()) { - fout << "\t"+label+"\t () " << newinsn->GetCallback() << " # acts as a call <callback> insn" << endl; + fout << "\t"+label+"\t () " << newinsn->getCallback() << " # acts as a call <callback> insn" << endl; fout << "\t"+ getPostCallbackLabel(newinsn)+" ** "; } else @@ -470,7 +445,7 @@ static string emit_spri_instruction(FileIR_t* fileIRp, Instruction_t *newinsn, o //(disasm.Argument1.ArgType & CONSTANT_TYPE)!=0 // and has a constant argument type 1 disasm.isBranch() && !disasm.isReturn() && - disasm.getOperand(0).isConstant() + disasm.getOperand(0)->isConstant() ) { emit_jump(fileIRp, fout, disasm,newinsn,old_insn, original_target, emit_later); @@ -553,19 +528,20 @@ static string emit_spri_instruction(FileIR_t* fileIRp, Instruction_t *newinsn, o fout<<endl; } - for(set<Relocation_t*>::iterator it=newinsn->GetRelocations().begin(); it!=newinsn->GetRelocations().end(); ++it) + //for(set<Relocation_t*>::iterator it=newinsn->GetRelocations().begin(); it!=newinsn->GetRelocations().end(); ++it) + for(auto this_reloc : newinsn->getRelocations()) { - Relocation_t* this_reloc=*it; - emit_relocation(fileIRp, fout, this_reloc->GetOffset(),this_reloc->GetType(), newinsn); + //Relocation_t* this_reloc=*it; + emit_relocation(fileIRp, fout, this_reloc->getOffset(),this_reloc->getType(), newinsn); } - ICFS_t *IB_targets = newinsn->GetIBTargets(); + auto IB_targets = newinsn->getIBTargets(); if (NULL != IB_targets) { - if (IB_targets->IsComplete()) + if (IB_targets->isComplete()) { // Iterate through all IB targets and produce SPRI rules for IBTL (IB Target Limitation). - for (InstructionSet_t::iterator TargIter = IB_targets->begin(); TargIter != IB_targets->end(); ++TargIter) + for (auto TargIter = IB_targets->begin(); TargIter != IB_targets->end(); ++TargIter) { fout << "\t" << labelfy(newinsn) << " IL " << qualified_labelfy(fileIRp, *TargIter) << endl; } @@ -582,19 +558,19 @@ static string emit_spri_instruction(FileIR_t* fileIRp, Instruction_t *newinsn, o static bool needs_spri_rule(Instruction_t* newinsn,Instruction_t* oldinsn) { // check if this is an inserted instruction - if(newinsn->GetOriginalAddressID()==BaseObj_t::NOT_IN_DATABASE) + if(newinsn->getOriginalAddressID()==BaseObj_t::NOT_IN_DATABASE) return true; assert(oldinsn); - assert(newinsn->GetOriginalAddressID()==oldinsn->GetAddress()->GetBaseID()); + assert(newinsn->getOriginalAddressID()==oldinsn->getAddress()->getBaseID()); /* We moved the instruction to a new address*/ - if(newinsn->GetAddress()->GetVirtualOffset()!=oldinsn->GetAddress()->GetVirtualOffset()) + if(newinsn->getAddress()->getVirtualOffset()!=oldinsn->getAddress()->getVirtualOffset()) return true; /* We moved the instruction to a new file? */ - if(newinsn->GetAddress()->GetFileID()!=oldinsn->GetAddress()->GetFileID()) + if(newinsn->getAddress()->getFileID()!=oldinsn->getAddress()->getFileID()) { // // coders: verify this is OK before allowing an insn to change files. @@ -604,10 +580,10 @@ static bool needs_spri_rule(Instruction_t* newinsn,Instruction_t* oldinsn) } - Instruction_t *newFT=newinsn->GetFallthrough(); - Instruction_t *newTG=newinsn->GetTarget(); - Instruction_t *oldFT=oldinsn->GetFallthrough(); - Instruction_t *oldTG=oldinsn->GetTarget(); + auto newFT=newinsn->getFallthrough(); + auto newTG=newinsn->getTarget(); + auto oldFT=oldinsn->getFallthrough(); + auto oldTG=oldinsn->getTarget(); // // check that both have a fallthrough or both don't have a fallthrough @@ -621,15 +597,15 @@ static bool needs_spri_rule(Instruction_t* newinsn,Instruction_t* oldinsn) return true; // if there's a fallthrough, but it is different, return true - if(newFT && newFT->GetOriginalAddressID()!=oldFT->GetAddress()->GetBaseID()) + if(newFT && newFT->getOriginalAddressID()!=oldFT->getAddress()->getBaseID()) return true; // if there's a target, but it is different, return true - if(newTG && newTG->GetOriginalAddressID()!=oldTG->GetAddress()->GetBaseID()) + if(newTG && newTG->getOriginalAddressID()!=oldTG->getAddress()->getBaseID()) return true; // data bits themselves changed - if(newinsn->GetDataBits() != oldinsn->GetDataBits()) + if(newinsn->getDataBits() != oldinsn->getDataBits()) return true; return false; @@ -645,10 +621,10 @@ static void emit_spri_rule(FileIR_t* fileIRp, Instruction_t* newinsn, ostream& f Instruction_t* old_insn=insnMap[newinsn]; fout << endl << "# Orig addr: "<<addressify(newinsn)<<" insn_id: "<< std::dec - << newinsn->GetBaseID()<<" with comment "<<newinsn->GetComment()<<endl; - if (newinsn->GetIndirectBranchTargetAddress()) + << newinsn->getBaseID()<<" with comment "<<newinsn->getComment()<<endl; + if (newinsn->getIndirectBranchTargetAddress()) fout << "# Orig addr: "<<addressify(newinsn)<<" indirect branch target: " - <<newinsn->GetIndirectBranchTargetAddress()->GetVirtualOffset() << endl; + <<newinsn->getIndirectBranchTargetAddress()->getVirtualOffset() << endl; bool redirected_addr=false; bool redirected_ibt=false; @@ -666,23 +642,24 @@ static void emit_spri_rule(FileIR_t* fileIRp, Instruction_t* newinsn, ostream& f } /* if this insn is an IB target, emit the redirect appropriately */ - if (newinsn->GetIndirectBranchTargetAddress()) + if (newinsn->getIndirectBranchTargetAddress()) { redirected_ibt=true; /* If the IBT address isn't this insns address, redirect appropriately. * If this insn isn't an unmoved insn target, always redirect appropriately. */ - if((old_insn && (*newinsn->GetIndirectBranchTargetAddress()) != (*old_insn->GetAddress())) - || !redirected_addr) + // if((old_insn && (*newinsn->getIndirectBranchTargetAddress()) != (*old_insn->getAddress())) + // || !redirected_addr) + assert(0); // couldn't make this work { // use the better qualify address to check for file matches. fout << "# because has indir "<<endl; - fout << better_qualify_address(fileIRp,newinsn->GetIndirectBranchTargetAddress()) + fout << better_qualify_address(fileIRp,newinsn->getIndirectBranchTargetAddress()) <<" -> ."<<endl; } /* i don't understand this part. hopefully this is right */ - if(!newinsn->GetCallback().empty()) + if(!newinsn->getCallback().empty()) fout << ". -> "<< getPostCallbackLabel(newinsn) <<endl; } // if there's a corresponding "old" instruction (i.e., in Variant 0, aka from the binary) @@ -693,7 +670,7 @@ static void emit_spri_rule(FileIR_t* fileIRp, Instruction_t* newinsn, ostream& f /* check to see if this address an IBT somewhere else */ /* and we havne't already redirected it */ - if (ibts.find(*old_insn->GetAddress()) == ibts.end() && !redirected_ibt && !redirected_addr) + if (ibts.find(*old_insn->getAddress()) == ibts.end() && !redirected_ibt && !redirected_addr) { // with ILR turned off, we don't try to redirect to 0 @@ -715,7 +692,7 @@ static void emit_spri_rule(FileIR_t* fileIRp, Instruction_t* newinsn, ostream& f // this may be tricky because it seems we are overloading the indirect branch // target address to mean two things for instructions with callbacks. Good luck if // you're reading this. - assert(newinsn->GetCallback().empty()); + assert(newinsn->getCallback().empty()); } @@ -723,17 +700,17 @@ static void emit_spri_rule(FileIR_t* fileIRp, Instruction_t* newinsn, ostream& f /* if there's a fallthrough instruction, jump to it. */ - if(newinsn->GetFallthrough()) + if(newinsn->getFallthrough()) { - fout << ". -> " << qualified_labelfy(fileIRp,newinsn->GetFallthrough())<<endl; + fout << ". -> " << qualified_labelfy(fileIRp,newinsn->getFallthrough())<<endl; } else { //DISASM disasm; //disasm.Options = NasmSyntax + PrefixedNumeral + ShowSegmentRegs; - //disasm.Archi = fileIRp->GetArchitectureBitWidth(); - //disasm.EIP = (UIntPtr)newinsn->GetDataBits().c_str(); - //disasm.VirtualAddr = old_insn ? old_insn->GetAddress()->GetVirtualOffset() : 0; + //disasm.Archi = fileIRp->getArchitectureBitWidth(); + //disasm.EIP = (UIntPtr)newinsn->getDataBits().c_str(); + //disasm.VirtualAddr = old_insn ? old_insn->getAddress()->getVirtualOffset() : 0; const auto disasm=DecodedInstruction_t(newinsn); /* Disassemble the instruction */ @@ -747,7 +724,7 @@ static void emit_spri_rule(FileIR_t* fileIRp, Instruction_t* newinsn, ostream& f { assert(old_insn); /* it's an error to insert a new, non-unconditional branch instruction * and not specify it's fallthrough */ - fout << ". -> " << qualify(fileIRp)<< "0x" << std::hex << old_insn->GetAddress()->GetVirtualOffset()+instr_len <<endl; + fout << ". -> " << qualify(fileIRp)<< "0x" << std::hex << old_insn->getAddress()->getVirtualOffset()+instr_len <<endl; } } @@ -787,8 +764,8 @@ static void generate_insn_to_insn_maps(FileIR_t *fileIRp, FileIR_t *orig_fileIRp /* loop through each insn in the original program */ for( - std::set<Instruction_t*>::const_iterator it=orig_fileIRp->GetInstructions().begin(); - it!=orig_fileIRp->GetInstructions().end(); + auto it=orig_fileIRp->getInstructions().begin(); + it!=orig_fileIRp->getInstructions().end(); ++it ) { @@ -797,12 +774,12 @@ static void generate_insn_to_insn_maps(FileIR_t *fileIRp, FileIR_t *orig_fileIRp assert(insn); /* get it's ID */ - db_id_t address_id=insn->GetAddress()->GetBaseID(); + db_id_t address_id=insn->getAddress()->getBaseID(); assert(address_id!=-1); /* sanity check */ - assert(insn->GetAddress()->GetFileID()!=-1); - assert(insn->GetAddress()->GetVirtualOffset()!=0); + assert(insn->getAddress()->getFileID()!=-1); + assert(insn->getAddress()->getVirtualOffset()!=0); /* insert into map */ idMap[address_id]=insn; @@ -819,7 +796,7 @@ static void generate_insn_to_insn_maps(FileIR_t *fileIRp, FileIR_t *orig_fileIRp Instruction_t *insn=*it; assert(insn); - db_id_t orig_addr=insn->GetOriginalAddressID(); + db_id_t orig_addr=insn->getOriginalAddressID(); /* no mapping if this is true */ if(orig_addr==-1) @@ -841,14 +818,14 @@ void FileIR_t::GenerateSPRI(ostream &fout, bool with_ilr) assert(orig_varidp.IsRegistered()==true); for( - set<File_t*>::iterator it=orig_varidp.GetFiles().begin(); - it!=orig_varidp.GetFiles().end(); + set<File_t*>::iterator it=orig_varidp.getFiles().begin(); + it!=orig_varidp.getFiles().end(); ++it ) { File_t* the_file=*it; - if(the_file->GetBaseID()==fileptr->orig_fid) + if(the_file->getBaseID()==fileptr->orig_fid) { fout <<"# Generating spri for "<< the_file->GetURL()<<endl; @@ -877,7 +854,7 @@ static void generate_IBT_set(FileIR_t* fileIRp) ) { Instruction_t *insn=*it; - AddressID_t *ibt=insn->GetIndirectBranchTargetAddress(); + AddressID_t *ibt=insn->getIndirectBranchTargetAddress(); if(ibt) { @@ -910,24 +887,26 @@ static void generate_unmoved_insn_targets_set(FileIR_t* fileIRp) !needs_spri_rule(insn, insnMap[insn]) ) { - unmoved_insn_targets.insert(insn->GetTarget()); - unmoved_insn_targets.insert(insn->GetFallthrough()); + unmoved_insn_targets.insert(insn->getTarget()); + unmoved_insn_targets.insert(insn->getFallthrough()); } } } - +#endif void FileIR_t::GenerateSPRI(FileIR_t *orig_fileIRp, ostream &fout, bool with_ilr) { + assert(0); + /* //Resolve (assemble) any instructions in the registry. AssembleRegistry(); // give 'this' a name FileIR_t *fileIRp=this; - SetBaseIDS(); // need unique ID to generate unique label name + setBaseIDS(); // need unique ID to generate unique label name // generate the map from new instruction to old instruction needed for this transform. generate_insn_to_insn_maps(fileIRp, orig_fileIRp); @@ -962,5 +941,6 @@ void FileIR_t::GenerateSPRI(FileIR_t *orig_fileIRp, ostream &fout, bool with_ilr update_label_offset(fileIRp); fout<<"#DEBUG: maximum ID is "<<label_offset<<endl; + */ } diff --git a/libIRDB/src/core/icfs.cpp b/libIRDB-core/src/icfs.cpp similarity index 80% rename from libIRDB/src/core/icfs.cpp rename to libIRDB-core/src/icfs.cpp index a81b5469ebacc9febc6dfc2efd083de49572f100..f5e26b287aa6fa3a95f23e6264bda3c7702a0a1e 100644 --- a/libIRDB/src/core/icfs.cpp +++ b/libIRDB-core/src/icfs.cpp @@ -19,7 +19,7 @@ */ #include <all.hpp> -#include <utils.hpp> +#include <irdb-util> using namespace libIRDB; using namespace std; @@ -27,13 +27,13 @@ using namespace std; static string getICFSAnalysisStatus(const ICFS_Analysis_Status_t p_status) { // strings must match DB definition switch (p_status) { - case ICFS_Analysis_Incomplete: + case IRDB_SDK::iasAnalysisIncomplete: return string("icfs_analysis_incomplete"); break; - case ICFS_Analysis_Module_Complete: + case IRDB_SDK::iasAnalysisModuleComplete: return string("icfs_analysis_module_complete"); break; - case ICFS_Analysis_Complete: + case IRDB_SDK::iasAnalysisComplete: return string("icfs_analysis_complete"); break; default: @@ -47,19 +47,19 @@ static string getICFSAnalysisStatus(const ICFS_Analysis_Status_t p_status) { ICFS_t::ICFS_t(db_id_t p_set_id, const ICFS_Analysis_Status_t p_status) : BaseObj_t(NULL) { - SetBaseID(p_set_id); - SetAnalysisStatus(p_status); + setBaseID(p_set_id); + setAnalysisStatus(p_status); } ICFS_t::ICFS_t(db_id_t p_set_id, const string p_statusString) : BaseObj_t(NULL) { - SetBaseID(p_set_id); + setBaseID(p_set_id); if (p_statusString == "icfs_analysis_incomplete") { - SetAnalysisStatus(ICFS_Analysis_Incomplete); + setAnalysisStatus(IRDB_SDK::iasAnalysisIncomplete); } else if (p_statusString == "icfs_analysis_module_complete") { - SetAnalysisStatus(ICFS_Analysis_Module_Complete); + setAnalysisStatus(IRDB_SDK::iasAnalysisModuleComplete); } else if (p_statusString == "icfs_analysis_complete") { - SetAnalysisStatus(ICFS_Analysis_Complete); + setAnalysisStatus(IRDB_SDK::iasAnalysisComplete); } else { std::cerr << "error: unknown ICFS analysis status string: " << p_statusString << std::endl; assert(0); @@ -70,9 +70,9 @@ string ICFS_t::WriteToDB(File_t *fid) { assert(fid); - db_id_t icfs_id = GetBaseID(); + db_id_t icfs_id = getBaseID(); - string analysis_status = getICFSAnalysisStatus(GetAnalysisStatus()); + string analysis_status = getICFSAnalysisStatus(getAnalysisStatus()); string q=string("insert into ") + fid->icfs_table_name + string(" (icfs_id, icfs_status) VALUES (") + @@ -82,10 +82,10 @@ string ICFS_t::WriteToDB(File_t *fid) for (InstructionSet_t::const_iterator it = this->begin(); it != this->end(); ++it) { - Instruction_t *insn = *it; + auto insn = *it; assert(insn); - db_id_t address_id = insn->GetAddress()->GetBaseID(); + auto address_id = insn->getAddress()->getBaseID(); q += string("insert into ") + fid->icfs_map_table_name + string(" (icfs_id, address_id) VALUES(") + diff --git a/libIRDB/src/core/instruction.cpp b/libIRDB-core/src/instruction.cpp similarity index 66% rename from libIRDB/src/core/instruction.cpp rename to libIRDB-core/src/instruction.cpp index 7a876821660082bf3116ac9b57082fdf200c7ade..447f432de30535e300160d5231786c6e85ed0202 100644 --- a/libIRDB/src/core/instruction.cpp +++ b/libIRDB-core/src/instruction.cpp @@ -19,12 +19,12 @@ */ #include <all.hpp> -#include <utils.hpp> +#include <irdb-util> #include <stdlib.h> #include <fstream> #include <sstream> #include <iomanip> -#include <utils.hpp> +#include <irdb-util> #undef EIP @@ -46,7 +46,7 @@ Instruction_t::Instruction_t() : eh_pgm(NULL), eh_cs(NULL) { - SetBaseID(NOT_IN_DATABASE); + setBaseID(NOT_IN_DATABASE); } Instruction_t::Instruction_t(db_id_t id, @@ -73,7 +73,7 @@ Instruction_t::Instruction_t(db_id_t id, eh_pgm(NULL), eh_cs(NULL) { - SetBaseID(id); + setBaseID(id); } /* @@ -83,9 +83,9 @@ int Instruction_t::Disassemble(DISASM &disasm) const memset(&disasm, 0, sizeof(DISASM)); disasm.Options = NasmSyntax + PrefixedNumeral; - disasm.Archi = FileIR_t::GetArchitectureBitWidth(); - disasm.EIP = (UIntPtr) GetDataBits().c_str(); - disasm.VirtualAddr = GetAddress()->GetVirtualOffset(); + disasm.Archi = FileIR_t::getArchitectureBitWidth(); + disasm.EIP = (UIntPtr) getDataBits().c_str(); + disasm.VirtualAddr = getAddress()->getVirtualOffset(); int instr_len = Disasm(&disasm); return instr_len; @@ -98,15 +98,15 @@ std::string Instruction_t::getDisassembly() const // Disassemble(this,disasm); // return std::string(disasm.CompleteInstr); - const auto d=DecodedInstruction_t(this); - return d.getDisassembly(); + const auto d=DecodedInstruction_t::factory(this); + return d->getDisassembly(); } // // Given an instruction in assembly, returns the raw bits in a string // On error, return the empty string // -bool Instruction_t::Assemble(string assembly) +bool Instruction_t::assemble(string assembly) { const string assemblyFile = "tmp.asm"; const string binaryOutputFile = "tmp.bin"; @@ -124,7 +124,7 @@ bool Instruction_t::Assemble(string assembly) return false; } - asmFile<<"BITS "<<std::dec<<FileIR_t::GetArchitectureBitWidth()<<endl; + asmFile<<"BITS "<<std::dec<<FileIR_t::getArchitectureBitWidth()<<endl; asmFile<<assembly<<endl; asmFile.close(); @@ -161,7 +161,7 @@ bool Instruction_t::Assemble(string assembly) // should erase those 2 files here - this->SetDataBits(rawBits); + this->setDataBits(rawBits); return true; } @@ -171,29 +171,29 @@ vector<string> Instruction_t::WriteToDB(File_t *fid, db_id_t newid) assert(fid); assert(my_address); - if(GetBaseID()==NOT_IN_DATABASE) - SetBaseID(newid); + if(getBaseID()==NOT_IN_DATABASE) + setBaseID(newid); auto func_id=NOT_IN_DATABASE; - if(my_function) func_id=my_function->GetBaseID(); + if(my_function) func_id=my_function->getBaseID(); auto ft_id=NOT_IN_DATABASE; - if(fallthrough) ft_id=fallthrough->GetBaseID(); + if(fallthrough) ft_id=fallthrough->getBaseID(); auto targ_id=NOT_IN_DATABASE; - if(target) targ_id=target->GetBaseID(); + if(target) targ_id=target->getBaseID(); auto icfs_id=NOT_IN_DATABASE; - if (icfs) icfs_id=icfs->GetBaseID(); + if (icfs) icfs_id=icfs->getBaseID(); auto indirect_bt_id=NOT_IN_DATABASE; - if(indTarg) indirect_bt_id=indTarg->GetBaseID(); + if(indTarg) indirect_bt_id=indTarg->getBaseID(); auto eh_pgm_id=NOT_IN_DATABASE; - if(eh_pgm) eh_pgm_id=eh_pgm->GetBaseID(); + if(eh_pgm) eh_pgm_id=eh_pgm->getBaseID(); auto eh_css_id=NOT_IN_DATABASE; - if(eh_cs) eh_css_id=eh_cs->GetBaseID(); + if(eh_cs) eh_css_id=eh_cs->getBaseID(); ostringstream hex_data; hex_data << setfill('0') << hex;; @@ -202,8 +202,8 @@ vector<string> Instruction_t::WriteToDB(File_t *fid, db_id_t newid) return { - to_string(GetBaseID()), - to_string(my_address->GetBaseID()), + to_string(getBaseID()), + to_string(my_address->getBaseID()), to_string(func_id), to_string(orig_address_id), to_string(ft_id), @@ -215,24 +215,24 @@ vector<string> Instruction_t::WriteToDB(File_t *fid, db_id_t newid) callback, comment, to_string(indirect_bt_id), - to_string(GetDoipID()) }; + to_string(getDoipID()) }; } /* return true if this instructino exits the function -- true if there's no function, because each instruction is it's own function? */ -bool Instruction_t::IsFunctionExit() const +bool Instruction_t::isFunctionExit() const { if(!my_function) return true; /* if there's a target that's outside this function */ - Instruction_t *target=GetTarget(); - if(target && target->GetFunction()!=GetFunction()) // !is_in_set(my_function->GetInstructions(),target)) + auto target=getTarget(); + if(target && target->getFunction()!=getFunction()) // !is_in_set(my_function->GetInstructions(),target)) return true; /* if there's a fallthrough that's outside this function */ - Instruction_t *ft=GetFallthrough(); - if(fallthrough && ft->GetFunction()!=GetFunction()) // !is_in_set(my_function->GetInstructions(),ft)) + auto ft=getFallthrough(); + if(fallthrough && ft->getFunction()!=getFunction()) // !is_in_set(my_function->GetInstructions(),ft)) return true; /* some instructions have no next-isntructions defined in the db, and we call them function exits */ @@ -242,36 +242,23 @@ bool Instruction_t::IsFunctionExit() const return false; } - -/* -bool Instruction_t::SetsStackPointer(ARGTYPE* arg) +IRDB_SDK::Function_t* Instruction_t::getFunction() const { - if((arg->AccessMode & WRITE ) == 0) - return false; - int access_type=arg->ArgType; - - if(access_type==REGISTER_TYPE + GENERAL_REG +REG4) - return true; - return false; - + return my_function; } -bool Instruction_t::SetsStackPointer(DISASM* disasm) -{ - if(strstr(disasm->Instruction.Mnemonic, "push")!=NULL) - return true; - if(strstr(disasm->Instruction.Mnemonic, "pop")!=NULL) - return true; - if(strstr(disasm->Instruction.Mnemonic, "call")!=NULL) - return true; - if(disasm->Instruction.ImplicitModifiedRegs==REGISTER_TYPE+GENERAL_REG+REG4) - return true; - if(SetsStackPointer(&disasm->Argument1)) return true; - if(SetsStackPointer(&disasm->Argument2)) return true; - if(SetsStackPointer(&disasm->Argument3)) return true; +IRDB_SDK::EhProgram_t* Instruction_t::getEhProgram() const { return eh_pgm; } +IRDB_SDK::EhCallSite_t* Instruction_t::getEhCallSite() const { return eh_cs; } +IRDB_SDK::AddressID_t* Instruction_t::getIndirectBranchTargetAddress() const { return indTarg; } + +void Instruction_t::setAddress (IRDB_SDK::AddressID_t* newaddr) { my_address=dynamic_cast<AddressID_t*>(newaddr); } +void Instruction_t::setFunction (IRDB_SDK::Function_t* func ) { my_function=dynamic_cast<Function_t*>(func);} +void Instruction_t::setFallthrough (IRDB_SDK::Instruction_t* i) { fallthrough=dynamic_cast<Instruction_t*>(i); } +void Instruction_t::setTarget (IRDB_SDK::Instruction_t* i) { target=dynamic_cast<Instruction_t*>(i); } +void Instruction_t::setIBTargets (IRDB_SDK::ICFS_t *p_icfs) { icfs=dynamic_cast<ICFS_t*>(p_icfs); } +void Instruction_t::setEhProgram(IRDB_SDK::EhProgram_t* orig) { eh_pgm=dynamic_cast<EhProgram_t*>(orig); } +void Instruction_t::setEhCallSite(IRDB_SDK::EhCallSite_t* orig) { eh_cs=dynamic_cast<EhCallSite_t*>(orig); } +void Instruction_t::setIndirectBranchTargetAddress(IRDB_SDK::AddressID_t* myIndTarg) { indTarg=dynamic_cast<AddressID_t*>(myIndTarg); } - return false; -} -*/ diff --git a/libIRDB-core/src/operand_csarm.cpp b/libIRDB-core/src/operand_csarm.cpp new file mode 100644 index 0000000000000000000000000000000000000000..01a20a17d5061ca3ed15f602c074ed6b06caeea2 --- /dev/null +++ b/libIRDB-core/src/operand_csarm.cpp @@ -0,0 +1,310 @@ + +#include <libIRDB-core.hpp> +#include <memory> +#include <decode_base.hpp> +#include <decode_csarm.hpp> +#include <operand_base.hpp> +#include <operand_csarm.hpp> + + +using namespace std; +using namespace libIRDB; + +#include <capstone.h> +static const auto ARM64_REG_PC=(arm64_reg)(ARM64_REG_ENDING+1); + + +DecodedOperandCapstoneARM64_t::DecodedOperandCapstoneARM64_t( const shared_ptr<void> & p_my_insn, uint8_t p_op_num) + : + my_insn(p_my_insn), + op_num(p_op_num) +{ + +} + +DecodedOperandCapstoneARM64_t::~DecodedOperandCapstoneARM64_t() +{ +} + + +bool DecodedOperandCapstoneARM64_t::isConstant() const +{ + const auto the_insn=static_cast<cs_insn*>(my_insn.get()); + const auto &op = (the_insn->detail->arm64.operands[op_num]); + return op.type==ARM64_OP_IMM; +} + +uint64_t DecodedOperandCapstoneARM64_t::getConstant() const +{ + if(!isConstant()) throw std::logic_error(string("Cannot ")+__FUNCTION__+" of non-constant operand"); + + const auto the_insn=static_cast<cs_insn*>(my_insn.get()); + const auto &op = (the_insn->detail->arm64.operands[op_num]); + return op.imm; +} + +string DecodedOperandCapstoneARM64_t::getString() const +{ + const auto the_insn=static_cast<cs_insn*>(my_insn.get()); + const auto &op = (the_insn->detail->arm64.operands[op_num]); + const auto handle=DecodedInstructionCapstoneARM64_t::cs_handle->getHandle(); + + switch(op.type) + { + case ARM64_OP_REG: + return string(cs_reg_name(handle, op.reg)); + case ARM64_OP_REG_MRS: + case ARM64_OP_REG_MSR: + case ARM64_OP_FP: + return string("fpcr"); + case ARM64_OP_IMM: + return to_string(op.imm); + case ARM64_OP_MEM: + { + string ret_val; + if (op.mem.base != ARM64_REG_INVALID) + ret_val+=cs_reg_name(handle, op.mem.base); + + if (op.mem.index != ARM64_REG_INVALID) + ret_val+=string(" + ") +cs_reg_name(handle, op.mem.index); + + if (op.mem.disp != 0) + ret_val+=" + "+ to_string(op.mem.disp); + + if(ret_val=="") + return "0"; + + return ret_val; + } + default: + assert(0); + } +} + +bool DecodedOperandCapstoneARM64_t::isRegister() const +{ + const auto the_insn=static_cast<cs_insn*>(my_insn.get()); + const auto &op = (the_insn->detail->arm64.operands[op_num]); + return op.type==ARM64_OP_REG; +} + +bool DecodedOperandCapstoneARM64_t::isGeneralPurposeRegister() const +{ + const auto gp_regs=set<arm64_reg>({ + ARM64_REG_X29, ARM64_REG_X30, ARM64_REG_SP, ARM64_REG_WSP, ARM64_REG_WZR, ARM64_REG_XZR, + ARM64_REG_W0, ARM64_REG_W1, ARM64_REG_W2, ARM64_REG_W3, ARM64_REG_W4, ARM64_REG_W5, ARM64_REG_W6, ARM64_REG_W7, + ARM64_REG_W8, ARM64_REG_W9, ARM64_REG_W10, ARM64_REG_W11, ARM64_REG_W12, ARM64_REG_W13, ARM64_REG_W14, ARM64_REG_W15, + ARM64_REG_W16, ARM64_REG_W17, ARM64_REG_W18, ARM64_REG_W19, ARM64_REG_W20, ARM64_REG_W21, ARM64_REG_W22, ARM64_REG_W23, + ARM64_REG_W24, ARM64_REG_W25, ARM64_REG_W26, ARM64_REG_W27, ARM64_REG_W28, ARM64_REG_W29, ARM64_REG_W30, + ARM64_REG_X0, ARM64_REG_X1, ARM64_REG_X2, ARM64_REG_X3, ARM64_REG_X4, ARM64_REG_X5, ARM64_REG_X6, ARM64_REG_X7, + ARM64_REG_X8, ARM64_REG_X9, ARM64_REG_X10, ARM64_REG_X11, ARM64_REG_X12, ARM64_REG_X13, ARM64_REG_X14, ARM64_REG_X15, + ARM64_REG_X16, ARM64_REG_X17, ARM64_REG_X18, ARM64_REG_X19, ARM64_REG_X20, ARM64_REG_X21, ARM64_REG_X22, ARM64_REG_X23, + ARM64_REG_X24, ARM64_REG_X25, ARM64_REG_X26, ARM64_REG_X27, ARM64_REG_X28, + }); + + const auto the_insn=static_cast<cs_insn*>(my_insn.get()); + const auto &op = (the_insn->detail->arm64.operands[op_num]); + return isRegister() && gp_regs.find(op.reg)!=end(gp_regs); + +} + +bool DecodedOperandCapstoneARM64_t::isMmxRegister() const +{ + return false; +} + +bool DecodedOperandCapstoneARM64_t::isFpuRegister() const +{ + const auto fpu_regs=set<arm64_reg>({ + ARM64_REG_B0, ARM64_REG_B1, ARM64_REG_B2, ARM64_REG_B3, ARM64_REG_B4, ARM64_REG_B5, ARM64_REG_B6, ARM64_REG_B7, + ARM64_REG_B8, ARM64_REG_B9, ARM64_REG_B10, ARM64_REG_B11, ARM64_REG_B12, ARM64_REG_B13, ARM64_REG_B14, ARM64_REG_B15, + ARM64_REG_B16, ARM64_REG_B17, ARM64_REG_B18, ARM64_REG_B19, ARM64_REG_B20, ARM64_REG_B21, ARM64_REG_B22, ARM64_REG_B23, + ARM64_REG_B24, ARM64_REG_B25, ARM64_REG_B26, ARM64_REG_B27, ARM64_REG_B28, ARM64_REG_B29, ARM64_REG_B30, ARM64_REG_B31, + ARM64_REG_H0, ARM64_REG_H1, ARM64_REG_H2, ARM64_REG_H3, ARM64_REG_H4, ARM64_REG_H5, ARM64_REG_H6, ARM64_REG_H7, + ARM64_REG_H8, ARM64_REG_H9, ARM64_REG_H10, ARM64_REG_H11, ARM64_REG_H12, ARM64_REG_H13, ARM64_REG_H14, ARM64_REG_H15, + ARM64_REG_H16, ARM64_REG_H17, ARM64_REG_H18, ARM64_REG_H19, ARM64_REG_H20, ARM64_REG_H21, ARM64_REG_H22, ARM64_REG_H23, + ARM64_REG_H24, ARM64_REG_H25, ARM64_REG_H26, ARM64_REG_H27, ARM64_REG_H28, ARM64_REG_H29, ARM64_REG_H30, ARM64_REG_H31, + ARM64_REG_D0, ARM64_REG_D1, ARM64_REG_D2, ARM64_REG_D3, ARM64_REG_D4, ARM64_REG_D5, ARM64_REG_D6, ARM64_REG_D7, + ARM64_REG_D8, ARM64_REG_D9, ARM64_REG_D10, ARM64_REG_D11, ARM64_REG_D12, ARM64_REG_D13, ARM64_REG_D14, ARM64_REG_D15, + ARM64_REG_D16, ARM64_REG_D17, ARM64_REG_D18, ARM64_REG_D19, ARM64_REG_D20, ARM64_REG_D21, ARM64_REG_D22, ARM64_REG_D23, + ARM64_REG_D24, ARM64_REG_D25, ARM64_REG_D26, ARM64_REG_D27, ARM64_REG_D28, ARM64_REG_D29, ARM64_REG_D30, ARM64_REG_D31, + ARM64_REG_H0, ARM64_REG_H1, ARM64_REG_H2, ARM64_REG_H3, ARM64_REG_H4, ARM64_REG_H5, ARM64_REG_H6, ARM64_REG_H7, + ARM64_REG_H8, ARM64_REG_H9, ARM64_REG_H10, ARM64_REG_H11, ARM64_REG_H12, ARM64_REG_H13, ARM64_REG_H14, ARM64_REG_H15, + ARM64_REG_H16, ARM64_REG_H17, ARM64_REG_H18, ARM64_REG_H19, ARM64_REG_H20, ARM64_REG_H21, ARM64_REG_H22, ARM64_REG_H23, + ARM64_REG_H24, ARM64_REG_H25, ARM64_REG_H26, ARM64_REG_H27, ARM64_REG_H28, ARM64_REG_H29, ARM64_REG_H30, ARM64_REG_H31, + ARM64_REG_Q0, ARM64_REG_Q1, ARM64_REG_Q2, ARM64_REG_Q3, ARM64_REG_Q4, ARM64_REG_Q5, ARM64_REG_Q6, ARM64_REG_Q7, + ARM64_REG_Q8, ARM64_REG_Q9, ARM64_REG_Q10, ARM64_REG_Q11, ARM64_REG_Q12, ARM64_REG_Q13, ARM64_REG_Q14, ARM64_REG_Q15, + ARM64_REG_Q16, ARM64_REG_Q17, ARM64_REG_Q18, ARM64_REG_Q19, ARM64_REG_Q20, ARM64_REG_Q21, ARM64_REG_Q22, ARM64_REG_Q23, + ARM64_REG_Q24, ARM64_REG_Q25, ARM64_REG_Q26, ARM64_REG_Q27, ARM64_REG_Q28, ARM64_REG_Q29, ARM64_REG_Q30, ARM64_REG_Q31, + ARM64_REG_S0, ARM64_REG_S1, ARM64_REG_S2, ARM64_REG_S3, ARM64_REG_S4, ARM64_REG_S5, ARM64_REG_S6, ARM64_REG_S7, + ARM64_REG_S8, ARM64_REG_S9, ARM64_REG_S10, ARM64_REG_S11, ARM64_REG_S12, ARM64_REG_S13, ARM64_REG_S14, ARM64_REG_S15, + ARM64_REG_S16, ARM64_REG_S17, ARM64_REG_S18, ARM64_REG_S19, ARM64_REG_S20, ARM64_REG_S21, ARM64_REG_S22, ARM64_REG_S23, + ARM64_REG_S24, ARM64_REG_S25, ARM64_REG_S26, ARM64_REG_S27, ARM64_REG_S28, ARM64_REG_S29, ARM64_REG_S30, ARM64_REG_S31, + }); + + const auto the_insn=static_cast<cs_insn*>(my_insn.get()); + const auto &op = (the_insn->detail->arm64.operands[op_num]); + return isRegister() && fpu_regs.find(op.reg)!=end(fpu_regs); +} + +bool DecodedOperandCapstoneARM64_t::isSseRegister() const +{ + return false; +} + +bool DecodedOperandCapstoneARM64_t::isAvxRegister() const +{ + return false; +} + +bool DecodedOperandCapstoneARM64_t::isZmmRegister() const +{ + return false; +} + +bool DecodedOperandCapstoneARM64_t::isSpecialRegister() const +{ + const auto special_regs=set<arm64_reg>({ + ARM64_REG_NZCV, + }); + + const auto the_insn=static_cast<cs_insn*>(my_insn.get()); + const auto &op = (the_insn->detail->arm64.operands[op_num]); + return isRegister() && special_regs.find(op.reg)!=end(special_regs); + return false; +} + +bool DecodedOperandCapstoneARM64_t::isSegmentRegister() const +{ + return false; +} + + + +uint32_t DecodedOperandCapstoneARM64_t::getRegNumber() const +{ + const auto the_insn=static_cast<cs_insn*>(my_insn.get()); + const auto &op = (the_insn->detail->arm64.operands[op_num]); + return op.reg; +} + +bool DecodedOperandCapstoneARM64_t::isMemory() const +{ + const auto the_insn=static_cast<cs_insn*>(my_insn.get()); + const auto &op = (the_insn->detail->arm64.operands[op_num]); + return op.type==ARM64_OP_MEM; + +} + +bool DecodedOperandCapstoneARM64_t::hasBaseRegister() const +{ + const auto the_insn=static_cast<cs_insn*>(my_insn.get()); + const auto &op = (the_insn->detail->arm64.operands[op_num]); + return isMemory() && op.mem.base!=ARM64_REG_INVALID; + +} + +bool DecodedOperandCapstoneARM64_t::hasIndexRegister() const +{ + const auto the_insn=static_cast<cs_insn*>(my_insn.get()); + const auto &op = (the_insn->detail->arm64.operands[op_num]); + return isMemory() && op.mem.index!=ARM64_REG_INVALID; +} + +uint32_t DecodedOperandCapstoneARM64_t::getBaseRegister() const +{ + if(!isMemory()) throw std::logic_error(string("Cannot ")+__FUNCTION__+" of non-memory operand"); + const auto the_insn=static_cast<cs_insn*>(my_insn.get()); + const auto &op = (the_insn->detail->arm64.operands[op_num]); + return op.mem.base; +} + +uint32_t DecodedOperandCapstoneARM64_t::getIndexRegister() const +{ + if(!isMemory()) throw std::logic_error(string("Cannot ")+__FUNCTION__+" of non-memory operand"); + const auto the_insn=static_cast<cs_insn*>(my_insn.get()); + const auto &op = (the_insn->detail->arm64.operands[op_num]); + return op.mem.index; +} + +uint32_t DecodedOperandCapstoneARM64_t::getScaleValue() const +{ + assert(0); +} + +bool DecodedOperandCapstoneARM64_t::hasMemoryDisplacement() const +{ + const auto the_insn=static_cast<cs_insn*>(my_insn.get()); + const auto &op = (the_insn->detail->arm64.operands[op_num]); + return op.mem.disp!=0; + +} // end of DecodedOperandCapstoneARM64_t::hasMemoryDisplacement() + +virtual_offset_t DecodedOperandCapstoneARM64_t::getMemoryDisplacement() const +{ + if(!isMemory()) throw std::logic_error(string("Cannot ")+__FUNCTION__+" of non-memory operand"); + const auto the_insn=static_cast<cs_insn*>(my_insn.get()); + const auto &op = (the_insn->detail->arm64.operands[op_num]); + return op.mem.disp; +} + +bool DecodedOperandCapstoneARM64_t::isPcrel() const +{ + const auto the_insn=static_cast<cs_insn*>(my_insn.get()); + const auto &op = (the_insn->detail->arm64.operands[op_num]); + + // covers ldr, ldrsw, prfm + // note: capstone's reports ldr, ldrsw, and prfm as using an imm, when they actually access memory. + // jdh fixed this in the IRDB's Disassemble routine + if(isMemory() && op.mem.base==ARM64_REG_PC) + return true; + + const auto mnemonic=string(the_insn->mnemonic); + const auto is_adr_type= mnemonic=="adr" || mnemonic=="adrp"; + if(is_adr_type && op.type==ARM64_OP_IMM) + return true; + + return false; // no PC as general purpose reg. +} + +/* in bytes */ +uint32_t DecodedOperandCapstoneARM64_t::getMemoryDisplacementEncodingSize() const +{ + if(!isMemory()) throw std::logic_error(string("Cannot ")+__FUNCTION__+" of non-memory operand"); + assert(0); +} + +uint32_t DecodedOperandCapstoneARM64_t::getArgumentSizeInBytes() const +{ + return false; +} + +uint32_t DecodedOperandCapstoneARM64_t::getArgumentSizeInBits() const +{ + return getArgumentSizeInBytes()*8; +} + +bool DecodedOperandCapstoneARM64_t::hasSegmentRegister() const +{ + return false; +} + +uint32_t DecodedOperandCapstoneARM64_t::getSegmentRegister() const +{ + throw std::logic_error(string("Cannot ")+__FUNCTION__+" on ARM architecture"); +} + +bool DecodedOperandCapstoneARM64_t::isRead() const +{ + const auto the_insn=static_cast<cs_insn*>(my_insn.get()); + const auto &op = (the_insn->detail->arm64.operands[op_num]); + return (op.access & CS_AC_READ)!=0; +} + +bool DecodedOperandCapstoneARM64_t::isWritten() const +{ + // default: use capstone's advice. + const auto the_insn=static_cast<cs_insn*>(my_insn.get()); + const auto &op = (the_insn->detail->arm64.operands[op_num]); + return (op.access & CS_AC_WRITE)!=0; +} diff --git a/libIRDB/src/core/operand_cs.cpp b/libIRDB-core/src/operand_csx86.cpp similarity index 87% rename from libIRDB/src/core/operand_cs.cpp rename to libIRDB-core/src/operand_csx86.cpp index f74aff7b91e04bac2020ac16bd3eb16d37e6f74a..ce863a9ef45d60a35f2354a6fc2a5f81e0b65e91 100644 --- a/libIRDB/src/core/operand_cs.cpp +++ b/libIRDB-core/src/operand_csx86.cpp @@ -1,8 +1,12 @@ #include <libIRDB-core.hpp> #include <memory> -#include <core/operand_cs.hpp> -#include <core/decode_cs.hpp> +#include <decode_base.hpp> +#include <decode_csx86.hpp> +#include <operand_base.hpp> +#include <operand_csx86.hpp> + + using namespace std; using namespace libIRDB; @@ -138,17 +142,17 @@ static uint32_t to_reg_number(const x86_reg ®) // methods -//DecodedOperandCapstone_t& DecodedOperandCapstone_t::operator=(const DecodedOperandCapstone_t& copy) +//DecodedOperandCapstoneX86_t& DecodedOperandCapstoneX86_t::operator=(const DecodedOperandCapstoneX86_t& copy) //{ // return *this; //} // -//DecodedOperandCapstone_t::DecodedOperandCapstone_t(const DecodedOperandCapstone_t& copy) +//DecodedOperandCapstoneX86_t::DecodedOperandCapstoneX86_t(const DecodedOperandCapstoneX86_t& copy) //{ // *this=copy; //} -DecodedOperandCapstone_t::DecodedOperandCapstone_t( const shared_ptr<void> & p_my_insn, uint8_t p_op_num) +DecodedOperandCapstoneX86_t::DecodedOperandCapstoneX86_t( const shared_ptr<void> & p_my_insn, uint8_t p_op_num) : my_insn(p_my_insn), op_num(p_op_num) @@ -156,12 +160,12 @@ DecodedOperandCapstone_t::DecodedOperandCapstone_t( const shared_ptr<void> & p_m } -DecodedOperandCapstone_t::~DecodedOperandCapstone_t() +DecodedOperandCapstoneX86_t::~DecodedOperandCapstoneX86_t() { } -bool DecodedOperandCapstone_t::isConstant() const +bool DecodedOperandCapstoneX86_t::isConstant() const { const auto the_insn=static_cast<cs_insn*>(my_insn.get()); const auto &op = (the_insn->detail->x86.operands[op_num]); @@ -169,7 +173,7 @@ bool DecodedOperandCapstone_t::isConstant() const return op.type==X86_OP_IMM; } -uint64_t DecodedOperandCapstone_t::getConstant() const +uint64_t DecodedOperandCapstoneX86_t::getConstant() const { if(!isConstant()) throw std::logic_error(string("Cannot ")+__FUNCTION__+" of non-constant operand"); @@ -178,11 +182,11 @@ uint64_t DecodedOperandCapstone_t::getConstant() const return op.imm; } -string DecodedOperandCapstone_t::getString() const +string DecodedOperandCapstoneX86_t::getString() const { const auto the_insn=static_cast<cs_insn*>(my_insn.get()); const auto &op = (the_insn->detail->x86.operands[op_num]); - const auto handle=DecodedInstructionCapstone_t::cs_handle->getHandle(); + const auto handle=DecodedInstructionCapstoneX86_t::cs_handle->getHandle(); switch(op.type) { @@ -227,14 +231,14 @@ string DecodedOperandCapstone_t::getString() const } } -bool DecodedOperandCapstone_t::isRegister() const +bool DecodedOperandCapstoneX86_t::isRegister() const { const auto the_insn=static_cast<cs_insn*>(my_insn.get()); const auto &op = (the_insn->detail->x86.operands[op_num]); return op.type==X86_OP_REG; } -bool DecodedOperandCapstone_t::isGeneralPurposeRegister() const +bool DecodedOperandCapstoneX86_t::isGeneralPurposeRegister() const { const auto gp_regs=set<x86_reg>({ @@ -261,7 +265,7 @@ bool DecodedOperandCapstone_t::isGeneralPurposeRegister() const return isRegister() && gp_regs.find(op.reg)!=end(gp_regs); } -bool DecodedOperandCapstone_t::isMmxRegister() const +bool DecodedOperandCapstoneX86_t::isMmxRegister() const { const auto regs=set<x86_reg>({ X86_REG_MM0, X86_REG_MM1, @@ -272,7 +276,7 @@ bool DecodedOperandCapstone_t::isMmxRegister() const return isRegister() && regs.find(op.reg)!=end(regs); } -bool DecodedOperandCapstone_t::isFpuRegister() const +bool DecodedOperandCapstoneX86_t::isFpuRegister() const { const auto regs=set<x86_reg>({ X86_REG_ST0, X86_REG_ST1, X86_REG_ST2, X86_REG_ST3, @@ -283,7 +287,7 @@ bool DecodedOperandCapstone_t::isFpuRegister() const return isRegister() && regs.find(op.reg)!=end(regs); } -bool DecodedOperandCapstone_t::isSseRegister() const +bool DecodedOperandCapstoneX86_t::isSseRegister() const { const auto regs=set<x86_reg>({ X86_REG_XMM0, X86_REG_XMM1, X86_REG_XMM2, X86_REG_XMM3, X86_REG_XMM4, @@ -299,7 +303,7 @@ bool DecodedOperandCapstone_t::isSseRegister() const return isRegister() && regs.find(op.reg)!=end(regs); } -bool DecodedOperandCapstone_t::isAvxRegister() const +bool DecodedOperandCapstoneX86_t::isAvxRegister() const { const auto regs=set<x86_reg>({ X86_REG_YMM0, X86_REG_YMM1, X86_REG_YMM2, @@ -315,7 +319,7 @@ bool DecodedOperandCapstone_t::isAvxRegister() const return isRegister() && regs.find(op.reg)!=end(regs); } -bool DecodedOperandCapstone_t::isZmmRegister() const +bool DecodedOperandCapstoneX86_t::isZmmRegister() const { const auto regs=set<x86_reg>({ X86_REG_ZMM0, X86_REG_ZMM1, X86_REG_ZMM2, @@ -331,7 +335,7 @@ bool DecodedOperandCapstone_t::isZmmRegister() const return isRegister() && regs.find(op.reg)!=end(regs); } -bool DecodedOperandCapstone_t::isSpecialRegister() const +bool DecodedOperandCapstoneX86_t::isSpecialRegister() const { const auto regs=set<x86_reg>({ X86_REG_CR1, X86_REG_CR2, X86_REG_CR3, X86_REG_CR4, X86_REG_CR5, @@ -345,7 +349,7 @@ bool DecodedOperandCapstone_t::isSpecialRegister() const return isRegister() && regs.find(op.reg)!=end(regs); } -bool DecodedOperandCapstone_t::isSegmentRegister() const +bool DecodedOperandCapstoneX86_t::isSegmentRegister() const { const auto regs=set<x86_reg>({ X86_REG_CS, @@ -362,7 +366,7 @@ bool DecodedOperandCapstone_t::isSegmentRegister() const -uint32_t DecodedOperandCapstone_t::getRegNumber() const +uint32_t DecodedOperandCapstoneX86_t::getRegNumber() const { const auto the_insn=static_cast<cs_insn*>(my_insn.get()); const auto &op = (the_insn->detail->x86.operands[op_num]); @@ -384,28 +388,28 @@ uint32_t DecodedOperandCapstone_t::getRegNumber() const assert(0); } -bool DecodedOperandCapstone_t::isMemory() const +bool DecodedOperandCapstoneX86_t::isMemory() const { const auto the_insn=static_cast<cs_insn*>(my_insn.get()); const auto &op = (the_insn->detail->x86.operands[op_num]); return op.type==X86_OP_MEM; } -bool DecodedOperandCapstone_t::hasBaseRegister() const +bool DecodedOperandCapstoneX86_t::hasBaseRegister() const { const auto the_insn=static_cast<cs_insn*>(my_insn.get()); const auto &op = (the_insn->detail->x86.operands[op_num]); return isMemory() && op.mem.base!=X86_REG_INVALID && op.mem.base!=X86_REG_RIP; } -bool DecodedOperandCapstone_t::hasIndexRegister() const +bool DecodedOperandCapstoneX86_t::hasIndexRegister() const { const auto the_insn=static_cast<cs_insn*>(my_insn.get()); const auto &op = (the_insn->detail->x86.operands[op_num]); return isMemory() && op.mem.index!=X86_REG_INVALID; } -uint32_t DecodedOperandCapstone_t::getBaseRegister() const +uint32_t DecodedOperandCapstoneX86_t::getBaseRegister() const { if(!isMemory()) throw std::logic_error(string("Cannot ")+__FUNCTION__+" of non-memory operand"); const auto the_insn=static_cast<cs_insn*>(my_insn.get()); @@ -413,7 +417,7 @@ uint32_t DecodedOperandCapstone_t::getBaseRegister() const return to_reg_number((x86_reg)op.mem.base); } -uint32_t DecodedOperandCapstone_t::getIndexRegister() const +uint32_t DecodedOperandCapstoneX86_t::getIndexRegister() const { if(!isMemory()) throw std::logic_error(string("Cannot ")+__FUNCTION__+" of non-memory operand"); const auto the_insn=static_cast<cs_insn*>(my_insn.get()); @@ -421,7 +425,7 @@ uint32_t DecodedOperandCapstone_t::getIndexRegister() const return to_reg_number((x86_reg)op.mem.index); } -uint32_t DecodedOperandCapstone_t::getScaleValue() const +uint32_t DecodedOperandCapstoneX86_t::getScaleValue() const { if(!isMemory()) throw std::logic_error(string("Cannot ")+__FUNCTION__+" of non-memory operand"); const auto the_insn=static_cast<cs_insn*>(my_insn.get()); @@ -429,7 +433,7 @@ uint32_t DecodedOperandCapstone_t::getScaleValue() const return op.mem.scale; } -bool DecodedOperandCapstone_t::hasMemoryDisplacement() const +bool DecodedOperandCapstoneX86_t::hasMemoryDisplacement() const { if(!isMemory()) throw std::logic_error(string("Cannot ")+__FUNCTION__+" of non-memory operand"); @@ -470,9 +474,9 @@ bool DecodedOperandCapstone_t::hasMemoryDisplacement() const assert(0); //unreachable } assert(0); // unreachable -} // end of DecodedOperandCapstone_t::hasMemoryDisplacement() +} // end of DecodedOperandCapstoneX86_t::hasMemoryDisplacement() -virtual_offset_t DecodedOperandCapstone_t::getMemoryDisplacement() const +virtual_offset_t DecodedOperandCapstoneX86_t::getMemoryDisplacement() const { if(!isMemory()) throw std::logic_error(string("Cannot ")+__FUNCTION__+" of non-memory operand"); const auto the_insn=static_cast<cs_insn*>(my_insn.get()); @@ -480,7 +484,7 @@ virtual_offset_t DecodedOperandCapstone_t::getMemoryDisplacement() const return op.mem.disp; } -bool DecodedOperandCapstone_t::isPcrel() const +bool DecodedOperandCapstoneX86_t::isPcrel() const { if(!isMemory()) return false; const auto the_insn=static_cast<cs_insn*>(my_insn.get()); @@ -490,7 +494,7 @@ bool DecodedOperandCapstone_t::isPcrel() const } /* in bytes */ -uint32_t DecodedOperandCapstone_t::getMemoryDisplacementEncodingSize() const +uint32_t DecodedOperandCapstoneX86_t::getMemoryDisplacementEncodingSize() const { if(!isMemory()) throw std::logic_error(string("Cannot ")+__FUNCTION__+" of non-memory operand"); const auto the_insn=static_cast<cs_insn*>(my_insn.get()); @@ -526,19 +530,19 @@ uint32_t DecodedOperandCapstone_t::getMemoryDisplacementEncodingSize() const assert(0); } -uint32_t DecodedOperandCapstone_t::getArgumentSizeInBytes() const +uint32_t DecodedOperandCapstoneX86_t::getArgumentSizeInBytes() const { const auto the_insn=static_cast<cs_insn*>(my_insn.get()); const auto &op = (the_insn->detail->x86.operands[op_num]); return op.size; } -uint32_t DecodedOperandCapstone_t::getArgumentSizeInBits() const +uint32_t DecodedOperandCapstoneX86_t::getArgumentSizeInBits() const { return getArgumentSizeInBytes()*8; } -bool DecodedOperandCapstone_t::hasSegmentRegister() const +bool DecodedOperandCapstoneX86_t::hasSegmentRegister() const { const auto the_insn=static_cast<cs_insn*>(my_insn.get()); const auto &op = (the_insn->detail->x86.operands[op_num]); @@ -546,7 +550,7 @@ bool DecodedOperandCapstone_t::hasSegmentRegister() const } -uint32_t DecodedOperandCapstone_t::getSegmentRegister() const +uint32_t DecodedOperandCapstoneX86_t::getSegmentRegister() const { if(!isMemory()) throw std::logic_error(string("Cannot ")+__FUNCTION__+" of operand without memory operand"); const auto the_insn=static_cast<cs_insn*>(my_insn.get()); @@ -725,12 +729,12 @@ set<string> read_only_operand_mnemonics= -bool DecodedOperandCapstone_t::isRead() const +bool DecodedOperandCapstoneX86_t::isRead() const { if(!isWritten()) return true; - const auto d=DecodedInstructionCapstone_t(my_insn); + const auto d=DecodedInstructionCapstoneX86_t(my_insn); const auto d_mnemonic=d.getMnemonic(); const auto woom_it=write_only_operand_mnemonics.find(d_mnemonic); const auto in_woom=(woom_it!=end(write_only_operand_mnemonics)); @@ -744,7 +748,7 @@ bool DecodedOperandCapstone_t::isRead() const if(op_num!=0) return true; - const auto d=DecodedInstructionCapstone_t(my_insn); + const auto d=DecodedInstructionCapstoneX86_t(my_insn); if(d.isBranch()) return true; @@ -763,9 +767,9 @@ bool DecodedOperandCapstone_t::isRead() const */ } -bool DecodedOperandCapstone_t::isWritten() const +bool DecodedOperandCapstoneX86_t::isWritten() const { - const auto d=DecodedInstructionCapstone_t(my_insn); + const auto d=DecodedInstructionCapstoneX86_t(my_insn); const auto d_mnemonic=d.getMnemonic(); // special case check: all operands are reads @@ -802,7 +806,7 @@ bool DecodedOperandCapstone_t::isWritten() const /* if(op_num!=0) return false; - const auto d=DecodedInstructionCapstone_t(my_insn); + const auto d=DecodedInstructionCapstoneX86_t(my_insn); if(d.isBranch()) return false; diff --git a/libIRDB/src/core/operand_meta.cpp b/libIRDB-core/src/operand_dispatch.cpp similarity index 67% rename from libIRDB/src/core/operand_meta.cpp rename to libIRDB-core/src/operand_dispatch.cpp index c75220bd94ad2cde2b0abc2baa805862b21a231d..0790f4677cdeb2637ee5ce37efe3a3df004b59c5 100644 --- a/libIRDB/src/core/operand_meta.cpp +++ b/libIRDB-core/src/operand_dispatch.cpp @@ -1,42 +1,41 @@ #include <libIRDB-core.hpp> -#include <core/operand_cs.hpp> -#include <core/decode_cs.hpp> -#include <core/operand_bea.hpp> -#include <core/decode_bea.hpp> -#include <core/operand_meta.hpp> -#include <core/decode_meta.hpp> +#include <operand_csx86.hpp> +#include <decode_csx86.hpp> +#include <operand_dispatch.hpp> +#include <decode_dispatch.hpp> using namespace std; using namespace libIRDB; -DecodedOperandMeta_t::DecodedOperandMeta_t(const DecodedOperandCapstone_t& copy_cs) : - cs(copy_cs) +DecodedOperandDispatcher_t::DecodedOperandDispatcher_t(const shared_ptr<DecodedOperandCapstone_t> copy_cs) { + cs=copy_cs; } -DecodedOperandMeta_t::DecodedOperandMeta_t(const DecodedOperandMeta_t& copy) : - cs(copy.cs) +DecodedOperandDispatcher_t::DecodedOperandDispatcher_t(const DecodedOperandDispatcher_t& copy) { + cs=copy.cs; } -DecodedOperandMeta_t::~DecodedOperandMeta_t() +DecodedOperandDispatcher_t::~DecodedOperandDispatcher_t() { } -DecodedOperandMeta_t& DecodedOperandMeta_t::operator=(const DecodedOperandMeta_t& copy) +DecodedOperandDispatcher_t& DecodedOperandDispatcher_t::operator=(const DecodedOperandDispatcher_t& copy) { cs=copy.cs; return *this; } #define passthrough_to_cs(ret_type, method_name) \ - ret_type DecodedOperandMeta_t::method_name() const \ + ret_type DecodedOperandDispatcher_t::method_name() const \ { \ - return cs.method_name(); \ + return cs->method_name(); \ } passthrough_to_cs(bool, isConstant); +passthrough_to_cs(uint64_t, getConstant); passthrough_to_cs(string, getString); passthrough_to_cs(bool, isRegister); passthrough_to_cs(bool, isGeneralPurposeRegister); diff --git a/libIRDB/src/core/pqxxdb.cpp b/libIRDB-core/src/pqxxdb.cpp similarity index 76% rename from libIRDB/src/core/pqxxdb.cpp rename to libIRDB-core/src/pqxxdb.cpp index f0f1c4232a0d965d4e7d11d7b5ab44ad04fad324..37fa2e986e477755c5b39590eb26cfad403f6fbf 100644 --- a/libIRDB/src/core/pqxxdb.cpp +++ b/libIRDB-core/src/pqxxdb.cpp @@ -31,25 +31,25 @@ pqxxDB_t::pqxxDB_t() : DBinterface_t(), txn(conn) /* no other init needed */ } -void pqxxDB_t::IssueQuery(std::string query) +void pqxxDB_t::issueQuery(std::string query) { results=txn.exec(query); results_iter=results.begin(); } -void pqxxDB_t::IssueQuery(std::stringstream & query) +void pqxxDB_t::issueQuery(std::stringstream & query) { results=txn.exec(query); results_iter=results.begin(); } -void pqxxDB_t::MoveToNextRow() +void pqxxDB_t::moveToNextRow() { - assert(!IsDone()); + assert(!isDone()); ++results_iter; } -std::string pqxxDB_t::GetResultColumn(std::string colname) +std::string pqxxDB_t::getResultColumn(std::string colname) { if(results_iter[colname].is_null()) return std::string(""); @@ -61,14 +61,17 @@ std::string pqxxDB_t::GetResultColumn(std::string colname) // return results_iter[colname].as<std::string>(); } -bool pqxxDB_t::IsDone() +bool pqxxDB_t::isDone() { return results_iter==results.end(); } -void pqxxDB_t::Commit() +void pqxxDB_t::commit() { txn.commit(); } - +unique_ptr<IRDB_SDK::pqxxDB_t> IRDB_SDK::pqxxDB_t::factory() +{ + return unique_ptr<IRDB_SDK::pqxxDB_t>(new libIRDB::pqxxDB_t); +} diff --git a/libIRDB/src/core/reloc.cpp b/libIRDB-core/src/reloc.cpp similarity index 84% rename from libIRDB/src/core/reloc.cpp rename to libIRDB-core/src/reloc.cpp index 4500d27b833d121c968de6c708b61050111c3b74..dac3a40c8a3f6cb214501f89280d4e88510c4705 100644 --- a/libIRDB/src/core/reloc.cpp +++ b/libIRDB-core/src/reloc.cpp @@ -19,13 +19,13 @@ */ #include <all.hpp> -#include <utils.hpp> +#include <irdb-util> using namespace std; vector<std::string> Relocation_t::WriteToDB(File_t* fid, BaseObj_t* myinsn) { - db_id_t wrt_id=wrt_obj ? wrt_obj->GetBaseID() : BaseObj_t::NOT_IN_DATABASE; + db_id_t wrt_id=wrt_obj ? wrt_obj->getBaseID() : BaseObj_t::NOT_IN_DATABASE; /* string q; q ="insert into " + fid->relocs_table_name; @@ -33,13 +33,13 @@ vector<std::string> Relocation_t::WriteToDB(File_t* fid, BaseObj_t* myinsn) string(" VALUES (") + */ return { - to_string(GetBaseID()), + to_string(getBaseID()), to_string(offset), (type), - to_string(myinsn->GetBaseID()), + to_string(myinsn->getBaseID()), to_string(addend), to_string(wrt_id), - to_string(GetDoipID()) + to_string(getDoipID()) }; } diff --git a/libIRDB/src/core/scoop.cpp b/libIRDB-core/src/scoop.cpp similarity index 85% rename from libIRDB/src/core/scoop.cpp rename to libIRDB-core/src/scoop.cpp index ab50f42c25a4fb485e39f539dff874555ed86c6f..ff6512a9eab76f8e43ad4511197f1e5b623c2606 100644 --- a/libIRDB/src/core/scoop.cpp +++ b/libIRDB-core/src/scoop.cpp @@ -1,5 +1,5 @@ #include "all.hpp" -#include <utils.hpp> +#include <irdb-util> #include <sstream> #include <iomanip> @@ -42,7 +42,7 @@ string DataScoop_t::WriteToDBRange(File_t *fid, db_id_t newid, int start, int en */ - db_id_t type_id=(GetType() ? GetType()->GetBaseID() : BaseObj_t::NOT_IN_DATABASE); + db_id_t type_id=(getType() ? getType()->getBaseID() : BaseObj_t::NOT_IN_DATABASE); ostringstream hex_data; @@ -50,22 +50,22 @@ string DataScoop_t::WriteToDBRange(File_t *fid, db_id_t newid, int start, int en string q=string("insert into ")+table_name+ string(" (scoop_id, name, type_id, start_address_id, end_address_id, data, permissions, relro) ")+ string(" VALUES (") + - string("'") + to_string(GetBaseID()) + string("', ") + - string("'") + GetName() + string("', ") + + string("'") + to_string(getBaseID()) + string("', ") + + string("'") + getName() + string("', ") + string("'") + to_string(type_id) + string("', ") + - string("'") + to_string(GetStart()->GetBaseID()) + string("', ") + - string("'") + to_string(GetEnd()->GetBaseID()) + string("', ") + + string("'") + to_string(getStart()->getBaseID()) + string("', ") + + string("'") + to_string(getEnd()->getBaseID()) + string("', ") + string("'") + /* empty data field -- for now + */ string("', ") + string("'") + to_string(permissions) + string("', ") + string("'") + to_string(is_relro) + string("'); ") ; // add the table row with empty data field. - dbintr->IssueQuery(q); + dbintr->issueQuery(q); // now try to append the data to the field in chunks. string query_start="update "+table_name+" set data = data || decode('"; - string query_end="', 'hex') where scoop_id="+ string("'") + to_string(GetBaseID()) + string("'; ") ; + string query_end="', 'hex') where scoop_id="+ string("'") + to_string(getBaseID()) + string("'; ") ; hex_data << query_start << setfill('0') << hex; @@ -85,7 +85,7 @@ string DataScoop_t::WriteToDBRange(File_t *fid, db_id_t newid, int start, int en hex_data << query_end; // append this chunk to the db. - dbintr->IssueQuery(hex_data.str()); + dbintr->issueQuery(hex_data.str()); // restart hex_data.str(""); // reset to empty @@ -96,7 +96,7 @@ string DataScoop_t::WriteToDBRange(File_t *fid, db_id_t newid, int start, int en hex_data << query_end; // append this chunk to the db. - dbintr->IssueQuery(hex_data.str()); + dbintr->issueQuery(hex_data.str()); return ""; } diff --git a/libIRDB/src/core/type.cpp b/libIRDB-core/src/type.cpp similarity index 67% rename from libIRDB/src/core/type.cpp rename to libIRDB-core/src/type.cpp index 7dc8f2a188422dd0ac94fa04cd2af4b9714f3187..67ceb48b61da9637c3012b9ec8424e667af0007a 100644 --- a/libIRDB/src/core/type.cpp +++ b/libIRDB-core/src/type.cpp @@ -19,15 +19,19 @@ */ #include "all.hpp" -#include <utils.hpp> +#include <irdb-util> using namespace std; using namespace libIRDB; -bool BasicType_t::IsNumericType() const +bool BasicType_t::isNumericType() const { - int type = GetTypeID(); - return type == T_NUMERIC || type == T_INT || type == T_FLOAT || type == T_DOUBLE || type == T_CHAR; + auto type = getTypeID(); + return type == IRDB_SDK::itNumeric || + type == IRDB_SDK::itInt || + type == IRDB_SDK::itFloat || + type == IRDB_SDK::itDouble || + type == IRDB_SDK::itChar; } /* @@ -47,15 +51,12 @@ string BasicType_t::WriteToDB(File_t *fid, db_id_t newid) { assert(fid); -// if(GetBaseID()==NOT_IN_DATABASE) -// SetBaseID(newid); - string q=string("insert into ")+fid->types_table_name + string(" (type_id, type, name, ref_type_id, pos, ref_type_id2) ")+ string(" VALUES (") + - string("'") + to_string(GetBaseID()) + string("', ") + - string("'") + to_string(GetTypeID()) + string("', ") + - string("'") + GetName() + string("','-1','-1','-1') ; ") ; + string("'") + to_string(getBaseID()) + string("', ") + + string("'") + to_string(getTypeID()) + string("', ") + + string("'") + getName() + string("','-1','-1','-1') ; ") ; // cout << "BasicType_t::WriteToDB(): " << q << endl; return q; @@ -63,14 +64,14 @@ string BasicType_t::WriteToDB(File_t *fid, db_id_t newid) string PointerType_t::WriteToDB(File_t *fid, db_id_t newid) { - assert(fid && GetReferentType()); + assert(fid && getReferentType()); string q=string("insert into ")+fid->types_table_name + string(" (type_id, type, name, ref_type_id,pos,ref_type_id2) ")+ string(" VALUES (") + - string("'") + to_string(GetBaseID()) + string("', ") + - string("'") + to_string(GetTypeID()) + string("', ") + - string("'") + GetName() + string("', ") + - string("'") + to_string(GetReferentType()->GetBaseID()) + + string("'") + to_string(getBaseID()) + string("', ") + + string("'") + to_string(getTypeID()) + string("', ") + + string("'") + getName() + string("', ") + + string("'") + to_string(getReferentType()->getBaseID()) + string("','-1','-1') ; ") ; // cout << "PointerType_t::WriteToDB(): " << q << endl; @@ -80,20 +81,20 @@ string PointerType_t::WriteToDB(File_t *fid, db_id_t newid) string AggregateType_t::WriteToDB(File_t *fid, db_id_t newid) { assert(fid); - assert(GetNumAggregatedTypes() > 0); + assert(getNumAggregatedTypes() > 0); string q; - for (auto i = 0U; i < GetNumAggregatedTypes(); ++i) + for (auto i = 0U; i < getNumAggregatedTypes(); ++i) { - Type_t* t = GetAggregatedType(i); + auto t = getAggregatedType(i); q+=string("insert into ")+fid->types_table_name + string(" (type_id, type, name, ref_type_id, pos,ref_type_id2) ")+ string(" VALUES (") + - string("'") + to_string(GetBaseID()) + string("', ") + - string("'") + to_string(GetTypeID()) + string("', ") + - string("'") + GetName() + string("', ") + - string("'") + to_string(t->GetBaseID()) + string("', ") + + string("'") + to_string(getBaseID()) + string("', ") + + string("'") + to_string(getTypeID()) + string("', ") + + string("'") + getName() + string("', ") + + string("'") + to_string(t->getBaseID()) + string("', ") + string("'") + to_string(i) + string("','-1') ; ") ; } @@ -102,7 +103,7 @@ string AggregateType_t::WriteToDB(File_t *fid, db_id_t newid) return q; } -void AggregateType_t::AddAggregatedType(Type_t *t, int pos) +void AggregateType_t::addAggregatedType(IRDB_SDK::Type_t *t, int pos) { refTypes.push_back(t); @@ -124,16 +125,16 @@ CREATE TABLE #TYP# string FuncType_t::WriteToDB(File_t *fid, db_id_t newid) { assert(fid); - assert(GetReturnType()); - assert(GetArgumentsType()); + assert(getReturnType()); + assert(getArgumentsType()); string q=string("insert into ")+fid->types_table_name + string(" (type_id, type, name, ref_type_id, ref_type_id2,pos) ")+ string(" VALUES (") + - string("'") + to_string(GetBaseID()) + string("', ") + - string("'") + to_string(GetTypeID()) + string("', ") + - string("'") + GetName() + string("', ") + - string("'") + to_string(GetReturnType()->GetBaseID()) + string("', ") + - string("'") + to_string(GetArgumentsType()->GetBaseID()) + + string("'") + to_string(getBaseID()) + string("', ") + + string("'") + to_string(getTypeID()) + string("', ") + + string("'") + getName() + string("', ") + + string("'") + to_string(getReturnType()->getBaseID()) + string("', ") + + string("'") + to_string(getArgumentsType()->getBaseID()) + string("','-1') ; ") ; // cout << "FuncType_t::WriteToDB(): " << q << endl; diff --git a/libIRDB/src/core/variantid.cpp b/libIRDB-core/src/variantid.cpp similarity index 65% rename from libIRDB/src/core/variantid.cpp rename to libIRDB-core/src/variantid.cpp index df50ce94979590ef862885f5e08a32895c11a569..fc33c6ed9434e96cab9d5383315dacfb67a8e681 100644 --- a/libIRDB/src/core/variantid.cpp +++ b/libIRDB-core/src/variantid.cpp @@ -21,10 +21,19 @@ #include <all.hpp> -#include <utils.hpp> +#include <irdb-util> #include <stdlib.h> using namespace std; +template <class T> +inline string to_string (const T& t) +{ + stringstream ss; + ss << t; + return ss.str(); +} + + /* * Create a new variant ID that is not yet in the database @@ -61,7 +70,7 @@ VariantID_t::VariantID_t(db_id_t pid) : BaseObj_t(NULL) try { - BaseObj_t::dbintr->IssueQuery(q); + BaseObj_t::dbintr->issueQuery(q); } catch (const std::exception &e) { @@ -72,29 +81,29 @@ VariantID_t::VariantID_t(db_id_t pid) : BaseObj_t(NULL) throw DatabaseError_t(DatabaseError_t::VariantTableNotRegistered); }; - if(BaseObj_t::dbintr->IsDone()) + if(BaseObj_t::dbintr->isDone()) throw DatabaseError_t(DatabaseError_t::VariantNotInDatabase); - SetBaseID(atoi(BaseObj_t::dbintr->GetResultColumn("variant_id").c_str())); - schema_ver=atoi(BaseObj_t::dbintr->GetResultColumn("schema_version_id").c_str()); - orig_pid=atoi(BaseObj_t::dbintr->GetResultColumn("orig_variant_id").c_str()); - name=(BaseObj_t::dbintr->GetResultColumn("name")); + setBaseID(atoi(BaseObj_t::dbintr->getResultColumn("variant_id").c_str())); + schema_ver=atoi(BaseObj_t::dbintr->getResultColumn("schema_version_id").c_str()); + orig_pid=atoi(BaseObj_t::dbintr->getResultColumn("orig_variant_id").c_str()); + name=(BaseObj_t::dbintr->getResultColumn("name")); - BaseObj_t::dbintr->MoveToNextRow(); - assert(BaseObj_t::dbintr->IsDone()); + BaseObj_t::dbintr->moveToNextRow(); + assert(BaseObj_t::dbintr->isDone()); ReadFilesFromDB(); } -bool VariantID_t::IsRegistered() +bool VariantID_t::isRegistered() const { - return GetBaseID()!=BaseObj_t::NOT_IN_DATABASE; + return getBaseID()!=BaseObj_t::NOT_IN_DATABASE; } -bool VariantID_t::Register() +bool VariantID_t::registerID() { - assert(!IsRegistered()); + assert(!isRegistered()); std::string q; q="insert into variant_info (schema_version_id,name) " @@ -105,35 +114,35 @@ bool VariantID_t::Register() q+="')"; q+="returning variant_id;"; - dbintr->IssueQuery(q); - assert(!BaseObj_t::dbintr->IsDone()); + dbintr->issueQuery(q); + assert(!BaseObj_t::dbintr->isDone()); - db_id_t newid=atoi(dbintr->GetResultColumn("variant_id").c_str()); + db_id_t newid=atoi(dbintr->getResultColumn("variant_id").c_str()); /* set IDs */ - SetBaseID(newid); + setBaseID(newid); if(NOT_IN_DATABASE==orig_pid) orig_pid=newid; - BaseObj_t::dbintr->MoveToNextRow(); - assert(BaseObj_t::dbintr->IsDone()); + BaseObj_t::dbintr->moveToNextRow(); + assert(BaseObj_t::dbintr->isDone()); return true; } -VariantID_t* VariantID_t::Clone(bool deep) +IRDB_SDK::VariantID_t* VariantID_t::clone(bool deep) { - assert(IsRegistered()); // cannot clone something that's not registered + assert(isRegistered()); // cannot clone something that's not registered // create the new program id VariantID_t *ret=new VariantID_t; // set the inhereted fields - ret->SetName(name+"_cloneof"+to_string(GetBaseID())); + ret->setName(name+"_cloneof"+to_string(getBaseID())); ret->orig_pid=orig_pid; // register the new VID to the database. - ret->Register(); + ret->registerID(); // and write it to the database ret->WriteToDB(); @@ -144,11 +153,11 @@ VariantID_t* VariantID_t::Clone(bool deep) // the old variant depended upon. The new rows will indicate that the // new variant also depends on those files q="insert into variant_dependency (variant_id, file_id, doip_id) select '"; - q+=to_string(ret->GetBaseID()); + q+=to_string(ret->getBaseID()); q+="', file_id, doip_id from variant_dependency where variant_id='"; - q+=to_string(GetBaseID()); + q+=to_string(getBaseID()); q+="';"; - dbintr->IssueQuery(q); + dbintr->issueQuery(q); if(deep) ret->CloneFiles(files); @@ -159,7 +168,10 @@ VariantID_t* VariantID_t::Clone(bool deep) void VariantID_t::CloneFiles(FileSet_t &files) { for(auto fiter=files.begin(); fiter!=files.end(); ++fiter) - files.insert(CloneFile(*fiter)); + { + auto the_file=dynamic_cast<File_t*>(*fiter); + files.insert(CloneFile(the_file)); + } } File_t* VariantID_t::CloneFile(File_t* fptr) @@ -181,15 +193,15 @@ File_t* VariantID_t::CloneFile(File_t* fptr) to_string(fptr->hash) + "', '" + to_string(fptr->arch) + "', '" + to_string(fptr->elfoid) + "', '" + - to_string(fptr->GetDoipID()) + + to_string(fptr->getDoipID()) + "' ) "; q+=" returning file_id; "; - dbintr->IssueQuery(q); - assert(!BaseObj_t::dbintr->IsDone()); + dbintr->issueQuery(q); + assert(!BaseObj_t::dbintr->isDone()); - db_id_t newfid=atoi(dbintr->GetResultColumn("file_id").c_str()); + db_id_t newfid=atoi(dbintr->getResultColumn("file_id").c_str()); std::string atn="atnfid"+to_string(newfid); std::string ftn="ftnfid"+to_string(newfid); @@ -217,10 +229,10 @@ File_t* VariantID_t::CloneFile(File_t* fptr) q+=to_string(newfid); q+="' ; "; - dbintr->IssueQuery(q); + dbintr->issueQuery(q); File_t* newfile=new File_t(newfid, fptr->orig_fid, fptr->url, fptr->hash, fptr->arch, - fptr->elfoid, atn, ftn, itn, icfs, icfsmap, rtn, typ, dtn, ehp, css, fptr->GetDoipID()); + fptr->elfoid, atn, ftn, itn, icfs, icfsmap, rtn, typ, dtn, ehp, css, fptr->getDoipID()); newfile->CreateTables(); @@ -228,57 +240,57 @@ File_t* VariantID_t::CloneFile(File_t* fptr) q="drop table "; q+=itn; q+=" ; "; - dbintr->IssueQuery(q); + dbintr->issueQuery(q); q="drop table "; q+=icfsmap; q+=" ; "; - dbintr->IssueQuery(q); + dbintr->issueQuery(q); q="drop table "; q+=icfs; q+=" ; "; - dbintr->IssueQuery(q); + dbintr->issueQuery(q); q="drop table "; q+=atn; q+=" ; "; - dbintr->IssueQuery(q); + dbintr->issueQuery(q); q="drop table "; q+=ftn; q+=" ; "; - dbintr->IssueQuery(q); + dbintr->issueQuery(q); q="drop table "; q+=rtn; q+=" ; "; - dbintr->IssueQuery(q); + dbintr->issueQuery(q); q="drop table "; q+=typ; q+=" ; "; - dbintr->IssueQuery(q); + dbintr->issueQuery(q); q="drop table "; q+=dtn; q+=" ; "; - dbintr->IssueQuery(q); + dbintr->issueQuery(q); q="drop table "; q+=dtn_part2; q+=" ; "; - dbintr->IssueQuery(q); + dbintr->issueQuery(q); q="drop table "; q+=ehp; q+=" ; "; - dbintr->IssueQuery(q); + dbintr->issueQuery(q); q="drop table "; q+=css; q+=" ; "; - dbintr->IssueQuery(q); + dbintr->issueQuery(q); // next issue SQL to clone each table @@ -287,87 +299,87 @@ File_t* VariantID_t::CloneFile(File_t* fptr) q+=" from "; q+=fptr->address_table_name; q+=" ;"; - dbintr->IssueQuery(q); + dbintr->issueQuery(q); q="select * into "; q+=itn; q+=" from "; q+=fptr->instruction_table_name; q+=" ;"; - dbintr->IssueQuery(q); + dbintr->issueQuery(q); q="select * into "; q+=icfs; q+=" from "; q+=fptr->icfs_table_name; q+=" ;"; - dbintr->IssueQuery(q); + dbintr->issueQuery(q); q="select * into "; q+=icfsmap; q+=" from "; q+=fptr->icfs_map_table_name; q+=" ;"; - dbintr->IssueQuery(q); + dbintr->issueQuery(q); q="select * into "; q+=ftn; q+=" from "; q+=fptr->function_table_name; q+=" ;"; - dbintr->IssueQuery(q); + dbintr->issueQuery(q); q="select * into "; q+=rtn; q+=" from "; q+=fptr->relocs_table_name; q+=" ;"; - dbintr->IssueQuery(q); + dbintr->issueQuery(q); q="select * into "; q+=typ; q+=" from "; q+=fptr->types_table_name; q+=" ;"; - dbintr->IssueQuery(q); + dbintr->issueQuery(q); q="select * into "; q+=dtn; q+=" from "; q+=fptr->scoop_table_name; q+=" ;"; - dbintr->IssueQuery(q); + dbintr->issueQuery(q); q="select * into "; q+=dtn_part2; q+=" from "; q+=fptr->scoop_table_name+"_part2"; q+=" ;"; - dbintr->IssueQuery(q); + dbintr->issueQuery(q); q="select * into "; q+=ehp; q+=" from "; q+=fptr->ehpgm_table_name; q+=" ;"; - dbintr->IssueQuery(q); + dbintr->issueQuery(q); q="select * into "; q+=css; q+=" from "; q+=fptr->ehcss_table_name; q+=" ;"; - dbintr->IssueQuery(q); + dbintr->issueQuery(q); // update the variant dependency table to represent the deep clone q = "update variant_dependency set file_id='" + to_string(newfid) + "' where variant_id='" + - to_string(GetBaseID()) + + to_string(getBaseID()) + "' AND file_id='" + - to_string(fptr->GetBaseID()) + + to_string(fptr->getBaseID()) + "' ;"; - dbintr->IssueQuery(q); + dbintr->issueQuery(q); return newfile; @@ -376,26 +388,25 @@ File_t* VariantID_t::CloneFile(File_t* fptr) void VariantID_t::WriteToDB() { - assert(IsRegistered()); + assert(isRegistered()); std::string q="update variant_info SET "; q+=" schema_version_id = '" + to_string(schema_ver) + "', "; q+=" name = '" + name + "', "; q+=" orig_variant_id = '" + to_string(orig_pid) + "', "; - q+=" doip_id = '" + to_string(GetDoipID()) + "' "; - q+=" where variant_id = '" + to_string(GetBaseID()) + "';"; + q+=" doip_id = '" + to_string(getDoipID()) + "' "; + q+=" where variant_id = '" + to_string(getBaseID()) + "';"; - dbintr->IssueQuery(q); + dbintr->issueQuery(q); } -std::ostream& libIRDB::operator<<(std::ostream& out, const VariantID_t& pid) +std::ostream& IRDB_SDK::operator<<(std::ostream& out, const IRDB_SDK::VariantID_t& pid) { - out << "(" - "variant_id="<<pid.GetBaseID()<<":" - "schema="<<pid.schema_ver<<":" - "orig_pid="<<pid.orig_pid<<":" - "name="<<pid.name<<":" + out << "(" << + "variant_id=" << pid.getBaseID() << ":" << + "orig_pid=" << pid.getOriginalVariantID() << ":" << + "name=" << pid.getName() << ")" ; return out; } @@ -403,21 +414,21 @@ std::ostream& libIRDB::operator<<(std::ostream& out, const VariantID_t& pid) void VariantID_t::DropFromDB() { - assert(IsRegistered()); + assert(isRegistered()); string q; - q+=string("delete from variant_dependency where variant_id = '") + to_string(GetBaseID()) + string("';"); - q+=string("delete from variant_info where variant_id = '") + to_string(GetBaseID()) + string("';"); + q+=string("delete from variant_dependency where variant_id = '") + to_string(getBaseID()) + string("';"); + q+=string("delete from variant_info where variant_id = '") + to_string(getBaseID()) + string("';"); - dbintr->IssueQuery(q); + dbintr->issueQuery(q); - SetBaseID(NOT_IN_DATABASE); + setBaseID(NOT_IN_DATABASE); orig_pid=NOT_IN_DATABASE; schema_ver=CURRENT_SCHEMA; } -File_t* VariantID_t::GetMainFile() const +IRDB_SDK::File_t* VariantID_t::getMainFile() const { for( auto it=files.begin(); @@ -425,7 +436,7 @@ File_t* VariantID_t::GetMainFile() const ++it ) { - if ((*it)->GetURL().find("a.ncexe") != string::npos) + if ((*it)->getURL().find("a.ncexe") != string::npos) return *it; } /* we should have found the main file somewhere. */ @@ -443,32 +454,32 @@ void VariantID_t::ReadFilesFromDB() " file_info.scoop_table_name, file_info.ehpgm_table_name, file_info.ehcss_table_name, file_info.file_id, file_info.url, file_info.hash," " file_info.arch, file_info.type, file_info.elfoid, file_info.doip_id " " from file_info,variant_dependency " - " where variant_dependency.variant_id = '" + to_string(GetBaseID()) + "' AND " + " where variant_dependency.variant_id = '" + to_string(getBaseID()) + "' AND " " file_info.file_id = variant_dependency.file_id ; "; - dbintr->IssueQuery(q); + dbintr->issueQuery(q); - while(!dbintr->IsDone()) + while(!dbintr->isDone()) { // file_info.file_id, file_info.url, file_info.hash, file_info.arch, file_info.type, file_info.doip_id - db_id_t file_id=atoi(dbintr->GetResultColumn("file_id").c_str()); - db_id_t orig_fid=atoi(dbintr->GetResultColumn("orig_file_id").c_str()); - std::string url=dbintr->GetResultColumn("url"); - std::string hash=dbintr->GetResultColumn("hash"); - std::string type=dbintr->GetResultColumn("type"); - int oid=atoi(dbintr->GetResultColumn("elfoid").c_str()); - db_id_t doipid=atoi(dbintr->GetResultColumn("doip_id").c_str()); - std::string atn=(BaseObj_t::dbintr->GetResultColumn("address_table_name")); - std::string ftn=(BaseObj_t::dbintr->GetResultColumn("function_table_name")); - std::string itn=(BaseObj_t::dbintr->GetResultColumn("instruction_table_name")); - std::string dtn=(BaseObj_t::dbintr->GetResultColumn("scoop_table_name")); - std::string ehp=(BaseObj_t::dbintr->GetResultColumn("ehpgm_table_name")); - std::string css=(BaseObj_t::dbintr->GetResultColumn("ehcss_table_name")); - std::string icfs=(BaseObj_t::dbintr->GetResultColumn("icfs_table_name")); - std::string icfs_map=(BaseObj_t::dbintr->GetResultColumn("icfs_map_table_name")); - std::string rtn=(BaseObj_t::dbintr->GetResultColumn("relocs_table_name")); - std::string typ=(BaseObj_t::dbintr->GetResultColumn("types_table_name")); + db_id_t file_id=atoi(dbintr->getResultColumn("file_id").c_str()); + db_id_t orig_fid=atoi(dbintr->getResultColumn("orig_file_id").c_str()); + std::string url=dbintr->getResultColumn("url"); + std::string hash=dbintr->getResultColumn("hash"); + std::string type=dbintr->getResultColumn("type"); + int oid=atoi(dbintr->getResultColumn("elfoid").c_str()); + db_id_t doipid=atoi(dbintr->getResultColumn("doip_id").c_str()); + std::string atn=(BaseObj_t::dbintr->getResultColumn("address_table_name")); + std::string ftn=(BaseObj_t::dbintr->getResultColumn("function_table_name")); + std::string itn=(BaseObj_t::dbintr->getResultColumn("instruction_table_name")); + std::string dtn=(BaseObj_t::dbintr->getResultColumn("scoop_table_name")); + std::string ehp=(BaseObj_t::dbintr->getResultColumn("ehpgm_table_name")); + std::string css=(BaseObj_t::dbintr->getResultColumn("ehcss_table_name")); + std::string icfs=(BaseObj_t::dbintr->getResultColumn("icfs_table_name")); + std::string icfs_map=(BaseObj_t::dbintr->getResultColumn("icfs_map_table_name")); + std::string rtn=(BaseObj_t::dbintr->getResultColumn("relocs_table_name")); + std::string typ=(BaseObj_t::dbintr->getResultColumn("types_table_name")); File_t *newfile=new File_t(file_id,orig_fid,url,hash,type,oid,atn,ftn,itn,icfs,icfs_map,rtn,typ,dtn,ehp,css,doipid); @@ -478,6 +489,26 @@ void VariantID_t::ReadFilesFromDB() files.insert(newfile); - dbintr->MoveToNextRow(); + dbintr->moveToNextRow(); } } + + +namespace IRDB_SDK +{ + +unique_ptr<VariantID_t> VariantID_t::factory(const DatabaseID_t& id) +{ + return unique_ptr<VariantID_t>(new libIRDB::VariantID_t(id)); +} + +unique_ptr<FileIR_t> FileIR_t::factory(VariantID_t *p_progid, File_t* p_fid) +{ + const auto progid=dynamic_cast<libIRDB::VariantID_t*>(p_progid); + const auto fid=dynamic_cast<libIRDB::File_t*>(p_fid); + return unique_ptr<FileIR_t>(new libIRDB::FileIR_t(*progid,fid)); +} + + +} + diff --git a/libElfDep/SConscript b/libIRDB-elfdep/SConscript similarity index 100% rename from libElfDep/SConscript rename to libIRDB-elfdep/SConscript diff --git a/libElfDep/SConstruct b/libIRDB-elfdep/SConstruct similarity index 100% rename from libElfDep/SConstruct rename to libIRDB-elfdep/SConstruct diff --git a/libElfDep/src/SConscript b/libIRDB-elfdep/src/SConscript similarity index 64% rename from libElfDep/src/SConscript rename to libIRDB-elfdep/src/SConscript index 9da08bd9c97e3e28caa1f2c475ec161be03df536..dc8652648f1822c490a9b6f46d906450c9f41dd6 100644 --- a/libElfDep/src/SConscript +++ b/libIRDB-elfdep/src/SConscript @@ -9,21 +9,20 @@ myenv.Replace(SECURITY_TRANSFORMS_HOME=os.environ['SECURITY_TRANSFORMS_HOME']) files="elfdep.cpp" cpppath=''' + . + $IRDB_SDK/include $SECURITY_TRANSFORMS_HOME/libIRDB/include $SECURITY_TRANSFORMS_HOME/libtransform/include - $SECURITY_TRANSFORMS_HOME/libEXEIO/include/ - $SECURITY_TRANSFORMS_HOME/libMEDSannotation//include/ - $SECURITY_TRANSFORMS_HOME/libElfDep/include ''' LIBPATH="$SECURITY_TRANSFORMS_HOME/lib" -LIBS=Split("IRDB-core transform") +LIBS=Split("irdb-core irdb-transform") myenv=myenv.Clone(CPPPATH=Split(cpppath)) myenv.Append(CXXFLAGS = " -std=c++11 ") -lib=myenv.SharedLibrary("ElfDep", Split(files), LIBPATH=LIBPATH, LIBS=LIBS) +lib=myenv.SharedLibrary("irdb-elfdep", Split(files), LIBPATH=LIBPATH, LIBS=LIBS) install=myenv.Install("$SECURITY_TRANSFORMS_HOME/lib/", lib) Default(install) diff --git a/libElfDep/src/SConstruct b/libIRDB-elfdep/src/SConstruct similarity index 100% rename from libElfDep/src/SConstruct rename to libIRDB-elfdep/src/SConstruct diff --git a/libElfDep/src/elfdep.cpp b/libIRDB-elfdep/src/elfdep.cpp similarity index 68% rename from libElfDep/src/elfdep.cpp rename to libIRDB-elfdep/src/elfdep.cpp index b2d3bcd12aa27aa127cc17d37752994473f38f5a..91cd97a15a2c9306a19878c6249f26103645275f 100644 --- a/libElfDep/src/elfdep.cpp +++ b/libIRDB-elfdep/src/elfdep.cpp @@ -19,19 +19,26 @@ */ -#include "utils.hpp" -#include "Rewrite_Utility.hpp" +#include <irdb-core> +#include <irdb-transform> +#include <irdb-elfdep> #include <stdlib.h> #include <memory> #include <math.h> -#include <exeio.h> #include <elf.h> #include <libElfDep.hpp> #include <iterator> +#include <algorithm> using namespace libIRDB; using namespace std; -using namespace libTransform; + +// use some of IRDB_SDK, without committing to all of it. +// it's too confusing to use libIRDB namespace as well as the IRDB_SDK namespace; +using IRDB_SDK::VirtualOffset_t; +using IRDB_SDK::Relocation_t; +using IRDB_SDK::Instruction_t; +using IRDB_SDK::DataScoop_t; // defines #define REV_ALLOF(a) rbegin(a), rend(a) @@ -40,106 +47,106 @@ using namespace libTransform; // static helpers // use this to determine whether a scoop has a given name. -static struct ScoopFinder : binary_function<const DataScoop_t*,const string,bool> +static struct ScoopFinder : binary_function<const IRDB_SDK::DataScoop_t*,const string,bool> { // declare a simple scoop finder function that finds scoops by name - bool operator()(const DataScoop_t* scoop, const string& name) const + bool operator()(const IRDB_SDK::DataScoop_t* scoop, const string& name) const { - return (scoop->GetName() == name); + return (scoop->getName() == name); }; } finder; -static DataScoop_t* find_scoop(FileIR_t *firp,const string &name) +static IRDB_SDK::DataScoop_t* find_scoop(IRDB_SDK::FileIR_t *firp,const string &name) { - auto it=find_if(firp->GetDataScoops().begin(), firp->GetDataScoops().end(), bind2nd(finder, name)) ; - if( it != firp->GetDataScoops().end() ) + auto it=find_if(firp->getDataScoops().begin(), firp->getDataScoops().end(), bind2nd(finder, name)) ; + if( it != firp->getDataScoops().end() ) return *it; return NULL; }; -static unsigned int add_to_scoop(const string &str, DataScoop_t* scoop) +static unsigned int add_to_scoop(const string &str, IRDB_SDK::DataScoop_t* scoop) { // assert that this scoop is unpinned. may need to enable --step move_globals --step-option move_globals:--cfi - assert(scoop->GetStart()->GetVirtualOffset()==0); + assert(scoop->getStart()->getVirtualOffset()==0); int len=str.length(); - scoop->SetContents(scoop->GetContents()+str); - virtual_offset_t oldend=scoop->GetEnd()->GetVirtualOffset(); - virtual_offset_t newend=oldend+len; - scoop->GetEnd()->SetVirtualOffset(newend); + scoop->setContents(scoop->getContents()+str); + VirtualOffset_t oldend=scoop->getEnd()->getVirtualOffset(); + VirtualOffset_t newend=oldend+len; + scoop->getEnd()->setVirtualOffset(newend); return oldend+1; }; template<int ptrsize> -static void insert_into_scoop_at(const string &str, DataScoop_t* scoop, FileIR_t* firp, const unsigned int at) +static void insert_into_scoop_at(const string &str, IRDB_SDK::DataScoop_t* scoop, IRDB_SDK::FileIR_t* firp, const unsigned int at) { // assert that this scoop is unpinned. may need to enable --step move_globals --step-option move_globals:--cfi - assert(scoop->GetStart()->GetVirtualOffset()==0); + assert(scoop->getStart()->getVirtualOffset()==0); int len=str.length(); - string new_scoop_contents=scoop->GetContents(); + string new_scoop_contents=scoop->getContents(); new_scoop_contents.insert(at,str); - scoop->SetContents(new_scoop_contents); + scoop->setContents(new_scoop_contents); - virtual_offset_t oldend=scoop->GetEnd()->GetVirtualOffset(); - virtual_offset_t newend=oldend+len; - scoop->GetEnd()->SetVirtualOffset(newend); + VirtualOffset_t oldend=scoop->getEnd()->getVirtualOffset(); + VirtualOffset_t newend=oldend+len; + scoop->getEnd()->setVirtualOffset(newend); // update each reloc to point to the new location. - for_each(scoop->GetRelocations().begin(), scoop->GetRelocations().end(), [str,at](Relocation_t* reloc) + for_each(scoop->getRelocations().begin(), scoop->getRelocations().end(), [str,at](IRDB_SDK::Relocation_t* reloc) { - if((unsigned int)reloc->GetOffset()>=at) - reloc->SetOffset(reloc->GetOffset()+str.size()); + if((unsigned int)reloc->getOffset()>=at) + reloc->setOffset(reloc->getOffset()+str.size()); }); // check relocations for pointers to this object. // we'll update dataptr_to_scoop relocs, but nothing else // so assert if we find something else - for_each(firp->GetRelocations().begin(), firp->GetRelocations().end(), [scoop](Relocation_t* reloc) + for_each(firp->getRelocations().begin(), firp->getRelocations().end(), [scoop](IRDB_SDK::Relocation_t* reloc) { - DataScoop_t* wrt=dynamic_cast<DataScoop_t*>(reloc->GetWRT()); - assert(wrt != scoop || reloc->GetType()=="dataptr_to_scoop"); + auto wrt=dynamic_cast<IRDB_SDK::DataScoop_t*>(reloc->getWRT()); + assert(wrt != scoop || reloc->getType()=="dataptr_to_scoop"); }); // for each scoop - for_each(firp->GetDataScoops().begin(), firp->GetDataScoops().end(), [&str,scoop,firp,at](DataScoop_t* scoop_to_update) + for_each(firp->getDataScoops().begin(), firp->getDataScoops().end(), [&str,scoop,firp,at](IRDB_SDK::DataScoop_t* scoop_to_update) { // for each relocation for that scoop - for_each(scoop_to_update->GetRelocations().begin(), scoop_to_update->GetRelocations().end(), [&str,scoop,firp,scoop_to_update,at](Relocation_t* reloc) + for_each(scoop_to_update->getRelocations().begin(), scoop_to_update->getRelocations().end(), [&str,scoop,firp,scoop_to_update,at](IRDB_SDK::Relocation_t* reloc) { // if it's a reloc that's wrt scoop - DataScoop_t* wrt=dynamic_cast<DataScoop_t*>(reloc->GetWRT()); + auto wrt=dynamic_cast<IRDB_SDK::DataScoop_t*>(reloc->getWRT()); if(wrt==scoop) { // then we need to update the scoop - if(reloc->GetType()=="dataptr_to_scoop") + if(reloc->getType()=="dataptr_to_scoop") { - string contents=scoop_to_update->GetContents(); + string contents=scoop_to_update->getContents(); // subtract the stringsize from the (implicitly stored) addend // taking pointer size into account. switch(ptrsize) { case 4: { - unsigned int val=*((unsigned int*)&contents.c_str()[reloc->GetOffset()]); + unsigned int val=*((unsigned int*)&contents.c_str()[reloc->getOffset()]); if(val>=at) val +=str.size(); - contents.replace(reloc->GetOffset(), ptrsize, (const char*)&val, ptrsize); + contents.replace(reloc->getOffset(), ptrsize, (const char*)&val, ptrsize); break; } case 8: { - unsigned long long val=*((long long*)&contents.c_str()[reloc->GetOffset()]); + unsigned long long val=*((long long*)&contents.c_str()[reloc->getOffset()]); if(val>=at) val +=str.size(); - contents.replace(reloc->GetOffset(), ptrsize, (const char*)&val, ptrsize); + contents.replace(reloc->getOffset(), ptrsize, (const char*)&val, ptrsize); break; } default: assert(0); } - scoop_to_update->SetContents(contents); + scoop_to_update->setContents(contents); } } @@ -149,7 +156,7 @@ static void insert_into_scoop_at(const string &str, DataScoop_t* scoop, FileIR_t }; template<int ptrsize> -static void prefix_scoop(const string &str, DataScoop_t* scoop, FileIR_t* firp) +static void prefix_scoop(const string &str, IRDB_SDK::DataScoop_t* scoop, IRDB_SDK::FileIR_t* firp) { insert_into_scoop_at<ptrsize>(str,scoop,firp,0); }; @@ -160,15 +167,15 @@ static void prefix_scoop(const string &str, DataScoop_t* scoop, FileIR_t* firp) // constructors -ElfDependencies_t::ElfDependencies_t(FileIR_t* firp) - : Transform(NULL,firp,NULL) +ElfDependencies_t::ElfDependencies_t(IRDB_SDK::FileIR_t* firp) + : Transform(firp) { typedef ElfDependencies_t::ElfDependenciesImpl_t<Elf64_Sym, Elf64_Rela, Elf64_Dyn, R_X86_64_GLOB_DAT, 32, 8> ElfDependencies64_t; typedef ElfDependencies_t::ElfDependenciesImpl_t<Elf32_Sym, Elf32_Rel, Elf32_Dyn, R_386_GLOB_DAT, 8, 4> ElfDependencies32_t; - if(firp->GetArchitectureBitWidth()==32) + if(firp->getArchitectureBitWidth()==32) transformer.reset(new ElfDependencies32_t(firp)); - else if(firp->GetArchitectureBitWidth()==64) + else if(firp->getArchitectureBitWidth()==64) transformer.reset(new ElfDependencies64_t(firp)); else assert(0); @@ -176,21 +183,21 @@ ElfDependencies_t::ElfDependencies_t(FileIR_t* firp) template<typename T_Elf_Sym, typename T_Elf_Rela, typename T_Elf_Dyn, int reloc_type, int rela_shift, int ptrsize> -ElfDependencies_t::ElfDependenciesImpl_t<T_Elf_Sym,T_Elf_Rela,T_Elf_Dyn,reloc_type,rela_shift,ptrsize>::ElfDependenciesImpl_t(FileIR_t* firp) +ElfDependencies_t::ElfDependenciesImpl_t<T_Elf_Sym,T_Elf_Rela,T_Elf_Dyn,reloc_type,rela_shift,ptrsize>::ElfDependenciesImpl_t(IRDB_SDK::FileIR_t* firp) : ElfDependencies_t::ElfDependenciesBase_t(firp) { } template<typename T_Elf_Sym, typename T_Elf_Rela, typename T_Elf_Dyn, int reloc_type, int rela_shift, int ptrsize> -pair<DataScoop_t*,int> ElfDependencies_t::ElfDependenciesImpl_t<T_Elf_Sym,T_Elf_Rela,T_Elf_Dyn,reloc_type,rela_shift,ptrsize>::appendGotEntry(const string &name) +pair<IRDB_SDK::DataScoop_t*,int> ElfDependencies_t::ElfDependenciesImpl_t<T_Elf_Sym,T_Elf_Rela,T_Elf_Dyn,reloc_type,rela_shift,ptrsize>::appendGotEntry(const string &name) { auto got_scoop=add_got_entry(name); return {got_scoop,0}; } template<typename T_Elf_Sym, typename T_Elf_Rela, typename T_Elf_Dyn, int reloc_type, int rela_shift, int ptrsize> -Instruction_t* ElfDependencies_t::ElfDependenciesImpl_t<T_Elf_Sym,T_Elf_Rela,T_Elf_Dyn,reloc_type,rela_shift,ptrsize>::appendPltEntry(const string &name) +IRDB_SDK::Instruction_t* ElfDependencies_t::ElfDependenciesImpl_t<T_Elf_Sym,T_Elf_Rela,T_Elf_Dyn,reloc_type,rela_shift,ptrsize>::appendPltEntry(const string &name) { static int labelcounter=0; @@ -202,11 +209,15 @@ Instruction_t* ElfDependencies_t::ElfDependenciesImpl_t<T_Elf_Sym,T_Elf_Rela,T_E auto newinsn=addNewAssembly(labelstream.str()+": jmp [rel "+labelstream.str()+"]"); + /* auto newreloc=new Relocation_t(BaseObj_t::NOT_IN_DATABASE, 0, "pcrel", got_scoop); - newinsn->GetRelocations().insert(newreloc); - getFileIR()->GetRelocations().insert(newreloc); - newinsn->GetAddress()->SetFileID(getFileIR()->GetFile()->GetBaseID()); + dynamic_cast<libIRDB::Instruction_t*>(newinsn)->GetRelocations().insert(newreloc); + dynamic_cast<libIRDB::FileIR_t*>(getFileIR())->GetRelocations().insert(newreloc); + */ + auto newreloc=getFileIR()->addNewRelocation(newinsn, 0,"pcrel", got_scoop); + (void)newreloc; // just give to IR. + newinsn->getAddress()->setFileID(getFileIR()->getFile()->getBaseID()); return newinsn; } @@ -219,28 +230,28 @@ Instruction_t* ElfDependencies_t::ElfDependenciesImpl_t<T_Elf_Sym,T_Elf_Rela,T_E // we need a use case to test this code -- it was copied from CFI. template<typename T_Elf_Sym, typename T_Elf_Rela, typename T_Elf_Dyn, int reloc_type, int rela_shift, int ptrsize> -Instruction_t* ElfDependencies_t::ElfDependenciesImpl_t<T_Elf_Sym,T_Elf_Rela,T_Elf_Dyn,reloc_type,rela_shift,ptrsize>::find_runtime_resolve(DataScoop_t* gotplt_scoop) +IRDB_SDK::Instruction_t* ElfDependencies_t::ElfDependenciesImpl_t<T_Elf_Sym,T_Elf_Rela,T_Elf_Dyn,reloc_type,rela_shift,ptrsize>::find_runtime_resolve(IRDB_SDK::DataScoop_t* gotplt_scoop) { const auto firp=getFileIR(); // find any data_to_insn_ptr reloc for the gotplt scoop - auto it=find_if(gotplt_scoop->GetRelocations().begin(), gotplt_scoop->GetRelocations().end(), [](Relocation_t* reloc) + auto it=find_if(gotplt_scoop->getRelocations().begin(), gotplt_scoop->getRelocations().end(), [](IRDB_SDK::Relocation_t* reloc) { - return reloc->GetType()=="data_to_insn_ptr"; + return reloc->getType()=="data_to_insn_ptr"; }); // there _should_ be one. - assert(it!=gotplt_scoop->GetRelocations().end()); + assert(it!=gotplt_scoop->getRelocations().end()); Relocation_t* reloc=*it; - Instruction_t* wrt=dynamic_cast<Instruction_t*>(reloc->GetWRT()); + auto wrt=dynamic_cast<Instruction_t*>(reloc->getWRT()); assert(wrt); // should be a WRT assert(wrt->getDisassembly().find("push ") != string::npos); // should be push K insn - return wrt->GetFallthrough(); // jump to the jump, or not.. doesn't matter. zopt will fix + return wrt->getFallthrough(); // jump to the jump, or not.. doesn't matter. zopt will fix } template<typename T_Elf_Sym, typename T_Elf_Rela, typename T_Elf_Dyn, int reloc_type, int rela_shift, int ptrsize> -DataScoop_t* ElfDependencies_t::ElfDependenciesImpl_t<T_Elf_Sym,T_Elf_Rela,T_Elf_Dyn,reloc_type,rela_shift,ptrsize>::add_got_entry(const std::string& name) +IRDB_SDK::DataScoop_t* ElfDependencies_t::ElfDependenciesImpl_t<T_Elf_Sym,T_Elf_Rela,T_Elf_Dyn,reloc_type,rela_shift,ptrsize>::add_got_entry(const std::string& name) { - const auto firp=getFileIR(); + const auto firp=getFileIR(); // dynamic_cast<libIRDB::FileIR_t*>(getFileIR()); // find relevant scoops auto dynamic_scoop=find_scoop(firp,".dynamic"); // auto gotplt_scoop=find_scoop(firp,".got.plt"); @@ -252,7 +263,7 @@ DataScoop_t* ElfDependencies_t::ElfDependenciesImpl_t<T_Elf_Sym,T_Elf_Rela,T_Elf auto relscoop=relaplt_scoop!=NULL ? relaplt_scoop : relplt_scoop; auto gnu_version_scoop=find_scoop(firp,".gnu.version"); assert(gnu_version_scoop); - assert(gnu_version_scoop->GetStart()->GetVirtualOffset()==0); + assert(gnu_version_scoop->getStart()->getVirtualOffset()==0); if (!relscoop) throw std::logic_error("Cannot find rela.plt or rel.plt. Did you remember to use move_globals with --elf_tables?"); @@ -263,14 +274,19 @@ DataScoop_t* ElfDependencies_t::ElfDependenciesImpl_t<T_Elf_Sym,T_Elf_Rela,T_Elf // create a new, unpinned, rw+relro scoop that's an empty pointer. - AddressID_t* start_addr=new AddressID_t(BaseObj_t::NOT_IN_DATABASE, firp->GetFile()->GetBaseID(), 0); - AddressID_t* end_addr=new AddressID_t(BaseObj_t::NOT_IN_DATABASE, firp->GetFile()->GetBaseID(), ptrsize-1); - DataScoop_t* external_func_addr_scoop=new DataScoop_t(BaseObj_t::NOT_IN_DATABASE, + /* + auto start_addr=new AddressID_t(BaseObj_t::NOT_IN_DATABASE, firp->getFile()->getBaseID(), 0); + auto end_addr=new AddressID_t(BaseObj_t::NOT_IN_DATABASE, firp->getFile()->getBaseID(), ptrsize-1); + auto external_func_addr_scoop=new DataScoop_t(BaseObj_t::NOT_IN_DATABASE, name, start_addr,end_addr, NULL, 6, true, new_got_entry_str); firp->GetAddresses().insert(start_addr); firp->GetAddresses().insert(end_addr); firp->GetDataScoops().insert(external_func_addr_scoop); + */ + auto start_addr=firp->addNewAddress(firp->getFile()->getBaseID(), 0); + auto end_addr =firp->addNewAddress(firp->getFile()->getBaseID(), ptrsize-1); + auto external_func_addr_scoop=firp->addNewDataScoop(name,start_addr,end_addr,NULL,6,true,new_got_entry_str); // add string to string table auto dl_str_pos=add_to_scoop(name+'\0', dynstr_scoop); @@ -291,9 +307,9 @@ DataScoop_t* ElfDependencies_t::ElfDependenciesImpl_t<T_Elf_Sym,T_Elf_Rela,T_Elf // find the rela count. can't insert before that. int rela_count=0; - for(int i=0;i+sizeof(T_Elf_Dyn)<dynamic_scoop->GetSize(); i+=sizeof(T_Elf_Dyn)) + for(int i=0;i+sizeof(T_Elf_Dyn)<dynamic_scoop->getSize(); i+=sizeof(T_Elf_Dyn)) { - T_Elf_Dyn &dyn_entry=*(T_Elf_Dyn*)&dynamic_scoop->GetContents().c_str()[i]; + T_Elf_Dyn &dyn_entry=*(T_Elf_Dyn*)&dynamic_scoop->getContents().c_str()[i]; if(dyn_entry.d_tag==DT_RELACOUNT) // diff than rela size. { // add to the size @@ -314,15 +330,19 @@ DataScoop_t* ElfDependencies_t::ElfDependenciesImpl_t<T_Elf_Sym,T_Elf_Rela,T_Elf unsigned int at=rela_count*sizeof(T_Elf_Rela); insert_into_scoop_at<ptrsize>(dl_rel_str, relscoop, firp, at); - Relocation_t* dl_reloc=new Relocation_t(BaseObj_t::NOT_IN_DATABASE, at+((uintptr_t)&dl_rel.r_offset -(uintptr_t)&dl_rel), "dataptr_to_scoop", external_func_addr_scoop); - relscoop->GetRelocations().insert(dl_reloc); + /* + auto dl_reloc=new Relocation_t(BaseObj_t::NOT_IN_DATABASE, at+((uintptr_t)&dl_rel.r_offset -(uintptr_t)&dl_rel), "dataptr_to_scoop", external_func_addr_scoop); + dynamic_cast<libIRDB::DataScoop_t*>(relscoop)->GetRelocations().insert(dl_reloc); firp->GetRelocations().insert(dl_reloc); + */ + auto dl_reloc=firp->addNewRelocation(relscoop,at+((uintptr_t)&dl_rel.r_offset -(uintptr_t)&dl_rel), "dataptr_to_scoop", external_func_addr_scoop); + (void)dl_reloc; // just give to IR; - for(int i=0;i+sizeof(T_Elf_Dyn)<dynamic_scoop->GetSize(); i+=sizeof(T_Elf_Dyn)) + for(int i=0;i+sizeof(T_Elf_Dyn)<dynamic_scoop->getSize(); i+=sizeof(T_Elf_Dyn)) { // cast the index'd c_str to an Elf_Dyn pointer and deref it to assign to a // reference structure. That way editing the structure directly edits the string. - T_Elf_Dyn &dyn_entry=*(T_Elf_Dyn*)&dynamic_scoop->GetContents().c_str()[i]; + T_Elf_Dyn &dyn_entry=*(T_Elf_Dyn*)&dynamic_scoop->getContents().c_str()[i]; if(dyn_entry.d_tag==DT_RELASZ) // add to the size dyn_entry.d_un.d_val+=sizeof(T_Elf_Rela); @@ -416,7 +436,7 @@ bool ElfDependencies_t::ElfDependenciesImpl_t<T_Elf_Sym,T_Elf_Rela,T_Elf_Dyn,rel template<typename T_Elf_Sym, typename T_Elf_Rela, typename T_Elf_Dyn, int reloc_type, int rela_shift, int ptrsize> void ElfDependencies_t::ElfDependenciesImpl_t<T_Elf_Sym,T_Elf_Rela,T_Elf_Dyn,reloc_type,rela_shift,ptrsize>::appendLibraryDepedencies(const string &libraryName) { - const auto firp=getFileIR(); + const auto firp=getFileIR(); // dynamic_cast<FileIR_t*>(getFileIR()); auto dynamic_scoop=find_scoop(firp,".dynamic"); auto dynstr_scoop=find_scoop(firp,".dynstr"); @@ -426,7 +446,7 @@ void ElfDependencies_t::ElfDependenciesImpl_t<T_Elf_Sym,T_Elf_Rela,T_Elf_Dyn,rel throw std::logic_error("Cannot change libraries in statically linked program"); // may need to enable --step move_globals --step-option move_globals:--cfi - if(dynamic_scoop->GetStart()->GetVirtualOffset()!=0) + if(dynamic_scoop->getStart()->getVirtualOffset()!=0) { cerr<<"Cannot find relocation-scoop pair: Did you enable '--step move_globals --step-option move_globals:--cfi' ? "<<endl; exit(1); @@ -449,9 +469,9 @@ void ElfDependencies_t::ElfDependenciesImpl_t<T_Elf_Sym,T_Elf_Rela,T_Elf_Dyn,rel while(1) { // assert we don't run off the end. - assert((index+1)*sizeof(T_Elf_Dyn) <= dynamic_scoop->GetContents().size()); + assert((index+1)*sizeof(T_Elf_Dyn) <= dynamic_scoop->getContents().size()); - const auto dyn_ptr=(T_Elf_Dyn*) & dynamic_scoop->GetContents().c_str()[index*sizeof(T_Elf_Dyn)]; + const auto dyn_ptr=(T_Elf_Dyn*) & dynamic_scoop->getContents().c_str()[index*sizeof(T_Elf_Dyn)]; if(memcmp(dyn_ptr,&null_dynamic_entry,sizeof(T_Elf_Dyn)) == 0 ) { @@ -460,14 +480,16 @@ void ElfDependencies_t::ElfDependenciesImpl_t<T_Elf_Sym,T_Elf_Rela,T_Elf_Dyn,rel for(auto i=0U; i<sizeof(T_Elf_Dyn); i++) { // copy new_dynamic_entry ontop of null entry. - dynamic_scoop->GetContents()[index*sizeof(T_Elf_Dyn) + i ] = ((char*)&new_dynamic_entry)[i]; + auto str=dynamic_scoop->getContents(); + str[index*sizeof(T_Elf_Dyn) + i ] = ((char*)&new_dynamic_entry)[i]; + dynamic_scoop->setContents(str); } // check if there's room for the new null entry - if((index+2)*sizeof(T_Elf_Dyn) <= dynamic_scoop->GetContents().size()) + if((index+2)*sizeof(T_Elf_Dyn) <= dynamic_scoop->getContents().size()) { /* yes */ - const auto next_entry=(T_Elf_Dyn*)&dynamic_scoop->GetContents().c_str()[(index+1)*sizeof(T_Elf_Dyn)]; + const auto next_entry=(T_Elf_Dyn*)&dynamic_scoop->getContents().c_str()[(index+1)*sizeof(T_Elf_Dyn)]; // assert it's actually null assert(memcmp(next_entry,&null_dynamic_entry,sizeof(T_Elf_Dyn)) == 0 ); } @@ -499,7 +521,7 @@ void ElfDependencies_t::ElfDependenciesImpl_t<T_Elf_Sym,T_Elf_Rela,T_Elf_Dyn,rel throw std::logic_error("Cannot change libraries in statically linked program"); // may need to enable --step move_globals --step-option move_globals:--cfi - if(dynamic_scoop->GetStart()->GetVirtualOffset()!=0) + if(dynamic_scoop->getStart()->getVirtualOffset()!=0) { cerr<<"Cannot find relocation-scoop pair: Did you enable '--step move_globals --step-option move_globals:--cfi' ? "<<endl; exit(1); @@ -515,3 +537,9 @@ void ElfDependencies_t::ElfDependenciesImpl_t<T_Elf_Sym,T_Elf_Rela,T_Elf_Dyn,rel prefix_scoop<ptrsize>(new_dynamic_entry_str, dynamic_scoop, firp) ; } + +unique_ptr<IRDB_SDK::ElfDependencies_t> IRDB_SDK::ElfDependencies_t::factory(IRDB_SDK::FileIR_t* firp) +{ + return unique_ptr<IRDB_SDK::ElfDependencies_t>(new libIRDB::ElfDependencies_t(firp)); +} + diff --git a/libElfDep/include/libElfDep.hpp b/libIRDB-elfdep/src/libElfDep.hpp similarity index 51% rename from libElfDep/include/libElfDep.hpp rename to libIRDB-elfdep/src/libElfDep.hpp index b4444eba3f3d5b487f7f48758ee90929b3ce7f24..4b7eb1e5f7818fdb05b0315e05afc202530ab140 100644 --- a/libElfDep/include/libElfDep.hpp +++ b/libIRDB-elfdep/src/libElfDep.hpp @@ -1,6 +1,7 @@ -#include <libIRDB-core.hpp> -#include <transform.hpp> +#include <irdb-core> +#include <irdb-transform> +#include <irdb-elfdep> #include <string> #include <memory> @@ -8,34 +9,32 @@ namespace libIRDB { -using namespace libIRDB; using namespace std; -using namespace libTransform; -class ElfDependencies_t : public Transform +class ElfDependencies_t : public IRDB_SDK::Transform, public IRDB_SDK::ElfDependencies_t { public: - ElfDependencies_t(FileIR_t* firp); + ElfDependencies_t(IRDB_SDK::FileIR_t* firp); void prependLibraryDepedencies(const string& libName) { transformer->prependLibraryDepedencies(libName); } void appendLibraryDepedencies(const string& libName) { transformer->appendLibraryDepedencies(libName); } // return scoop and offset - pair<DataScoop_t*,int> appendGotEntry(const string &symbolName) { return transformer->appendGotEntry(symbolName); } + pair<IRDB_SDK::DataScoop_t*,int> appendGotEntry(const string &symbolName) { return transformer->appendGotEntry(symbolName); } // return instruction that's the plt entry. - Instruction_t* appendPltEntry(const string &symbolName) { return transformer->appendPltEntry(symbolName); } + IRDB_SDK::Instruction_t* appendPltEntry(const string &symbolName) { return transformer->appendPltEntry(symbolName); } private: class ElfDependenciesBase_t : public Transform { public: - ElfDependenciesBase_t(FileIR_t* firp) : Transform(NULL, firp, NULL) {} + ElfDependenciesBase_t(IRDB_SDK::FileIR_t* firp) : Transform(firp) {} virtual void prependLibraryDepedencies(const string &libraryName)=0; virtual void appendLibraryDepedencies(const string &libraryName)=0; - virtual pair<DataScoop_t*,int> appendGotEntry(const string &name)=0; - virtual Instruction_t* appendPltEntry(const string &name)=0; + virtual pair<IRDB_SDK::DataScoop_t*,int> appendGotEntry(const string &name)=0; + virtual IRDB_SDK::Instruction_t* appendPltEntry(const string &name)=0; }; @@ -44,19 +43,18 @@ class ElfDependencies_t : public Transform { public: - ElfDependenciesImpl_t(FileIR_t* fipr); + ElfDependenciesImpl_t(IRDB_SDK::FileIR_t* fipr); virtual void prependLibraryDepedencies(const string& libraryName); virtual void appendLibraryDepedencies(const string& libraryName); - virtual pair<DataScoop_t*,int> appendGotEntry(const string& name); - virtual Instruction_t* appendPltEntry(const string& name); + virtual pair<IRDB_SDK::DataScoop_t*,int> appendGotEntry(const string& name); + virtual IRDB_SDK::Instruction_t* appendPltEntry(const string& name); private: bool add_dl_support(); - Instruction_t* find_runtime_resolve(DataScoop_t* gotplt_scoop); - DataScoop_t* add_got_entry(const std::string& name); - //bool add_got_entries(); + IRDB_SDK::Instruction_t* find_runtime_resolve(IRDB_SDK::DataScoop_t* gotplt_scoop); + IRDB_SDK::DataScoop_t* add_got_entry(const std::string& name); bool add_libdl_as_needed_support(string libName); bool execute(); diff --git a/libElfDep/test/.gitignore b/libIRDB-elfdep/test/.gitignore similarity index 100% rename from libElfDep/test/.gitignore rename to libIRDB-elfdep/test/.gitignore diff --git a/libElfDep/test/SConscript b/libIRDB-elfdep/test/SConscript similarity index 60% rename from libElfDep/test/SConscript rename to libIRDB-elfdep/test/SConscript index e457589bcc480f365b4b5f164a57f68de53be2ba..3f62a1b032e5b3d6ac70e2ea1f60adb7cbba3d7d 100644 --- a/libElfDep/test/SConscript +++ b/libIRDB-elfdep/test/SConscript @@ -9,21 +9,14 @@ myenv=env.Clone() myenv.Replace(SECURITY_TRANSFORMS_HOME=os.environ['SECURITY_TRANSFORMS_HOME']) myenv.Replace(ZIPR_HOME=os.environ['ZIPR_HOME']) myenv.Replace(ZIPR_SDK=os.environ['ZIPR_SDK']) +myenv.Replace(IRDB_SDK=os.environ['IRDB_SDK']) myenv.Replace(ZIPR_INSTALL=os.environ['ZIPR_INSTALL']) + myenv.Replace(CXXFLAGS = " -g -std=c++11 -Wall ") +myenv.Append(LINKFLAGS = " -Wl,-unresolved-symbols=ignore-in-shared-libs ") cpppath=''' - $SECURITY_TRANSFORMS_HOME/include - $SECURITY_TRANSFORMS_HOME/libIRDB/include - $SECURITY_TRANSFORMS_HOME/libMEDSannotation/include - $SECURITY_TRANSFORMS_HOME/beaengine/include - $SECURITY_TRANSFORMS_HOME/libtransform/include - $SECURITY_TRANSFORMS_HOME/libStructDiv/include - $SECURITY_TRANSFORMS_HOME/libEXEIO/include - $SECURITY_TRANSFORMS_HOME/libElfDep/include - $SMPSA_HOME/include - $ZIPR_HOME/include - $ZIPR_SDK/include + $IRDB_SDK/include ''' @@ -32,7 +25,7 @@ files=Glob( Dir('.').srcnode().abspath+"/edt*.cpp") pgm="edt.exe" LIBPATH="$SECURITY_TRANSFORMS_HOME/lib" -LIBS=Split("stars "+ myenv.subst('$BASE_IRDB_LIBS')+ " IRDB-core libIRDB-cfg libIRDB-util.so pqxx capstone transform MEDSannotation EXEIO pebliss ElfDep") +LIBS=Split("irdb-core irdb-transform irdb-elfdep") myenv=myenv.Clone(CPPPATH=Split(cpppath)) pgm=myenv.Program(pgm, files, LIBPATH=LIBPATH, LIBS=LIBS) install=myenv.Install("$SECURITY_TRANSFORMS_HOME/plugins_install/", pgm) diff --git a/libElfDep/test/SConstruct b/libIRDB-elfdep/test/SConstruct similarity index 100% rename from libElfDep/test/SConstruct rename to libIRDB-elfdep/test/SConstruct diff --git a/libElfDep/test/edt.cpp b/libIRDB-elfdep/test/edt.cpp similarity index 66% rename from libElfDep/test/edt.cpp rename to libIRDB-elfdep/test/edt.cpp index 77cff3e41f288bc2d67fe976f0beb5e8a449b2a0..ff1d95391fe8128bf79fa90e1c5d9eba4875a977 100644 --- a/libElfDep/test/edt.cpp +++ b/libIRDB-elfdep/test/edt.cpp @@ -1,18 +1,15 @@ #include "edt.hpp" -#include <libElfDep.hpp> -#include "Rewrite_Utility.hpp" +#include <irdb-elfdep> #include <algorithm> -using namespace libTransform; -using namespace libIRDB; +using namespace IRDB_SDK; using namespace std; -using namespace IRDBUtility; using namespace ElfDep_Tester; ElfDep_Tester_t::ElfDep_Tester_t(FileIR_t* firp) - : Transform (NULL, firp, NULL) + : Transform (firp) { } @@ -23,20 +20,20 @@ ElfDep_Tester_t::ElfDep_Tester_t(FileIR_t* firp) int ElfDep_Tester_t::execute() { // insert the PLT and GOT entries needed - auto ed=ElfDependencies_t(getFileIR()); - (void)ed.appendLibraryDepedencies("libelf_dep_test.so"); - auto edpcb=ed.appendPltEntry("elf_dep_test_callback"); - auto edvar=ed.appendGotEntry("elf_dep_test_var"); + auto ed=ElfDependencies_t::factory(getFileIR()); + (void)ed->appendLibraryDepedencies("libelf_dep_test.so"); + auto edpcb=ed->appendPltEntry("elf_dep_test_callback"); + auto edvar=ed->appendGotEntry("elf_dep_test_var"); auto edvar_scoop=edvar.first; auto edvar_offset=edvar.second; // find the insertion point. - const auto &all_funcs=getFileIR()->GetFunctions(); - const auto main_func_it=find_if(ALLOF(all_funcs), [&](const Function_t* f) { return f->GetName()=="main";}); + const auto &all_funcs=getFileIR()->getFunctions(); + const auto main_func_it=find_if(ALLOF(all_funcs), [&](const Function_t* f) { return f->getName()=="main";}); assert(main_func_it!=all_funcs.end()); const auto main_func=*main_func_it; - auto insert_loc=main_func->GetEntryPoint(); + auto insert_loc=main_func->getEntryPoint(); // insert the instrumentation @@ -61,10 +58,8 @@ int ElfDep_Tester_t::execute() // map the load to point at the GOT entry. - auto got_reloc=new Relocation_t(BaseObj_t::NOT_IN_DATABASE, edvar_offset, "pcrel", edvar_scoop); - getFileIR()->GetRelocations().insert(got_reloc); - got_insn->GetRelocations().insert(got_reloc); - + auto got_reloc=getFileIR()->addNewRelocation(got_insn, edvar_offset, "pcrel", edvar_scoop); + (void)got_reloc; // just give to IR return 0; } diff --git a/libElfDep/test/edt.hpp b/libIRDB-elfdep/test/edt.hpp similarity index 56% rename from libElfDep/test/edt.hpp rename to libIRDB-elfdep/test/edt.hpp index 32ec207792084e2f003dbaa7c3b60e39b580bac0..24c082c478f7391dd985b011fcbcfd978cde67c2 100644 --- a/libElfDep/test/edt.hpp +++ b/libIRDB-elfdep/test/edt.hpp @@ -1,19 +1,18 @@ #include <string> #include <set> -#include <libIRDB-core.hpp> -#include <transform.hpp> +#include <irdb-core> +#include <irdb-transform> namespace ElfDep_Tester { -using namespace libTransform; -using namespace libIRDB; +using namespace IRDB_SDK; using namespace std; typedef set<string> StringSet_t; -class ElfDep_Tester_t : libTransform::Transform +class ElfDep_Tester_t : Transform { public: ElfDep_Tester_t(FileIR_t* firp); diff --git a/libElfDep/test/edt_driver.cpp b/libIRDB-elfdep/test/edt_driver.cpp similarity index 80% rename from libElfDep/test/edt_driver.cpp rename to libIRDB-elfdep/test/edt_driver.cpp index 6a9133c25be700afda2208e45fcdf23139f59d7e..52d836f477b87b1e49f367205ec58a6450c7c251 100644 --- a/libElfDep/test/edt_driver.cpp +++ b/libIRDB-elfdep/test/edt_driver.cpp @@ -2,11 +2,11 @@ #include <fstream> #include <string> #include "edt.hpp" -#include <libIRDB-core.hpp> +#include <irdb-core> #include <getopt.h> using namespace std; -using namespace libIRDB; +using namespace IRDB_SDK; using namespace ElfDep_Tester; void usage(string programName) @@ -21,8 +21,7 @@ int main(int argc, char **argv) char *strtolError = NULL; int transformExitCode = 0; int variantID = -1; - VariantID_t *pidp = NULL; - pqxxDB_t pqxx_interface; + auto pqxx_interface=pqxxDB_t::factory(); int exit_code=0; /* @@ -69,21 +68,21 @@ int main(int argc, char **argv) /* setup the interface to the sql server */ - BaseObj_t::SetInterface(&pqxx_interface); + BaseObj_t::setInterface(pqxx_interface.get()); - pidp=new VariantID_t(variantID); - assert(pidp && pidp->IsRegistered()==true); + auto pidp=VariantID_t::factory(variantID); + assert(pidp && pidp->isRegistered()==true); - for(set<File_t*>::iterator it=pidp->GetFiles().begin(); - it!=pidp->GetFiles().end(); + for(set<File_t*>::iterator it=pidp->getFiles().begin(); + it!=pidp->getFiles().end(); ++it) { try { /* read the IR from the DB */ File_t* this_file = *it; - FileIR_t *firp = new FileIR_t(*pidp, this_file); - cout<<"Transforming "<<this_file->GetURL()<<endl; + auto firp = FileIR_t::factory(pidp.get(), this_file); + cout<<"Transforming "<<this_file->getURL()<<endl; assert(firp && pidp); @@ -91,7 +90,7 @@ int main(int argc, char **argv) * Create a transformation and then * invoke its execution. */ - auto ed=ElfDep_Tester_t(firp); + auto ed=ElfDep_Tester_t(firp.get()); transformExitCode = ed.execute(); /* * If everything about the transformation @@ -102,9 +101,8 @@ int main(int argc, char **argv) { if(getenv("MG_NOUPDATE")==NULL) { - firp->WriteToDB(); + firp->writeToDB(); } - delete firp; } else { @@ -129,8 +127,7 @@ int main(int argc, char **argv) exit(1); } } - pqxx_interface.Commit(); - delete pidp; + pqxx_interface->commit(); return exit_code; } diff --git a/libElfDep/test/elf_dep_test.cpp b/libIRDB-elfdep/test/elf_dep_test.cpp similarity index 100% rename from libElfDep/test/elf_dep_test.cpp rename to libIRDB-elfdep/test/elf_dep_test.cpp diff --git a/libElfDep/test/test-elfdep.sh b/libIRDB-elfdep/test/test-elfdep.sh similarity index 100% rename from libElfDep/test/test-elfdep.sh rename to libIRDB-elfdep/test/test-elfdep.sh diff --git a/libIRDB/include/libIRDB-syscall.hpp b/libIRDB-syscall/include/libIRDB-syscall.hpp similarity index 88% rename from libIRDB/include/libIRDB-syscall.hpp rename to libIRDB-syscall/include/libIRDB-syscall.hpp index e97d812316fd07b23b465aadcc2ed79ee24913e9..3ac7c4ccc9e94ae0436d7d16567bd9650a6dd135 100644 --- a/libIRDB/include/libIRDB-syscall.hpp +++ b/libIRDB-syscall/include/libIRDB-syscall.hpp @@ -23,18 +23,14 @@ /* Building a CFG depends on core functionality */ -#include <libIRDB-core.hpp> -#include <libIRDB-util.hpp> #include <vector> #include <set> #include <map> #include <ostream> -namespace libIRDB -{ -#include <syscall/syscall.hpp> -}; + +#include <syscall.hpp> #endif diff --git a/libIRDB-syscall/include/syscall.hpp b/libIRDB-syscall/include/syscall.hpp new file mode 100644 index 0000000000000000000000000000000000000000..0e54e9931b42fa48e15d4ac3e7f369a844861bde --- /dev/null +++ b/libIRDB-syscall/include/syscall.hpp @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2014 - Zephyr Software + * + * This file may be used and modified for non-commercial purposes as long as + * all copyright, permission, and nonwarranty notices are preserved. + * Redistribution is prohibited without prior written consent from Zephyr + * Software. + * + * Please contact the authors for restrictions applying to commercial use. + * + * THIS SOURCE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * Author: Zephyr Software + * e-mail: jwd@zephyr-software.com + * URL : http://www.zephyr-software.com/ + * + */ + +#ifndef irdb_syscall_hpp +#define irdb_syscall_hpp + +namespace libIRDB +{ + + class SyscallSite_t : public IRDB_SDK::SyscallSite_t + { + public: + SyscallSite_t(IRDB_SDK::Instruction_t* p_site, IRDB_SDK::SyscallNumber_t p_num) : site(p_site), num(p_num) {} + + IRDB_SDK::Instruction_t* getSyscallSite() const { return site; } + IRDB_SDK::Instruction_t* getSite() const { return site; } + IRDB_SDK::SyscallNumber_t getSyscallNumber() const { return num; } + + private: + IRDB_SDK::Instruction_t* site; + IRDB_SDK::SyscallNumber_t num; + }; + + class Syscalls_t : public IRDB_SDK::Syscalls_t + { + public: + Syscalls_t(IRDB_SDK::FileIR_t *the_firp=NULL) { if(the_firp) FindSystemCalls(the_firp); } + virtual ~Syscalls_t(); + + + + const IRDB_SDK::SyscallSiteSet_t& getSyscalls() {return syscalls;} + protected: + IRDB_SDK::SyscallNumber_t FindSystemCallNumber(IRDB_SDK::Instruction_t* insn, + const IRDB_SDK::InstructionPredecessors_t& preds); + + bool FindSystemCalls(const IRDB_SDK::FileIR_t* firp); + private: + IRDB_SDK::SyscallSiteSet_t syscalls; + }; + +} +#endif + diff --git a/libIRDB/src/syscall/SConscript b/libIRDB-syscall/src/SConscript similarity index 61% rename from libIRDB/src/syscall/SConscript rename to libIRDB-syscall/src/SConscript index 2a5acdb1c9e4901dd7f686a81fadda160cbaa61f..b1d91ed7655ef3401ee373c067c1d06a7fefa917 100644 --- a/libIRDB/src/syscall/SConscript +++ b/libIRDB-syscall/src/SConscript @@ -5,13 +5,15 @@ myenv=env myenv.Replace(SECURITY_TRANSFORMS_HOME=os.environ['SECURITY_TRANSFORMS_HOME']) -libname="IRDB-syscall" +libname="irdb-syscall" files= ''' syscall.cpp ''' cpppath=''' + $IRDB_SDK/include/ $SECURITY_TRANSFORMS_HOME/include/ - $SECURITY_TRANSFORMS_HOME/libIRDB/include/ + $SECURITY_TRANSFORMS_HOME/libIRDB-core/include/ + $SECURITY_TRANSFORMS_HOME/libIRDB-syscall/include/ ''' #myenv.Append(CCFLAGS=" -Wall -W -Wextra -Wconversion ") @@ -20,7 +22,7 @@ myenv.Append(CXXFLAGS = " -std=c++11 ") myenv=myenv.Clone(CPPPATH=Split(cpppath)) -lib=myenv.SharedLibrary(libname, Split(files), LIBS=Split("IRDB-core IRDB-util"), LIBPATH=Split("$SECURITY_TRANSFORMS_HOME/lib")) +lib=myenv.SharedLibrary(libname, Split(files), LIBS=Split("irdb-core irdb-util"), LIBPATH=Split("$SECURITY_TRANSFORMS_HOME/lib")) install=myenv.Install("$SECURITY_TRANSFORMS_HOME/lib/", lib) Default(install) diff --git a/tools/dump_insns/SConstruct b/libIRDB-syscall/src/SConstruct similarity index 100% rename from tools/dump_insns/SConstruct rename to libIRDB-syscall/src/SConstruct diff --git a/libIRDB/src/syscall/syscall.cpp b/libIRDB-syscall/src/syscall.cpp similarity index 59% rename from libIRDB/src/syscall/syscall.cpp rename to libIRDB-syscall/src/syscall.cpp index 42a6745e870cd7ff45002091568580a2124ea01a..c4fc4e7108c22397f686c72e3819bdaec5b8488e 100644 --- a/libIRDB/src/syscall/syscall.cpp +++ b/libIRDB-syscall/src/syscall.cpp @@ -18,25 +18,32 @@ * */ -//#include <libIRDB-core.hpp> -//#include <libIRDB-util.hpp> -#include <stdlib.h> +#include <irdb-core> +#include <irdb-util> +#include <irdb-syscall> #include <libIRDB-syscall.hpp> +#include <stdlib.h> using namespace std; using namespace libIRDB; -SyscallNumber_t Syscalls_t::FindSystemCallNumber(Instruction_t* insn, const libIRDB::InstructionPredecessors_t& preds) +Syscalls_t::~Syscalls_t() +{ + for(auto site : syscalls) + delete site; + syscalls.clear(); +} + +IRDB_SDK::SyscallNumber_t Syscalls_t::FindSystemCallNumber(IRDB_SDK::Instruction_t* insn, const IRDB_SDK::InstructionPredecessors_t& preds) { - Instruction_t *pred_insn=NULL; + IRDB_SDK::Instruction_t *pred_insn=nullptr; - for( const InstructionSet_t *cs_preds=&preds[insn]; + for( auto cs_preds=&preds[insn]; cs_preds->size()==1; cs_preds=&preds[pred_insn] ) { pred_insn=*(cs_preds->begin()); - // cout<<"Pred is "<<pred_insn->getDisassembly()<<endl; string disass=pred_insn->getDisassembly(); @@ -49,41 +56,37 @@ SyscallNumber_t Syscalls_t::FindSystemCallNumber(Instruction_t* insn, const libI if(loc ==string::npos) { // no, quit looking backwards - return SNT_Unknown; + return IRDB_SDK::sntUnknown; } - size_t val=strtol(disass.substr(loc+to_find.length()).c_str(),NULL,16); + size_t val=strtol(disass.substr(loc+to_find.length()).c_str(),nullptr,16); // check to see if it's a mov of eax - return (SyscallNumber_t)val; + return (IRDB_SDK::SyscallNumber_t)val; } } - return SNT_Unknown; + return IRDB_SDK::sntUnknown; } -bool Syscalls_t::FindSystemCalls(const FileIR_t *firp2) +bool Syscalls_t::FindSystemCalls(const IRDB_SDK::FileIR_t *firp2) { - FileIR_t* firp=(FileIR_t*)firp2; // discard const qualifer, but we aren't changing anything. + auto firp=const_cast<IRDB_SDK::FileIR_t*>(firp2); // discard const qualifer, but we aren't changing anything. assert(firp); - libIRDB::InstructionPredecessors_t preds; - preds.AddFile(firp); + auto predsp=IRDB_SDK::InstructionPredecessors_t::factory(firp); + auto &preds = * predsp; bool found_one=false; - for(InstructionSet_t::iterator it=firp->GetInstructions().begin(); - it!=firp->GetInstructions().end(); - ++it - ) + for(auto insn : firp->getInstructions()) { - Instruction_t* insn=*it; - if(insn->IsSyscall()) + if(insn->getDisassembly()=="int 0x80") { - SyscallNumber_t num=FindSystemCallNumber(insn, preds); - syscalls.insert(SyscallSite_t(insn,num)); + auto num=FindSystemCallNumber(insn, preds); + syscalls.insert(new libIRDB::SyscallSite_t(insn,num)); found_one=true; if(getenv("PRINTSYSCALLSFOUND")) - cout<<"Found system call "<< insn->GetBaseID()<< ":'"<< insn->getDisassembly() << "' with eax value "<< (size_t)num<<endl; + cout<<"Found system call "<< insn->getBaseID()<< ":'"<< insn->getDisassembly() << "' with eax value "<< (size_t)num<<endl; } } return found_one; diff --git a/libtransform/Makefile b/libIRDB-transform/Makefile similarity index 100% rename from libtransform/Makefile rename to libIRDB-transform/Makefile diff --git a/libtransform/SConscript b/libIRDB-transform/SConscript similarity index 100% rename from libtransform/SConscript rename to libIRDB-transform/SConscript diff --git a/libtransform/SConstruct b/libIRDB-transform/SConstruct similarity index 100% rename from libtransform/SConstruct rename to libIRDB-transform/SConstruct diff --git a/libtransform/src/Makefile.in b/libIRDB-transform/include-unused-delete-later/Makefile.in similarity index 100% rename from libtransform/src/Makefile.in rename to libIRDB-transform/include-unused-delete-later/Makefile.in diff --git a/libtransform/include/Rewrite_Utility.hpp b/libIRDB-transform/include-unused-delete-later/Rewrite_Utility.hpp similarity index 84% rename from libtransform/include/Rewrite_Utility.hpp rename to libIRDB-transform/include-unused-delete-later/Rewrite_Utility.hpp index bdaabccf39e026fb4fa265273446640dae5aa8b2..7a9f1f90a0f1f02a3d981954ec78fdda87a4e81e 100644 --- a/libtransform/include/Rewrite_Utility.hpp +++ b/libIRDB-transform/include-unused-delete-later/Rewrite_Utility.hpp @@ -18,22 +18,12 @@ * */ -#include <libIRDB-core.hpp> +#include <irdb-core> -using namespace libIRDB; -using namespace std; namespace IRDBUtility { -// make sure these match values in detector_handlers.h in the strata library -/*enum mitigation_policy -{ - P_NONE=0, - P_CONTINUE_EXECUTION, - P_CONTROLLED_EXIT, - P_CONTINUE_EXECUTION_SATURATING_ARITHMETIC, - P_CONTINUE_EXECUTION_WARNONLY -};*/ - +using namespace IRDB_SDK; +using namespace std; //The "first" instruction will have its contents replaced and a duplicate of "first" will be in the follow of first. //This duplicate is returned since the user already has a pointer to first. @@ -60,10 +50,9 @@ Instruction_t* copyInstruction(FileIR_t* virp, Instruction_t* instr); //copy src to destination void copyInstruction(Instruction_t* src, Instruction_t* dest); -Instruction_t* allocateNewInstruction(FileIR_t* virp, db_id_t p_fileID,Function_t* func); +Instruction_t* allocateNewInstruction(FileIR_t* virp, DatabaseID_t p_fileID,Function_t* func); Instruction_t* allocateNewInstruction(FileIR_t* virp, Instruction_t *template_instr); void setInstructionAssembly(FileIR_t* virp,Instruction_t *p_instr, string p_assembly, Instruction_t *p_fallThrough, Instruction_t *p_target); -//Instruction_t* getHandlerCode(FileIR_t* virp, Instruction_t* fallthrough, mitigation_policy policy ); } diff --git a/libtransform/src/integertransform.cpp b/libIRDB-transform/include-unused-delete-later/integertransform.cpp similarity index 100% rename from libtransform/src/integertransform.cpp rename to libIRDB-transform/include-unused-delete-later/integertransform.cpp diff --git a/libtransform/include/integertransform.hpp b/libIRDB-transform/include-unused-delete-later/integertransform.hpp similarity index 100% rename from libtransform/include/integertransform.hpp rename to libIRDB-transform/include-unused-delete-later/integertransform.hpp diff --git a/libtransform/src/integertransform32.cpp b/libIRDB-transform/include-unused-delete-later/integertransform32.cpp similarity index 87% rename from libtransform/src/integertransform32.cpp rename to libIRDB-transform/include-unused-delete-later/integertransform32.cpp index 84630171a90461719454c8b86de15560500dfbfb..3f63ef75561fff2b9d8086393e3ec25ac69819b5 100644 --- a/libtransform/src/integertransform32.cpp +++ b/libIRDB-transform/include-unused-delete-later/integertransform32.cpp @@ -106,10 +106,10 @@ int IntegerTransform32::execute() { Instruction_t* insn=*it; - if (insn && insn->GetAddress()) + if (insn && insn->getAddress()) { int policy = POLICY_DEFAULT; // use Strata default settings - virtual_offset_t irdb_vo = insn->GetAddress()->GetVirtualOffset(); + virtual_offset_t irdb_vo = insn->getAddress()->GetVirtualOffset(); if (irdb_vo == 0) continue; VirtualOffset vo(irdb_vo); @@ -183,7 +183,7 @@ int IntegerTransform32::execute() continue; } - if (!insn->GetFallthrough()) + if (!insn->getFallthrough()) { logMessage(__func__, "Warning: no fall through for instruction -- skipping"); continue; @@ -268,7 +268,7 @@ void IntegerTransform32::addSignednessCheck(Instruction_t *p_instruction, const return; } - db_id_t fileID = p_instruction->GetAddress()->GetFileID(); + DatabaseID_t fileID = p_instruction->getAddress()->getFileID(); Function_t* func = p_instruction->GetFunction(); Instruction_t* pushf_i = allocateNewInstruction(fileID, func); @@ -279,8 +279,8 @@ void IntegerTransform32::addSignednessCheck(Instruction_t *p_instruction, const addPushf(pushf_i, test_i); Instruction_t* originalInstrumentInstr = carefullyInsertBefore(p_instruction, pushf_i); - pushf_i->SetFallthrough(test_i); - pushf_i->SetComment("-- in signedness check"); + pushf_i->setFallthrough(test_i); + pushf_i->setComment("-- in signedness check"); addTestRegister(test_i, p_annotation.getRegister(), jns_i); addJns(jns_i, nop_i, popf_i); addNop(nop_i, popf_i); @@ -300,9 +300,9 @@ void IntegerTransform32::addSignednessCheck(Instruction_t *p_instruction, const if (p_policy == POLICY_CONTINUE_SATURATING_ARITHMETIC) { // implement saturating arithmetic on register, i.e.: mov <reg>, value - Instruction_t* saturate_i = allocateNewInstruction(p_instruction->GetAddress()->GetFileID(), p_instruction->GetFunction()); + Instruction_t* saturate_i = allocateNewInstruction(p_instruction->getAddress()->getFileID(), p_instruction->GetFunction()); - addCallbackHandler(detector, originalInstrumentInstr, nop_i, saturate_i, p_policy, p_instruction->GetAddress()); + addCallbackHandler(detector, originalInstrumentInstr, nop_i, saturate_i, p_policy, p_instruction->getAddress()); if (p_annotation.isSigned()) addMaxSaturation(saturate_i, p_annotation.getRegister(), p_annotation, popf_i); else @@ -310,7 +310,7 @@ void IntegerTransform32::addSignednessCheck(Instruction_t *p_instruction, const } else { - addCallbackHandler(detector, originalInstrumentInstr, nop_i, popf_i, p_policy, p_instruction->GetAddress()); + addCallbackHandler(detector, originalInstrumentInstr, nop_i, popf_i, p_policy, p_instruction->getAddress()); } addPopf(popf_i, originalInstrumentInstr); @@ -499,7 +499,7 @@ void IntegerTransform32::addOverflowCheckNoFlag_RegPlusReg(Instruction_t *p_inst // fallthrough-->originalNext // - db_id_t fileID = p_instruction->GetAddress()->GetFileID(); + DatabaseID_t fileID = p_instruction->getAddress()->getFileID(); Function_t* func = p_instruction->GetFunction(); Instruction_t* pushr1_i = allocateNewInstruction(fileID, func); @@ -521,18 +521,18 @@ void IntegerTransform32::addOverflowCheckNoFlag_RegPlusReg(Instruction_t *p_inst addRR_annot.setUnknownSign(); string msg = "Originally: " + p_instruction->getDisassembly(); - Instruction_t* originalNextInstr = p_instruction->GetFallthrough(); - AddressID_t *originalAddress = p_instruction->GetAddress(); + Instruction_t* originalNextInstr = p_instruction->getFallthrough(); + AddressID_t *originalAddress = p_instruction->getAddress(); addPushRegister(pushr1_i, p_reg1, pushf_i); Instruction_t* originalInstrumentInstr = carefullyInsertBefore(p_instruction, pushr1_i); - pushr1_i->SetFallthrough(pushf_i); - pushr1_i->SetComment("-- carefullyInsertBefore NoFlagRegPlusReg"); + pushr1_i->setFallthrough(pushf_i); + pushr1_i->setComment("-- carefullyInsertBefore NoFlagRegPlusReg"); addPushf(pushf_i, addRR_i); addAddRegisters(addRR_i, p_reg1, p_reg2, popf_i); - addRR_i->SetComment(msg); + addRR_i->setComment(msg); addPopf(popf_i, popr1_i); addPopRegister(popr1_i, p_reg1, originalInstrumentInstr); @@ -564,7 +564,7 @@ void IntegerTransform32::addOverflowCheckNoFlag_RegPlusReg(Instruction_t *p_inst Instruction_t* popR1sat_i = allocateNewInstruction(fileID, func); Instruction_t* saturate_i = allocateNewInstruction(fileID, func); - addRR_i->SetFallthrough(j_i); + addRR_i->setFallthrough(j_i); if (p_annotation.isSigned()) { @@ -649,7 +649,7 @@ void IntegerTransform32::addOverflowCheckNoFlag_RegPlusConstant(Instruction_t *p // Note: if r3 == r1, code still works (though inefficiently) // - db_id_t fileID = p_instruction->GetAddress()->GetFileID(); + DatabaseID_t fileID = p_instruction->getAddress()->getFileID(); Function_t* func = p_instruction->GetFunction(); Instruction_t* pushR3_i = allocateNewInstruction(fileID, func); @@ -671,14 +671,14 @@ void IntegerTransform32::addOverflowCheckNoFlag_RegPlusConstant(Instruction_t *p addR3Constant_annot.setUnknownSign(); string msg = "Originally: " + p_instruction->getDisassembly(); - Instruction_t* originalNextInstr = p_instruction->GetFallthrough(); + Instruction_t* originalNextInstr = p_instruction->getFallthrough(); - AddressID_t *originalAddress = p_instruction->GetAddress(); + AddressID_t *originalAddress = p_instruction->getAddress(); addPushRegister(pushR3_i, p_reg3, pushf_i); Instruction_t* originalInstrumentInstr = carefullyInsertBefore(p_instruction, pushR3_i); - pushR3_i->SetComment("in lea -- RegPlusConstant"); - pushR3_i->SetFallthrough(pushf_i); + pushR3_i->setComment("in lea -- RegPlusConstant"); + pushR3_i->setFallthrough(pushf_i); addPushf(pushf_i, movR3R1_i); addMovRegisters(movR3R1_i, p_reg3, p_reg1, addR3Constant_i); @@ -686,7 +686,7 @@ void IntegerTransform32::addOverflowCheckNoFlag_RegPlusConstant(Instruction_t *p addPopf(popf_i, popR3_i); addPopRegister(popR3_i, p_reg3, originalInstrumentInstr); - addR3Constant_i->SetComment(msg); + addR3Constant_i->setComment(msg); if (p_policy == POLICY_CONTINUE_SATURATING_ARITHMETIC) { // (jno|jnc <restore>) ; SIGNED|UNSIGNED @@ -709,7 +709,7 @@ void IntegerTransform32::addOverflowCheckNoFlag_RegPlusConstant(Instruction_t *p Instruction_t* popR3sat_i = allocateNewInstruction(fileID, func); Instruction_t* saturate_i = allocateNewInstruction(fileID, func); - addR3Constant_i->SetFallthrough(j_i); + addR3Constant_i->setFallthrough(j_i); if (p_annotation.isSigned()) { @@ -770,7 +770,7 @@ void IntegerTransform32::addOverflowCheckNoFlag_RegTimesConstant(Instruction_t * // // Note: if r3 == r1, code still works (though inefficiently) // - db_id_t fileID = p_instruction->GetAddress()->GetFileID(); + DatabaseID_t fileID = p_instruction->getAddress()->getFileID(); Function_t* func = p_instruction->GetFunction(); Instruction_t* pushR3_i = allocateNewInstruction(fileID, func); @@ -792,14 +792,14 @@ void IntegerTransform32::addOverflowCheckNoFlag_RegTimesConstant(Instruction_t * mulR3Constant_annot.setUnknownSign(); string msg = "Originally: " + p_instruction->getDisassembly(); - Instruction_t* originalNextInstr = p_instruction->GetFallthrough(); + Instruction_t* originalNextInstr = p_instruction->getFallthrough(); - AddressID_t *originalAddress = p_instruction->GetAddress(); + AddressID_t *originalAddress = p_instruction->getAddress(); addPushRegister(pushR3_i, p_reg3, pushf_i); Instruction_t* originalInstrumentInstr = carefullyInsertBefore(p_instruction, pushR3_i); - pushR3_i->SetFallthrough(pushf_i); - pushR3_i->SetComment("in lea -- Reg * Constant"); + pushR3_i->setFallthrough(pushf_i); + pushR3_i->setComment("in lea -- Reg * Constant"); addPushf(pushf_i, movR3R1_i); addMovRegisters(movR3R1_i, p_reg3, p_reg1, mulR3Constant_i); @@ -807,7 +807,7 @@ void IntegerTransform32::addOverflowCheckNoFlag_RegTimesConstant(Instruction_t * addPopf(popf_i, popR3_i); addPopRegister(popR3_i, p_reg3, originalInstrumentInstr); - mulR3Constant_i->SetComment(msg); + mulR3Constant_i->setComment(msg); if (p_policy == POLICY_CONTINUE_SATURATING_ARITHMETIC) { @@ -824,7 +824,7 @@ void IntegerTransform32::addOverflowCheckNoFlag_RegTimesConstant(Instruction_t * Instruction_t* popR3sat_i = allocateNewInstruction(fileID, func); Instruction_t* saturate_i = allocateNewInstruction(fileID, func); - mulR3Constant_i->SetFallthrough(jo_i); + mulR3Constant_i->setFallthrough(jo_i); addOverflowCheckForLea(mulR3Constant_i, mulR3Constant_annot, p_policy, originalAddress); addJo(jo_i, popf_i, popfsat_i); @@ -843,7 +843,7 @@ void IntegerTransform32::addOverflowCheckNoFlag_RegTimesConstant(Instruction_t * void IntegerTransform32::handleFISTTruncation(Instruction_t *p_instruction){ cerr << "IntegerTransform32::handleFISTTruncation(): instr: " << p_instruction->getDisassembly() << " address: " - << p_instruction->GetAddress() << endl; + << p_instruction->getAddress() << endl; int len=0; //We skip the qword case. @@ -870,7 +870,7 @@ void IntegerTransform32::handleFISTTruncation(Instruction_t *p_instruction){ void IntegerTransform32::addFistpTruncationCheck(Instruction_t *p_instruction, int len){ if(len!=32 && len!=16) return; - db_id_t fileID = p_instruction->GetAddress()->GetFileID(); + DatabaseID_t fileID = p_instruction->getAddress()->getFileID(); Function_t* func = p_instruction->GetFunction(); string dataBits; @@ -945,7 +945,7 @@ void IntegerTransform32::addFistpTruncationCheck(Instruction_t *p_instruction, i addPusha(pusha_i, pushf_i);//pusha Instruction_t* originalInstrumentInstr = carefullyInsertBefore(p_instruction, pusha_i); - pusha_i->SetFallthrough(pushf_i); + pusha_i->setFallthrough(pushf_i); addPushf(pushf_i, sub_esp_0x70);//pushf @@ -956,55 +956,55 @@ void IntegerTransform32::addFistpTruncationCheck(Instruction_t *p_instruction, i dataBits[3] = 0x00; dataBits[4] = 0x00; dataBits[5] = 0x00; - sub_esp_0x70->SetFallthrough(fst_esp); - sub_esp_0x70->SetDataBits(dataBits); - sub_esp_0x70->SetComment(sub_esp_0x70->getDisassembly()); + sub_esp_0x70->setFallthrough(fst_esp); + sub_esp_0x70->setDataBits(dataBits); + sub_esp_0x70->setComment(sub_esp_0x70->getDisassembly()); addInstruction(sub_esp_0x70, dataBits, fst_esp, NULL); dataBits.resize(3);//fst [esp] dataBits[0] = 0xd9; dataBits[1] = 0x14; dataBits[2] = 0x24; - fst_esp->SetFallthrough(fsave_esp_4); - fst_esp->SetDataBits(dataBits); - fst_esp->SetComment(fst_esp->getDisassembly()); + fst_esp->setFallthrough(fsave_esp_4); + fst_esp->setDataBits(dataBits); + fst_esp->setComment(fst_esp->getDisassembly()); addInstruction(fst_esp, dataBits, fsave_esp_4, NULL); dataBits.resize(1);//fsave [esp+4] dataBits[0] = 0x9b; - fsave_esp_4->SetFallthrough(pushretaddress); - fsave_esp_4->SetDataBits(dataBits); - fsave_esp_4->SetComment(fsave_wait->getDisassembly()); + fsave_esp_4->setFallthrough(pushretaddress); + fsave_esp_4->setDataBits(dataBits); + fsave_esp_4->setComment(fsave_wait->getDisassembly()); addInstruction(fsave_wait, dataBits, fsave_esp_4, NULL); dataBits.resize(4); dataBits[0] = 0xdd; dataBits[1] = 0x74; dataBits[2] = 0x24; dataBits[3] = 0x04; - fsave_esp_4->SetFallthrough(pushretaddress); - fsave_esp_4->SetDataBits(dataBits); - fsave_esp_4->SetComment(fsave_esp_4->getDisassembly()); + fsave_esp_4->setFallthrough(pushretaddress); + fsave_esp_4->setDataBits(dataBits); + fsave_esp_4->setComment(fsave_esp_4->getDisassembly()); addInstruction(fsave_esp_4, dataBits, pushretaddress, NULL); virtual_offset_t AfterTheCheckerReturn = getAvailableAddress(); - nop->GetAddress()->SetVirtualOffset(AfterTheCheckerReturn); - nop->GetAddress()->SetFileID(BaseObj_t::NOT_IN_DATABASE); + nop->getAddress()->SetVirtualOffset(AfterTheCheckerReturn); + nop->getAddress()->SetFileID(BaseObj_t::NOT_IN_DATABASE); dataBits.resize(5);//push return_address dataBits[0] = 0x68; virtual_offset_t *tmp; tmp = (virtual_offset_t *) &dataBits[1]; *tmp = AfterTheCheckerReturn; - pushretaddress->SetDataBits(dataBits); - pushretaddress->SetComment(pushretaddress->getDisassembly()); - pushretaddress->SetFallthrough(nop); + pushretaddress->setDataBits(dataBits); + pushretaddress->setComment(pushretaddress->getDisassembly()); + pushretaddress->setFallthrough(nop); dataBits.resize(1);//nop dataBits[0] = 0x90; - nop->SetDataBits(dataBits); - nop->SetComment(nop->getDisassembly() + " -- with callback to floating number check") ; - nop->SetFallthrough(frstor_esp_4); - nop->SetIndirectBranchTargetAddress(nop->GetAddress()); + nop->setDataBits(dataBits); + nop->setComment(nop->getDisassembly() + " -- with callback to floating number check") ; + nop->setFallthrough(frstor_esp_4); + nop->SetIndirectBranchTargetAddress(nop->getAddress()); if(len==32) nop->SetCallback(string("FloatingRangeCheck32")); else @@ -1015,14 +1015,14 @@ void IntegerTransform32::addFistpTruncationCheck(Instruction_t *p_instruction, i dataBits[1] = 0x64; dataBits[2] = 0x24; dataBits[3] = 0x04; - frstor_esp_4->SetDataBits(dataBits); - frstor_esp_4->SetFallthrough(test_eax_0); - frstor_esp_4->SetComment(frstor_esp_4->getDisassembly()); + frstor_esp_4->setDataBits(dataBits); + frstor_esp_4->setFallthrough(test_eax_0); + frstor_esp_4->setComment(frstor_esp_4->getDisassembly()); dataBits.resize(2);//test eax, eax dataBits[0] = 0x85; dataBits[1] = 0xC0; - test_eax_0->SetDataBits(dataBits); - test_eax_0->SetFallthrough(jz_eax_0); + test_eax_0->setDataBits(dataBits); + test_eax_0->setFallthrough(jz_eax_0); addInstruction(test_eax_0, dataBits, jz_eax_0, NULL); addJz(jz_eax_0, test_eax_1, add_esp_0x70_label0); @@ -1037,9 +1037,9 @@ void IntegerTransform32::addFistpTruncationCheck(Instruction_t *p_instruction, i dataBits[3] = 0x00; dataBits[4] = 0x00; dataBits[5] = 0x00; - add_esp_0x70_label0->SetFallthrough(popf_label0); - add_esp_0x70_label0->SetDataBits(dataBits); - add_esp_0x70_label0->SetComment(add_esp_0x70_label0->getDisassembly()); + add_esp_0x70_label0->setFallthrough(popf_label0); + add_esp_0x70_label0->setDataBits(dataBits); + add_esp_0x70_label0->setComment(add_esp_0x70_label0->getDisassembly()); addInstruction(add_esp_0x70_label0, dataBits, popf_label0, NULL); addPopf(popf_label0, popa_label0); @@ -1048,7 +1048,7 @@ void IntegerTransform32::addFistpTruncationCheck(Instruction_t *p_instruction, i dataBits.resize(2); dataBits[0] = 0xeb; - jmpOriginalInst->SetComment("Jump to original Inst"); + jmpOriginalInst->setComment("Jump to original Inst"); addInstruction(jmpOriginalInst,dataBits,NULL, originalInstrumentInstr); //label 1: @@ -1059,9 +1059,9 @@ void IntegerTransform32::addFistpTruncationCheck(Instruction_t *p_instruction, i dataBits[2] = 0x00; dataBits[3] = 0x00; dataBits[4] = 0x00; - test_eax_1->SetDataBits(dataBits); - test_eax_1->SetComment(test_eax_1->getDisassembly()) ; - test_eax_1->SetFallthrough(jz_eax_1); + test_eax_1->setDataBits(dataBits); + test_eax_1->setComment(test_eax_1->getDisassembly()) ; + test_eax_1->setFallthrough(jz_eax_1); addInstruction(test_eax_1, dataBits, jz_eax_1, NULL); addJz(jz_eax_1, add_esp_0x70_label1, add_esp_0x70_label2); @@ -1073,9 +1073,9 @@ void IntegerTransform32::addFistpTruncationCheck(Instruction_t *p_instruction, i dataBits[3] = 0x00; dataBits[4] = 0x00; dataBits[5] = 0x00; - add_esp_0x70_label1->SetFallthrough(popf_label1); - add_esp_0x70_label1->SetDataBits(dataBits); - add_esp_0x70_label1->SetComment(add_esp_0x70_label1->getDisassembly()); + add_esp_0x70_label1->setFallthrough(popf_label1); + add_esp_0x70_label1->setDataBits(dataBits); + add_esp_0x70_label1->setComment(add_esp_0x70_label1->getDisassembly()); addInstruction(add_esp_0x70_label1, dataBits, popf_label1, NULL); addPopf(popf_label1, popa_label1); @@ -1088,20 +1088,20 @@ void IntegerTransform32::addFistpTruncationCheck(Instruction_t *p_instruction, i string instrStr= originalInstrumentInstr->getDisassembly(); string addExpr = instrStr.substr(instrStr.find(" ")+1); mov0x7FFFFFFF->Assemble("mov "+ addExpr + ", 0x7FFFFFFF"); - mov0x7FFFFFFF->SetComment(mov0x7FFFFFFF->getDisassembly()); + mov0x7FFFFFFF->setComment(mov0x7FFFFFFF->getDisassembly()); addInstruction(mov0x7FFFFFFF, mov0x7FFFFFFF->GetDataBits(), fstpST0, NULL); - popa_label1->SetComment("just before " + mov0x7FFFFFFF->getDisassembly()); + popa_label1->setComment("just before " + mov0x7FFFFFFF->getDisassembly()); dataBits.resize(2);//fstp st(0) dataBits[0] = 0xDD; dataBits[1] = 0xD8; - fstpST0->SetDataBits(dataBits); - fstpST0->SetFallthrough(jmpOriginalInstNext); + fstpST0->setDataBits(dataBits); + fstpST0->setFallthrough(jmpOriginalInstNext); addInstruction(fstpST0, dataBits, jmpOriginalInstNext, NULL); dataBits.resize(2); dataBits[0] = 0xeb; - addInstruction(jmpOriginalInstNext,dataBits,NULL, originalInstrumentInstr->GetFallthrough()); + addInstruction(jmpOriginalInstNext,dataBits,NULL, originalInstrumentInstr->getFallthrough()); } else{ Instruction_t* mov0x7FFF = allocateNewInstruction(fileID, func); @@ -1112,22 +1112,22 @@ void IntegerTransform32::addFistpTruncationCheck(Instruction_t *p_instruction, i string instrStr= originalInstrumentInstr->getDisassembly(); string addExpr = instrStr.substr(instrStr.find(" ")+1); mov0x7FFF->Assemble("mov "+ addExpr + ", 0x7FFF"); - mov0x7FFF->SetComment(mov0x7FFF->getDisassembly()); + mov0x7FFF->setComment(mov0x7FFF->getDisassembly()); - //mov0x7FFF->SetFallthrough(fstpST0); + //mov0x7FFF->setFallthrough(fstpST0); addInstruction(mov0x7FFF, mov0x7FFF->GetDataBits(), fstpST0, NULL); dataBits.resize(2);//fstp st(0) dataBits[0] = 0xDD; dataBits[1] = 0xD8; - fstpST0->SetDataBits(dataBits); - fstpST0->SetFallthrough(jmpOriginalInstNext); + fstpST0->setDataBits(dataBits); + fstpST0->setFallthrough(jmpOriginalInstNext); addInstruction(fstpST0, dataBits, jmpOriginalInstNext, NULL); dataBits.resize(2); dataBits[0] = 0xeb; - addInstruction(jmpOriginalInstNext,dataBits,NULL, originalInstrumentInstr->GetFallthrough()); + addInstruction(jmpOriginalInstNext,dataBits,NULL, originalInstrumentInstr->getFallthrough()); } dataBits.resize(6);//add esp,0x70 @@ -1137,9 +1137,9 @@ void IntegerTransform32::addFistpTruncationCheck(Instruction_t *p_instruction, i dataBits[3] = 0x00; dataBits[4] = 0x00; dataBits[5] = 0x00; - add_esp_0x70_label2->SetFallthrough(popf_label2); - add_esp_0x70_label2->SetDataBits(dataBits); - add_esp_0x70_label2->SetComment(add_esp_0x70_label2->getDisassembly()); + add_esp_0x70_label2->setFallthrough(popf_label2); + add_esp_0x70_label2->setDataBits(dataBits); + add_esp_0x70_label2->setComment(add_esp_0x70_label2->getDisassembly()); addInstruction(add_esp_0x70_label2, dataBits, popf_label2, NULL); addPopf(popf_label2, popa_label2); @@ -1152,8 +1152,8 @@ void IntegerTransform32::addFistpTruncationCheck(Instruction_t *p_instruction, i string instrStr= originalInstrumentInstr->getDisassembly(); string addExpr = instrStr.substr(instrStr.find(" ")+1); mov0x80000000->Assemble("mov "+ addExpr + ", 0x80000001"); - mov0x80000000->SetComment(mov0x80000000->getDisassembly()); - mov0x80000000->SetFallthrough(fstpST0); + mov0x80000000->setComment(mov0x80000000->getDisassembly()); + mov0x80000000->setFallthrough(fstpST0); addInstruction(mov0x80000000, mov0x80000000->GetDataBits(), fstpST0, NULL); dataBits.resize(2);//fstp st(0) @@ -1164,7 +1164,7 @@ void IntegerTransform32::addFistpTruncationCheck(Instruction_t *p_instruction, i dataBits.resize(2); dataBits[0] = 0xeb; - addInstruction(jmpOriginalInstNext,dataBits,NULL, originalInstrumentInstr->GetFallthrough()); + addInstruction(jmpOriginalInstNext,dataBits,NULL, originalInstrumentInstr->getFallthrough()); } else{ Instruction_t* mov0x8000 = allocateNewInstruction(fileID, func); @@ -1175,7 +1175,7 @@ void IntegerTransform32::addFistpTruncationCheck(Instruction_t *p_instruction, i string instrStr= originalInstrumentInstr->getDisassembly(); string addExpr = instrStr.substr(instrStr.find(" ")+1); mov0x8000->Assemble("mov "+ addExpr + ", 0x8001"); - mov0x8000->SetComment(mov0x8000->getDisassembly()); + mov0x8000->setComment(mov0x8000->getDisassembly()); addInstruction(mov0x8000, mov0x8000->GetDataBits(), fstpST0, NULL); @@ -1186,7 +1186,7 @@ void IntegerTransform32::addFistpTruncationCheck(Instruction_t *p_instruction, i addInstruction(fstpST0, dataBits, jmpOriginalInstNext, NULL); dataBits.resize(2); dataBits[0] = 0xeb; - addInstruction(jmpOriginalInstNext,dataBits,NULL, originalInstrumentInstr->GetFallthrough()); + addInstruction(jmpOriginalInstNext,dataBits,NULL, originalInstrumentInstr->getFallthrough()); } m_numFP++; @@ -1195,7 +1195,7 @@ void IntegerTransform32::addFistpTruncationCheck(Instruction_t *p_instruction, i void IntegerTransform32::addFistTruncationCheck(Instruction_t *p_instruction, int len){ if(len!=32 && len!=16) return; - db_id_t fileID = p_instruction->GetAddress()->GetFileID(); + DatabaseID_t fileID = p_instruction->getAddress()->getFileID(); Function_t* func = p_instruction->GetFunction(); string dataBits; @@ -1268,7 +1268,7 @@ void IntegerTransform32::addFistTruncationCheck(Instruction_t *p_instruction, in addPusha(pusha_i, pushf_i);//pusha Instruction_t* originalInstrumentInstr = carefullyInsertBefore(p_instruction, pusha_i); - pusha_i->SetFallthrough(pushf_i); + pusha_i->setFallthrough(pushf_i); addPushf(pushf_i, sub_esp_0x70);//pushf @@ -1279,55 +1279,55 @@ void IntegerTransform32::addFistTruncationCheck(Instruction_t *p_instruction, in dataBits[3] = 0x00; dataBits[4] = 0x00; dataBits[5] = 0x00; - sub_esp_0x70->SetFallthrough(fst_esp); - sub_esp_0x70->SetDataBits(dataBits); - sub_esp_0x70->SetComment(sub_esp_0x70->getDisassembly()); + sub_esp_0x70->setFallthrough(fst_esp); + sub_esp_0x70->setDataBits(dataBits); + sub_esp_0x70->setComment(sub_esp_0x70->getDisassembly()); addInstruction(sub_esp_0x70, dataBits, fst_esp, NULL); dataBits.resize(3);//fst [esp] dataBits[0] = 0xd9; dataBits[1] = 0x14; dataBits[2] = 0x24; - fst_esp->SetFallthrough(fsave_esp_4); - fst_esp->SetDataBits(dataBits); - fst_esp->SetComment(fst_esp->getDisassembly()); + fst_esp->setFallthrough(fsave_esp_4); + fst_esp->setDataBits(dataBits); + fst_esp->setComment(fst_esp->getDisassembly()); addInstruction(fst_esp, dataBits, fsave_esp_4, NULL); dataBits.resize(1);//fsave [esp+4] dataBits[0] = 0x9b; - fsave_esp_4->SetFallthrough(pushretaddress); - fsave_esp_4->SetDataBits(dataBits); - fsave_esp_4->SetComment(fsave_wait->getDisassembly()); + fsave_esp_4->setFallthrough(pushretaddress); + fsave_esp_4->setDataBits(dataBits); + fsave_esp_4->setComment(fsave_wait->getDisassembly()); addInstruction(fsave_wait, dataBits, fsave_esp_4, NULL); dataBits.resize(4); dataBits[0] = 0xdd; dataBits[1] = 0x74; dataBits[2] = 0x24; dataBits[3] = 0x04; - fsave_esp_4->SetFallthrough(pushretaddress); - fsave_esp_4->SetDataBits(dataBits); - fsave_esp_4->SetComment(fsave_esp_4->getDisassembly()); + fsave_esp_4->setFallthrough(pushretaddress); + fsave_esp_4->setDataBits(dataBits); + fsave_esp_4->setComment(fsave_esp_4->getDisassembly()); addInstruction(fsave_esp_4, dataBits, pushretaddress, NULL); virtual_offset_t AfterTheCheckerReturn = getAvailableAddress(); - nop->GetAddress()->SetVirtualOffset(AfterTheCheckerReturn); - nop->GetAddress()->SetFileID(BaseObj_t::NOT_IN_DATABASE); + nop->getAddress()->SetVirtualOffset(AfterTheCheckerReturn); + nop->getAddress()->SetFileID(BaseObj_t::NOT_IN_DATABASE); dataBits.resize(5);//push return_address dataBits[0] = 0x68; virtual_offset_t *tmp; tmp = (virtual_offset_t *) &dataBits[1]; *tmp = AfterTheCheckerReturn; - pushretaddress->SetDataBits(dataBits); - pushretaddress->SetComment(pushretaddress->getDisassembly()); - pushretaddress->SetFallthrough(nop); + pushretaddress->setDataBits(dataBits); + pushretaddress->setComment(pushretaddress->getDisassembly()); + pushretaddress->setFallthrough(nop); dataBits.resize(1);//nop dataBits[0] = 0x90; - nop->SetDataBits(dataBits); - nop->SetComment(nop->getDisassembly() + " -- with callback to floating number check") ; - nop->SetFallthrough(frstor_esp_4); - nop->SetIndirectBranchTargetAddress(nop->GetAddress()); + nop->setDataBits(dataBits); + nop->setComment(nop->getDisassembly() + " -- with callback to floating number check") ; + nop->setFallthrough(frstor_esp_4); + nop->SetIndirectBranchTargetAddress(nop->getAddress()); if(len==32) nop->SetCallback(string("FloatingRangeCheck32")); else @@ -1338,14 +1338,14 @@ void IntegerTransform32::addFistTruncationCheck(Instruction_t *p_instruction, in dataBits[1] = 0x64; dataBits[2] = 0x24; dataBits[3] = 0x04; - frstor_esp_4->SetDataBits(dataBits); - frstor_esp_4->SetFallthrough(test_eax_0); - frstor_esp_4->SetComment(frstor_esp_4->getDisassembly()); + frstor_esp_4->setDataBits(dataBits); + frstor_esp_4->setFallthrough(test_eax_0); + frstor_esp_4->setComment(frstor_esp_4->getDisassembly()); dataBits.resize(2);//test eax, eax dataBits[0] = 0x85; dataBits[1] = 0xC0; - test_eax_0->SetDataBits(dataBits); - test_eax_0->SetFallthrough(jz_eax_0); + test_eax_0->setDataBits(dataBits); + test_eax_0->setFallthrough(jz_eax_0); addInstruction(test_eax_0, dataBits, jz_eax_0, NULL); addJz(jz_eax_0, test_eax_1, add_esp_0x70_label0); @@ -1360,9 +1360,9 @@ void IntegerTransform32::addFistTruncationCheck(Instruction_t *p_instruction, in dataBits[3] = 0x00; dataBits[4] = 0x00; dataBits[5] = 0x00; - add_esp_0x70_label0->SetFallthrough(popf_label0); - add_esp_0x70_label0->SetDataBits(dataBits); - add_esp_0x70_label0->SetComment(add_esp_0x70_label0->getDisassembly()); + add_esp_0x70_label0->setFallthrough(popf_label0); + add_esp_0x70_label0->setDataBits(dataBits); + add_esp_0x70_label0->setComment(add_esp_0x70_label0->getDisassembly()); addInstruction(add_esp_0x70_label0, dataBits, popf_label0, NULL); addPopf(popf_label0, popa_label0); @@ -1371,7 +1371,7 @@ void IntegerTransform32::addFistTruncationCheck(Instruction_t *p_instruction, in dataBits.resize(2); dataBits[0] = 0xeb; - jmpOriginalInst->SetComment("Jump to original Inst"); + jmpOriginalInst->setComment("Jump to original Inst"); addInstruction(jmpOriginalInst,dataBits,NULL, originalInstrumentInstr); //label 1: @@ -1382,9 +1382,9 @@ void IntegerTransform32::addFistTruncationCheck(Instruction_t *p_instruction, in dataBits[2] = 0x00; dataBits[3] = 0x00; dataBits[4] = 0x00; - test_eax_1->SetDataBits(dataBits); - test_eax_1->SetComment(test_eax_1->getDisassembly()) ; - test_eax_1->SetFallthrough(jz_eax_1); + test_eax_1->setDataBits(dataBits); + test_eax_1->setComment(test_eax_1->getDisassembly()) ; + test_eax_1->setFallthrough(jz_eax_1); addInstruction(test_eax_1, dataBits, jz_eax_1, NULL); addJz(jz_eax_1, add_esp_0x70_label1, add_esp_0x70_label2); @@ -1396,9 +1396,9 @@ void IntegerTransform32::addFistTruncationCheck(Instruction_t *p_instruction, in dataBits[3] = 0x00; dataBits[4] = 0x00; dataBits[5] = 0x00; - add_esp_0x70_label1->SetFallthrough(popf_label1); - add_esp_0x70_label1->SetDataBits(dataBits); - add_esp_0x70_label1->SetComment(add_esp_0x70_label1->getDisassembly()); + add_esp_0x70_label1->setFallthrough(popf_label1); + add_esp_0x70_label1->setDataBits(dataBits); + add_esp_0x70_label1->setComment(add_esp_0x70_label1->getDisassembly()); addInstruction(add_esp_0x70_label1, dataBits, popf_label1, NULL); addPopf(popf_label1, popa_label1); @@ -1411,20 +1411,20 @@ void IntegerTransform32::addFistTruncationCheck(Instruction_t *p_instruction, in string instrStr= originalInstrumentInstr->getDisassembly(); string addExpr = instrStr.substr(instrStr.find(" ")+1); mov0x7FFFFFFF->Assemble("mov "+ addExpr + ", 0x7FFFFFFF"); - mov0x7FFFFFFF->SetComment(mov0x7FFFFFFF->getDisassembly()); + mov0x7FFFFFFF->setComment(mov0x7FFFFFFF->getDisassembly()); addInstruction(mov0x7FFFFFFF, mov0x7FFFFFFF->GetDataBits(), jmpOriginalInstNext, NULL); - popa_label1->SetComment("just before " + mov0x7FFFFFFF->getDisassembly()); + popa_label1->setComment("just before " + mov0x7FFFFFFF->getDisassembly()); //dataBits.resize(2);//fstp st(0) //dataBits[0] = 0xDD; //dataBits[1] = 0xD8; - //fstpST0->SetDataBits(dataBits); - //fstpST0->SetFallthrough(jmpOriginalInstNext); + //fstpST0->setDataBits(dataBits); + //fstpST0->setFallthrough(jmpOriginalInstNext); //addInstruction(fstpST0, dataBits, jmpOriginalInstNext, NULL); dataBits.resize(2); dataBits[0] = 0xeb; - addInstruction(jmpOriginalInstNext,dataBits,NULL, originalInstrumentInstr->GetFallthrough()); + addInstruction(jmpOriginalInstNext,dataBits,NULL, originalInstrumentInstr->getFallthrough()); } else{ Instruction_t* mov0x7FFF = allocateNewInstruction(fileID, func); @@ -1435,22 +1435,22 @@ void IntegerTransform32::addFistTruncationCheck(Instruction_t *p_instruction, in string instrStr= originalInstrumentInstr->getDisassembly(); string addExpr = instrStr.substr(instrStr.find(" ")+1); mov0x7FFF->Assemble("mov "+ addExpr + ", 0x7FFF"); - mov0x7FFF->SetComment(mov0x7FFF->getDisassembly()); + mov0x7FFF->setComment(mov0x7FFF->getDisassembly()); - //mov0x7FFF->SetFallthrough(fstpST0); + //mov0x7FFF->setFallthrough(fstpST0); addInstruction(mov0x7FFF, mov0x7FFF->GetDataBits(), jmpOriginalInstNext, NULL); //dataBits.resize(2);//fstp st(0) //dataBits[0] = 0xDD; //dataBits[1] = 0xD8; - //fstpST0->SetDataBits(dataBits); - //fstpST0->SetFallthrough(jmpOriginalInstNext); + //fstpST0->setDataBits(dataBits); + //fstpST0->setFallthrough(jmpOriginalInstNext); //addInstruction(fstpST0, dataBits, jmpOriginalInstNext, NULL); dataBits.resize(2); dataBits[0] = 0xeb; - addInstruction(jmpOriginalInstNext,dataBits,NULL, originalInstrumentInstr->GetFallthrough()); + addInstruction(jmpOriginalInstNext,dataBits,NULL, originalInstrumentInstr->getFallthrough()); } dataBits.resize(6);//add esp,0x70 @@ -1460,9 +1460,9 @@ void IntegerTransform32::addFistTruncationCheck(Instruction_t *p_instruction, in dataBits[3] = 0x00; dataBits[4] = 0x00; dataBits[5] = 0x00; - add_esp_0x70_label2->SetFallthrough(popf_label2); - add_esp_0x70_label2->SetDataBits(dataBits); - add_esp_0x70_label2->SetComment(add_esp_0x70_label2->getDisassembly()); + add_esp_0x70_label2->setFallthrough(popf_label2); + add_esp_0x70_label2->setDataBits(dataBits); + add_esp_0x70_label2->setComment(add_esp_0x70_label2->getDisassembly()); addInstruction(add_esp_0x70_label2, dataBits, popf_label2, NULL); addPopf(popf_label2, popa_label2); @@ -1475,8 +1475,8 @@ void IntegerTransform32::addFistTruncationCheck(Instruction_t *p_instruction, in string instrStr= originalInstrumentInstr->getDisassembly(); string addExpr = instrStr.substr(instrStr.find(" ")+1); mov0x80000000->Assemble("mov "+ addExpr + ", 0x80000001"); - mov0x80000000->SetComment(mov0x80000000->getDisassembly()); - //mov0x80000000->SetFallthrough(fstpST0); + mov0x80000000->setComment(mov0x80000000->getDisassembly()); + //mov0x80000000->setFallthrough(fstpST0); addInstruction(mov0x80000000, mov0x80000000->GetDataBits(), jmpOriginalInstNext, NULL); //dataBits.resize(2);//fstp st(0) @@ -1487,7 +1487,7 @@ void IntegerTransform32::addFistTruncationCheck(Instruction_t *p_instruction, in dataBits.resize(2); dataBits[0] = 0xeb; - addInstruction(jmpOriginalInstNext,dataBits,NULL, originalInstrumentInstr->GetFallthrough()); + addInstruction(jmpOriginalInstNext,dataBits,NULL, originalInstrumentInstr->getFallthrough()); } else{ Instruction_t* mov0x8000 = allocateNewInstruction(fileID, func); @@ -1498,7 +1498,7 @@ void IntegerTransform32::addFistTruncationCheck(Instruction_t *p_instruction, in string instrStr= originalInstrumentInstr->getDisassembly(); string addExpr = instrStr.substr(instrStr.find(" ")+1); mov0x8000->Assemble("mov "+ addExpr + ", 0x8001"); - mov0x8000->SetComment(mov0x8000->getDisassembly()); + mov0x8000->setComment(mov0x8000->getDisassembly()); addInstruction(mov0x8000, mov0x8000->GetDataBits(), jmpOriginalInstNext, NULL); @@ -1509,7 +1509,7 @@ void IntegerTransform32::addFistTruncationCheck(Instruction_t *p_instruction, in //addInstruction(fstpST0, dataBits, jmpOriginalInstNext, NULL); dataBits.resize(2); dataBits[0] = 0xeb; - addInstruction(jmpOriginalInstNext,dataBits,NULL, originalInstrumentInstr->GetFallthrough()); + addInstruction(jmpOriginalInstNext,dataBits,NULL, originalInstrumentInstr->getFallthrough()); } m_numFP++; @@ -1542,16 +1542,16 @@ void IntegerTransform32::handleInfiniteLoop(Instruction_t *p_instruction, const logMessage(__func__, "handling infinite loop"); - db_id_t fileID = p_instruction->GetAddress()->GetFileID(); + DatabaseID_t fileID = p_instruction->getAddress()->getFileID(); Function_t* func = p_instruction->GetFunction(); - AddressID_t *originalAddress = p_instruction->GetAddress(); + AddressID_t *originalAddress = p_instruction->getAddress(); Instruction_t* nop_i = allocateNewInstruction(fileID, func); addNop(nop_i, p_instruction); Instruction_t* originalInstrumentInstr = carefullyInsertBefore(p_instruction, nop_i); - addCallbackHandler(string(INFINITE_LOOP_DETECTOR), originalInstrumentInstr, nop_i, nop_i->GetFallthrough(), p_policy, originalAddress); + addCallbackHandler(string(INFINITE_LOOP_DETECTOR), originalInstrumentInstr, nop_i, nop_i->getFallthrough(), p_policy, originalAddress); } // @@ -1573,7 +1573,7 @@ void IntegerTransform32::handleInfiniteLoop(Instruction_t *p_instruction, const // p_addressOriginalInstruction is set when we call method from lea instrumentation void IntegerTransform32::addOverflowCheck(Instruction_t *p_instruction, const MEDS_InstructionCheckAnnotation& p_annotation, int p_policy) { - assert(getFileIR() && p_instruction && p_instruction->GetFallthrough()); + assert(getFileIR() && p_instruction && p_instruction->getFallthrough()); RegisterName targetReg = getTargetRegister(p_instruction); if (targetReg == rn_UNKNOWN) @@ -1586,7 +1586,7 @@ void IntegerTransform32::addOverflowCheck(Instruction_t *p_instruction, const ME return; } -cerr << __func__ << ": instr: " << p_instruction->getDisassembly() << " address: " << std::hex << p_instruction->GetAddress() << " annotation: " << p_annotation.toString() << " policy: " << p_policy << endl; +cerr << __func__ << ": instr: " << p_instruction->getDisassembly() << " address: " << std::hex << p_instruction->getAddress() << " annotation: " << p_annotation.toString() << " policy: " << p_policy << endl; string detector(INTEGER_OVERFLOW_DETECTOR); string dataBits; @@ -1595,14 +1595,14 @@ cerr << __func__ << ": instr: " << p_instruction->getDisassembly() << " address // update to cleaner style Function_t* origFunction = p_instruction->GetFunction(); AddressID_t *jncond_a =new AddressID_t; - jncond_a->SetFileID(p_instruction->GetAddress()->GetFileID()); + jncond_a->SetFileID(p_instruction->getAddress()->getFileID()); Instruction_t* jncond_i = new Instruction_t; jncond_i->SetFunction(origFunction); jncond_i->SetAddress(jncond_a); // set fallthrough for the original instruction - Instruction_t* nextOrig_i = p_instruction->GetFallthrough(); - p_instruction->SetFallthrough(jncond_i); + Instruction_t* nextOrig_i = p_instruction->getFallthrough(); + p_instruction->setFallthrough(jncond_i); // jncond dataBits.resize(2); @@ -1645,23 +1645,23 @@ cerr << __func__ << ": instr: " << p_instruction->getDisassembly() << " address cerr << "integertransform: SIGNED OVERFLOW: " << detector << endl; } - jncond_i->SetDataBits(dataBits); - jncond_i->SetComment(jncond_i->getDisassembly()); - jncond_i->SetTarget(nextOrig_i); + jncond_i->setDataBits(dataBits); + jncond_i->setComment(jncond_i->getDisassembly()); + jncond_i->setTarget(nextOrig_i); - p_instruction->SetFallthrough(jncond_i); + p_instruction->setFallthrough(jncond_i); if (p_policy == POLICY_CONTINUE_SATURATING_ARITHMETIC) { // implement saturating arithmetic, e.g.: // mov <reg>, value - Instruction_t* saturate_i = allocateNewInstruction(p_instruction->GetAddress()->GetFileID(), p_instruction->GetFunction()); + Instruction_t* saturate_i = allocateNewInstruction(p_instruction->getAddress()->getFileID(), p_instruction->GetFunction()); if (p_annotation.flowsIntoCriticalSink() && p_annotation.getBitWidth() == 32) { logMessage(__func__, "OVERFLOW UNSIGNED 32: CRITICAL SINK: saturate by masking"); - db_id_t fileID = p_instruction->GetAddress()->GetFileID(); + DatabaseID_t fileID = p_instruction->getAddress()->getFileID(); Function_t* func = p_instruction->GetFunction(); Instruction_t* pushf_i = allocateNewInstruction(fileID, func); Instruction_t* popf_i = allocateNewInstruction(fileID, func); @@ -1681,7 +1681,7 @@ cerr << __func__ << ": instr: " << p_instruction->getDisassembly() << " address addCallbackHandler(detector, p_instruction, jncond_i, nextOrig_i, p_policy); } - getFileIR()->GetAddresses().insert(jncond_a); + getFileIR()->getAddresses().insert(jncond_a); getFileIR()->GetInstructions().insert(jncond_i); if (p_annotation.isUnderflow()) @@ -1712,12 +1712,12 @@ void IntegerTransform32::addUnderflowCheck(Instruction_t *p_instruction, const M RegisterName targetReg = getTargetRegister(p_instruction); if (targetReg == rn_UNKNOWN) { - cerr << "IntegerTransform32::addUnderflowCheck(): instr: " << p_instruction->getDisassembly() << " address: " << p_instruction->GetAddress() << " annotation: " << p_annotation.toString() << "-- SKIP b/c no target registers" << endl; + cerr << "IntegerTransform32::addUnderflowCheck(): instr: " << p_instruction->getDisassembly() << " address: " << p_instruction->getAddress() << " annotation: " << p_annotation.toString() << "-- SKIP b/c no target registers" << endl; m_numUnderflowsSkipped++; return; } - cerr << "IntegerTransform32::addUnderflowCheck(): instr: " << p_instruction->getDisassembly() << " address: " << p_instruction->GetAddress() << " annotation: " << p_annotation.toString() << endl; + cerr << "IntegerTransform32::addUnderflowCheck(): instr: " << p_instruction->getDisassembly() << " address: " << p_instruction->getAddress() << " annotation: " << p_annotation.toString() << endl; string detector(INTEGER_OVERFLOW_DETECTOR); string dataBits; @@ -1726,14 +1726,14 @@ void IntegerTransform32::addUnderflowCheck(Instruction_t *p_instruction, const M // update to cleaner style Function_t* origFunction = p_instruction->GetFunction(); AddressID_t *jncond_a =new AddressID_t; - jncond_a->SetFileID(p_instruction->GetAddress()->GetFileID()); + jncond_a->SetFileID(p_instruction->getAddress()->getFileID()); Instruction_t* jncond_i = new Instruction_t; jncond_i->SetFunction(origFunction); jncond_i->SetAddress(jncond_a); // set fallthrough for the original instruction - Instruction_t* nextOrig_i = p_instruction->GetFallthrough(); - p_instruction->SetFallthrough(jncond_i); + Instruction_t* nextOrig_i = p_instruction->getFallthrough(); + p_instruction->setFallthrough(jncond_i); // jncond dataBits.resize(2); @@ -1778,17 +1778,17 @@ void IntegerTransform32::addUnderflowCheck(Instruction_t *p_instruction, const M cerr << "integertransform: UNDERFLOW UNKONWN: assume signed for now: " << detector << endl; } - jncond_i->SetDataBits(dataBits); - jncond_i->SetComment(jncond_i->getDisassembly()); - jncond_i->SetTarget(nextOrig_i); + jncond_i->setDataBits(dataBits); + jncond_i->setComment(jncond_i->getDisassembly()); + jncond_i->setTarget(nextOrig_i); - p_instruction->SetFallthrough(jncond_i); + p_instruction->setFallthrough(jncond_i); if (p_policy == POLICY_CONTINUE_SATURATING_ARITHMETIC) { // implement saturating arithmetic, e.g.: // mov <reg>, value - Instruction_t* saturate_i = allocateNewInstruction(p_instruction->GetAddress()->GetFileID(), p_instruction->GetFunction()); + Instruction_t* saturate_i = allocateNewInstruction(p_instruction->getAddress()->getFileID(), p_instruction->GetFunction()); addCallbackHandler(detector, p_instruction, jncond_i, saturate_i, p_policy); addMinSaturation(saturate_i, targetReg, p_annotation, nextOrig_i); @@ -1798,7 +1798,7 @@ void IntegerTransform32::addUnderflowCheck(Instruction_t *p_instruction, const M addCallbackHandler(detector, p_instruction, jncond_i, nextOrig_i, p_policy); } - getFileIR()->GetAddresses().insert(jncond_a); + getFileIR()->getAddresses().insert(jncond_a); getFileIR()->GetInstructions().insert(jncond_i); m_numUnderflows++; @@ -1822,7 +1822,7 @@ void IntegerTransform32::addTruncationCheck(Instruction_t *p_instruction, const assert(getFileIR() && p_instruction); assert(p_annotation.getTruncationFromWidth() == 32 && p_annotation.getTruncationToWidth() == 8 || p_annotation.getTruncationToWidth() == 16); - cerr << __func__ << ": instr: " << p_instruction->getDisassembly() << " address: " << p_instruction->GetAddress() << " annotation: " << p_annotation.toString() << " policy: " << p_policy << endl; + cerr << __func__ << ": instr: " << p_instruction->getDisassembly() << " address: " << p_instruction->getAddress() << " annotation: " << p_annotation.toString() << " policy: " << p_policy << endl; string detector; @@ -1866,9 +1866,9 @@ void IntegerTransform32::addTruncationCheck(Instruction_t *p_instruction, const // mov [ebp+var_4], al ; <originalInstruction> // - db_id_t fileID = p_instruction->GetAddress()->GetFileID(); + DatabaseID_t fileID = p_instruction->getAddress()->getFileID(); Function_t* func = p_instruction->GetFunction(); - AddressID_t *saveAddress = p_instruction->GetAddress(); + AddressID_t *saveAddress = p_instruction->getAddress(); Instruction_t* pushf_i = allocateNewInstruction(fileID, func); Instruction_t* test_i = allocateNewInstruction(fileID, func); @@ -1883,9 +1883,9 @@ void IntegerTransform32::addTruncationCheck(Instruction_t *p_instruction, const addPushf(pushf_i, test_i); Instruction_t* originalInstrumentInstr = carefullyInsertBefore(p_instruction, pushf_i); - pushf_i->SetFallthrough(test_i); - pushf_i->SetComment("-- in truncation"); - originalInstrumentInstr->SetComment("-- in truncation (was original)"); + pushf_i->setFallthrough(test_i); + pushf_i->setComment("-- in truncation"); + originalInstrumentInstr->setComment("-- in truncation (was original)"); unsigned mask = 0; unsigned mask2 = 0; @@ -1925,12 +1925,12 @@ void IntegerTransform32::addTruncationCheck(Instruction_t *p_instruction, const if (p_policy == POLICY_CONTINUE_SATURATING_ARITHMETIC) { addNop(nop_i, saturate_i); - nop_i->SetComment("UNSIGNED TRUNC: fallthrough: saturating arithmetic instruction"); + nop_i->setComment("UNSIGNED TRUNC: fallthrough: saturating arithmetic instruction"); addCallbackHandler(detector, originalInstrumentInstr, nop_i, saturate_i, p_policy, saveAddress); } else { addNop(nop_i, popf_i); - nop_i->SetComment(string("UNSIGNED TRUNC: fallthrough: popf")); + nop_i->setComment(string("UNSIGNED TRUNC: fallthrough: popf")); addCallbackHandler(detector, originalInstrumentInstr, nop_i, popf_i, p_policy, saveAddress); } } @@ -1968,19 +1968,19 @@ void IntegerTransform32::addTruncationCheck(Instruction_t *p_instruction, const Instruction_t* s_jae_i = allocateNewInstruction(fileID, func); addJz(jz_i, s_cmp_i, popf_i); // target = popf_i, fall-through = s_cmp_i - jz_i->SetComment(string("jz - SIGNED or UNKNOWNSIGN TRUNC")); + jz_i->setComment(string("jz - SIGNED or UNKNOWNSIGN TRUNC")); addCmpRegisterMask(s_cmp_i, p_annotation.getRegister(), mask2, s_jae_i); addJae(s_jae_i, nop_i, popf_i); // target = popf_i, fall-through = nop_i - s_jae_i->SetComment(string("jae - SIGNED or UNKNOWNSIGN TRUNC")); + s_jae_i->setComment(string("jae - SIGNED or UNKNOWNSIGN TRUNC")); if (p_policy == POLICY_CONTINUE_SATURATING_ARITHMETIC) { addNop(nop_i, saturate_i); - nop_i->SetComment("SIGNED or UNKNOWNSIGN TRUNC: fallthrough: saturating arithmetic instruction"); + nop_i->setComment("SIGNED or UNKNOWNSIGN TRUNC: fallthrough: saturating arithmetic instruction"); addCallbackHandler(detector, originalInstrumentInstr, nop_i, saturate_i, p_policy, saveAddress); } else { addNop(nop_i, popf_i); - nop_i->SetComment(string("SIGNED or UNKNOWNSIGN TRUNC: fallthrough: popf")); + nop_i->setComment(string("SIGNED or UNKNOWNSIGN TRUNC: fallthrough: popf")); addCallbackHandler(detector, originalInstrumentInstr, nop_i, popf_i, p_policy, saveAddress); } } // end of SIGNED and UNKNOWNSIGN case @@ -1994,7 +1994,7 @@ void IntegerTransform32::addSaturation(Instruction_t *p_instruction, RegisterNam { assert(getFileIR() && p_instruction); - p_instruction->SetFallthrough(p_fallthrough); + p_instruction->setFallthrough(p_fallthrough); addMovRegisterUnsignedConstant(p_instruction, p_reg, p_value, p_fallthrough); } @@ -2003,7 +2003,7 @@ void IntegerTransform32::addZeroSaturation(Instruction_t *p_instruction, Registe { assert(getFileIR() && p_instruction); - p_instruction->SetFallthrough(p_fallthrough); + p_instruction->setFallthrough(p_fallthrough); addMovRegisterUnsignedConstant(p_instruction, p_reg, 0, p_fallthrough); } @@ -2018,7 +2018,7 @@ void IntegerTransform32::addZeroSaturation(Instruction_t *p_instruction, Registe // void IntegerTransform32::addOverflowCheckUnknownSign(Instruction_t *p_instruction, const MEDS_InstructionCheckAnnotation& p_annotation, int p_policy) { - assert(getFileIR() && p_instruction && p_instruction->GetFallthrough()); + assert(getFileIR() && p_instruction && p_instruction->getFallthrough()); RegisterName targetReg = getTargetRegister(p_instruction); if (targetReg == rn_UNKNOWN) @@ -2028,7 +2028,7 @@ void IntegerTransform32::addOverflowCheckUnknownSign(Instruction_t *p_instructio return; } -cerr << __func__ << ": instr: " << p_instruction->getDisassembly() << " address: " << std::hex << p_instruction->GetAddress() << " annotation: " << p_annotation.toString() << " policy: " << p_policy << endl; +cerr << __func__ << ": instr: " << p_instruction->getDisassembly() << " address: " << std::hex << p_instruction->getAddress() << " annotation: " << p_annotation.toString() << " policy: " << p_policy << endl; // set detector/handler string detector(OVERFLOW_UNKNOWN_SIGN_DETECTOR); @@ -2043,26 +2043,26 @@ cerr << __func__ << ": instr: " << p_instruction->getDisassembly() << " address: } // for now assume we're dealing with add/sub 32 bit - db_id_t fileID = p_instruction->GetAddress()->GetFileID(); + DatabaseID_t fileID = p_instruction->getAddress()->getFileID(); Function_t* func = p_instruction->GetFunction(); - Instruction_t* jno_i = allocateNewInstruction(p_instruction->GetAddress()->GetFileID(), p_instruction->GetFunction()); - Instruction_t* jnc_i = allocateNewInstruction(p_instruction->GetAddress()->GetFileID(), p_instruction->GetFunction()); - Instruction_t* nop_i = allocateNewInstruction(p_instruction->GetAddress()->GetFileID(), p_instruction->GetFunction()); + Instruction_t* jno_i = allocateNewInstruction(p_instruction->getAddress()->getFileID(), p_instruction->GetFunction()); + Instruction_t* jnc_i = allocateNewInstruction(p_instruction->getAddress()->getFileID(), p_instruction->GetFunction()); + Instruction_t* nop_i = allocateNewInstruction(p_instruction->getAddress()->getFileID(), p_instruction->GetFunction()); // save fallthrough from original instruction - Instruction_t* nextOrig_i = p_instruction->GetFallthrough(); + Instruction_t* nextOrig_i = p_instruction->getFallthrough(); // instrument for both jno and jnc // redundant for imul, but that's ok, optimize later - p_instruction->SetFallthrough(jno_i); + p_instruction->setFallthrough(jno_i); addJno(jno_i, jnc_i, nextOrig_i); addJnc(jnc_i, nop_i, nextOrig_i); addNop(nop_i, nextOrig_i); if (p_policy == POLICY_CONTINUE_SATURATING_ARITHMETIC) { - Instruction_t* saturate_i = allocateNewInstruction(p_instruction->GetAddress()->GetFileID(), p_instruction->GetFunction()); + Instruction_t* saturate_i = allocateNewInstruction(p_instruction->getAddress()->getFileID(), p_instruction->GetFunction()); addCallbackHandler(detector, p_instruction, nop_i, saturate_i, p_policy); addMaxSaturation(saturate_i, targetReg, p_annotation, nextOrig_i); } @@ -2094,7 +2094,7 @@ cerr << __func__ << ": instr: " << p_instruction->getDisassembly() << " address: // p_addressOriginalInstruction is set when we call method from lea instrumentation void IntegerTransform32::addOverflowCheckForLea(Instruction_t *p_instruction, const MEDS_InstructionCheckAnnotation& p_annotation, int p_policy, AddressID_t *p_addressOriginalInstruction) { - assert(getFileIR() && p_instruction && p_instruction->GetFallthrough()); + assert(getFileIR() && p_instruction && p_instruction->getFallthrough()); cerr << __func__ << ": comment: " << p_instruction->GetComment() << " annotation: " << p_annotation.toString() << " policy: " << p_policy << endl; @@ -2102,11 +2102,11 @@ cerr << __func__ << ": comment: " << p_instruction->GetComment() << " annotation string detector(INTEGER_OVERFLOW_DETECTOR); // this will be either jno or jnc - Instruction_t* jncond_i = allocateNewInstruction(p_instruction->GetAddress()->GetFileID(), p_instruction->GetFunction()); + Instruction_t* jncond_i = allocateNewInstruction(p_instruction->getAddress()->getFileID(), p_instruction->GetFunction()); // set fallthrough for the original instruction - Instruction_t* nextOrig_i = p_instruction->GetFallthrough(); - p_instruction->SetFallthrough(jncond_i); + Instruction_t* nextOrig_i = p_instruction->getFallthrough(); + p_instruction->setFallthrough(jncond_i); // jncond int isMultiply = isMultiplyInstruction(p_instruction); @@ -2152,7 +2152,7 @@ cerr << __func__ << ": comment: " << p_instruction->GetComment() << " annotation else if (p_annotation.getBitWidth() == 8) detector = string(ADDSUB_OVERFLOW_DETECTOR_UNKNOWN_8); - jnc_i = allocateNewInstruction(p_instruction->GetAddress()->GetFileID(), p_instruction->GetFunction()); + jnc_i = allocateNewInstruction(p_instruction->getAddress()->getFileID(), p_instruction->GetFunction()); addJno(jncond_i, jnc_i, nextOrig_i); addJnc(jnc_i, NULL, nextOrig_i); // fallthrough will be set by the callback handler diff --git a/libtransform/include/integertransform32.hpp b/libIRDB-transform/include-unused-delete-later/integertransform32.hpp similarity index 100% rename from libtransform/include/integertransform32.hpp rename to libIRDB-transform/include-unused-delete-later/integertransform32.hpp diff --git a/libtransform/src/integertransform64.cpp b/libIRDB-transform/include-unused-delete-later/integertransform64.cpp similarity index 89% rename from libtransform/src/integertransform64.cpp rename to libIRDB-transform/include-unused-delete-later/integertransform64.cpp index 6cf561f286144a859c742f3b56a681695e345196..06315471f9fce669110366d7a760a1de0fb4d58c 100644 --- a/libtransform/src/integertransform64.cpp +++ b/libIRDB-transform/include-unused-delete-later/integertransform64.cpp @@ -102,7 +102,7 @@ int IntegerTransform64::execute() { Instruction_t* insn=*it; - if (insn && insn->GetAddress()) + if (insn && insn->getAddress()) { int policy = POLICY_DEFAULT; @@ -119,7 +119,7 @@ int IntegerTransform64::execute() policy = POLICY_CONTINUE; } - virtual_offset_t irdb_vo = insn->GetAddress()->GetVirtualOffset(); + virtual_offset_t irdb_vo = insn->getAddress()->GetVirtualOffset(); if (irdb_vo == 0) continue; VirtualOffset vo(irdb_vo); @@ -154,7 +154,7 @@ int IntegerTransform64::execute() continue; } - if (!insn->GetFallthrough()) + if (!insn->getFallthrough()) { logMessage(__func__, "Warning: no fall through for instruction -- skipping"); continue; @@ -314,7 +314,7 @@ bool IntegerTransform64::addOverflowUnderflowCheck(Instruction_t *p_instruction, { char tmpbuf[1024]; - assert(getFileIR() && p_instruction && p_instruction->GetFallthrough()); + assert(getFileIR() && p_instruction && p_instruction->getFallthrough()); RegisterName targetReg = getTargetRegister(p_instruction); if (targetReg == rn_UNKNOWN) { @@ -332,18 +332,18 @@ bool IntegerTransform64::addOverflowUnderflowCheck(Instruction_t *p_instruction, return false; } - Instruction_t* jncond_i = allocateNewInstruction(p_instruction->GetAddress()->GetFileID(), p_instruction->GetFunction()); - Instruction_t* nop_i = allocateNewInstruction(p_instruction->GetAddress()->GetFileID(), p_instruction->GetFunction()); + Instruction_t* jncond_i = allocateNewInstruction(p_instruction->getAddress()->getFileID(), p_instruction->GetFunction()); + Instruction_t* nop_i = allocateNewInstruction(p_instruction->getAddress()->getFileID(), p_instruction->GetFunction()); Instruction_t* policy_i; - Instruction_t* next_i = p_instruction->GetFallthrough(); - p_instruction->SetFallthrough(jncond_i); + Instruction_t* next_i = p_instruction->getFallthrough(); + p_instruction->setFallthrough(jncond_i); setAssembly(nop_i, "nop"); if (p_policy == POLICY_CONTINUE_SATURATING_ARITHMETIC) { - policy_i = allocateNewInstruction(p_instruction->GetAddress()->GetFileID(), p_instruction->GetFunction()); + policy_i = allocateNewInstruction(p_instruction->getAddress()->getFileID(), p_instruction->GetFunction()); } else { @@ -360,7 +360,7 @@ bool IntegerTransform64::addOverflowUnderflowCheck(Instruction_t *p_instruction, } else { // unknown sign - Instruction_t* jnc_i = allocateNewInstruction(p_instruction->GetAddress()->GetFileID(), p_instruction->GetFunction()); + Instruction_t* jnc_i = allocateNewInstruction(p_instruction->getAddress()->getFileID(), p_instruction->GetFunction()); addJno(jncond_i, jnc_i, next_i); addJnc(jnc_i, policy_i, next_i); } @@ -381,8 +381,8 @@ bool IntegerTransform64::addOverflowUnderflowCheck(Instruction_t *p_instruction, std::string detector = p_annotation.isOverflow() ? OVERFLOW64_DETECTOR : UNDERFLOW64_DETECTOR; Instruction_t* cb = addCallbackHandlerSequence(p_instruction, next_i, detector, p_policy); - nop_i->SetFallthrough(cb); - cb->SetComment("underflow callback/instrumentation"); + nop_i->setFallthrough(cb); + cb->setComment("underflow callback/instrumentation"); return true; } @@ -490,7 +490,7 @@ Instruction_t* IntegerTransform64::addCallbackHandlerSequence(Instruction_t *p_o char tmpbuf[1024]; Instruction_t* lea = addNewAssembly("lea rsp, [rsp-128]"); // red zone - lea->SetComment("callback: " + p_detector); + lea->setComment("callback: " + p_detector); // must save flags as strata will perturb them Instruction_t* saveFlags = addNewAssembly(lea, "pushf"); @@ -499,21 +499,21 @@ Instruction_t* IntegerTransform64::addCallbackHandlerSequence(Instruction_t *p_o // pass in p_policy sprintf(tmpbuf,"push 0x%08x", p_policy); Instruction_t* instr = addNewAssembly(saveFlags, tmpbuf); - sprintf(tmpbuf,"push 0x%08x", p_orig->GetAddress()->GetVirtualOffset()); + sprintf(tmpbuf,"push 0x%08x", p_orig->getAddress()->GetVirtualOffset()); instr = addNewAssembly(instr, tmpbuf); - Instruction_t* call = allocateNewInstruction(p_orig->GetAddress()->GetFileID(), p_orig->GetFunction()); - instr->SetFallthrough(call); + Instruction_t* call = allocateNewInstruction(p_orig->getAddress()->getFileID(), p_orig->GetFunction()); + instr->setFallthrough(call); setAssembly(call, "call 0"); addCallbackHandler64(call, p_detector, 2); // 2 args for now - assert(call->GetTarget()); + assert(call->getTarget()); instr = addNewAssembly(call, "lea rsp, [rsp+16]"); instr = addNewAssembly(instr, "popf"); instr = addNewAssembly(instr, "lea rsp, [rsp+128]"); - instr->SetFallthrough(p_fallthrough); + instr->setFallthrough(p_fallthrough); return lea; } @@ -553,16 +553,16 @@ Instruction_t* IntegerTransform64::addCallbackHandlerSequence(Instruction_t *p_o // void IntegerTransform64::addOverflowCheckNoFlag_RegPlusReg(Instruction_t *p_instruction, const MEDS_InstructionCheckAnnotation& p_annotation, const RegisterName& p_reg1, const RegisterName& p_reg2, const RegisterName& p_reg3, int p_policy) { - assert(p_instruction && p_instruction->GetFallthrough()); + assert(p_instruction && p_instruction->getFallthrough()); cerr << __func__ << ": r3 <-- r1+r2: r1: " << Register::toString(p_reg1) << " r2: " << Register::toString(p_reg2) << " target register: " << Register::toString(p_reg3) << " annotation: " << p_annotation.toString() << endl; - Instruction_t *origFallthrough = p_instruction->GetFallthrough(); + Instruction_t *origFallthrough = p_instruction->getFallthrough(); Instruction_t *instr, *first, *saturation_policy; Instruction_t *restore = addNewAssembly("popf"); saturation_policy = addNewAssembly("nop"); - saturation_policy->SetComment("lea overflow instrumentation(reg+reg): policy code sequence"); + saturation_policy->setComment("lea overflow instrumentation(reg+reg): policy code sequence"); // Original code sequence: // lea r3, [r1+r2] @@ -579,11 +579,11 @@ void IntegerTransform64::addOverflowCheckNoFlag_RegPlusReg(Instruction_t *p_inst // fallthrough--><policy> // // first = addNewAssembly("push " + Register::toString(p_reg1)); -// first->SetComment("lea overflow instrumentation(reg+reg): start"); +// first->setComment("lea overflow instrumentation(reg+reg): start"); // Instruction_t* originalInstrumentInstr = carefullyInsertBefore(p_instruction, first); Instruction_t* originalInstrumentInstr = IRDBUtility::insertAssemblyBefore(getFileIR(), p_instruction, "lea rsp, [rsp-128]" , NULL); - p_instruction->SetComment("lea overflow instrumentation(reg+reg): start"); + p_instruction->setComment("lea overflow instrumentation(reg+reg): start"); instr = addNewAssembly(p_instruction, std::string("push ") + Register::toString(p_reg1)); instr = addNewAssembly(instr, "pushf"); @@ -591,23 +591,23 @@ void IntegerTransform64::addOverflowCheckNoFlag_RegPlusReg(Instruction_t *p_inst if (p_annotation.isSigned()) { instr = addNewAssembly(instr, "jno 0x22"); - instr->SetFallthrough(saturation_policy); - instr->SetTarget(restore); - instr->SetComment("signed: lea: reg+reg"); + instr->setFallthrough(saturation_policy); + instr->setTarget(restore); + instr->setComment("signed: lea: reg+reg"); } else if (p_annotation.isUnsigned()) { instr = addNewAssembly(instr, "jnc 0x22"); - instr->SetFallthrough(saturation_policy); - instr->SetTarget(restore); + instr->setFallthrough(saturation_policy); + instr->setTarget(restore); } else { Instruction_t *instr2 = addNewAssembly(instr, "jno 0x22"); // this generates bogus assembly code, why? - instr2->SetTarget(restore); + instr2->setTarget(restore); instr = addNewAssembly(instr2, "jnc 0x22"); - instr->SetFallthrough(saturation_policy); - instr->SetTarget(restore); + instr->setFallthrough(saturation_policy); + instr->setTarget(restore); } // <policy> @@ -623,18 +623,18 @@ void IntegerTransform64::addOverflowCheckNoFlag_RegPlusReg(Instruction_t *p_inst // Instruction_t *popf = addNewAssembly("popf"); Instruction_t *callback = addCallbackHandlerSequence(p_instruction, popf, OVERFLOW64_DETECTOR, p_policy); - saturation_policy->SetFallthrough(callback); + saturation_policy->setFallthrough(callback); instr = addNewAssembly(popf, "pop " + Register::toString(p_reg1)); if (p_policy == POLICY_CONTINUE_SATURATING_ARITHMETIC) { instr = addNewMaxSaturation(instr, p_reg3, p_annotation); instr = addNewAssembly(instr, "lea rsp, [rsp+128]"); - instr->SetFallthrough(origFallthrough); + instr->setFallthrough(origFallthrough); } else { instr = addNewAssembly(instr, "lea rsp, [rsp+128]"); - instr->SetFallthrough(originalInstrumentInstr); + instr->setFallthrough(originalInstrumentInstr); } // <restore> @@ -644,10 +644,10 @@ void IntegerTransform64::addOverflowCheckNoFlag_RegPlusReg(Instruction_t *p_inst // <orig>: lea r3, [r1+r2] ; original instruction // <originalNext> ; original next instruction // - restore->SetComment("lea overflow instrumentation(reg+reg): restore"); + restore->setComment("lea overflow instrumentation(reg+reg): restore"); instr = addNewAssembly(restore, "pop " + Register::toString(p_reg1)); instr = addNewAssembly(instr, "lea rsp, [rsp+128]"); - instr->SetFallthrough(originalInstrumentInstr); + instr->setFallthrough(originalInstrumentInstr); } // Example annotation to handle @@ -685,15 +685,15 @@ void IntegerTransform64::addOverflowCheckNoFlag_RegPlusReg(Instruction_t *p_inst // void IntegerTransform64::addOverflowCheckNoFlag_RegTimesReg(Instruction_t *p_instruction, const MEDS_InstructionCheckAnnotation& p_annotation, const RegisterName& p_reg1, const RegisterName& p_reg2, const RegisterName& p_reg3, int p_policy) { - assert(p_instruction && p_instruction->GetFallthrough()); + assert(p_instruction && p_instruction->getFallthrough()); cerr << __func__ << ": r3 <-- r1*r2: r1: " << Register::toString(p_reg1) << " r2: " << Register::toString(p_reg2) << " target register: " << Register::toString(p_reg3) << " annotation: " << p_annotation.toString() << endl; - Instruction_t *origFallthrough = p_instruction->GetFallthrough(); + Instruction_t *origFallthrough = p_instruction->getFallthrough(); Instruction_t *instr, *first, *saturation_policy; Instruction_t *restore = addNewAssembly("popf"); saturation_policy = addNewAssembly("nop"); - saturation_policy->SetComment("lea overflow instrumentation(reg*reg): policy code sequence"); + saturation_policy->setComment("lea overflow instrumentation(reg*reg): policy code sequence"); // Original code sequence: @@ -709,14 +709,14 @@ void IntegerTransform64::addOverflowCheckNoFlag_RegTimesReg(Instruction_t *p_ins // fallthrough--><policy> // Instruction_t* originalInstrumentInstr = IRDBUtility::insertAssemblyBefore(getFileIR(), p_instruction, "lea rsp, [rsp-128]" , NULL); - p_instruction->SetComment("lea overflow instrumentation(reg*reg): start"); + p_instruction->setComment("lea overflow instrumentation(reg*reg): start"); instr = addNewAssembly(p_instruction, std::string("push ") + Register::toString(p_reg1)); instr = addNewAssembly(instr, "pushf"); instr = addNewAssembly(instr, "imul " + Register::toString(p_reg1) + "," + Register::toString(p_reg2)); instr = addNewAssembly(instr, "jno 0x22"); - instr->SetFallthrough(saturation_policy); - instr->SetTarget(restore); + instr->setFallthrough(saturation_policy); + instr->setTarget(restore); // <policy> // nop ; @@ -731,18 +731,18 @@ void IntegerTransform64::addOverflowCheckNoFlag_RegTimesReg(Instruction_t *p_ins // Instruction_t *popf = addNewAssembly("popf"); Instruction_t *callback = addCallbackHandlerSequence(p_instruction, popf, OVERFLOW64_DETECTOR, p_policy); - saturation_policy->SetFallthrough(callback); + saturation_policy->setFallthrough(callback); instr = addNewAssembly(popf, "pop " + Register::toString(p_reg1)); if (p_policy == POLICY_CONTINUE_SATURATING_ARITHMETIC) { instr = addNewMaxSaturation(instr, p_reg3, p_annotation); instr = addNewAssembly(instr, "lea rsp, [rsp+128]"); - instr->SetFallthrough(origFallthrough); + instr->setFallthrough(origFallthrough); } else { instr = addNewAssembly(instr, "lea rsp, [rsp+128]"); - instr->SetFallthrough(originalInstrumentInstr); + instr->setFallthrough(originalInstrumentInstr); } // <restore> @@ -752,10 +752,10 @@ void IntegerTransform64::addOverflowCheckNoFlag_RegTimesReg(Instruction_t *p_ins // <orig>: lea r3, [r1*r2] ; original instruction // <originalNext> ; original next instruction // - restore->SetComment("lea overflow instrumentation(reg*reg): restore"); + restore->setComment("lea overflow instrumentation(reg*reg): restore"); instr = addNewAssembly(restore, "pop " + Register::toString(p_reg1)); instr = addNewAssembly(instr, "lea rsp, [rsp+128]"); - instr->SetFallthrough(originalInstrumentInstr); + instr->setFallthrough(originalInstrumentInstr); } // Example annotation to handle @@ -793,7 +793,7 @@ void IntegerTransform64::addOverflowCheckNoFlag_RegTimesReg(Instruction_t *p_ins // void IntegerTransform64::addOverflowCheckNoFlag_RegPlusConstant(Instruction_t *p_instruction, const MEDS_InstructionCheckAnnotation& p_annotation, const RegisterName& p_reg1, const int p_constant, const RegisterName& p_reg3, int p_policy) { - assert(p_instruction && p_instruction->GetFallthrough()); + assert(p_instruction && p_instruction->getFallthrough()); if (p_annotation.isUnsigned() && (p_constant < 0)) { logMessage(__func__, "lea reg+neg constant pattern: skip this annotation type (prone to false positives)"); @@ -803,11 +803,11 @@ void IntegerTransform64::addOverflowCheckNoFlag_RegPlusConstant(Instruction_t *p cerr << __func__ << ": r3 <-- r1+k: r1: " << Register::toString(p_reg1) << " k: " << p_constant << " target register: " << Register::toString(p_reg3) << " annotation: " << p_annotation.toString() << endl; - Instruction_t *origFallthrough = p_instruction->GetFallthrough(); + Instruction_t *origFallthrough = p_instruction->getFallthrough(); Instruction_t *instr, *first, *saturation_policy; Instruction_t *restore = addNewAssembly("popf"); saturation_policy = addNewAssembly("nop"); - saturation_policy->SetComment("lea overflow instrumentation(reg+k): policy code sequence"); + saturation_policy->setComment("lea overflow instrumentation(reg+k): policy code sequence"); // Original code sequence: // lea r3, [r1+k] @@ -826,18 +826,18 @@ void IntegerTransform64::addOverflowCheckNoFlag_RegPlusConstant(Instruction_t *p // /* first = addNewAssembly("push " + Register::toString(p_reg1)); - first->SetComment("lea overflow instrumentation(reg+k): start"); + first->setComment("lea overflow instrumentation(reg+k): start"); Instruction_t* originalInstrumentInstr = carefullyInsertBefore(p_instruction, first); instr = addNewAssembly(first, "pushf"); */ Instruction_t* originalInstrumentInstr = IRDBUtility::insertAssemblyBefore(getFileIR(), p_instruction, "lea rsp, [rsp-128]" , NULL); - p_instruction->SetComment("lea overflow instrumentation(reg+k): start"); + p_instruction->setComment("lea overflow instrumentation(reg+k): start"); instr = addNewAssembly(p_instruction, std::string("push ") + Register::toString(p_reg1)); instr = addNewAssembly(instr, "pushf"); //------------------- // make sure we set the fallthrough post careful insertion -// first->SetFallthrough(instr); +// first->setFallthrough(instr); std::ostringstream s; if (p_constant >= 0) { @@ -852,22 +852,22 @@ void IntegerTransform64::addOverflowCheckNoFlag_RegPlusConstant(Instruction_t *p if (p_annotation.isSigned()) { instr = addNewAssembly(instr, "jno 0x22"); - instr->SetFallthrough(saturation_policy); - instr->SetTarget(restore); + instr->setFallthrough(saturation_policy); + instr->setTarget(restore); } else if (p_annotation.isUnsigned()) { instr = addNewAssembly(instr, "jnc 0x22"); - instr->SetFallthrough(saturation_policy); - instr->SetTarget(restore); + instr->setFallthrough(saturation_policy); + instr->setTarget(restore); } else { Instruction_t *instr2 = addNewAssembly(instr, "jno 0x22"); - instr2->SetTarget(restore); + instr2->setTarget(restore); instr = addNewAssembly(instr2, "jnc 0x22"); - instr->SetFallthrough(saturation_policy); - instr->SetTarget(restore); + instr->setFallthrough(saturation_policy); + instr->setTarget(restore); } // <policy> @@ -883,18 +883,18 @@ void IntegerTransform64::addOverflowCheckNoFlag_RegPlusConstant(Instruction_t *p // Instruction_t *popf = addNewAssembly("popf"); Instruction_t *callback = addCallbackHandlerSequence(p_instruction, popf, OVERFLOW64_DETECTOR, p_policy); - saturation_policy->SetFallthrough(callback); + saturation_policy->setFallthrough(callback); instr = addNewAssembly(popf, "pop " + Register::toString(p_reg1)); if (p_policy == POLICY_CONTINUE_SATURATING_ARITHMETIC) { instr = addNewMaxSaturation(instr, p_reg3, p_annotation); instr = addNewAssembly(instr, "lea rsp, [rsp+128]"); - instr->SetFallthrough(origFallthrough); + instr->setFallthrough(origFallthrough); } else { instr = addNewAssembly(instr, "lea rsp, [rsp+128]"); - instr->SetFallthrough(originalInstrumentInstr); + instr->setFallthrough(originalInstrumentInstr); } // <restore> @@ -904,11 +904,11 @@ void IntegerTransform64::addOverflowCheckNoFlag_RegPlusConstant(Instruction_t *p // <orig>: lea r3, [r1+k] ; original instruction // <originalNext> ; original next instruction // - restore->SetComment("lea overflow instrumentation(reg+k): restore"); + restore->setComment("lea overflow instrumentation(reg+k): restore"); instr = addNewAssembly(restore, "pop " + Register::toString(p_reg1)); instr = addNewAssembly(instr, "lea rsp, [rsp+128]"); - instr->SetFallthrough(originalInstrumentInstr); - originalInstrumentInstr->SetFallthrough(origFallthrough); + instr->setFallthrough(originalInstrumentInstr); + originalInstrumentInstr->setFallthrough(origFallthrough); } @@ -945,15 +945,15 @@ void IntegerTransform64::addOverflowCheckNoFlag_RegPlusConstant(Instruction_t *p // void IntegerTransform64::addOverflowCheckNoFlag_RegTimesConstant(Instruction_t *p_instruction, const MEDS_InstructionCheckAnnotation& p_annotation, const RegisterName& p_reg1, const int p_constant, const RegisterName& p_reg3, int p_policy) { - assert(p_instruction && p_instruction->GetFallthrough()); + assert(p_instruction && p_instruction->getFallthrough()); cerr << __func__ << ": r3 <-- r1*k: r1: " << Register::toString(p_reg1) << " k: " << p_constant << " target register: " << Register::toString(p_reg3) << " annotation: " << p_annotation.toString() << endl; - Instruction_t *origFallthrough = p_instruction->GetFallthrough(); + Instruction_t *origFallthrough = p_instruction->getFallthrough(); Instruction_t *instr, *first, *saturation_policy; Instruction_t *restore = addNewAssembly("popf"); saturation_policy = addNewAssembly("nop"); - saturation_policy->SetComment("lea overflow instrumentation(reg*k): policy code sequence"); + saturation_policy->setComment("lea overflow instrumentation(reg*k): policy code sequence"); // Original code sequence: // lea r3, [r1*k] @@ -969,25 +969,25 @@ void IntegerTransform64::addOverflowCheckNoFlag_RegTimesConstant(Instruction_t * // /* first = addNewAssembly("push " + Register::toString(p_reg1)); - first->SetComment("lea overflow instrumentation(reg*k): start"); + first->setComment("lea overflow instrumentation(reg*k): start"); Instruction_t* originalInstrumentInstr = carefullyInsertBefore(p_instruction, first); instr = addNewAssembly(first, "pushf"); */ Instruction_t* originalInstrumentInstr = IRDBUtility::insertAssemblyBefore(getFileIR(), p_instruction, "lea rsp, [rsp-128]" , NULL); - p_instruction->SetComment("lea overflow instrumentation(reg*k): start"); + p_instruction->setComment("lea overflow instrumentation(reg*k): start"); instr = addNewAssembly(p_instruction, std::string("push ") + Register::toString(p_reg1)); instr = addNewAssembly(instr, "pushf"); /*--------------*/ // make sure we set the fallthrough post careful insertion -// first->SetFallthrough(instr); +// first->setFallthrough(instr); std::ostringstream s; s << "imul " << Register::toString(p_reg1) << "," << p_constant; instr = addNewAssembly(instr, s.str()); instr = addNewAssembly(instr, "jno 0x22"); - instr->SetFallthrough(saturation_policy); - instr->SetTarget(restore); + instr->setFallthrough(saturation_policy); + instr->setTarget(restore); // <policy> // nop ; @@ -1002,18 +1002,18 @@ void IntegerTransform64::addOverflowCheckNoFlag_RegTimesConstant(Instruction_t * // Instruction_t *popf = addNewAssembly("popf"); Instruction_t *callback = addCallbackHandlerSequence(p_instruction, popf, OVERFLOW64_DETECTOR, p_policy); - saturation_policy->SetFallthrough(callback); + saturation_policy->setFallthrough(callback); instr = addNewAssembly(popf, "pop " + Register::toString(p_reg1)); if (p_policy == POLICY_CONTINUE_SATURATING_ARITHMETIC) { instr = addNewMaxSaturation(instr, p_reg3, p_annotation); instr = addNewAssembly(instr, "lea rsp, [rsp+128]"); - instr->SetFallthrough(origFallthrough); + instr->setFallthrough(origFallthrough); } else { instr = addNewAssembly(instr, "lea rsp, [rsp+128]"); - instr->SetFallthrough(originalInstrumentInstr); + instr->setFallthrough(originalInstrumentInstr); } // <restore> @@ -1023,11 +1023,11 @@ void IntegerTransform64::addOverflowCheckNoFlag_RegTimesConstant(Instruction_t * // <orig>: lea r3, [r1*k] ; original instruction // <originalNext> ; original next instruction // - restore->SetComment("lea overflow instrumentation(reg*reg): restore"); + restore->setComment("lea overflow instrumentation(reg*reg): restore"); instr = addNewAssembly(restore, "pop " + Register::toString(p_reg1)); instr = addNewAssembly(instr, "lea rsp, [rsp+128]"); - instr->SetFallthrough(originalInstrumentInstr); - originalInstrumentInstr->SetFallthrough(origFallthrough); + instr->setFallthrough(originalInstrumentInstr); + originalInstrumentInstr->setFallthrough(origFallthrough); } // @@ -1045,7 +1045,7 @@ void IntegerTransform64::addOverflowCheckNoFlag_RegTimesConstant(Instruction_t * bool IntegerTransform64::addTruncationCheck32(Instruction_t *p_instruction, const MEDS_InstructionCheckAnnotation& p_annotation, int p_policy) { - assert(p_instruction && p_instruction->GetFallthrough() && + assert(p_instruction && p_instruction->getFallthrough() && p_annotation.getTruncationFromWidth() == 32 && (p_annotation.getTruncationToWidth() == 16 || p_annotation.getTruncationToWidth() == 8) && isMovInstruction(p_instruction)); @@ -1094,7 +1094,7 @@ bool IntegerTransform64::addTruncationCheck32(Instruction_t *p_instruction, cons unsigned mask = 0, mask2 = 0; string saturationValue = "0x0"; - p_instruction->SetComment("monitor for truncation32"); + p_instruction->setComment("monitor for truncation32"); if (p_annotation.getTruncationToWidth() == 16) { @@ -1161,14 +1161,14 @@ bool IntegerTransform64::addTruncationCheck32(Instruction_t *p_instruction, cons // char buf[MAX_ASSEMBLY_SIZE]; - Instruction_t *origFallthrough = p_instruction->GetFallthrough(); + Instruction_t *origFallthrough = p_instruction->getFallthrough(); Instruction_t *instr, *save, *test; Instruction_t *restore = addNewAssembly("popf"); - restore->SetComment("trunc: restore flags"); + restore->setComment("trunc: restore flags"); /* save = addNewAssembly("pushf"); - save->SetComment("start truncation sequence"); + save->setComment("start truncation sequence"); */ if (p_annotation.isSigned()) @@ -1188,16 +1188,16 @@ bool IntegerTransform64::addTruncationCheck32(Instruction_t *p_instruction, cons /*--------------*/ // Instruction_t* originalInstrumentInstr = IRDBUtility::insertAssemblyBefore(getFileIR(), p_instruction, std::string("pushf"), NULL); Instruction_t* originalInstrumentInstr = IRDBUtility::insertAssemblyBefore(getFileIR(), p_instruction, "lea rsp, [rsp-128]" , NULL); - p_instruction->SetComment("start truncation sequence"); + p_instruction->setComment("start truncation sequence"); instr = addNewAssembly(p_instruction, "pushf"); test = addNewAssembly(instr, buf); /*--------------*/ - // p_instruction->SetFallthrough(test); + // p_instruction->setFallthrough(test); -// save->SetFallthrough(test); +// save->setFallthrough(test); instr = addNewAssembly(restore, "lea rsp, [rsp+128]"); - instr->SetFallthrough(originalInstrumentInstr); + instr->setFallthrough(originalInstrumentInstr); if (p_annotation.isUnsigned()) { @@ -1205,8 +1205,8 @@ bool IntegerTransform64::addTruncationCheck32(Instruction_t *p_instruction, cons Instruction_t *nop = addNewAssembly("nop"); instr = addNewAssembly(test, "jz 0x22"); // bogus jump target for now - instr->SetTarget(restore); - instr->SetFallthrough(nop); + instr->setTarget(restore); + instr->setFallthrough(nop); Instruction_t *callback; @@ -1214,16 +1214,16 @@ bool IntegerTransform64::addTruncationCheck32(Instruction_t *p_instruction, cons { string saturationInstruction = "mov " + p_annotation.getTarget2() + ", " + saturationValue; Instruction_t *saturation = addNewAssembly(saturationInstruction); - saturation->SetComment("trunc/unsigned/saturate"); + saturation->setComment("trunc/unsigned/saturate"); callback = addCallbackHandlerSequence(p_instruction, saturation, detector, p_policy); - nop->SetFallthrough(callback); - saturation->SetFallthrough(restore); + nop->setFallthrough(callback); + saturation->setFallthrough(restore); } else { callback = addCallbackHandlerSequence(p_instruction, restore, detector, p_policy); - nop->SetFallthrough(callback); + nop->setFallthrough(callback); } } else @@ -1253,15 +1253,15 @@ bool IntegerTransform64::addTruncationCheck32(Instruction_t *p_instruction, cons Instruction_t *nop = addNewAssembly("nop"); instr = addNewAssembly(test, "jz 0x22"); // bogus jump target for now - instr->SetTarget(restore); + instr->setTarget(restore); std::ostringstream s; s << "cmp " << Register::toString(p_annotation.getRegister()) << ", 0x" << hex << mask2 << dec; instr = addNewAssembly(instr, s.str()); instr = addNewAssembly(instr, "jae 0x22"); - instr->SetTarget(restore); - instr->SetFallthrough(nop); + instr->setTarget(restore); + instr->setFallthrough(nop); Instruction_t *callback; @@ -1270,18 +1270,18 @@ bool IntegerTransform64::addTruncationCheck32(Instruction_t *p_instruction, cons string saturationInstruction = "mov " + p_annotation.getTarget2() + ", " + saturationValue; Instruction_t *saturation = addNewAssembly(saturationInstruction); if (p_annotation.isSigned()) - saturation->SetComment("trunc/signed/saturate"); + saturation->setComment("trunc/signed/saturate"); else - saturation->SetComment("trunc/unknown/saturate"); + saturation->setComment("trunc/unknown/saturate"); callback = addCallbackHandlerSequence(p_instruction, saturation, detector, p_policy); - nop->SetFallthrough(callback); - saturation->SetFallthrough(restore); + nop->setFallthrough(callback); + saturation->setFallthrough(restore); } else { callback = addCallbackHandlerSequence(p_instruction, restore, detector, p_policy); - nop->SetFallthrough(callback); + nop->setFallthrough(callback); } } @@ -1328,7 +1328,7 @@ string IntegerTransform64::buildSaturationAssembly(Instruction_t *p_instruction, bool IntegerTransform64::addTruncationCheck64(Instruction_t *p_instruction, const MEDS_InstructionCheckAnnotation& p_annotation, int p_policy) { - assert(p_instruction && p_instruction->GetFallthrough() && + assert(p_instruction && p_instruction->getFallthrough() && p_annotation.getTruncationFromWidth() == 64 && (p_annotation.getTruncationToWidth() == 32 || p_annotation.getTruncationToWidth() == 16 || p_annotation.getTruncationToWidth() == 8) && isMovInstruction(p_instruction)); @@ -1398,7 +1398,7 @@ bool IntegerTransform64::addTruncationCheck64(Instruction_t *p_instruction, cons long long unsigned mask = 0, mask2 = 0; string saturationValue = "0x0"; - p_instruction->SetComment("monitor for truncation64"); + p_instruction->setComment("monitor for truncation64"); if (p_annotation.getTruncationToWidth() == 32) { @@ -1493,15 +1493,15 @@ bool IntegerTransform64::addTruncationCheck64(Instruction_t *p_instruction, cons // char buf[MAX_ASSEMBLY_SIZE]; - Instruction_t *origFallthrough = p_instruction->GetFallthrough(); + Instruction_t *origFallthrough = p_instruction->getFallthrough(); Instruction_t *instr, *save, *test, *pushf; Instruction_t *restore = addNewAssembly("popf"); - restore->SetComment("trunc: restore flags"); + restore->setComment("trunc: restore flags"); Instruction_t *restoreReg = addNewAssembly("pop " + Register::toString(borrowReg)); /* save = addNewAssembly("push " + Register::toString(borrowReg)); - save->SetComment("start truncation sequence"); + save->setComment("start truncation sequence"); pushf = addNewAssembly(save, "pushf"); @@ -1524,7 +1524,7 @@ bool IntegerTransform64::addTruncationCheck64(Instruction_t *p_instruction, cons // Instruction_t* originalInstrumentInstr = IRDBUtility::insertAssemblyBefore(getFileIR(), p_instruction, std::string("push ") + Register::toString(borrowReg), NULL); // Instruction_t* lea = addNewAssembly("lea rsp, [rsp-128]"); // red zone Instruction_t* originalInstrumentInstr = IRDBUtility::insertAssemblyBefore(getFileIR(), p_instruction, "lea rsp, [rsp-128]" , NULL); - p_instruction->SetComment("start truncation sequence"); + p_instruction->setComment("start truncation sequence"); instr = addNewAssembly(p_instruction, std::string("push ") + Register::toString(borrowReg)); instr = addNewAssembly(instr, "pushf"); if (p_annotation.isSigned()) @@ -1540,11 +1540,11 @@ bool IntegerTransform64::addTruncationCheck64(Instruction_t *p_instruction, cons // test eax, <reg> ; (for 8 bit) /*--------------*/ -// save->SetFallthrough(pushf); +// save->setFallthrough(pushf); - restore->SetFallthrough(restoreReg); + restore->setFallthrough(restoreReg); instr = addNewAssembly(restoreReg, "lea rsp, [rsp+128]"); - instr->SetFallthrough(originalInstrumentInstr); + instr->setFallthrough(originalInstrumentInstr); if (p_annotation.isUnsigned()) { @@ -1552,8 +1552,8 @@ bool IntegerTransform64::addTruncationCheck64(Instruction_t *p_instruction, cons Instruction_t *nop = addNewAssembly("nop"); instr = addNewAssembly(test, "jz 0x22"); // bogus jump target for now - instr->SetTarget(restore); - instr->SetFallthrough(nop); + instr->setTarget(restore); + instr->setFallthrough(nop); Instruction_t *callback; @@ -1561,16 +1561,16 @@ bool IntegerTransform64::addTruncationCheck64(Instruction_t *p_instruction, cons { string saturationInstruction = "mov " + p_annotation.getTarget2() + ", " + saturationValue; Instruction_t *saturation = addNewAssembly(saturationInstruction); - saturation->SetComment("trunc/unsigned/saturate"); + saturation->setComment("trunc/unsigned/saturate"); callback = addCallbackHandlerSequence(p_instruction, saturation, detector, p_policy); - nop->SetFallthrough(callback); - saturation->SetFallthrough(restore); + nop->setFallthrough(callback); + saturation->setFallthrough(restore); } else { callback = addCallbackHandlerSequence(p_instruction, restore, detector, p_policy); - nop->SetFallthrough(callback); + nop->setFallthrough(callback); } } else @@ -1603,7 +1603,7 @@ bool IntegerTransform64::addTruncationCheck64(Instruction_t *p_instruction, cons Instruction_t *nop = addNewAssembly("nop"); instr = addNewAssembly(test, "jz 0x22"); // bogus jump target for now - instr->SetTarget(restore); + instr->setTarget(restore); std::ostringstream s; s << "mov " << Register::toString(borrowReg) << ", 0x" << hex << mask2 << dec; @@ -1614,8 +1614,8 @@ bool IntegerTransform64::addTruncationCheck64(Instruction_t *p_instruction, cons instr = addNewAssembly(instr, s2.str()); instr = addNewAssembly(instr, "jae 0x22"); - instr->SetTarget(restore); - instr->SetFallthrough(nop); + instr->setTarget(restore); + instr->setFallthrough(nop); Instruction_t *callback; @@ -1624,18 +1624,18 @@ bool IntegerTransform64::addTruncationCheck64(Instruction_t *p_instruction, cons string saturationInstruction = "mov " + p_annotation.getTarget2() + ", " + saturationValue; Instruction_t *saturation = addNewAssembly(saturationInstruction); if (p_annotation.isSigned()) - saturation->SetComment("trunc/signed/saturate"); + saturation->setComment("trunc/signed/saturate"); else - saturation->SetComment("trunc/unknown/saturate"); + saturation->setComment("trunc/unknown/saturate"); callback = addCallbackHandlerSequence(p_instruction, saturation, detector, p_policy); - nop->SetFallthrough(callback); - saturation->SetFallthrough(restore); + nop->setFallthrough(callback); + saturation->setFallthrough(restore); } else { callback = addCallbackHandlerSequence(p_instruction, restore, detector, p_policy); - nop->SetFallthrough(callback); + nop->setFallthrough(callback); } } @@ -1658,7 +1658,7 @@ bool IntegerTransform64::addSignednessCheck(Instruction_t *p_instruction, const return false; string detector = p_annotation.isSigned() ? SIGNEDNESS64_DETECTOR_SIGNED : SIGNEDNESS64_DETECTOR_UNSIGNED; - Instruction_t *origFallthrough = p_instruction->GetFallthrough(); + Instruction_t *origFallthrough = p_instruction->getFallthrough(); Instruction_t* originalInstrumentInstr = IRDBUtility::insertAssemblyBefore(getFileIR(), p_instruction, std::string("lea rsp, [rsp-128]"), NULL); Instruction_t *save = addNewAssembly(p_instruction, "pushf"); @@ -1666,15 +1666,15 @@ bool IntegerTransform64::addSignednessCheck(Instruction_t *p_instruction, const std::ostringstream s; s << "test " << Register::toString(p_annotation.getRegister()) << "," << Register::toString(p_annotation.getRegister()); Instruction_t *test = addNewAssembly(save, s.str()); - originalInstrumentInstr->SetFallthrough(origFallthrough); + originalInstrumentInstr->setFallthrough(origFallthrough); Instruction_t *jns = addNewAssembly(test, "jns 0x22"); Instruction_t *nop = addNewAssembly(jns, "nop"); Instruction_t *restore = addNewAssembly("popf"); Instruction_t *learestore = addNewAssembly(restore, "lea rsp, [rsp+128]"); - learestore->SetFallthrough(originalInstrumentInstr); + learestore->setFallthrough(originalInstrumentInstr); - jns->SetTarget(restore); + jns->setTarget(restore); Instruction_t *callback = NULL; @@ -1684,18 +1684,18 @@ bool IntegerTransform64::addSignednessCheck(Instruction_t *p_instruction, const Instruction_t *saturation = addNewMaxSaturation(nop, p_annotation.getRegister(), p_annotation); if (p_annotation.isSigned()) - saturation->SetComment("signedness/signed/saturate"); + saturation->setComment("signedness/signed/saturate"); else - saturation->SetComment("signedness/unsigned/saturate"); + saturation->setComment("signedness/unsigned/saturate"); callback = addCallbackHandlerSequence(p_instruction, saturation, detector, p_policy); - nop->SetFallthrough(callback); - saturation->SetFallthrough(restore); + nop->setFallthrough(callback); + saturation->setFallthrough(restore); } else { callback = addCallbackHandlerSequence(p_instruction, restore, detector, p_policy); - nop->SetFallthrough(callback); + nop->setFallthrough(callback); } return true; diff --git a/libtransform/include/integertransform64.hpp b/libIRDB-transform/include-unused-delete-later/integertransform64.hpp similarity index 100% rename from libtransform/include/integertransform64.hpp rename to libIRDB-transform/include-unused-delete-later/integertransform64.hpp diff --git a/libtransform/src/leapattern.cpp b/libIRDB-transform/include-unused-delete-later/leapattern.cpp similarity index 100% rename from libtransform/src/leapattern.cpp rename to libIRDB-transform/include-unused-delete-later/leapattern.cpp diff --git a/libtransform/include/leapattern.hpp b/libIRDB-transform/include-unused-delete-later/leapattern.hpp similarity index 100% rename from libtransform/include/leapattern.hpp rename to libIRDB-transform/include-unused-delete-later/leapattern.hpp diff --git a/libtransform/src/pointercheck64.cpp b/libIRDB-transform/include-unused-delete-later/pointercheck64.cpp similarity index 95% rename from libtransform/src/pointercheck64.cpp rename to libIRDB-transform/include-unused-delete-later/pointercheck64.cpp index 7f11e1f613ad2a41b3b885bfe2fc2f3973c05e8b..3c4ba7d64f82de8ecb949cf94719ef4d69e51ac4 100644 --- a/libtransform/src/pointercheck64.cpp +++ b/libIRDB-transform/include-unused-delete-later/pointercheck64.cpp @@ -31,7 +31,7 @@ Instruction_t* PointerCheck64::addCallbackHandlerSequence(Instruction_t *p_orig, Instruction_t* exit_sequence = addNewAssembly("mov rax, 60"); Instruction_t* i = addNewAssembly(exit_sequence, "mov rdi, 25"); i = addNewAssembly(i, "syscall"); - i->SetFallthrough(p_fallthrough); + i->setFallthrough(p_fallthrough); return exit_sequence; } else @@ -70,11 +70,11 @@ int PointerCheck64::execute() { Instruction_t* insn=*it; - if (insn && insn->GetAddress()) + if (insn && insn->getAddress()) { int policy = POLICY_EXIT; - virtual_offset_t irdb_vo = insn->GetAddress()->GetVirtualOffset(); + virtual_offset_t irdb_vo = insn->getAddress()->GetVirtualOffset(); if (irdb_vo == 0) continue; VirtualOffset vo(irdb_vo); @@ -108,7 +108,7 @@ int PointerCheck64::execute() continue; } - if (!insn->GetFallthrough()) + if (!insn->getFallthrough()) { logMessage(__func__, "Warning: no fall through for instruction -- skipping"); continue; diff --git a/libtransform/include/pointercheck64.hpp b/libIRDB-transform/include-unused-delete-later/pointercheck64.hpp similarity index 100% rename from libtransform/include/pointercheck64.hpp rename to libIRDB-transform/include-unused-delete-later/pointercheck64.hpp diff --git a/libtransform/include/transform.hpp b/libIRDB-transform/include-unused-delete-later/transform.hpp similarity index 91% rename from libtransform/include/transform.hpp rename to libIRDB-transform/include-unused-delete-later/transform.hpp index 775acf9c9926957ba59f2a895644494b2a6fd7ed..325fa40d6e1ae85a3b92efa8b9ad6813543a453c 100644 --- a/libtransform/include/transform.hpp +++ b/libIRDB-transform/include-unused-delete-later/transform.hpp @@ -25,21 +25,26 @@ #include <set> #include <map> -#include <libIRDB-core.hpp> +#include <irdb-core> #include "MEDS_InstructionCheckAnnotation.hpp" #include "VirtualOffset.hpp" -using namespace std; -using namespace libIRDB; -using namespace MEDS_Annotation; - #define MAX_ASSEMBLY_SIZE 2048 +namespace libIRDB +{ + class FileIR_t; +} namespace libTransform { +using namespace std; +using namespace IRDB_SDK; +using namespace MEDS_Annotation; -class Transform { + +class Transform +{ public: Transform(VariantID_t *, FileIR_t *, set<std::string> *p_filteredFunctions); @@ -85,18 +90,14 @@ class Transform { void addMulRegisterConstant(Instruction_t *p_instr, RegisterName p_regTgt, int p_constantValue, Instruction_t *p_fallThrough); void addMovRegisters(Instruction_t *p_instr, RegisterName p_regTgt, RegisterName p_regSrc, Instruction_t *p_fallThrough); - Instruction_t* allocateNewInstruction(db_id_t p_fileID=BaseObj_t::NOT_IN_DATABASE, Function_t* p_func=NULL); + Instruction_t* allocateNewInstruction(DatabaseID_t p_fileID=BaseObj_t::NOT_IN_DATABASE, Function_t* p_func=NULL); - virtual_offset_t getAvailableAddress(); + VirtualOffset_t getAvailableAddress(); VariantID_t* getVariantID() { return m_variantID; } - FileIR_t* getFileIR() { return m_fileIR; } + FileIR_t* getFileIR(); // { return dynamic_cast<FileIR_t*>(m_fileIR); } set<std::string>* getFilteredFunctions() { return m_filteredFunctions; } - // bool isMultiplyInstruction(libIRDB::Instruction_t*); - //bool isMovInstruction(libIRDB::Instruction_t*); - //bool isAddSubNonEspInstruction(libIRDB::Instruction_t*); - //RegisterName getTargetRegister(libIRDB::Instruction_t*, int argNo = 1); Instruction_t* addNewMaxSaturation(Instruction_t *p_prev, RegisterName p_reg, const MEDS_InstructionCheckAnnotation p_annotation); void addMinSaturation(Instruction_t *p_instruction, RegisterName p_reg, const MEDS_InstructionCheckAnnotation& p_annotation, Instruction_t *p_fallthrough); void addMaxSaturation(Instruction_t *p_instruction, RegisterName p_reg, const MEDS_InstructionCheckAnnotation& p_annotation, Instruction_t *p_fallthrough); @@ -114,10 +115,9 @@ class Transform { void addTestRegister32(Instruction_t *p_instr, RegisterName, Instruction_t *p_fallThrough); void addTestRegisterMask32(Instruction_t *p_instr, RegisterName, unsigned p_mask, Instruction_t *p_fallThrough); void addCmpRegisterMask32(Instruction_t *p_instr, RegisterName, unsigned p_mask, Instruction_t *p_fallThrough); - //bool hasTargetRegister(libIRDB::Instruction_t*, int argNo = 1); VariantID_t *m_variantID; - FileIR_t *m_fileIR; + libIRDB::FileIR_t *m_fileIR; set<std::string> *m_filteredFunctions; std::map<std::string, Instruction_t*> m_handlerMap; }; diff --git a/libtransform/src/SConscript b/libIRDB-transform/src/SConscript similarity index 52% rename from libtransform/src/SConscript rename to libIRDB-transform/src/SConscript index d075920eb834ac1559db6c85db1387a88fd4111e..0c250bfeb153f70a9b77739937e968904158601a 100644 --- a/libtransform/src/SConscript +++ b/libIRDB-transform/src/SConscript @@ -6,24 +6,25 @@ Import('env') myenv=env.Clone() myenv.Replace(SECURITY_TRANSFORMS_HOME=os.environ['SECURITY_TRANSFORMS_HOME']) -#files="integertransform32.cpp integertransform64.cpp integertransform.cpp leapattern.cpp pointercheck64.cpp Rewrite_Utility.cpp transform.cpp" -files="Rewrite_Utility.cpp transform.cpp" +files="rewrite_util.cpp transform.cpp" cpppath=''' + $IRDB_SDK/include $SECURITY_TRANSFORMS_HOME/include - $SECURITY_TRANSFORMS_HOME/libIRDB/include - $SECURITY_TRANSFORMS_HOME/libtransform/include + $SECURITY_TRANSFORMS_HOME/libIRDB-core/include + $SECURITY_TRANSFORMS_HOME/libIRDB-cfg/include + $SECURITY_TRANSFORMS_HOME/libIRDB-util/include $SECURITY_TRANSFORMS_HOME/libMEDSannotation/include/ ''' LIBPATH="$SECURITY_TRANSFORMS_HOME/lib" -LIBS=Split("IRDB-core IRDB-cfg IRDB-util MEDSannotation") +LIBS=Split("irdb-core irdb-cfg irdb-util MEDSannotation") myenv=myenv.Clone(CPPPATH=Split(cpppath)) myenv.Append(CXXFLAGS = " -std=c++11 ") -lib=myenv.SharedLibrary("transform", Split(files), LIBPATH=LIBPATH, LIBS=LIBS) +lib=myenv.SharedLibrary("irdb-transform", Split(files), LIBPATH=LIBPATH, LIBS=LIBS) install=myenv.Install("$SECURITY_TRANSFORMS_HOME/lib/", lib) Default(install) Return('install') diff --git a/libtransform/src/SConstruct b/libIRDB-transform/src/SConstruct similarity index 100% rename from libtransform/src/SConstruct rename to libIRDB-transform/src/SConstruct diff --git a/libIRDB-transform/src/rewrite_util.cpp b/libIRDB-transform/src/rewrite_util.cpp new file mode 100644 index 0000000000000000000000000000000000000000..443236f80fd64c1cda89e5171160824d553c1dd0 --- /dev/null +++ b/libIRDB-transform/src/rewrite_util.cpp @@ -0,0 +1,276 @@ + +#include <irdb-transform> +#include <libIRDB-core.hpp> + +// Copied from PnTransform +// @todo: create a utility library with the one interface + + +using namespace std; +using namespace IRDB_SDK; + +void copyInstruction(Instruction_t* src, Instruction_t* dest); +Instruction_t* copyInstruction(FileIR_t* virp, Instruction_t* instr); +Instruction_t* allocateNewInstruction(FileIR_t* virp, DatabaseID_t p_fileID,Function_t* func); +Instruction_t* allocateNewInstruction(FileIR_t* virp, Instruction_t *template_instr); + + + +void setInstructionsDetails(FileIR_t* virp, Instruction_t *p_instr, string p_dataBits, Instruction_t *p_fallThrough, Instruction_t *p_target) +{ + if (p_instr == NULL) return; + + p_instr->setDataBits(p_dataBits); + p_instr->setComment(p_instr->getDisassembly()); + p_instr->setFallthrough(p_fallThrough); + p_instr->setTarget(p_target); + + auto real_virp=dynamic_cast<libIRDB::FileIR_t*>(virp); + assert(real_virp); + + real_virp->GetAddresses().insert(p_instr->getAddress()); + real_virp->GetInstructions().insert(p_instr); +} + + +//For all insertBefore functions: +//The "first" instruction will have its contents replaced and a duplicate of "first" will be in the follow of first. +//This duplicate is returned since the user already has a pointer to first. +//To insert before an instruction is the same as modifying the original instruction, and inserting after it +//a copy of the original instruction +Instruction_t* IRDB_SDK::insertAssemblyBefore(FileIR_t* virp, Instruction_t* first, string assembly, Instruction_t *target) +{ + Instruction_t* next = copyInstruction(virp,first); + + //In case the fallthrough is null, generate spri has to have a + //place to jump, which is determined by the original address. + //This code is not placed in copyInstruction since this is only needed + //when inserting before + next->setOriginalAddressID(first->getOriginalAddressID()); + //"Null" out the original address (it should be as if the instruction was not in the database). + first->setOriginalAddressID(BaseObj_t::NOT_IN_DATABASE); + auto real_first=dynamic_cast<libIRDB::Instruction_t*>(first); + assert(real_first); + real_first->GetRelocations().clear(); + first->setIBTargets(NULL); + //Note that the instruction just inserted should have the same exception handling + //info as the instructions immediately around it. + //Thus the exception handling information (EhCallSite and EhProgram) are kept the + //same from the copy of first (unlike with relocations and IBT's). + + virp->changeRegistryKey(first,next); + IRDB_SDK::setInstructionAssembly(virp,first,assembly,next,target); + + return next; +} + +#if 0 +Instruction_t* insertAssemblyBefore(FileIR_t* virp, Instruction_t* first, string assembly) +{ + return insertAssemblyBefore(virp,first,assembly,NULL); +} + + +Instruction_t* insertDataBitsBefore(FileIR_t* virp, Instruction_t* first, string dataBits) +{ + return insertDataBitsBefore(virp,first,dataBits,NULL); +} +#endif + +Instruction_t* IRDB_SDK::insertDataBitsBefore(FileIR_t* virp, Instruction_t* first, string dataBits, Instruction_t *target) +{ + Instruction_t* next = copyInstruction(virp,first); + + //In case the fallthrough is null, generate spri has to have a + //place to jump, which is determined by the original address. + //This code is not placed in copyInstruction since this is only needed + //when inserting before + next->setOriginalAddressID(first->getOriginalAddressID()); + //"Null" out the original address (it should be as if the instruction was not in the database). + first->setOriginalAddressID(BaseObj_t::NOT_IN_DATABASE); + auto real_first=dynamic_cast<libIRDB::Instruction_t*>(first); + assert(real_first); + real_first->GetRelocations().clear(); + first->setIBTargets(NULL); + //Note that the instruction just inserted should have the same exception handling + //info as the instructions immediately around it. + //Thus the exception handling information (EhCallSite and EhProgram) are kept the + //same from the copy of first (unlike with relocations and IBT's). + + virp->changeRegistryKey(first,next); + setInstructionsDetails(virp,first,dataBits,next,target); + + return next; +} + +Instruction_t* IRDB_SDK::insertAssemblyAfter(FileIR_t* virp, Instruction_t* first, string assembly, Instruction_t *target) +{ + Instruction_t *new_instr = allocateNewInstruction(virp,first); + IRDB_SDK::setInstructionAssembly(virp,new_instr,assembly,first->getFallthrough(), target); + first->setFallthrough(new_instr); + return new_instr; +} + +#if 0 +Instruction_t* insertAssemblyAfter(FileIR_t* virp, Instruction_t* first, string assembly) +{ + return insertAssemblyAfter(virp,first,assembly,NULL); + +} +#endif + +Instruction_t* IRDB_SDK::insertDataBitsAfter(FileIR_t* virp, Instruction_t* first, string dataBits, Instruction_t *target) +{ + Instruction_t *new_instr = allocateNewInstruction(virp,first); + setInstructionsDetails(virp,new_instr,dataBits,first->getFallthrough(), target); + first->setFallthrough(new_instr); + + return new_instr; +} + +#if 0 +Instruction_t* insertDataBitsAfter(FileIR_t* virp, Instruction_t* first, string dataBits) +{ + return insertDataBitsAfter(virp,first,dataBits,NULL); +} +#endif + +Instruction_t* IRDB_SDK::addNewDataBits(FileIR_t* firp, Instruction_t *p_instr, string p_bits) +{ + Instruction_t* newinstr; + if (p_instr) + newinstr = allocateNewInstruction(firp,p_instr->getAddress()->getFileID(), p_instr->getFunction()); + else + newinstr = allocateNewInstruction(firp,firp->getFile()->getFileID(), NULL); + + newinstr->setDataBits(p_bits); + + if (p_instr) + { + newinstr->setFallthrough(p_instr->getFallthrough()); + p_instr->setFallthrough(newinstr); + } + + return newinstr; +} + +Instruction_t* IRDB_SDK::addNewDataBits(FileIR_t* firp, string p_bits) +{ + return IRDB_SDK::addNewDataBits(firp,nullptr,p_bits); +} + + +Instruction_t* IRDB_SDK::addNewAssembly(FileIR_t* firp, Instruction_t *p_instr, string p_asm) +{ + Instruction_t* newinstr; + if (p_instr) + newinstr = allocateNewInstruction(firp,p_instr->getAddress()->getFileID(), p_instr->getFunction()); + else + newinstr = allocateNewInstruction(firp,firp->getFile()->getFileID(), NULL); + + firp->registerAssembly(newinstr, p_asm); + + if (p_instr) + { + newinstr->setFallthrough(p_instr->getFallthrough()); + p_instr->setFallthrough(newinstr); + } + + return newinstr; +} + +Instruction_t* IRDB_SDK::addNewAssembly(FileIR_t* firp, string p_asm) +{ + return IRDB_SDK::addNewAssembly(firp,nullptr,p_asm); +} + + +//Does not insert into any variant +Instruction_t* copyInstruction(Instruction_t* instr) +{ + Instruction_t* cpy = new libIRDB::Instruction_t(); + + copyInstruction(instr,cpy); + + return cpy; +} + +Instruction_t* copyInstruction(FileIR_t* virp, Instruction_t* instr) +{ + Instruction_t* cpy = allocateNewInstruction(virp,instr); + + copyInstruction(instr,cpy); + + return cpy; +} + +void copyInstruction(Instruction_t* src, Instruction_t* dest) +{ + auto real_dest=dynamic_cast<libIRDB::Instruction_t*>(dest); + dest->setDataBits(src->getDataBits()); + dest->setComment(src->getComment()); + dest->setCallback(src->getCallback()); + dest->setFallthrough(src->getFallthrough()); + dest->setTarget(src->getTarget()); + dest->setIBTargets(src->getIBTargets()); + real_dest->GetRelocations()=src->getRelocations(); + dest->setEhProgram(src->getEhProgram()); + dest->setEhCallSite(src->getEhCallSite()); +} + +Instruction_t* allocateNewInstruction(FileIR_t* virp, DatabaseID_t p_fileID,Function_t* func) +{ + auto instr = new libIRDB::Instruction_t(); + auto a = new libIRDB::AddressID_t(); + + a->setFileID(p_fileID); + + instr->setFunction(func); + instr->setAddress(a); + if(func) + { + auto real_func=dynamic_cast<libIRDB::Function_t*>(func); + assert(func); + real_func->GetInstructions().insert(instr); + } + + auto real_virp=dynamic_cast<libIRDB::FileIR_t*>(virp); + assert(real_virp); + real_virp->GetInstructions().insert(instr); + real_virp->GetAddresses().insert(a); + +// inserted_instr[func].insert(instr); +// inserted_addr[func].insert(a); + + return instr; +} + +Instruction_t* allocateNewInstruction(FileIR_t* virp, Instruction_t *template_instr) +{ + Function_t *func = template_instr->getFunction(); + DatabaseID_t fileID = template_instr->getAddress()->getFileID(); + return allocateNewInstruction(virp, fileID, func); +} + +void IRDB_SDK::setInstructionAssembly(FileIR_t* virp,Instruction_t *p_instr, const string& p_assembly, Instruction_t *p_fallThrough, Instruction_t *p_target) +{ + if (p_instr == NULL) return; + + ///TODO: what if bad assembly? + virp->registerAssembly(p_instr,p_assembly); + p_instr->setComment(p_assembly); + p_instr->setFallthrough(p_fallThrough); + p_instr->setTarget(p_target); + + auto real_virp=dynamic_cast<libIRDB::FileIR_t*>(virp); + assert(real_virp); + real_virp->GetAddresses().insert(p_instr->getAddress()); + real_virp->GetInstructions().insert(p_instr); +} + +void IRDB_SDK::setInstructionAssembly(FileIR_t* virp,Instruction_t *p_instr, const string& p_assembly) +{ + IRDB_SDK::setInstructionAssembly(virp,p_instr,p_assembly, p_instr->getFallthrough(), p_instr->getTarget()); +} + + diff --git a/libtransform/src/transform.cpp b/libIRDB-transform/src/transform.cpp similarity index 81% rename from libtransform/src/transform.cpp rename to libIRDB-transform/src/transform.cpp index f8093ae29a83fb74bf293c6fae9ecb690368ae6f..52e4e2469ec28bb77b63fad57991b076d2d8f59b 100644 --- a/libtransform/src/transform.cpp +++ b/libIRDB-transform/src/transform.cpp @@ -18,33 +18,75 @@ * */ -#include "transform.hpp" -#include "Rewrite_Utility.hpp" -#define OPTIMIZE_ASSEMBLY +#include <irdb-transform> -using namespace libTransform; -using namespace MEDS_Annotation; +using namespace IRDB_SDK; -// 20130415 Anh added support for additional registers for various utility functions -// 20130415 Anh added assert() statements for unhandled registers +Transform::Transform(FileIR_t *p_fileIR) + : + m_fileIR (p_fileIR) +{ + assert(m_fileIR); +} + +FileIR_t* Transform::getFileIR() +{ + return m_fileIR; +} + +Instruction_t* Transform::insertAssemblyBefore(Instruction_t* before, const string &the_asm, Instruction_t* target) +{ + return IRDB_SDK::insertAssemblyBefore(getFileIR(), before, the_asm, target); +} + + +Instruction_t* Transform::insertAssemblyAfter(Instruction_t* before, const string &the_asm, Instruction_t* target) +{ + return IRDB_SDK::insertAssemblyAfter(getFileIR(), before, the_asm, target); +} + +Instruction_t* Transform::insertDataBitsBefore(Instruction_t* before, const string &the_asm, Instruction_t* target) +{ + return IRDB_SDK::insertDataBitsBefore(getFileIR(), before, the_asm, target); +} + +Instruction_t* Transform::insertDataBitsAfter(Instruction_t* before, const string &the_asm, Instruction_t* target) +{ + return IRDB_SDK::insertDataBitsAfter(getFileIR(), before, the_asm, target); +} + +Instruction_t* Transform::addNewDataBits(const string& p_bits) +{ + return IRDB_SDK::addNewDataBits(getFileIR(), p_bits); +} + +Instruction_t* Transform::addNewAssembly(const string& p_bits) +{ + return IRDB_SDK::addNewAssembly(getFileIR(), p_bits); +} + +void Transform::setInstructionAssembly(Instruction_t* instr, const string& p_asm, Instruction_t *p_new_fallthrough, Instruction_t* p_new_target) +{ + return IRDB_SDK::setInstructionAssembly(getFileIR(), instr, p_asm, p_new_fallthrough, p_new_target); +} -Transform::Transform(VariantID_t *p_variantID, FileIR_t *p_fileIR, set<std::string> *p_filteredFunctions) +void Transform::setInstructionAssembly(Instruction_t* instr, const string& p_asm) { - m_variantID = p_variantID; // Current variant ID - m_fileIR = p_fileIR; // File IR (off the database) for variant - m_filteredFunctions = p_filteredFunctions; // Blacklisted funtions + return IRDB_SDK::setInstructionAssembly(getFileIR(), instr, p_asm); } + + +#if 0 void Transform::addInstruction(Instruction_t *p_instr, string p_dataBits, Instruction_t *p_fallThrough, Instruction_t *p_target) { if (p_instr == NULL) return; - p_instr->SetDataBits(p_dataBits); - p_instr->SetComment(p_instr->getDisassembly()); - p_instr->SetFallthrough(p_fallThrough); - p_instr->SetTarget(p_target); - - m_fileIR->GetAddresses().insert(p_instr->GetAddress()); + p_instr->setDataBits(p_dataBits); + p_instr->setComment(p_instr->getDisassembly()); + p_instr->setFallthrough(p_fallThrough); + p_instr->setTarget(p_target); + m_fileIR->GetAddresses().insert(p_instr->getAddress()); m_fileIR->GetInstructions().insert(p_instr); } @@ -65,29 +107,29 @@ Instruction_t* Transform::carefullyInsertBefore(Instruction_t* &p_instrumented, //a copy of the original instruction #ifdef BENSWAY - Instruction_t* i2 = IRDBUtility::insertAssemblyBefore(m_fileIR, p_instrumented, m_fileIR->LookupAssembly(p_newInstr), p_newInstr->GetTarget()); -cerr << "carefullyInsertBefore (Ben's Way): @: 0x" << std::hex << p_instrumented->GetAddress() << std::dec << " old instruction: " << p_instrumented->getDisassembly() << " new instruction: " << m_fileIR->LookupAssembly(p_newInstr) << endl; + Instruction_t* i2 = IRDBUtility::insertAssemblyBefore(m_fileIR, p_instrumented, m_fileIR->lookupAssembly(p_newInstr), p_newInstr->getTarget()); +cerr << "carefullyInsertBefore (Ben's Way): @: 0x" << std::hex << p_instrumented->getAddress() << std::dec << " old instruction: " << p_instrumented->getDisassembly() << " new instruction: " << m_fileIR->lookupAssembly(p_newInstr) << endl; return i2; #else - db_id_t fileID = p_instrumented->GetAddress()->GetFileID(); - Function_t* func = p_instrumented->GetFunction(); + DatabaseID_t fileID = p_instrumented->getAddress()->getFileID(); + Function_t* func = p_instrumented->getFunction(); - assert(p_instrumented && p_newInstr && p_instrumented->GetAddress()); + assert(p_instrumented && p_newInstr && p_instrumented->getAddress()); // why is old instrunction blank? -cerr << "(1) carefullyInsertBefore: @: 0x" << std::hex << p_instrumented->GetAddress() << std::dec << " old instruction: " << p_instrumented->getDisassembly() << " new instruction: " << m_fileIR->LookupAssembly(p_newInstr) << endl; +cerr << "(1) carefullyInsertBefore: @: 0x" << std::hex << p_instrumented->getAddress() << std::dec << " old instruction: " << p_instrumented->getDisassembly() << " new instruction: " << m_fileIR->lookupAssembly(p_newInstr) << endl; // duplicate old instrumented instruction Instruction_t* dupInstr = allocateNewInstruction(fileID, func); - dupInstr->SetDataBits(p_instrumented->GetDataBits()); - dupInstr->SetComment(p_instrumented->GetComment()); - dupInstr->SetCallback(p_instrumented->GetCallback()); - dupInstr->SetFallthrough(p_instrumented->GetFallthrough()); - dupInstr->SetTarget(p_instrumented->GetTarget()); - dupInstr->SetOriginalAddressID(p_instrumented->GetOriginalAddressID()); + dupInstr->setDataBits(p_instrumented->GetDataBits()); + dupInstr->setComment(p_instrumented->getComment()); + dupInstr->setCallback(p_instrumented->getCallback()); + dupInstr->setFallthrough(p_instrumented->getFallthrough()); + dupInstr->setTarget(p_instrumented->getTarget()); + dupInstr->setOriginalAddressID(p_instrumented->getOriginalAddressID()); AddressID_t *saveIBTA = p_instrumented->GetIndirectBranchTargetAddress(); - dupInstr->SetIndirectBranchTargetAddress(NULL); + dupInstr->setIndirectBranchTargetAddress(NULL); // // pre: p_instrument --> "mov edx, 1" @@ -97,39 +139,30 @@ cerr << "(1) carefullyInsertBefore: @: 0x" << std::hex << p_instrumented->GetAdd // // this function is equivalent to: // m_fileIR->UnregisterAssembly(p_instrumented); - // m_fileIR->RegisterAssembly(dupInstr, newAssemblyCode); + // m_fileIR->registerAssembly(dupInstr, newAssemblyCode); // m_fileIR->ChangeRegistryKey(p_instrumented, dupInstr); if (p_newInstr->GetDataBits().size() == 0) - m_fileIR->RegisterAssembly(p_instrumented, m_fileIR->LookupAssembly(p_newInstr)); + m_fileIR->registerAssembly(p_instrumented, m_fileIR->lookupAssembly(p_newInstr)); else - p_instrumented->SetDataBits(p_newInstr->GetDataBits()); + p_instrumented->setDataBits(p_newInstr->GetDataBits()); - p_instrumented->SetComment(p_newInstr->GetComment()); - p_instrumented->SetCallback(p_newInstr->GetCallback()); - p_instrumented->SetFallthrough(dupInstr); + p_instrumented->setComment(p_newInstr->getComment()); + p_instrumented->setCallback(p_newInstr->getCallback()); + p_instrumented->setFallthrough(dupInstr); - p_instrumented->SetOriginalAddressID(BaseObj_t::NOT_IN_DATABASE); - p_instrumented->SetIndirectBranchTargetAddress(saveIBTA); + p_instrumented->setOriginalAddressID(BaseObj_t::NOT_IN_DATABASE); + p_instrumented->setIndirectBranchTargetAddress(saveIBTA); p_instrumented->GetRelocations().clear(); p_newInstr = p_instrumented; -cerr << "(2) carefullyInsertBefore: @: 0x" << std::hex << p_instrumented->GetAddress() << std::dec << " old instruction: " << dupInstr->getDisassembly() << " new instruction: " << m_fileIR->LookupAssembly(p_newInstr) << endl; +cerr << "(2) carefullyInsertBefore: @: 0x" << std::hex << p_instrumented->getAddress() << std::dec << " old instruction: " << dupInstr->getDisassembly() << " new instruction: " << m_fileIR->lookupAssembly(p_newInstr) << endl; return dupInstr; #endif } -Instruction_t* Transform::insertAssemblyBefore(Instruction_t* before, const string &the_asm, Instruction_t* target) -{ - return IRDBUtility::insertAssemblyBefore(getFileIR(), before, the_asm, target); -} - -Instruction_t* Transform::insertAssemblyAfter(Instruction_t* before, const string &the_asm, Instruction_t* target) -{ - return IRDBUtility::insertAssemblyAfter(getFileIR(), before, the_asm, target); -} void Transform::addPushf(Instruction_t *p_pushf_i, Instruction_t *p_fallThrough) { @@ -336,26 +369,26 @@ void Transform::addNop(Instruction_t *p_nop_i, Instruction_t *p_fallThrough) string dataBits; dataBits.resize(1); dataBits[0] = 0x90; - p_nop_i->SetComment(string("NOP")); + p_nop_i->setComment(string("NOP")); addInstruction(p_nop_i, dataBits, p_fallThrough, NULL); } -Instruction_t* Transform::allocateNewInstruction(db_id_t p_fileID, Function_t* p_func) +Instruction_t* Transform::allocateNewInstruction(DatabaseID_t p_fileID, Function_t* p_func) { - Instruction_t *instr = new Instruction_t(); - AddressID_t *a = new AddressID_t(); + Instruction_t *instr = new libIRDB::Instruction_t(); + AddressID_t *a = new libIRDB::AddressID_t(); - a->SetFileID(p_fileID); + a->setFileID(p_fileID); - instr->SetFunction(p_func); - instr->SetAddress(a); + instr->setFunction(p_func); + instr->setAddress(a); m_fileIR->GetInstructions().insert(instr); m_fileIR->GetAddresses().insert(a); return instr; } -virtual_offset_t Transform::getAvailableAddress() +VirtualOffset_t Transform::getAvailableAddress() { /* // traverse all instructions @@ -364,7 +397,7 @@ virtual_offset_t Transform::getAvailableAddress() // @todo: lookup instruction size so that we don't waste any space // for some reason the max available address is incorrect! was ist los? - virtual_offset_t availableAddressOffset = 0; + VirtualOffset_t availableAddressOffset = 0; for( set<Instruction_t*>::const_iterator it=p_virp->GetInstructions().begin(); it!=p_virp->GetInstructions().end(); @@ -374,8 +407,8 @@ virtual_offset_t Transform::getAvailableAddress() Instruction_t* insn=*it; if (!insn) continue; - AddressID_t* addr = insn->GetAddress(); - virtual_offset_t offset = addr->GetVirtualOffset(); + AddressID_t* addr = insn->getAddress(); + VirtualOffset_t offset = addr->setVirtualOffset(); if (offset > availableAddressOffset) { @@ -392,12 +425,13 @@ virtual_offset_t Transform::getAvailableAddress() void Transform::addCallbackHandler(string p_detector, Instruction_t *p_instrumentedInstruction, Instruction_t *p_instruction, Instruction_t *p_fallThrough, int p_policy, AddressID_t *p_addressOriginalInstruction) { + assert(getFileIR() && p_instruction && p_fallThrough); string dataBits; - db_id_t fileID = p_instruction->GetAddress()->GetFileID(); - Function_t* func = p_instruction->GetFunction(); + DatabaseID_t fileID = p_instruction->getAddress()->getFileID(); + Function_t* func = p_instruction->getFunction(); // create and register new instructions (and addresses) Instruction_t* pushf_i = allocateNewInstruction(fileID, func); @@ -411,12 +445,12 @@ void Transform::addCallbackHandler(string p_detector, Instruction_t *p_instrumen Instruction_t* popf_i = allocateNewInstruction(fileID, func); // pin the poparg instruction - virtual_offset_t postDetectorReturn = getAvailableAddress(); - poparg_i->GetAddress()->SetVirtualOffset(postDetectorReturn); + VirtualOffset_t postDetectorReturn = getAvailableAddress(); + poparg_i->getAddress()->setVirtualOffset(postDetectorReturn); // link callback handler sequence to instrumented instruction - p_instruction->SetFallthrough(pushf_i); - p_instruction->SetComment(p_instruction->GetComment() + " -- start of callback handler sequence"); + p_instruction->setFallthrough(pushf_i); + p_instruction->setComment(p_instruction->getComment() + " -- start of callback handler sequence"); // pushf addPushf(pushf_i, pusha_i); @@ -433,49 +467,49 @@ void Transform::addCallbackHandler(string p_detector, Instruction_t *p_instrumen dataBits[0] = 0x68; int *tmpi = (int *) &dataBits[1]; *tmpi = p_policy; - pushPolicy_i->SetDataBits(dataBits); - pushPolicy_i->SetComment(pushPolicy_i->getDisassembly() + string(" - policy spec")); - pushPolicy_i->SetFallthrough(pusharg_i); + pushPolicy_i->setDataBits(dataBits); + pushPolicy_i->setComment(pushPolicy_i->getDisassembly() + string(" - policy spec")); + pushPolicy_i->setFallthrough(pusharg_i); // push (PC of instrumented instruction) dataBits.resize(5); dataBits[0] = 0x68; - virtual_offset_t *tmp = (virtual_offset_t *) &dataBits[1]; + VirtualOffset_t *tmp = (VirtualOffset_t *) &dataBits[1]; if (p_addressOriginalInstruction) - *tmp = p_addressOriginalInstruction->GetVirtualOffset(); + *tmp = p_addressOriginalInstruction->getVirtualOffset(); else - *tmp = p_instrumentedInstruction->GetAddress()->GetVirtualOffset(); - pusharg_i->SetDataBits(dataBits); - pusharg_i->SetComment(pusharg_i->getDisassembly()); - pusharg_i->SetFallthrough(pushret_i); + *tmp = p_instrumentedInstruction->getAddress()->getVirtualOffset(); + pusharg_i->setDataBits(dataBits); + pusharg_i->setComment(pusharg_i->getDisassembly()); + pusharg_i->setFallthrough(pushret_i); // pushret dataBits.resize(5); dataBits[0] = 0x68; - tmp = (virtual_offset_t *) &dataBits[1]; + tmp = (VirtualOffset_t *) &dataBits[1]; *tmp = postDetectorReturn; - pushret_i->SetDataBits(dataBits); - pushret_i->SetComment(pushret_i->getDisassembly()); - pushret_i->SetFallthrough(poparg_i); + pushret_i->setDataBits(dataBits); + pushret_i->setComment(pushret_i->getDisassembly()); + pushret_i->setFallthrough(poparg_i); // poparg dataBits.resize(1); dataBits[0] = 0x58; - poparg_i->SetDataBits(dataBits); - poparg_i->SetComment(poparg_i->getDisassembly() + " -- with callback to " + p_detector + " orig: " + p_instruction->GetComment()) ; - poparg_i->SetFallthrough(popPolicy_i); - poparg_i->SetCallback(p_detector); - AddressID_t *poparg_i_indTarg =new AddressID_t(); + poparg_i->setDataBits(dataBits); + poparg_i->setComment(poparg_i->getDisassembly() + " -- with callback to " + p_detector + " orig: " + p_instruction->getComment()) ; + poparg_i->setFallthrough(popPolicy_i); + poparg_i->setCallback(p_detector); + auto poparg_i_indTarg =new libIRDB::AddressID_t(); m_fileIR->GetAddresses().insert(poparg_i_indTarg); - poparg_i_indTarg->SetVirtualOffset(poparg_i->GetAddress()->GetVirtualOffset()); - poparg_i_indTarg->SetFileID(BaseObj_t::NOT_IN_DATABASE); - poparg_i->SetIndirectBranchTargetAddress(poparg_i_indTarg); + poparg_i_indTarg->setVirtualOffset(poparg_i->getAddress()->getVirtualOffset()); + poparg_i_indTarg->setFileID(BaseObj_t::NOT_IN_DATABASE); + poparg_i->setIndirectBranchTargetAddress(poparg_i_indTarg); // popPolicy dataBits.resize(1); dataBits[0] = 0x58; - popPolicy_i->SetDataBits(dataBits); - popPolicy_i->SetFallthrough(popa_i); + popPolicy_i->setDataBits(dataBits); + popPolicy_i->setFallthrough(popa_i); // popa addPopa(popa_i, popf_i); @@ -532,7 +566,7 @@ bool Transform::isMultiplyInstruction(Instruction_t *p_instruction) if (!p_instruction) return false; - std::string assembly = m_fileIR->LookupAssembly(p_instruction); + std::string assembly = m_fileIR->lookupAssembly(p_instruction); if (assembly.length() > 0) { return my_strcasestr(assembly.c_str(), "MUL") != NULL; @@ -554,7 +588,7 @@ bool Transform::isMovInstruction(Instruction_t *p_instruction) if (!p_instruction) return false; - std::string assembly = m_fileIR->LookupAssembly(p_instruction); + std::string assembly = m_fileIR->lookupAssembly(p_instruction); if (assembly.length() > 0) { return my_strcasestr(assembly.c_str(), "MOV") != NULL; @@ -1094,9 +1128,9 @@ void Transform::addAddRegisters(Instruction_t *p_instr, RegisterName p_regTgt, R // too many combinations, just use the assembler string assembly = "add " + Register::toString(p_regTgt) + ", " + Register::toString(p_regSrc); #ifdef OPTIMIZE_ASSEMBLY - m_fileIR->RegisterAssembly(p_instr, assembly); + m_fileIR->registerAssembly(p_instr, assembly); #else - if (!p_instr->Assemble(assembly)) + if (!p_instr->assemble(assembly)) { cerr << "addAddRegisters(): error in assembling instruction: " << assembly << endl; assert(0); @@ -1104,7 +1138,7 @@ void Transform::addAddRegisters(Instruction_t *p_instr, RegisterName p_regTgt, R } #endif - p_instr->SetFallthrough(p_fallThrough); + p_instr->setFallthrough(p_fallThrough); } // add r1, constant @@ -1115,9 +1149,9 @@ void Transform::addAddRegisterConstant(Instruction_t *p_instr, RegisterName p_re sprintf(buf, "add %s, %d", Register::toString(p_reg).c_str(), p_constantValue); string assembly(buf); #ifdef OPTIMIZE_ASSEMBLY - m_fileIR->RegisterAssembly(p_instr, assembly); + m_fileIR->registerAssembly(p_instr, assembly); #else - if (!p_instr->Assemble(assembly)) + if (!p_instr->assemble(assembly)) { cerr << "Transform::addAddConstant(): error in assembling instruction: " << assembly << endl; assert(0); @@ -1126,7 +1160,7 @@ void Transform::addAddRegisterConstant(Instruction_t *p_instr, RegisterName p_re #endif // cerr << "Transform::addAddConstant(): " << p_instr->getDisassembly() << endl; - p_instr->SetFallthrough(p_fallThrough); + p_instr->setFallthrough(p_fallThrough); } // imul r1, constant @@ -1137,7 +1171,7 @@ void Transform::addMulRegisterConstant(Instruction_t *p_instr, RegisterName p_re sprintf(buf, "imul %s, %d", Register::toString(p_reg).c_str(), p_constantValue); string assembly(buf); #ifdef OPTIMIZE_ASSEMBLY - m_fileIR->RegisterAssembly(p_instr, assembly); + m_fileIR->registerAssembly(p_instr, assembly); #else if (!p_instr->Assemble(assembly)) { @@ -1148,7 +1182,7 @@ void Transform::addMulRegisterConstant(Instruction_t *p_instr, RegisterName p_re #endif // cerr << "Transform::addMulRegisterConstant(): " << p_instr->getDisassembly() << endl; - p_instr->SetFallthrough(p_fallThrough); + p_instr->setFallthrough(p_fallThrough); } @@ -1158,7 +1192,7 @@ void Transform::addMovRegisters(Instruction_t *p_instr, RegisterName p_regTgt, R // too many combinations, just use the assembler string assembly = "mov " + Register::toString(p_regTgt) + ", " + Register::toString(p_regSrc); #ifdef OPTIMIZE_ASSEMBLY - m_fileIR->RegisterAssembly(p_instr, assembly); + m_fileIR->registerAssembly(p_instr, assembly); #else if (!p_instr->Assemble(assembly)) { @@ -1167,40 +1201,40 @@ void Transform::addMovRegisters(Instruction_t *p_instr, RegisterName p_regTgt, R return; } #endif - p_instr->SetFallthrough(p_fallThrough); + p_instr->setFallthrough(p_fallThrough); // cerr << "addMovRegisters(): " << p_instr->getDisassembly() << endl; } void Transform::addMovRegisterSignedConstant(Instruction_t *p_instr, RegisterName p_regTgt, long int p_constant, Instruction_t *p_fallThrough) { - p_instr->SetFallthrough(p_fallThrough); + p_instr->setFallthrough(p_fallThrough); char buf[128]; sprintf(buf,"mov %s, %ld", Register::toString(p_regTgt).c_str(), p_constant); string assembly(buf); - m_fileIR->RegisterAssembly(p_instr, assembly); + m_fileIR->registerAssembly(p_instr, assembly); - p_instr->SetComment("Saturating arithmetic"); + p_instr->setComment("Saturating arithmetic"); } void Transform::addMovRegisterUnsignedConstant(Instruction_t *p_instr, RegisterName p_regTgt, unsigned long int p_constant, Instruction_t *p_fallThrough) { - p_instr->SetFallthrough(p_fallThrough); + p_instr->setFallthrough(p_fallThrough); char buf[128]; sprintf(buf,"mov %s, %lu", Register::toString(p_regTgt).c_str(), p_constant); string assembly(buf); - m_fileIR->RegisterAssembly(p_instr, assembly); + m_fileIR->registerAssembly(p_instr, assembly); - p_instr->SetComment("Saturating arithmetic"); + p_instr->setComment("Saturating arithmetic"); } void Transform::addAndRegister32Mask(Instruction_t *p_instr, RegisterName p_regTgt, unsigned int p_mask, Instruction_t *p_fallThrough) { - p_instr->SetFallthrough(p_fallThrough); + p_instr->setFallthrough(p_fallThrough); char buf[128]; sprintf(buf,"and %s, 0x%08X", Register::toString(p_regTgt).c_str(), p_mask); @@ -1208,7 +1242,7 @@ void Transform::addAndRegister32Mask(Instruction_t *p_instr, RegisterName p_regT string assembly(buf); cerr << "addAndRegisterMask(): assembling instruction: " << assembly << endl; #ifdef OPTIMIZE_ASSEMBLY - m_fileIR->RegisterAssembly(p_instr, assembly); + m_fileIR->registerAssembly(p_instr, assembly); #else if (!p_instr->Assemble(assembly)) { @@ -1218,7 +1252,7 @@ void Transform::addAndRegister32Mask(Instruction_t *p_instr, RegisterName p_regT } #endif - p_instr->SetComment("Saturating arithmetic by masking"); + p_instr->setComment("Saturating arithmetic by masking"); } //----------------------------------------------------- @@ -1229,33 +1263,33 @@ void Transform::addAndRegister32Mask(Instruction_t *p_instr, RegisterName p_regT void Transform::addHlt(Instruction_t *p_instr, Instruction_t *p_fallThrough) { string assembly("hlt"); - m_fileIR->RegisterAssembly(p_instr, assembly); - p_instr->SetFallthrough(p_fallThrough); + m_fileIR->registerAssembly(p_instr, assembly); + p_instr->setFallthrough(p_fallThrough); } // jno - jump not overflow void Transform::addJno(Instruction_t *p_instr, Instruction_t *p_fallThrough, Instruction_t *p_target) { string assembly("jno 0x22"); - m_fileIR->RegisterAssembly(p_instr, assembly); - p_instr->SetFallthrough(p_fallThrough); - p_instr->SetTarget(p_target); + m_fileIR->registerAssembly(p_instr, assembly); + p_instr->setFallthrough(p_fallThrough); + p_instr->setTarget(p_target); } // jnc - jump not carry void Transform::addJnc(Instruction_t *p_instr, Instruction_t *p_fallThrough, Instruction_t *p_target) { string assembly("jnc 0x22"); - m_fileIR->RegisterAssembly(p_instr, assembly); - p_instr->SetFallthrough(p_fallThrough); - p_instr->SetTarget(p_target); + m_fileIR->registerAssembly(p_instr, assembly); + p_instr->setFallthrough(p_fallThrough); + p_instr->setTarget(p_target); } Instruction_t* Transform::addNewMaxSaturation(Instruction_t *p_prev, RegisterName p_reg, const MEDS_InstructionCheckAnnotation p_annotation) { - Instruction_t *mov = allocateNewInstruction(p_prev->GetAddress()->GetFileID(), p_prev->GetFunction()); + Instruction_t *mov = allocateNewInstruction(p_prev->getAddress()->getFileID(), p_prev->getFunction()); if (p_prev) - p_prev->SetFallthrough(mov); + p_prev->setFallthrough(mov); addMaxSaturation(mov, p_reg, p_annotation, NULL); return mov; } @@ -1265,7 +1299,7 @@ void Transform::addMaxSaturation(Instruction_t *p_instruction, RegisterName p_re #if 0 assert(getFileIR() && p_instruction); - p_instruction->SetFallthrough(p_fallthrough); + p_instruction->setFallthrough(p_fallthrough); if (p_annotation.isUnsigned()) { @@ -1323,7 +1357,7 @@ void Transform::addMinSaturation(Instruction_t *p_instruction, RegisterName p_re #if 0 assert(getFileIR() && p_instruction); - p_instruction->SetFallthrough(p_fallthrough); + p_instruction->setFallthrough(p_fallthrough); if (p_annotation.isUnsigned()) { @@ -1361,7 +1395,7 @@ void Transform::addMinSaturation(Instruction_t *p_instruction, RegisterName p_re void Transform::setAssembly(Instruction_t *p_instr, string p_asm) { - m_fileIR->RegisterAssembly(p_instr, p_asm); + m_fileIR->registerAssembly(p_instr, p_asm); } // @@ -1382,20 +1416,20 @@ Instruction_t* Transform::addNewAssembly(Instruction_t *p_instr, string p_asm) { Instruction_t* newinstr; if (p_instr) - newinstr = allocateNewInstruction(p_instr->GetAddress()->GetFileID(), p_instr->GetFunction()); + newinstr = allocateNewInstruction(p_instr->getAddress()->getFileID(), p_instr->getFunction()); else - newinstr = allocateNewInstruction(BaseObj_t::NOT_IN_DATABASE, NULL); + newinstr = allocateNewInstruction(m_fileIR->getFile()->getFileID(), NULL); - m_fileIR->RegisterAssembly(newinstr, p_asm); + m_fileIR->registerAssembly(newinstr, p_asm); if (p_instr) { - newinstr->SetFallthrough(p_instr->GetFallthrough()); - p_instr->SetFallthrough(newinstr); + newinstr->setFallthrough(p_instr->getFallthrough()); + p_instr->setFallthrough(newinstr); } else { - newinstr->SetFallthrough(NULL); + newinstr->setFallthrough(NULL); } return newinstr; @@ -1419,7 +1453,7 @@ void Transform::addCallbackHandler64(Instruction_t *p_orig, string p_callbackHan } if (p_orig) - p_orig->SetTarget(m_handlerMap[p_callbackHandler]); + p_orig->setTarget(m_handlerMap[p_callbackHandler]); } // x86-64 @@ -1480,8 +1514,8 @@ Instruction_t* Transform::registerCallbackHandler64(string p_callbackHandler, in // pin the instruction that follows the callback handler Instruction_t* postCallback = allocateNewInstruction(); - virtual_offset_t postCallbackReturn = getAvailableAddress(); - postCallback->GetAddress()->SetVirtualOffset(postCallbackReturn); + VirtualOffset_t postCallbackReturn = getAvailableAddress(); + postCallback->getAddress()->setVirtualOffset(postCallbackReturn); // push the address to return to once the callback handler is invoked sprintf(tmpbuf,"mov rax, 0x%x", (uint32_t)postCallbackReturn); @@ -1491,17 +1525,17 @@ Instruction_t* Transform::registerCallbackHandler64(string p_callbackHandler, in // use a nop instruction for the actual callback instr = addNewAssembly(instr, "nop"); - instr->SetComment(" -- callback: " + p_callbackHandler); - instr->SetCallback(p_callbackHandler); - instr->SetFallthrough(postCallback); + instr->setComment(" -- callback: " + p_callbackHandler); + instr->setCallback(p_callbackHandler); + instr->setFallthrough(postCallback); // need to make sure the post callback address is pinned // (so that ILR and other transforms do not relocate it) - AddressID_t *indTarg = new AddressID_t(); + AddressID_t *indTarg = new libIRDB::AddressID_t(); m_fileIR->GetAddresses().insert(indTarg); - indTarg->SetVirtualOffset(postCallback->GetAddress()->GetVirtualOffset()); - indTarg->SetFileID(BaseObj_t::NOT_IN_DATABASE); // SPRI global namespace - postCallback->SetIndirectBranchTargetAddress(indTarg); + indTarg->setVirtualOffset(postCallback->getAddress()->getVirtualOffset()); + indTarg->setFileID(BaseObj_t::NOT_IN_DATABASE); // SPRI global namespace + postCallback->setIndirectBranchTargetAddress(indTarg); // restore registers setAssembly(postCallback, "popf"); @@ -1545,3 +1579,7 @@ void libTransform::convertToLowercase(string &str) str[i] = tolower(str[i]); } } + +#endif + + diff --git a/libtransform/tests/Makefile b/libIRDB-transform/tests/Makefile similarity index 100% rename from libtransform/tests/Makefile rename to libIRDB-transform/tests/Makefile diff --git a/libtransform/tests/Makefile.pointers b/libIRDB-transform/tests/Makefile.pointers similarity index 100% rename from libtransform/tests/Makefile.pointers rename to libIRDB-transform/tests/Makefile.pointers diff --git a/libtransform/tests/austin/array.c b/libIRDB-transform/tests/austin/array.c similarity index 100% rename from libtransform/tests/austin/array.c rename to libIRDB-transform/tests/austin/array.c diff --git a/libtransform/tests/austin/branch.c b/libIRDB-transform/tests/austin/branch.c similarity index 100% rename from libtransform/tests/austin/branch.c rename to libIRDB-transform/tests/austin/branch.c diff --git a/libtransform/tests/austin/malloc.c b/libIRDB-transform/tests/austin/malloc.c similarity index 100% rename from libtransform/tests/austin/malloc.c rename to libIRDB-transform/tests/austin/malloc.c diff --git a/libtransform/tests/austin/memcpy.c b/libIRDB-transform/tests/austin/memcpy.c similarity index 100% rename from libtransform/tests/austin/memcpy.c rename to libIRDB-transform/tests/austin/memcpy.c diff --git a/libtransform/tests/austin/memset.c b/libIRDB-transform/tests/austin/memset.c similarity index 100% rename from libtransform/tests/austin/memset.c rename to libIRDB-transform/tests/austin/memset.c diff --git a/libtransform/tests/c++/prog.c b/libIRDB-transform/tests/c++/prog.c similarity index 100% rename from libtransform/tests/c++/prog.c rename to libIRDB-transform/tests/c++/prog.c diff --git a/libtransform/tests/clark1.c b/libIRDB-transform/tests/clark1.c similarity index 100% rename from libtransform/tests/clark1.c rename to libIRDB-transform/tests/clark1.c diff --git a/libtransform/tests/false_positives/cat.err b/libIRDB-transform/tests/false_positives/cat.err similarity index 100% rename from libtransform/tests/false_positives/cat.err rename to libIRDB-transform/tests/false_positives/cat.err diff --git a/libtransform/tests/false_positives/cat.out b/libIRDB-transform/tests/false_positives/cat.out similarity index 100% rename from libtransform/tests/false_positives/cat.out rename to libIRDB-transform/tests/false_positives/cat.out diff --git a/libtransform/tests/false_positives/cat.shared.orig b/libIRDB-transform/tests/false_positives/cat.shared.orig similarity index 100% rename from libtransform/tests/false_positives/cat.shared.orig rename to libIRDB-transform/tests/false_positives/cat.shared.orig diff --git a/libtransform/tests/false_positives/cat.shared.orig.peasoup b/libIRDB-transform/tests/false_positives/cat.shared.orig.peasoup similarity index 100% rename from libtransform/tests/false_positives/cat.shared.orig.peasoup rename to libIRDB-transform/tests/false_positives/cat.shared.orig.peasoup diff --git a/libtransform/tests/false_positives/ls.err b/libIRDB-transform/tests/false_positives/ls.err similarity index 100% rename from libtransform/tests/false_positives/ls.err rename to libIRDB-transform/tests/false_positives/ls.err diff --git a/libtransform/tests/false_positives/ls.out b/libIRDB-transform/tests/false_positives/ls.out similarity index 100% rename from libtransform/tests/false_positives/ls.out rename to libIRDB-transform/tests/false_positives/ls.out diff --git a/libtransform/tests/false_positives/ls.shared.orig b/libIRDB-transform/tests/false_positives/ls.shared.orig similarity index 100% rename from libtransform/tests/false_positives/ls.shared.orig rename to libIRDB-transform/tests/false_positives/ls.shared.orig diff --git a/libtransform/tests/false_positives/ls.shared.orig.peasoup b/libIRDB-transform/tests/false_positives/ls.shared.orig.peasoup similarity index 100% rename from libtransform/tests/false_positives/ls.shared.orig.peasoup rename to libIRDB-transform/tests/false_positives/ls.shared.orig.peasoup diff --git a/libtransform/tests/idiom18.c b/libIRDB-transform/tests/idiom18.c similarity index 100% rename from libtransform/tests/idiom18.c rename to libIRDB-transform/tests/idiom18.c diff --git a/libtransform/tests/int16overflow.c b/libIRDB-transform/tests/int16overflow.c similarity index 100% rename from libtransform/tests/int16overflow.c rename to libIRDB-transform/tests/int16overflow.c diff --git a/libtransform/tests/int32overflow.c b/libIRDB-transform/tests/int32overflow.c similarity index 100% rename from libtransform/tests/int32overflow.c rename to libIRDB-transform/tests/int32overflow.c diff --git a/libtransform/tests/integer/addsuboverflow/Makefile b/libIRDB-transform/tests/integer/addsuboverflow/Makefile similarity index 100% rename from libtransform/tests/integer/addsuboverflow/Makefile rename to libIRDB-transform/tests/integer/addsuboverflow/Makefile diff --git a/libtransform/tests/integer/addsuboverflow/acrossfunctions/Makefile b/libIRDB-transform/tests/integer/addsuboverflow/acrossfunctions/Makefile similarity index 100% rename from libtransform/tests/integer/addsuboverflow/acrossfunctions/Makefile rename to libIRDB-transform/tests/integer/addsuboverflow/acrossfunctions/Makefile diff --git a/libtransform/tests/integer/addsuboverflow/acrossfunctions/addsub.ctmpl b/libIRDB-transform/tests/integer/addsuboverflow/acrossfunctions/addsub.ctmpl similarity index 100% rename from libtransform/tests/integer/addsuboverflow/acrossfunctions/addsub.ctmpl rename to libIRDB-transform/tests/integer/addsuboverflow/acrossfunctions/addsub.ctmpl diff --git a/libtransform/tests/integer/addsuboverflow/acrossfunctions/addsub.shtmpl b/libIRDB-transform/tests/integer/addsuboverflow/acrossfunctions/addsub.shtmpl similarity index 100% rename from libtransform/tests/integer/addsuboverflow/acrossfunctions/addsub.shtmpl rename to libIRDB-transform/tests/integer/addsuboverflow/acrossfunctions/addsub.shtmpl diff --git a/libtransform/tests/integer/addsuboverflow/acrossfunctions/generate_addsub_tests.sh b/libIRDB-transform/tests/integer/addsuboverflow/acrossfunctions/generate_addsub_tests.sh similarity index 100% rename from libtransform/tests/integer/addsuboverflow/acrossfunctions/generate_addsub_tests.sh rename to libIRDB-transform/tests/integer/addsuboverflow/acrossfunctions/generate_addsub_tests.sh diff --git a/libtransform/tests/integer/addsuboverflow/acrossfunctions/run_tests.sh b/libIRDB-transform/tests/integer/addsuboverflow/acrossfunctions/run_tests.sh similarity index 100% rename from libtransform/tests/integer/addsuboverflow/acrossfunctions/run_tests.sh rename to libIRDB-transform/tests/integer/addsuboverflow/acrossfunctions/run_tests.sh diff --git a/libtransform/tests/integer/addsuboverflow/intraframe/Makefile b/libIRDB-transform/tests/integer/addsuboverflow/intraframe/Makefile similarity index 100% rename from libtransform/tests/integer/addsuboverflow/intraframe/Makefile rename to libIRDB-transform/tests/integer/addsuboverflow/intraframe/Makefile diff --git a/libtransform/tests/integer/addsuboverflow/intraframe/addsub.ctmpl b/libIRDB-transform/tests/integer/addsuboverflow/intraframe/addsub.ctmpl similarity index 100% rename from libtransform/tests/integer/addsuboverflow/intraframe/addsub.ctmpl rename to libIRDB-transform/tests/integer/addsuboverflow/intraframe/addsub.ctmpl diff --git a/libtransform/tests/integer/addsuboverflow/intraframe/addsub.int.int.-w.nobenchflag.test.sh b/libIRDB-transform/tests/integer/addsuboverflow/intraframe/addsub.int.int.-w.nobenchflag.test.sh similarity index 100% rename from libtransform/tests/integer/addsuboverflow/intraframe/addsub.int.int.-w.nobenchflag.test.sh rename to libIRDB-transform/tests/integer/addsuboverflow/intraframe/addsub.int.int.-w.nobenchflag.test.sh diff --git a/libtransform/tests/integer/addsuboverflow/intraframe/addsub.int.int.c b/libIRDB-transform/tests/integer/addsuboverflow/intraframe/addsub.int.int.c similarity index 100% rename from libtransform/tests/integer/addsuboverflow/intraframe/addsub.int.int.c rename to libIRDB-transform/tests/integer/addsuboverflow/intraframe/addsub.int.int.c diff --git a/libtransform/tests/integer/addsuboverflow/intraframe/addsub.int.unsigned+int.-w.nobenchflag.test.sh b/libIRDB-transform/tests/integer/addsuboverflow/intraframe/addsub.int.unsigned+int.-w.nobenchflag.test.sh similarity index 100% rename from libtransform/tests/integer/addsuboverflow/intraframe/addsub.int.unsigned+int.-w.nobenchflag.test.sh rename to libIRDB-transform/tests/integer/addsuboverflow/intraframe/addsub.int.unsigned+int.-w.nobenchflag.test.sh diff --git a/libtransform/tests/integer/addsuboverflow/intraframe/addsub.int.unsigned+int.c b/libIRDB-transform/tests/integer/addsuboverflow/intraframe/addsub.int.unsigned+int.c similarity index 100% rename from libtransform/tests/integer/addsuboverflow/intraframe/addsub.int.unsigned+int.c rename to libIRDB-transform/tests/integer/addsuboverflow/intraframe/addsub.int.unsigned+int.c diff --git a/libtransform/tests/integer/addsuboverflow/intraframe/addsub.shtmpl b/libIRDB-transform/tests/integer/addsuboverflow/intraframe/addsub.shtmpl similarity index 100% rename from libtransform/tests/integer/addsuboverflow/intraframe/addsub.shtmpl rename to libIRDB-transform/tests/integer/addsuboverflow/intraframe/addsub.shtmpl diff --git a/libtransform/tests/integer/addsuboverflow/intraframe/addsub.unsigned+int.int.-w.nobenchflag.test.sh b/libIRDB-transform/tests/integer/addsuboverflow/intraframe/addsub.unsigned+int.int.-w.nobenchflag.test.sh similarity index 100% rename from libtransform/tests/integer/addsuboverflow/intraframe/addsub.unsigned+int.int.-w.nobenchflag.test.sh rename to libIRDB-transform/tests/integer/addsuboverflow/intraframe/addsub.unsigned+int.int.-w.nobenchflag.test.sh diff --git a/libtransform/tests/integer/addsuboverflow/intraframe/addsub.unsigned+int.int.c b/libIRDB-transform/tests/integer/addsuboverflow/intraframe/addsub.unsigned+int.int.c similarity index 100% rename from libtransform/tests/integer/addsuboverflow/intraframe/addsub.unsigned+int.int.c rename to libIRDB-transform/tests/integer/addsuboverflow/intraframe/addsub.unsigned+int.int.c diff --git a/libtransform/tests/integer/addsuboverflow/intraframe/addsub.unsigned+int.unsigned+int.-w.nobenchflag.test.sh b/libIRDB-transform/tests/integer/addsuboverflow/intraframe/addsub.unsigned+int.unsigned+int.-w.nobenchflag.test.sh similarity index 100% rename from libtransform/tests/integer/addsuboverflow/intraframe/addsub.unsigned+int.unsigned+int.-w.nobenchflag.test.sh rename to libIRDB-transform/tests/integer/addsuboverflow/intraframe/addsub.unsigned+int.unsigned+int.-w.nobenchflag.test.sh diff --git a/libtransform/tests/integer/addsuboverflow/intraframe/addsub.unsigned+int.unsigned+int.c b/libIRDB-transform/tests/integer/addsuboverflow/intraframe/addsub.unsigned+int.unsigned+int.c similarity index 100% rename from libtransform/tests/integer/addsuboverflow/intraframe/addsub.unsigned+int.unsigned+int.c rename to libIRDB-transform/tests/integer/addsuboverflow/intraframe/addsub.unsigned+int.unsigned+int.c diff --git a/libtransform/tests/integer/addsuboverflow/intraframe/generate_addsub_tests.sh b/libIRDB-transform/tests/integer/addsuboverflow/intraframe/generate_addsub_tests.sh similarity index 100% rename from libtransform/tests/integer/addsuboverflow/intraframe/generate_addsub_tests.sh rename to libIRDB-transform/tests/integer/addsuboverflow/intraframe/generate_addsub_tests.sh diff --git a/libtransform/tests/integer/addsuboverflow/intraframe/run_tests.sh b/libIRDB-transform/tests/integer/addsuboverflow/intraframe/run_tests.sh similarity index 100% rename from libtransform/tests/integer/addsuboverflow/intraframe/run_tests.sh rename to libIRDB-transform/tests/integer/addsuboverflow/intraframe/run_tests.sh diff --git a/libtransform/tests/mitre/README b/libIRDB-transform/tests/mitre/README similarity index 100% rename from libtransform/tests/mitre/README rename to libIRDB-transform/tests/mitre/README diff --git a/libtransform/tests/mitre/TC_C_191_v304/README b/libIRDB-transform/tests/mitre/TC_C_191_v304/README similarity index 100% rename from libtransform/tests/mitre/TC_C_191_v304/README rename to libIRDB-transform/tests/mitre/TC_C_191_v304/README diff --git a/libtransform/tests/mitre/TC_C_191_v304/Release/makefile b/libIRDB-transform/tests/mitre/TC_C_191_v304/Release/makefile similarity index 95% rename from libtransform/tests/mitre/TC_C_191_v304/Release/makefile rename to libIRDB-transform/tests/mitre/TC_C_191_v304/Release/makefile index c4301e0053f62e450a0c7de926bb8dd5f0023560..c823419d8f199849793a8b8dc2583625bf418479 100644 --- a/libtransform/tests/mitre/TC_C_191_v304/Release/makefile +++ b/libIRDB-transform/tests/mitre/TC_C_191_v304/Release/makefile @@ -1,44 +1,44 @@ -################################################################################ -# Automatically-generated file. Do not edit! -################################################################################ - --include ../makefile.init - -RM := rm -rf - -# All of the sources participating in the build are defined here --include sources.mk --include subdir.mk --include src/subdir.mk --include objects.mk - -ifneq ($(MAKECMDGOALS),clean) -ifneq ($(strip $(C_DEPS)),) --include $(C_DEPS) -endif -endif - --include ../makefile.defs - -# Add inputs and outputs from these tool invocations to the build variables - -# All Target -all: TC_C_191_v304 - -# Tool invocations -TC_C_191_v304: $(OBJS) $(USER_OBJS) - @echo 'Building target: $@' - @echo 'Invoking: MinGW C Linker' - $(SS_LNK) -o"TC_C_191_v304" $(OBJS) $(USER_OBJS) $(LIBS)$ $(SS_LDFLAGS) - @echo 'Finished building target: $@' - @echo ' ' - -# Other Targets -clean: - -$(RM) $(OBJS)$(C_DEPS)$(EXECUTABLES) TC_C_191_v304 - -@echo ' ' - -.PHONY: all clean dependents -.SECONDARY: - --include ../makefile.targets +################################################################################ +# Automatically-generated file. Do not edit! +################################################################################ + +-include ../makefile.init + +RM := rm -rf + +# All of the sources participating in the build are defined here +-include sources.mk +-include subdir.mk +-include src/subdir.mk +-include objects.mk + +ifneq ($(MAKECMDGOALS),clean) +ifneq ($(strip $(C_DEPS)),) +-include $(C_DEPS) +endif +endif + +-include ../makefile.defs + +# Add inputs and outputs from these tool invocations to the build variables + +# All Target +all: TC_C_191_v304 + +# Tool invocations +TC_C_191_v304: $(OBJS) $(USER_OBJS) + @echo 'Building target: $@' + @echo 'Invoking: MinGW C Linker' + $(SS_LNK) -o"TC_C_191_v304" $(OBJS) $(USER_OBJS) $(LIBS)$ $(SS_LDFLAGS) + @echo 'Finished building target: $@' + @echo ' ' + +# Other Targets +clean: + -$(RM) $(OBJS)$(C_DEPS)$(EXECUTABLES) TC_C_191_v304 + -@echo ' ' + +.PHONY: all clean dependents +.SECONDARY: + +-include ../makefile.targets diff --git a/libtransform/tests/mitre/TC_C_191_v304/Release/objects.mk b/libIRDB-transform/tests/mitre/TC_C_191_v304/Release/objects.mk similarity index 96% rename from libtransform/tests/mitre/TC_C_191_v304/Release/objects.mk rename to libIRDB-transform/tests/mitre/TC_C_191_v304/Release/objects.mk index dc31e16c685929c0d9eb5bd448a36f54b1533d57..742c2da043f4f5d93c414dca3a725ab2204d9817 100644 --- a/libtransform/tests/mitre/TC_C_191_v304/Release/objects.mk +++ b/libIRDB-transform/tests/mitre/TC_C_191_v304/Release/objects.mk @@ -1,8 +1,8 @@ -################################################################################ -# Automatically-generated file. Do not edit! -################################################################################ - -USER_OBJS := - -LIBS := - +################################################################################ +# Automatically-generated file. Do not edit! +################################################################################ + +USER_OBJS := + +LIBS := + diff --git a/libtransform/tests/mitre/TC_C_191_v304/Release/sources.mk b/libIRDB-transform/tests/mitre/TC_C_191_v304/Release/sources.mk similarity index 96% rename from libtransform/tests/mitre/TC_C_191_v304/Release/sources.mk rename to libIRDB-transform/tests/mitre/TC_C_191_v304/Release/sources.mk index 6975694ac9a45d363f1ed85997abb064dd982456..57cf3c3f15374c8cf5b5cc315ea217c4470e4dca 100644 --- a/libtransform/tests/mitre/TC_C_191_v304/Release/sources.mk +++ b/libIRDB-transform/tests/mitre/TC_C_191_v304/Release/sources.mk @@ -1,17 +1,17 @@ -################################################################################ -# Automatically-generated file. Do not edit! -################################################################################ - -O_SRCS := -C_SRCS := -S_UPPER_SRCS := -OBJ_SRCS := -ASM_SRCS := -OBJS := -C_DEPS := -EXECUTABLES := - -# Every subdirectory with source files must be described here +################################################################################ +# Automatically-generated file. Do not edit! +################################################################################ + +O_SRCS := +C_SRCS := +S_UPPER_SRCS := +OBJ_SRCS := +ASM_SRCS := +OBJS := +C_DEPS := +EXECUTABLES := + +# Every subdirectory with source files must be described here SUBDIRS := \ src \ - + diff --git a/libtransform/tests/mitre/TC_C_191_v304/Release/src/recaman.d b/libIRDB-transform/tests/mitre/TC_C_191_v304/Release/src/recaman.d similarity index 97% rename from libtransform/tests/mitre/TC_C_191_v304/Release/src/recaman.d rename to libIRDB-transform/tests/mitre/TC_C_191_v304/Release/src/recaman.d index 687de8509174eab24fa17b30f06896390dd3df28..d22d96f1b5c45d72a689d340f2b4d735b12af49a 100644 --- a/libtransform/tests/mitre/TC_C_191_v304/Release/src/recaman.d +++ b/libIRDB-transform/tests/mitre/TC_C_191_v304/Release/src/recaman.d @@ -1 +1 @@ -src/recaman.d src/recaman.o: ../src/recaman.c +src/recaman.d src/recaman.o: ../src/recaman.c diff --git a/libtransform/tests/mitre/TC_C_191_v304/Release/src/subdir.mk b/libIRDB-transform/tests/mitre/TC_C_191_v304/Release/src/subdir.mk similarity index 97% rename from libtransform/tests/mitre/TC_C_191_v304/Release/src/subdir.mk rename to libIRDB-transform/tests/mitre/TC_C_191_v304/Release/src/subdir.mk index 56c7f898214ea6696e4124662e2e8dd1d0b76a01..5381eac771fd3a73b2c973aaccfd3a112deb876b 100644 --- a/libtransform/tests/mitre/TC_C_191_v304/Release/src/subdir.mk +++ b/libIRDB-transform/tests/mitre/TC_C_191_v304/Release/src/subdir.mk @@ -1,24 +1,24 @@ -################################################################################ -# Automatically-generated file. Do not edit! -################################################################################ - -# Add inputs and outputs from these tool invocations to the build variables +################################################################################ +# Automatically-generated file. Do not edit! +################################################################################ + +# Add inputs and outputs from these tool invocations to the build variables C_SRCS += \ -../src/recaman.c - +../src/recaman.c + OBJS += \ -./src/recaman.o - +./src/recaman.o + C_DEPS += \ -./src/recaman.d - - -# Each subdirectory must supply rules for building sources it contributes -src/%.o: ../src/%.c - @echo 'Building file: $<' - @echo 'Invoking: GCC C Compiler' - $(SS_CC) -O0 -Wall $(SS_CFLAGS) $(SS_OS_SPECIFIC_CFLAGS) -c -fmessage-length=0 -std=c99 -MMD -MP -MF"$(@:%.o=%.d)" -MT"$(@:%.o=%.d)" -o"$@" "$<" - @echo 'Finished building: $<' - @echo ' ' - - +./src/recaman.d + + +# Each subdirectory must supply rules for building sources it contributes +src/%.o: ../src/%.c + @echo 'Building file: $<' + @echo 'Invoking: GCC C Compiler' + $(SS_CC) -O0 -Wall $(SS_CFLAGS) $(SS_OS_SPECIFIC_CFLAGS) -c -fmessage-length=0 -std=c99 -MMD -MP -MF"$(@:%.o=%.d)" -MT"$(@:%.o=%.d)" -o"$@" "$<" + @echo 'Finished building: $<' + @echo ' ' + + diff --git a/libtransform/tests/mitre/TC_C_191_v304/io-specifications/io-TC_C_191_304_Bad1.xml b/libIRDB-transform/tests/mitre/TC_C_191_v304/io-specifications/io-TC_C_191_304_Bad1.xml similarity index 100% rename from libtransform/tests/mitre/TC_C_191_v304/io-specifications/io-TC_C_191_304_Bad1.xml rename to libIRDB-transform/tests/mitre/TC_C_191_v304/io-specifications/io-TC_C_191_304_Bad1.xml diff --git a/libtransform/tests/mitre/TC_C_191_v304/io-specifications/io-TC_C_191_304_Good1.xml b/libIRDB-transform/tests/mitre/TC_C_191_v304/io-specifications/io-TC_C_191_304_Good1.xml similarity index 100% rename from libtransform/tests/mitre/TC_C_191_v304/io-specifications/io-TC_C_191_304_Good1.xml rename to libIRDB-transform/tests/mitre/TC_C_191_v304/io-specifications/io-TC_C_191_304_Good1.xml diff --git a/libtransform/tests/mitre/TC_C_191_v304/io-specifications/io-TC_C_191_304_Good2.xml b/libIRDB-transform/tests/mitre/TC_C_191_v304/io-specifications/io-TC_C_191_304_Good2.xml similarity index 100% rename from libtransform/tests/mitre/TC_C_191_v304/io-specifications/io-TC_C_191_304_Good2.xml rename to libIRDB-transform/tests/mitre/TC_C_191_v304/io-specifications/io-TC_C_191_304_Good2.xml diff --git a/libtransform/tests/mitre/TC_C_191_v304/io-specifications/io-TC_C_191_304_Good3.xml b/libIRDB-transform/tests/mitre/TC_C_191_v304/io-specifications/io-TC_C_191_304_Good3.xml similarity index 100% rename from libtransform/tests/mitre/TC_C_191_v304/io-specifications/io-TC_C_191_304_Good3.xml rename to libIRDB-transform/tests/mitre/TC_C_191_v304/io-specifications/io-TC_C_191_304_Good3.xml diff --git a/libtransform/tests/mitre/TC_C_191_v304/io-specifications/io-TC_C_191_304_Good4.xml b/libIRDB-transform/tests/mitre/TC_C_191_v304/io-specifications/io-TC_C_191_304_Good4.xml similarity index 100% rename from libtransform/tests/mitre/TC_C_191_v304/io-specifications/io-TC_C_191_304_Good4.xml rename to libIRDB-transform/tests/mitre/TC_C_191_v304/io-specifications/io-TC_C_191_304_Good4.xml diff --git a/libtransform/tests/mitre/TC_C_191_v304/io-specifications/io-TC_C_191_304_Good5.xml b/libIRDB-transform/tests/mitre/TC_C_191_v304/io-specifications/io-TC_C_191_304_Good5.xml similarity index 100% rename from libtransform/tests/mitre/TC_C_191_v304/io-specifications/io-TC_C_191_304_Good5.xml rename to libIRDB-transform/tests/mitre/TC_C_191_v304/io-specifications/io-TC_C_191_304_Good5.xml diff --git a/libtransform/tests/mitre/TC_C_191_v304/io-specifications/io-good.xml b/libIRDB-transform/tests/mitre/TC_C_191_v304/io-specifications/io-good.xml similarity index 100% rename from libtransform/tests/mitre/TC_C_191_v304/io-specifications/io-good.xml rename to libIRDB-transform/tests/mitre/TC_C_191_v304/io-specifications/io-good.xml diff --git a/libtransform/tests/mitre/TC_C_191_v304/io-specifications/io-large input value.xml b/libIRDB-transform/tests/mitre/TC_C_191_v304/io-specifications/io-large input value.xml similarity index 100% rename from libtransform/tests/mitre/TC_C_191_v304/io-specifications/io-large input value.xml rename to libIRDB-transform/tests/mitre/TC_C_191_v304/io-specifications/io-large input value.xml diff --git a/libtransform/tests/mitre/TC_C_191_v304/metaData.xml b/libIRDB-transform/tests/mitre/TC_C_191_v304/metaData.xml similarity index 100% rename from libtransform/tests/mitre/TC_C_191_v304/metaData.xml rename to libIRDB-transform/tests/mitre/TC_C_191_v304/metaData.xml diff --git a/libtransform/tests/mitre/TC_C_191_v304/src/Makefile b/libIRDB-transform/tests/mitre/TC_C_191_v304/src/Makefile similarity index 100% rename from libtransform/tests/mitre/TC_C_191_v304/src/Makefile rename to libIRDB-transform/tests/mitre/TC_C_191_v304/src/Makefile diff --git a/libtransform/tests/mitre/TC_C_191_v304/src/out b/libIRDB-transform/tests/mitre/TC_C_191_v304/src/out similarity index 100% rename from libtransform/tests/mitre/TC_C_191_v304/src/out rename to libIRDB-transform/tests/mitre/TC_C_191_v304/src/out diff --git a/libtransform/tests/mitre/TC_C_191_v304/src/recaman.c b/libIRDB-transform/tests/mitre/TC_C_191_v304/src/recaman.c similarity index 96% rename from libtransform/tests/mitre/TC_C_191_v304/src/recaman.c rename to libIRDB-transform/tests/mitre/TC_C_191_v304/src/recaman.c index 95c710545dcdec2f62dafbd82e658f59a0fbec89..2db8bc266ab35e8bc7d78356525e615bad4cb4dd 100644 --- a/libtransform/tests/mitre/TC_C_191_v304/src/recaman.c +++ b/libIRDB-transform/tests/mitre/TC_C_191_v304/src/recaman.c @@ -1,190 +1,190 @@ -/******************************************* -** -** Copyright (C) 2011 The MITRE Corporation. ALL RIGHTS RESERVED -** -** Author: Mitchell Wills -** Date: 6/28/2011 -** -** Base Test Program -- recaman.c -** -** Variant Test Case Program -** -** -** The original base was altered so that when calculating a buffer index the -** number underflows causing the final buffer index to be negative -** -** STONESOUP Weakness Class: Number Handling -** CWE ID: CWE-191 -** Variant Spreadsheet Rev #: 2 -** Variant Spreadsheet ID: 304 -** -** Variant Features: -** Source Taint: PIPE -** Data Type: SIGNED_SHORT -** Control Flow: SEQUENCE -** Data Flow: BUFFER_ADDRESS_ARRAY_INDEX -** -** Initial Testing: (x means yes, - means no) -** Tested in MS Windows XP 32bit x -** Tested in MS Windows 7 64bit - -** Tested in Ubuntu10_10 Linux 32bit - -** Tested in Ubuntu10_10 Linux 64bit - -** -** Workflow: -** Created:6/28/2011 -** 1st Vett: <programmer> on <date> -** 2nd Vett: <peer> on <date> -** 3rd Vett: <teamleader> on <date> -** 4th Vett: Fortify Issues Fixed on <date> -** 5th Vett: Tested in Harness on <date> -** -** -** I/0 Pairs: -** Good: 1st Set: -** 2nd Set: -** 3rd Set: -** 4th Set: -** 5th Set: -** Bad: 1st Set: -*********************************************/ - -//Recaman's Sequence Generator -#include <stdio.h> -#include <stdlib.h> -#include <ctype.h> - -//Function prototypes -int mygeti (int *); -int recaman(int); -int inSequence(int, int *, int); - -//Securely read in the input number -//Buff[7] means that a maximum of 6 digits can be read -//Any input with a 6 digits in the beginning is valid -//e.g. 123456fffff is valid but ff123456 and 1234ff6234234 are not - -int main(void) -{ - printf("*************************************\n"); - printf("*** Recaman's Sequence Generator ***\n"); - printf("*************************************\n\n"); - - short value; - fputs("Enter a sequence number [ >= 0 ]: ", stdout); - fflush(stdout); - - fputs("A0", stdout); - fflush(stdout); - - char *end, buff [7]; - char* rBuff = fgets(buff, sizeof buff, stdin);//STONESOUP:INTERACTION_POINT //STONESOUP:feature-PIPE - if(!rBuff){//reached EOF - value = -1; - return 1; - } - fputs("A", stdout); - fflush(stdout); - value = (short) strtol(buff, &end, 10); - fflush(stdin); - if(!(!isspace(*buff) && end != buff && (*end == '\n' || *end == '\0'))) - return 1; - - fputs("B", stdout); - fflush(stdout); - - //-1 is the "magic" value that will quit out of the while loop - if (value == -1) { - return 1; - } - //Otherwise, send the value to the recaman function if its greater than zero - else if (value >= 0) { - fputs("C", stdout); - fflush(stdout); - signed short stuff[100];//STONESOUP:feature-SIGNED_SHORT - - short y = (short)(-(-32700-value))/(short)350;//STONESOUP:CROSSOVER_POINT - short x[2]={0, y}; - - *(stuff+x[1]) = value;//STONESOUP:TRIGGER_POINT //STONESOUP:feature-BUFFER_ADDRESS_ARRAY_INDEX - -// CLARK: if you uncomment the printf below, we will get a successful detection - printf("debug: value: %d %d\n", value, *(stuff+x[1])); // this causes the detection - - printf("%d\n\n", recaman(*(stuff+x[1]))); - } - else { - printf("Error: Please enter zero or a positive integer.\n\n"); - } - - return 0; -} - -//Calculate the actual sequence -//A(0) = 0. a(m) = a(m-1) - 1 if a(m) is positive and not already in the sequence, otherwise a(m) = a(m-1) + m. -//The first few numbers in the Recaman's Sequence is 0, 1, 3, 6, 2, 7, 13, 20, 12, 21, 11, 22, 10, 23, 9. -int recaman(int sequenceNo) -{ - int *sequence = NULL; - int i; - int currentValue; - int outputValue = 0; - -printf("sequenceNo = %d\n", sequenceNo); - - //Create the dynamic array for storing the sequence - sequence = (int*) calloc((sequenceNo+1),sizeof(int)); - - //Check to make sure the calloc call succeeded - if (sequence == NULL) { - printf("ERROR: Calloc memory allocation failed\n"); - return -1; - } - - //Setup the sequence precondition - //a(0) = 0 - sequence[0] = 0; - - for (i = 1; i <= sequenceNo; i++) { - currentValue = (sequence[i-1] - i); - - //Do the > 0 check: - if(currentValue > 0) { - //Check if the value has already been seen - if (!inSequence(currentValue, sequence, sequenceNo)) { - //Add it to the sequence if not - sequence[i] = currentValue; - } - else { - //Otherwise, do the addition method and add it to the sequence - sequence[i] = (sequence[i-1] + i); - } - } - //If the value is <0 then do the addition method and add it to the sequence - else { - sequence[i] = (sequence[i-1] + i); - } - } - - //Set the output value - outputValue = sequence[sequenceNo]; - - //Free the dynamic array - free(sequence); - sequence = NULL; - - return outputValue; -} - -//See if the input value is already in the sequence -int inSequence(int value, int *seq, int size) -{ - int j; - - for (j=0; j > -size; j--) { - if (seq[-j] == value) { - return 1; - } - } - - return 0; -} +/******************************************* +** +** Copyright (C) 2011 The MITRE Corporation. ALL RIGHTS RESERVED +** +** Author: Mitchell Wills +** Date: 6/28/2011 +** +** Base Test Program -- recaman.c +** +** Variant Test Case Program +** +** +** The original base was altered so that when calculating a buffer index the +** number underflows causing the final buffer index to be negative +** +** STONESOUP Weakness Class: Number Handling +** CWE ID: CWE-191 +** Variant Spreadsheet Rev #: 2 +** Variant Spreadsheet ID: 304 +** +** Variant Features: +** Source Taint: PIPE +** Data Type: SIGNED_SHORT +** Control Flow: SEQUENCE +** Data Flow: BUFFER_ADDRESS_ARRAY_INDEX +** +** Initial Testing: (x means yes, - means no) +** Tested in MS Windows XP 32bit x +** Tested in MS Windows 7 64bit - +** Tested in Ubuntu10_10 Linux 32bit - +** Tested in Ubuntu10_10 Linux 64bit - +** +** Workflow: +** Created:6/28/2011 +** 1st Vett: <programmer> on <date> +** 2nd Vett: <peer> on <date> +** 3rd Vett: <teamleader> on <date> +** 4th Vett: Fortify Issues Fixed on <date> +** 5th Vett: Tested in Harness on <date> +** +** +** I/0 Pairs: +** Good: 1st Set: +** 2nd Set: +** 3rd Set: +** 4th Set: +** 5th Set: +** Bad: 1st Set: +*********************************************/ + +//Recaman's Sequence Generator +#include <stdio.h> +#include <stdlib.h> +#include <ctype.h> + +//Function prototypes +int mygeti (int *); +int recaman(int); +int inSequence(int, int *, int); + +//Securely read in the input number +//Buff[7] means that a maximum of 6 digits can be read +//Any input with a 6 digits in the beginning is valid +//e.g. 123456fffff is valid but ff123456 and 1234ff6234234 are not + +int main(void) +{ + printf("*************************************\n"); + printf("*** Recaman's Sequence Generator ***\n"); + printf("*************************************\n\n"); + + short value; + fputs("Enter a sequence number [ >= 0 ]: ", stdout); + fflush(stdout); + + fputs("A0", stdout); + fflush(stdout); + + char *end, buff [7]; + char* rBuff = fgets(buff, sizeof buff, stdin);//STONESOUP:INTERACTION_POINT //STONESOUP:feature-PIPE + if(!rBuff){//reached EOF + value = -1; + return 1; + } + fputs("A", stdout); + fflush(stdout); + value = (short) strtol(buff, &end, 10); + fflush(stdin); + if(!(!isspace(*buff) && end != buff && (*end == '\n' || *end == '\0'))) + return 1; + + fputs("B", stdout); + fflush(stdout); + + //-1 is the "magic" value that will quit out of the while loop + if (value == -1) { + return 1; + } + //Otherwise, send the value to the recaman function if its greater than zero + else if (value >= 0) { + fputs("C", stdout); + fflush(stdout); + signed short stuff[100];//STONESOUP:feature-SIGNED_SHORT + + short y = (short)(-(-32700-value))/(short)350;//STONESOUP:CROSSOVER_POINT + short x[2]={0, y}; + + *(stuff+x[1]) = value;//STONESOUP:TRIGGER_POINT //STONESOUP:feature-BUFFER_ADDRESS_ARRAY_INDEX + +// CLARK: if you uncomment the printf below, we will get a successful detection + printf("debug: value: %d %d\n", value, *(stuff+x[1])); // this causes the detection + + printf("%d\n\n", recaman(*(stuff+x[1]))); + } + else { + printf("Error: Please enter zero or a positive integer.\n\n"); + } + + return 0; +} + +//Calculate the actual sequence +//A(0) = 0. a(m) = a(m-1) - 1 if a(m) is positive and not already in the sequence, otherwise a(m) = a(m-1) + m. +//The first few numbers in the Recaman's Sequence is 0, 1, 3, 6, 2, 7, 13, 20, 12, 21, 11, 22, 10, 23, 9. +int recaman(int sequenceNo) +{ + int *sequence = NULL; + int i; + int currentValue; + int outputValue = 0; + +printf("sequenceNo = %d\n", sequenceNo); + + //Create the dynamic array for storing the sequence + sequence = (int*) calloc((sequenceNo+1),sizeof(int)); + + //Check to make sure the calloc call succeeded + if (sequence == NULL) { + printf("ERROR: Calloc memory allocation failed\n"); + return -1; + } + + //Setup the sequence precondition + //a(0) = 0 + sequence[0] = 0; + + for (i = 1; i <= sequenceNo; i++) { + currentValue = (sequence[i-1] - i); + + //Do the > 0 check: + if(currentValue > 0) { + //Check if the value has already been seen + if (!inSequence(currentValue, sequence, sequenceNo)) { + //Add it to the sequence if not + sequence[i] = currentValue; + } + else { + //Otherwise, do the addition method and add it to the sequence + sequence[i] = (sequence[i-1] + i); + } + } + //If the value is <0 then do the addition method and add it to the sequence + else { + sequence[i] = (sequence[i-1] + i); + } + } + + //Set the output value + outputValue = sequence[sequenceNo]; + + //Free the dynamic array + free(sequence); + sequence = NULL; + + return outputValue; +} + +//See if the input value is already in the sequence +int inSequence(int value, int *seq, int size) +{ + int j; + + for (j=0; j > -size; j--) { + if (seq[-j] == value) { + return 1; + } + } + + return 0; +} diff --git a/libtransform/tests/mitre/TC_C_196_v459/README b/libIRDB-transform/tests/mitre/TC_C_196_v459/README similarity index 100% rename from libtransform/tests/mitre/TC_C_196_v459/README rename to libIRDB-transform/tests/mitre/TC_C_196_v459/README diff --git a/libtransform/tests/mitre/TC_C_196_v459/Release/makefile b/libIRDB-transform/tests/mitre/TC_C_196_v459/Release/makefile similarity index 95% rename from libtransform/tests/mitre/TC_C_196_v459/Release/makefile rename to libIRDB-transform/tests/mitre/TC_C_196_v459/Release/makefile index 31349eef48c01b09c0d0424ecd3d2a75f46bcf55..de71eb65e3928feafdf449541f65c18e2be032c7 100644 --- a/libtransform/tests/mitre/TC_C_196_v459/Release/makefile +++ b/libIRDB-transform/tests/mitre/TC_C_196_v459/Release/makefile @@ -1,44 +1,44 @@ -################################################################################ -# Automatically-generated file. Do not edit! -################################################################################ - --include ../makefile.init - -RM := rm -rf - -# All of the sources participating in the build are defined here --include sources.mk --include subdir.mk --include src/subdir.mk --include objects.mk - -ifneq ($(MAKECMDGOALS),clean) -ifneq ($(strip $(C_DEPS)),) --include $(C_DEPS) -endif -endif - --include ../makefile.defs - -# Add inputs and outputs from these tool invocations to the build variables - -# All Target -all: TC_C_196_v459 - -# Tool invocations -TC_C_196_v459: $(OBJS) $(USER_OBJS) - @echo 'Building target: $@' - @echo 'Invoking: MinGW C Linker' - $(SS_LNK) -o"TC_C_196_v459" $(OBJS) $(USER_OBJS) $(LIBS)$ $(SS_LDFLAGS) - @echo 'Finished building target: $@' - @echo ' ' - -# Other Targets -clean: - -$(RM) $(OBJS)$(C_DEPS)$(EXECUTABLES) TC_C_196_v459 - -@echo ' ' - -.PHONY: all clean dependents -.SECONDARY: - --include ../makefile.targets +################################################################################ +# Automatically-generated file. Do not edit! +################################################################################ + +-include ../makefile.init + +RM := rm -rf + +# All of the sources participating in the build are defined here +-include sources.mk +-include subdir.mk +-include src/subdir.mk +-include objects.mk + +ifneq ($(MAKECMDGOALS),clean) +ifneq ($(strip $(C_DEPS)),) +-include $(C_DEPS) +endif +endif + +-include ../makefile.defs + +# Add inputs and outputs from these tool invocations to the build variables + +# All Target +all: TC_C_196_v459 + +# Tool invocations +TC_C_196_v459: $(OBJS) $(USER_OBJS) + @echo 'Building target: $@' + @echo 'Invoking: MinGW C Linker' + $(SS_LNK) -o"TC_C_196_v459" $(OBJS) $(USER_OBJS) $(LIBS)$ $(SS_LDFLAGS) + @echo 'Finished building target: $@' + @echo ' ' + +# Other Targets +clean: + -$(RM) $(OBJS)$(C_DEPS)$(EXECUTABLES) TC_C_196_v459 + -@echo ' ' + +.PHONY: all clean dependents +.SECONDARY: + +-include ../makefile.targets diff --git a/libtransform/tests/mitre/TC_C_196_v459/Release/objects.mk b/libIRDB-transform/tests/mitre/TC_C_196_v459/Release/objects.mk similarity index 96% rename from libtransform/tests/mitre/TC_C_196_v459/Release/objects.mk rename to libIRDB-transform/tests/mitre/TC_C_196_v459/Release/objects.mk index dc31e16c685929c0d9eb5bd448a36f54b1533d57..742c2da043f4f5d93c414dca3a725ab2204d9817 100644 --- a/libtransform/tests/mitre/TC_C_196_v459/Release/objects.mk +++ b/libIRDB-transform/tests/mitre/TC_C_196_v459/Release/objects.mk @@ -1,8 +1,8 @@ -################################################################################ -# Automatically-generated file. Do not edit! -################################################################################ - -USER_OBJS := - -LIBS := - +################################################################################ +# Automatically-generated file. Do not edit! +################################################################################ + +USER_OBJS := + +LIBS := + diff --git a/libtransform/tests/mitre/TC_C_196_v459/Release/sources.mk b/libIRDB-transform/tests/mitre/TC_C_196_v459/Release/sources.mk similarity index 96% rename from libtransform/tests/mitre/TC_C_196_v459/Release/sources.mk rename to libIRDB-transform/tests/mitre/TC_C_196_v459/Release/sources.mk index 6975694ac9a45d363f1ed85997abb064dd982456..57cf3c3f15374c8cf5b5cc315ea217c4470e4dca 100644 --- a/libtransform/tests/mitre/TC_C_196_v459/Release/sources.mk +++ b/libIRDB-transform/tests/mitre/TC_C_196_v459/Release/sources.mk @@ -1,17 +1,17 @@ -################################################################################ -# Automatically-generated file. Do not edit! -################################################################################ - -O_SRCS := -C_SRCS := -S_UPPER_SRCS := -OBJ_SRCS := -ASM_SRCS := -OBJS := -C_DEPS := -EXECUTABLES := - -# Every subdirectory with source files must be described here +################################################################################ +# Automatically-generated file. Do not edit! +################################################################################ + +O_SRCS := +C_SRCS := +S_UPPER_SRCS := +OBJ_SRCS := +ASM_SRCS := +OBJS := +C_DEPS := +EXECUTABLES := + +# Every subdirectory with source files must be described here SUBDIRS := \ src \ - + diff --git a/libtransform/tests/mitre/TC_C_196_v459/Release/src/countlines.d b/libIRDB-transform/tests/mitre/TC_C_196_v459/Release/src/countlines.d similarity index 98% rename from libtransform/tests/mitre/TC_C_196_v459/Release/src/countlines.d rename to libIRDB-transform/tests/mitre/TC_C_196_v459/Release/src/countlines.d index ecb1a16785837aaee076f51258b333fddccb48ef..61403b4949f13819f660f5dc59e96b0b473ae4af 100644 --- a/libtransform/tests/mitre/TC_C_196_v459/Release/src/countlines.d +++ b/libIRDB-transform/tests/mitre/TC_C_196_v459/Release/src/countlines.d @@ -1 +1 @@ -src/countlines.d src/countlines.o: ../src/countlines.c +src/countlines.d src/countlines.o: ../src/countlines.c diff --git a/libtransform/tests/mitre/TC_C_196_v459/Release/src/subdir.mk b/libIRDB-transform/tests/mitre/TC_C_196_v459/Release/src/subdir.mk similarity index 97% rename from libtransform/tests/mitre/TC_C_196_v459/Release/src/subdir.mk rename to libIRDB-transform/tests/mitre/TC_C_196_v459/Release/src/subdir.mk index d4424adee0b96f6b3b081e77d7430fd1dd7fdbe7..bfc8b90c74dcea6411a467043834094db2d248c6 100644 --- a/libtransform/tests/mitre/TC_C_196_v459/Release/src/subdir.mk +++ b/libIRDB-transform/tests/mitre/TC_C_196_v459/Release/src/subdir.mk @@ -1,24 +1,24 @@ -################################################################################ -# Automatically-generated file. Do not edit! -################################################################################ - -# Add inputs and outputs from these tool invocations to the build variables +################################################################################ +# Automatically-generated file. Do not edit! +################################################################################ + +# Add inputs and outputs from these tool invocations to the build variables C_SRCS += \ -../src/countlines.c - +../src/countlines.c + OBJS += \ -./src/countlines.o - +./src/countlines.o + C_DEPS += \ -./src/countlines.d - - -# Each subdirectory must supply rules for building sources it contributes -src/%.o: ../src/%.c - @echo 'Building file: $<' - @echo 'Invoking: GCC C Compiler' - $(SS_CC) -O0 -Wall -c $(SS_CFLAGS) $(SS_SPECIFIC_CFLAGS) -fmessage-length=0 -std=c99 -MMD -MP -MF"$(@:%.o=%.d)" -MT"$(@:%.o=%.d)" -o"$@" "$<" - @echo 'Finished building: $<' - @echo ' ' - - +./src/countlines.d + + +# Each subdirectory must supply rules for building sources it contributes +src/%.o: ../src/%.c + @echo 'Building file: $<' + @echo 'Invoking: GCC C Compiler' + $(SS_CC) -O0 -Wall -c $(SS_CFLAGS) $(SS_SPECIFIC_CFLAGS) -fmessage-length=0 -std=c99 -MMD -MP -MF"$(@:%.o=%.d)" -MT"$(@:%.o=%.d)" -o"$@" "$<" + @echo 'Finished building: $<' + @echo ' ' + + diff --git a/libtransform/tests/mitre/TC_C_196_v459/io-specifications/io-Long File Name.xml b/libIRDB-transform/tests/mitre/TC_C_196_v459/io-specifications/io-Long File Name.xml similarity index 100% rename from libtransform/tests/mitre/TC_C_196_v459/io-specifications/io-Long File Name.xml rename to libIRDB-transform/tests/mitre/TC_C_196_v459/io-specifications/io-Long File Name.xml diff --git a/libtransform/tests/mitre/TC_C_196_v459/io-specifications/io-good.xml b/libIRDB-transform/tests/mitre/TC_C_196_v459/io-specifications/io-good.xml similarity index 100% rename from libtransform/tests/mitre/TC_C_196_v459/io-specifications/io-good.xml rename to libIRDB-transform/tests/mitre/TC_C_196_v459/io-specifications/io-good.xml diff --git a/libtransform/tests/mitre/TC_C_196_v459/metaData.xml b/libIRDB-transform/tests/mitre/TC_C_196_v459/metaData.xml similarity index 100% rename from libtransform/tests/mitre/TC_C_196_v459/metaData.xml rename to libIRDB-transform/tests/mitre/TC_C_196_v459/metaData.xml diff --git a/libtransform/tests/mitre/TC_C_196_v459/src/Makefile b/libIRDB-transform/tests/mitre/TC_C_196_v459/src/Makefile similarity index 100% rename from libtransform/tests/mitre/TC_C_196_v459/src/Makefile rename to libIRDB-transform/tests/mitre/TC_C_196_v459/src/Makefile diff --git a/libtransform/tests/mitre/TC_C_196_v459/src/countlines.c b/libIRDB-transform/tests/mitre/TC_C_196_v459/src/countlines.c similarity index 97% rename from libtransform/tests/mitre/TC_C_196_v459/src/countlines.c rename to libIRDB-transform/tests/mitre/TC_C_196_v459/src/countlines.c index 38f00ba7bed632061f82c8cabdb8d8f71017768d..cecacf59b0b81bae51597c1d37ed527163c690d9 100644 --- a/libtransform/tests/mitre/TC_C_196_v459/src/countlines.c +++ b/libIRDB-transform/tests/mitre/TC_C_196_v459/src/countlines.c @@ -1,305 +1,305 @@ -/******************************************* -** -** Copyright (C) 2011 The MITRE Corporation. ALL RIGHTS RESERVED -** -** Author: Mitchell Wills -** Date: 6/16/2011 -** -** Base Test Program -- countlines.c -** -** Variant Test Case Program -** -** This Base Test Program counts the number of lines of code in a Java Program -** ignoring whitespace and comment lines. It takes as input a single file that is -** located in the same directory as the executable. Note that technically this -** doesn't have to be a .java file and any file will work. This program just looks for -** comments that follow the Java language specification. -** -** Note that it is assumed that all lines of code are under 256 characters. If longer -** lines are encountered, then the counts will be incorrect. Also a /* sequence that -** appears within an escaped string (e.g. "A /* causes an error.") will lead to incorrect -** counts as the algorithim used will not recognize the escaped string and think this is -** the start of a multiline comment. -** -** The program has the following basic flow: -** -** - get filename -** - open file -** - read line -** - if it meets criteria increment counter -** - read next line -** - close file -** - output line count -** -** -** The original base was altered so that the loop counter used to check the file path for -** illegal characters is cast from a signed byte to an unsigned byte. When the file name -** is long the index becomes negative and negative memory is accessed and the program will -** go into an infinite loop (if not 0s exist in the 128 bytes before the buffer) or it will -** no validate all the characters so there is a possibility for path traversal. -** -** STONESOUP Weakness Class: Number Handling -** CWE ID: CWE-196 -** Variant Spreadsheet Rev #: 2 -** Variant Spreadsheet ID: 459 -** -** Variant Features: -** Source Taint: COMMAND_LINE -** Data Type: ARRAY -** Control Flow: LOOP_COMPLEXITY_TEST -** Data Flow: ADDRESS_AS_A_LINEAR_EXPRESSION -** -** Initial Testing: (x means yes, - means no) -** Tested in MS Windows XP 32bit x -** Tested in MS Windows 7 64bit - -** Tested in Ubuntu10_10 Linux 32bit - -** Tested in Ubuntu10_10 Linux 64bit - -** -** Workflow: -** Created:6/16/2011 -** 1st Vett: <programmer> on <date> -** 2nd Vett: <peer> on <date> -** 3rd Vett: <teamleader> on <date> -** 4th Vett: Fortify Issues Fixed on <date> -** 5th Vett: Tested in Harness on <date> -** -** -** I/0 Pairs: -** Good: 1st Set: -** 2nd Set: -** 3rd Set: -** 4th Set: -** 5th Set: -** Bad: 1st Set: -*********************************************/ - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <ctype.h> - -#define DEBUG 0 - -int main (int argc, char *argv[]) -{ - FILE *fp; - - char filename[256];//STONESOUP:feature-ARRAY - char line[256]; - - char *line_pointer; - - int line_already_counted; - int multi_line_comment; - int total_lines; - int lines_of_code; - - - signed char getI(unsigned char i){ - return (signed char)i; - } - - unsigned char i; - - // An incorrect number of arguments were supplied. Let the user know the expected format of - // the command line. One user supplied argument is expected. Remember that the first argument - // is always the program name so we really need to check that 2 arguments exist. - - if (argc != 2) - { - printf("\nERROR: Usage: countlines <filename>\n"); - return(EXIT_FAILURE); - } - - // Get the input that was supplied on the command line. One argument should be there. This - // argument is the name of the .java file that is being counted. - // - // For the file name argument, this code will only grab the first 255 characters from the - // command line argument, placing a NULL terminator at the end. - - memset(filename, '\0', 256); - strncpy(filename, argv[1], 255);//STONESOUP:INTERACTION_POINT //STONESOUP:feature-COMMAND_LINE - filename[255] = '\0'; - - // Validate that the filename provided is just a filename and not a path to some other - // directory. We do this through a blacklist that excludes slashes (both forward and - // backward) and the double dot sequence. - // - // Note that we only loop from 0 to 255 since the last character should be a NULL - // and there is no need to double check this. In addition, this guards against any - // possible buffer overread when we check filename[i+1]. - - for (i=0;getI(i)<255;i++)//STONESOUP:CROSSOVER_POINT //STONESOUP:TRIGGER_POINT //STONESOUP:feature-LOOP_COMPLEXITY_TEST - { - printf("%d %c\n", (signed char)i, *(filename+sizeof(signed char)*(signed char)i) ); - if (*(filename+sizeof(char)*(signed char)i)=='\0') break; - - if (*(filename+sizeof(char)*(signed char)i)=='\\' /*|| filename[(signed char)*(i+1)]=='/'*/) - { - printf("\nERROR: Filename must not contain a slash character.\n"); - return(EXIT_FAILURE); - } - - if (*(filename+sizeof(char)*(signed char)i)==':') - { - printf("\nERROR: Filename must not contain a colon character.\n"); - return(EXIT_FAILURE); - } - - if (*(filename+sizeof(char)*(signed char)i)=='.' && *(filename+sizeof(char)*((signed char)i+1))=='.') //STONESOUP:feature-ADDRESS_AS_A_LINEAR_EXPRESSION - { - printf("\nERROR: Filename must not contain a double dot (e.g. '..') sequence.\n"); - return(EXIT_FAILURE); - } - } - // Open the file in readonly mode. - - fp = fopen(filename, "r"); - if (fp == NULL) - { - printf("\nERROR: Cannot open file.\n"); - return(EXIT_FAILURE); - } - - // After initializing variables, loop through each line of the file using fgets(). The function - // fgets(str, num, fp) reads up to num - 1 characters from the file stream fp and dumps them - // into str. fgets() will stop when it reaches the end of a line, in which case str will be - // terminated with a newline. If fgets() reaches num - 1 characters or encounters the EOF, - // str will be null-terminated. fgets() returns str on success, and NULL on an error. - - multi_line_comment = 0; - total_lines = 0; - lines_of_code = 0; - - memset(line, '\0', 256); - - while (fgets(line,256,fp) != NULL) - { - total_lines++; - - // We are reading a new line so we need to reset the line_already_counted flag since - // it obviously hasn't been counted yet. - - line_already_counted = 0; - - // Since fgets() may terminate a string with a newline ... we need to strip any trailing - // '\n' and replace it with a NULL character. - - if (line[strlen(line)-1] == '\n') line[strlen(line)-1] = '\0'; - - // Set the line_pointer to the first character of the line. - - line_pointer = line; - - // We are now ready to parse the line character by character. - - while (*line_pointer != '\0') - { - // If we are currently in a multi line scenario, then we need to check if we have hit - // an end tag. Otherwise we just advance the pointer and keep looping. - - if (multi_line_comment == 1) - { - if (*line_pointer == '*') - { - // Advance the line_pointer. We need to check for the NULL character - // and break if found. If we don't do this, then the next line_pointer++ - //call (before the start of the next iteration) will advance us out of bounds. - - line_pointer++; - if (*line_pointer == '\0') break; - - if (*line_pointer == '/') - { - // An end tag has been found! Reset the multi_line_comment. - // Note that we still need to advance the pointer and continue - // the loop. - - multi_line_comment = 0; - } - } - - line_pointer++; - continue; - } - - // If the current character is a whitespace, then skip it and continue the loop - // inorder to examine the next character. - - if (isspace(*line_pointer) != 0) - { - line_pointer++; - continue; - } - - // If the current character is a slash, then we need to look at the following - // character to see if the line is a Java comment. If we are looking at a Java - // comment line, then just break out of the loop without incrementing the - // line counter. - - if (*line_pointer == '/') - { - // Advance the line_pointer. We need to check for the NULL character - // and break if found. If we don't do this, then the next line_pointer++ - //call (before the start of the next iteration) will advance us out of bounds. - - line_pointer++; - if (*line_pointer == '\0') break; - - // If the next character is a slash as well, then a single line comment has - // been found. The rest of this line is not code, so break out of this loop. - - if (*line_pointer == '/') break; - - // If the next character is an asteric, then a multi-line comment has been - // found. We now need to skip every line until the end of the comment. To - // do this, we will turn on the multi_line_comment flag and continue - // processing this line (and any following line) looking for the closing tag. - //Note that the end of the comment may contain code on the rest of the - // line after the closing comment tag. - - if (*line_pointer == '*') - { - multi_line_comment = 1; - line_pointer++; - continue; - } - - // Note that if we reach here, a Java comment was NOT found, so we should - // fall through to the default processing and count the current line as a - // valid line of code. - } - - // A line ofJava code has been found! If the line has not already been counted, then - // increment the line counter. - - if (line_already_counted == 0) - { - if (DEBUG) printf("DEBUG: %s\n", line_pointer); - lines_of_code++; - line_already_counted = 1; - } - - // Move the line pointer to the next character in the line so that the next - // iteration of the current loop doesn't try to process the same character. - - line_pointer++; - } - } - - // We are done with the file so close it. - - if (fclose(fp)) - { - printf("\nERROR: File close error.\n"); - return(EXIT_FAILURE); - } - - // We have finished looking at each line in the file, and now have the line count. So print it!! - - if (DEBUG) printf("\nDEBUG: The file '%s' contains %d total lines, of which %d are code.\n\n", filename, total_lines, lines_of_code); - printf("\nRESULT: %d", lines_of_code); - return(EXIT_SUCCESS); -} - -/* End of file */ +/******************************************* +** +** Copyright (C) 2011 The MITRE Corporation. ALL RIGHTS RESERVED +** +** Author: Mitchell Wills +** Date: 6/16/2011 +** +** Base Test Program -- countlines.c +** +** Variant Test Case Program +** +** This Base Test Program counts the number of lines of code in a Java Program +** ignoring whitespace and comment lines. It takes as input a single file that is +** located in the same directory as the executable. Note that technically this +** doesn't have to be a .java file and any file will work. This program just looks for +** comments that follow the Java language specification. +** +** Note that it is assumed that all lines of code are under 256 characters. If longer +** lines are encountered, then the counts will be incorrect. Also a /* sequence that +** appears within an escaped string (e.g. "A /* causes an error.") will lead to incorrect +** counts as the algorithim used will not recognize the escaped string and think this is +** the start of a multiline comment. +** +** The program has the following basic flow: +** +** - get filename +** - open file +** - read line +** - if it meets criteria increment counter +** - read next line +** - close file +** - output line count +** +** +** The original base was altered so that the loop counter used to check the file path for +** illegal characters is cast from a signed byte to an unsigned byte. When the file name +** is long the index becomes negative and negative memory is accessed and the program will +** go into an infinite loop (if not 0s exist in the 128 bytes before the buffer) or it will +** no validate all the characters so there is a possibility for path traversal. +** +** STONESOUP Weakness Class: Number Handling +** CWE ID: CWE-196 +** Variant Spreadsheet Rev #: 2 +** Variant Spreadsheet ID: 459 +** +** Variant Features: +** Source Taint: COMMAND_LINE +** Data Type: ARRAY +** Control Flow: LOOP_COMPLEXITY_TEST +** Data Flow: ADDRESS_AS_A_LINEAR_EXPRESSION +** +** Initial Testing: (x means yes, - means no) +** Tested in MS Windows XP 32bit x +** Tested in MS Windows 7 64bit - +** Tested in Ubuntu10_10 Linux 32bit - +** Tested in Ubuntu10_10 Linux 64bit - +** +** Workflow: +** Created:6/16/2011 +** 1st Vett: <programmer> on <date> +** 2nd Vett: <peer> on <date> +** 3rd Vett: <teamleader> on <date> +** 4th Vett: Fortify Issues Fixed on <date> +** 5th Vett: Tested in Harness on <date> +** +** +** I/0 Pairs: +** Good: 1st Set: +** 2nd Set: +** 3rd Set: +** 4th Set: +** 5th Set: +** Bad: 1st Set: +*********************************************/ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <ctype.h> + +#define DEBUG 0 + +int main (int argc, char *argv[]) +{ + FILE *fp; + + char filename[256];//STONESOUP:feature-ARRAY + char line[256]; + + char *line_pointer; + + int line_already_counted; + int multi_line_comment; + int total_lines; + int lines_of_code; + + + signed char getI(unsigned char i){ + return (signed char)i; + } + + unsigned char i; + + // An incorrect number of arguments were supplied. Let the user know the expected format of + // the command line. One user supplied argument is expected. Remember that the first argument + // is always the program name so we really need to check that 2 arguments exist. + + if (argc != 2) + { + printf("\nERROR: Usage: countlines <filename>\n"); + return(EXIT_FAILURE); + } + + // Get the input that was supplied on the command line. One argument should be there. This + // argument is the name of the .java file that is being counted. + // + // For the file name argument, this code will only grab the first 255 characters from the + // command line argument, placing a NULL terminator at the end. + + memset(filename, '\0', 256); + strncpy(filename, argv[1], 255);//STONESOUP:INTERACTION_POINT //STONESOUP:feature-COMMAND_LINE + filename[255] = '\0'; + + // Validate that the filename provided is just a filename and not a path to some other + // directory. We do this through a blacklist that excludes slashes (both forward and + // backward) and the double dot sequence. + // + // Note that we only loop from 0 to 255 since the last character should be a NULL + // and there is no need to double check this. In addition, this guards against any + // possible buffer overread when we check filename[i+1]. + + for (i=0;getI(i)<255;i++)//STONESOUP:CROSSOVER_POINT //STONESOUP:TRIGGER_POINT //STONESOUP:feature-LOOP_COMPLEXITY_TEST + { + printf("%d %c\n", (signed char)i, *(filename+sizeof(signed char)*(signed char)i) ); + if (*(filename+sizeof(char)*(signed char)i)=='\0') break; + + if (*(filename+sizeof(char)*(signed char)i)=='\\' /*|| filename[(signed char)*(i+1)]=='/'*/) + { + printf("\nERROR: Filename must not contain a slash character.\n"); + return(EXIT_FAILURE); + } + + if (*(filename+sizeof(char)*(signed char)i)==':') + { + printf("\nERROR: Filename must not contain a colon character.\n"); + return(EXIT_FAILURE); + } + + if (*(filename+sizeof(char)*(signed char)i)=='.' && *(filename+sizeof(char)*((signed char)i+1))=='.') //STONESOUP:feature-ADDRESS_AS_A_LINEAR_EXPRESSION + { + printf("\nERROR: Filename must not contain a double dot (e.g. '..') sequence.\n"); + return(EXIT_FAILURE); + } + } + // Open the file in readonly mode. + + fp = fopen(filename, "r"); + if (fp == NULL) + { + printf("\nERROR: Cannot open file.\n"); + return(EXIT_FAILURE); + } + + // After initializing variables, loop through each line of the file using fgets(). The function + // fgets(str, num, fp) reads up to num - 1 characters from the file stream fp and dumps them + // into str. fgets() will stop when it reaches the end of a line, in which case str will be + // terminated with a newline. If fgets() reaches num - 1 characters or encounters the EOF, + // str will be null-terminated. fgets() returns str on success, and NULL on an error. + + multi_line_comment = 0; + total_lines = 0; + lines_of_code = 0; + + memset(line, '\0', 256); + + while (fgets(line,256,fp) != NULL) + { + total_lines++; + + // We are reading a new line so we need to reset the line_already_counted flag since + // it obviously hasn't been counted yet. + + line_already_counted = 0; + + // Since fgets() may terminate a string with a newline ... we need to strip any trailing + // '\n' and replace it with a NULL character. + + if (line[strlen(line)-1] == '\n') line[strlen(line)-1] = '\0'; + + // Set the line_pointer to the first character of the line. + + line_pointer = line; + + // We are now ready to parse the line character by character. + + while (*line_pointer != '\0') + { + // If we are currently in a multi line scenario, then we need to check if we have hit + // an end tag. Otherwise we just advance the pointer and keep looping. + + if (multi_line_comment == 1) + { + if (*line_pointer == '*') + { + // Advance the line_pointer. We need to check for the NULL character + // and break if found. If we don't do this, then the next line_pointer++ + //call (before the start of the next iteration) will advance us out of bounds. + + line_pointer++; + if (*line_pointer == '\0') break; + + if (*line_pointer == '/') + { + // An end tag has been found! Reset the multi_line_comment. + // Note that we still need to advance the pointer and continue + // the loop. + + multi_line_comment = 0; + } + } + + line_pointer++; + continue; + } + + // If the current character is a whitespace, then skip it and continue the loop + // inorder to examine the next character. + + if (isspace(*line_pointer) != 0) + { + line_pointer++; + continue; + } + + // If the current character is a slash, then we need to look at the following + // character to see if the line is a Java comment. If we are looking at a Java + // comment line, then just break out of the loop without incrementing the + // line counter. + + if (*line_pointer == '/') + { + // Advance the line_pointer. We need to check for the NULL character + // and break if found. If we don't do this, then the next line_pointer++ + //call (before the start of the next iteration) will advance us out of bounds. + + line_pointer++; + if (*line_pointer == '\0') break; + + // If the next character is a slash as well, then a single line comment has + // been found. The rest of this line is not code, so break out of this loop. + + if (*line_pointer == '/') break; + + // If the next character is an asteric, then a multi-line comment has been + // found. We now need to skip every line until the end of the comment. To + // do this, we will turn on the multi_line_comment flag and continue + // processing this line (and any following line) looking for the closing tag. + //Note that the end of the comment may contain code on the rest of the + // line after the closing comment tag. + + if (*line_pointer == '*') + { + multi_line_comment = 1; + line_pointer++; + continue; + } + + // Note that if we reach here, a Java comment was NOT found, so we should + // fall through to the default processing and count the current line as a + // valid line of code. + } + + // A line ofJava code has been found! If the line has not already been counted, then + // increment the line counter. + + if (line_already_counted == 0) + { + if (DEBUG) printf("DEBUG: %s\n", line_pointer); + lines_of_code++; + line_already_counted = 1; + } + + // Move the line pointer to the next character in the line so that the next + // iteration of the current loop doesn't try to process the same character. + + line_pointer++; + } + } + + // We are done with the file so close it. + + if (fclose(fp)) + { + printf("\nERROR: File close error.\n"); + return(EXIT_FAILURE); + } + + // We have finished looking at each line in the file, and now have the line count. So print it!! + + if (DEBUG) printf("\nDEBUG: The file '%s' contains %d total lines, of which %d are code.\n\n", filename, total_lines, lines_of_code); + printf("\nRESULT: %d", lines_of_code); + return(EXIT_SUCCESS); +} + +/* End of file */ diff --git a/libtransform/tests/mitre/TC_C_196_v459/testData/1.java b/libIRDB-transform/tests/mitre/TC_C_196_v459/testData/1.java similarity index 100% rename from libtransform/tests/mitre/TC_C_196_v459/testData/1.java rename to libIRDB-transform/tests/mitre/TC_C_196_v459/testData/1.java diff --git a/libtransform/tests/mitre/TC_C_196_v459/testData/2.java b/libIRDB-transform/tests/mitre/TC_C_196_v459/testData/2.java similarity index 100% rename from libtransform/tests/mitre/TC_C_196_v459/testData/2.java rename to libIRDB-transform/tests/mitre/TC_C_196_v459/testData/2.java diff --git a/libtransform/tests/mitre/TC_C_196_v459/testData/3.java b/libIRDB-transform/tests/mitre/TC_C_196_v459/testData/3.java similarity index 100% rename from libtransform/tests/mitre/TC_C_196_v459/testData/3.java rename to libIRDB-transform/tests/mitre/TC_C_196_v459/testData/3.java diff --git a/libtransform/tests/mitre/TC_C_196_v459/testData/4.java b/libIRDB-transform/tests/mitre/TC_C_196_v459/testData/4.java similarity index 100% rename from libtransform/tests/mitre/TC_C_196_v459/testData/4.java rename to libIRDB-transform/tests/mitre/TC_C_196_v459/testData/4.java diff --git a/libtransform/tests/mitre/TC_C_196_v459/testData/5.java b/libIRDB-transform/tests/mitre/TC_C_196_v459/testData/5.java similarity index 84% rename from libtransform/tests/mitre/TC_C_196_v459/testData/5.java rename to libIRDB-transform/tests/mitre/TC_C_196_v459/testData/5.java index 2fc9642d9982e414872236d31eb4bd1c98a30bd7..8d218b78fb0fd1be6f620cd2be7a371725e6684c 100644 --- a/libtransform/tests/mitre/TC_C_196_v459/testData/5.java +++ b/libIRDB-transform/tests/mitre/TC_C_196_v459/testData/5.java @@ -1,11 +1,11 @@ -//hi -asdsfd -/*hello - -test*/ - -asfdsadf -adsfsadf - - +//hi +asdsfd +/*hello + +test*/ + +asfdsadf +adsfsadf + + 345345 \ No newline at end of file diff --git a/libtransform/tests/mul.c b/libIRDB-transform/tests/mul.c similarity index 100% rename from libtransform/tests/mul.c rename to libIRDB-transform/tests/mul.c diff --git a/libtransform/tests/sample_meds_int.annot b/libIRDB-transform/tests/sample_meds_int.annot similarity index 100% rename from libtransform/tests/sample_meds_int.annot rename to libIRDB-transform/tests/sample_meds_int.annot diff --git a/libtransform/tests/signed_add.64.c b/libIRDB-transform/tests/signed_add.64.c similarity index 100% rename from libtransform/tests/signed_add.64.c rename to libIRDB-transform/tests/signed_add.64.c diff --git a/libtransform/tests/signed_mul.32.c b/libIRDB-transform/tests/signed_mul.32.c similarity index 100% rename from libtransform/tests/signed_mul.32.c rename to libIRDB-transform/tests/signed_mul.32.c diff --git a/libtransform/tests/signed_mul.64.c b/libIRDB-transform/tests/signed_mul.64.c similarity index 100% rename from libtransform/tests/signed_mul.64.c rename to libIRDB-transform/tests/signed_mul.64.c diff --git a/libtransform/tests/signedness.64.unsigned.c b/libIRDB-transform/tests/signedness.64.unsigned.c similarity index 100% rename from libtransform/tests/signedness.64.unsigned.c rename to libIRDB-transform/tests/signedness.64.unsigned.c diff --git a/libtransform/tests/simpletest.c b/libIRDB-transform/tests/simpletest.c similarity index 100% rename from libtransform/tests/simpletest.c rename to libIRDB-transform/tests/simpletest.c diff --git a/libtransform/tests/test.signed_add.64.sh b/libIRDB-transform/tests/test.signed_add.64.sh similarity index 100% rename from libtransform/tests/test.signed_add.64.sh rename to libIRDB-transform/tests/test.signed_add.64.sh diff --git a/libtransform/tests/test.signed_mul.32.sh b/libIRDB-transform/tests/test.signed_mul.32.sh similarity index 100% rename from libtransform/tests/test.signed_mul.32.sh rename to libIRDB-transform/tests/test.signed_mul.32.sh diff --git a/libtransform/tests/test.signed_mul.64.sh b/libIRDB-transform/tests/test.signed_mul.64.sh similarity index 100% rename from libtransform/tests/test.signed_mul.64.sh rename to libIRDB-transform/tests/test.signed_mul.64.sh diff --git a/libtransform/tests/test.trunc.32.16.signed.sh b/libIRDB-transform/tests/test.trunc.32.16.signed.sh similarity index 100% rename from libtransform/tests/test.trunc.32.16.signed.sh rename to libIRDB-transform/tests/test.trunc.32.16.signed.sh diff --git a/libtransform/tests/test.trunc.32.16.unsigned.sh b/libIRDB-transform/tests/test.trunc.32.16.unsigned.sh similarity index 100% rename from libtransform/tests/test.trunc.32.16.unsigned.sh rename to libIRDB-transform/tests/test.trunc.32.16.unsigned.sh diff --git a/libtransform/tests/test.trunc.32.8.signed.sh b/libIRDB-transform/tests/test.trunc.32.8.signed.sh similarity index 100% rename from libtransform/tests/test.trunc.32.8.signed.sh rename to libIRDB-transform/tests/test.trunc.32.8.signed.sh diff --git a/libtransform/tests/test.trunc.32.8.unsigned.sh b/libIRDB-transform/tests/test.trunc.32.8.unsigned.sh similarity index 100% rename from libtransform/tests/test.trunc.32.8.unsigned.sh rename to libIRDB-transform/tests/test.trunc.32.8.unsigned.sh diff --git a/libtransform/tests/test.trunc.64.16.signed.sh b/libIRDB-transform/tests/test.trunc.64.16.signed.sh similarity index 100% rename from libtransform/tests/test.trunc.64.16.signed.sh rename to libIRDB-transform/tests/test.trunc.64.16.signed.sh diff --git a/libtransform/tests/test.trunc.64.16.unknown.sh b/libIRDB-transform/tests/test.trunc.64.16.unknown.sh similarity index 100% rename from libtransform/tests/test.trunc.64.16.unknown.sh rename to libIRDB-transform/tests/test.trunc.64.16.unknown.sh diff --git a/libtransform/tests/test.trunc.64.16.unsigned.sh b/libIRDB-transform/tests/test.trunc.64.16.unsigned.sh similarity index 100% rename from libtransform/tests/test.trunc.64.16.unsigned.sh rename to libIRDB-transform/tests/test.trunc.64.16.unsigned.sh diff --git a/libtransform/tests/test.trunc.64.32.signed.sh b/libIRDB-transform/tests/test.trunc.64.32.signed.sh similarity index 100% rename from libtransform/tests/test.trunc.64.32.signed.sh rename to libIRDB-transform/tests/test.trunc.64.32.signed.sh diff --git a/libtransform/tests/test.trunc.64.32.unsigned.sh b/libIRDB-transform/tests/test.trunc.64.32.unsigned.sh similarity index 100% rename from libtransform/tests/test.trunc.64.32.unsigned.sh rename to libIRDB-transform/tests/test.trunc.64.32.unsigned.sh diff --git a/libtransform/tests/test.trunc.64.8.signed.sh b/libIRDB-transform/tests/test.trunc.64.8.signed.sh similarity index 100% rename from libtransform/tests/test.trunc.64.8.signed.sh rename to libIRDB-transform/tests/test.trunc.64.8.signed.sh diff --git a/libtransform/tests/test.trunc.64.8.unknown.sh b/libIRDB-transform/tests/test.trunc.64.8.unknown.sh similarity index 100% rename from libtransform/tests/test.trunc.64.8.unknown.sh rename to libIRDB-transform/tests/test.trunc.64.8.unknown.sh diff --git a/libtransform/tests/test.trunc.64.8.unsigned.sh b/libIRDB-transform/tests/test.trunc.64.8.unsigned.sh similarity index 100% rename from libtransform/tests/test.trunc.64.8.unsigned.sh rename to libIRDB-transform/tests/test.trunc.64.8.unsigned.sh diff --git a/libtransform/tests/test.unsigned_add.64.sh b/libIRDB-transform/tests/test.unsigned_add.64.sh similarity index 100% rename from libtransform/tests/test.unsigned_add.64.sh rename to libIRDB-transform/tests/test.unsigned_add.64.sh diff --git a/libtransform/tests/test.unsigned_mul.32.sh b/libIRDB-transform/tests/test.unsigned_mul.32.sh similarity index 100% rename from libtransform/tests/test.unsigned_mul.32.sh rename to libIRDB-transform/tests/test.unsigned_mul.32.sh diff --git a/libtransform/tests/test.unsigned_mul.64.sh b/libIRDB-transform/tests/test.unsigned_mul.64.sh similarity index 100% rename from libtransform/tests/test.unsigned_mul.64.sh rename to libIRDB-transform/tests/test.unsigned_mul.64.sh diff --git a/libtransform/tests/testall b/libIRDB-transform/tests/testall similarity index 100% rename from libtransform/tests/testall rename to libIRDB-transform/tests/testall diff --git a/libtransform/tests/trunc.16.8.c b/libIRDB-transform/tests/trunc.16.8.c similarity index 100% rename from libtransform/tests/trunc.16.8.c rename to libIRDB-transform/tests/trunc.16.8.c diff --git a/libtransform/tests/trunc.32.16.signed.c b/libIRDB-transform/tests/trunc.32.16.signed.c similarity index 100% rename from libtransform/tests/trunc.32.16.signed.c rename to libIRDB-transform/tests/trunc.32.16.signed.c diff --git a/libtransform/tests/trunc.32.16.unsigned.c b/libIRDB-transform/tests/trunc.32.16.unsigned.c similarity index 100% rename from libtransform/tests/trunc.32.16.unsigned.c rename to libIRDB-transform/tests/trunc.32.16.unsigned.c diff --git a/libtransform/tests/trunc.32.8.signed.c b/libIRDB-transform/tests/trunc.32.8.signed.c similarity index 100% rename from libtransform/tests/trunc.32.8.signed.c rename to libIRDB-transform/tests/trunc.32.8.signed.c diff --git a/libtransform/tests/trunc.32.8.unsigned.c b/libIRDB-transform/tests/trunc.32.8.unsigned.c similarity index 100% rename from libtransform/tests/trunc.32.8.unsigned.c rename to libIRDB-transform/tests/trunc.32.8.unsigned.c diff --git a/libtransform/tests/trunc.64.16.signed.c b/libIRDB-transform/tests/trunc.64.16.signed.c similarity index 100% rename from libtransform/tests/trunc.64.16.signed.c rename to libIRDB-transform/tests/trunc.64.16.signed.c diff --git a/libtransform/tests/trunc.64.16.unknown.c b/libIRDB-transform/tests/trunc.64.16.unknown.c similarity index 100% rename from libtransform/tests/trunc.64.16.unknown.c rename to libIRDB-transform/tests/trunc.64.16.unknown.c diff --git a/libtransform/tests/trunc.64.16.unsigned.c b/libIRDB-transform/tests/trunc.64.16.unsigned.c similarity index 100% rename from libtransform/tests/trunc.64.16.unsigned.c rename to libIRDB-transform/tests/trunc.64.16.unsigned.c diff --git a/libtransform/tests/trunc.64.32.signed.c b/libIRDB-transform/tests/trunc.64.32.signed.c similarity index 100% rename from libtransform/tests/trunc.64.32.signed.c rename to libIRDB-transform/tests/trunc.64.32.signed.c diff --git a/libtransform/tests/trunc.64.32.unsigned.c b/libIRDB-transform/tests/trunc.64.32.unsigned.c similarity index 100% rename from libtransform/tests/trunc.64.32.unsigned.c rename to libIRDB-transform/tests/trunc.64.32.unsigned.c diff --git a/libtransform/tests/trunc.64.8.signed.c b/libIRDB-transform/tests/trunc.64.8.signed.c similarity index 100% rename from libtransform/tests/trunc.64.8.signed.c rename to libIRDB-transform/tests/trunc.64.8.signed.c diff --git a/libtransform/tests/trunc.64.8.unknown.c b/libIRDB-transform/tests/trunc.64.8.unknown.c similarity index 100% rename from libtransform/tests/trunc.64.8.unknown.c rename to libIRDB-transform/tests/trunc.64.8.unknown.c diff --git a/libtransform/tests/trunc.64.8.unsigned.c b/libIRDB-transform/tests/trunc.64.8.unsigned.c similarity index 100% rename from libtransform/tests/trunc.64.8.unsigned.c rename to libIRDB-transform/tests/trunc.64.8.unsigned.c diff --git a/libtransform/tests/unsigned_add.64.c b/libIRDB-transform/tests/unsigned_add.64.c similarity index 100% rename from libtransform/tests/unsigned_add.64.c rename to libIRDB-transform/tests/unsigned_add.64.c diff --git a/libtransform/tests/unsigned_add.c b/libIRDB-transform/tests/unsigned_add.c similarity index 100% rename from libtransform/tests/unsigned_add.c rename to libIRDB-transform/tests/unsigned_add.c diff --git a/libtransform/tests/unsigned_mul.32.c b/libIRDB-transform/tests/unsigned_mul.32.c similarity index 100% rename from libtransform/tests/unsigned_mul.32.c rename to libIRDB-transform/tests/unsigned_mul.32.c diff --git a/libtransform/tests/unsigned_mul.64.c b/libIRDB-transform/tests/unsigned_mul.64.c similarity index 100% rename from libtransform/tests/unsigned_mul.64.c rename to libIRDB-transform/tests/unsigned_mul.64.c diff --git a/libIRDB/include/util/IBT_Provenance.hpp b/libIRDB-util/include/IBT_Provenance.hpp similarity index 52% rename from libIRDB/include/util/IBT_Provenance.hpp rename to libIRDB-util/include/IBT_Provenance.hpp index 07f2b0bf7c4a62142e0d4560f1de6a9e041cf4ae..3aba669af6eca86d5688f0d144cf5a5fb35c3339 100644 --- a/libIRDB/include/util/IBT_Provenance.hpp +++ b/libIRDB-util/include/IBT_Provenance.hpp @@ -3,12 +3,12 @@ #include "Provenance.hpp" -class IBTProvenance_t +class IBTProvenance_t : public IRDB_SDK::IBTProvenance_t { private: // types - using InsnProvMap_t = std::map<const Instruction_t*, Provenance_t>; + using InsnProvMap_t = std::map<const IRDB_SDK::Instruction_t*, Provenance_t>; // data InsnProvMap_t prov_map; @@ -19,12 +19,16 @@ class IBTProvenance_t void AddProvs(const Provenance_t& p, const InstructionSet_t& after) ; public: - IBTProvenance_t(const FileIR_t* f=NULL) {Init(); if(f) AddFile(f);} + IBTProvenance_t(const IRDB_SDK::FileIR_t* f=NULL) {Init(); if(f) addFile(f);} virtual ~IBTProvenance_t() {} // default destructor not OK for some reason? - void AddFile(const FileIR_t* ); + void addFile(const IRDB_SDK::FileIR_t* ); + const Provenance_t& getProvenance (const IRDB_SDK::Instruction_t* i) const + { + return (*this)[i]; + } - const Provenance_t& operator[] (const Instruction_t* i) const + const Provenance_t& operator[] (const IRDB_SDK::Instruction_t* i) const { const auto it=prov_map.find(i); if (it!= prov_map.end()) diff --git a/libIRDB/include/util/Provenance.hpp b/libIRDB-util/include/Provenance.hpp similarity index 90% rename from libIRDB/include/util/Provenance.hpp rename to libIRDB-util/include/Provenance.hpp index 73a14041a09d185cf973c8d43e5a4d47bfe5ef5d..520ac73da6518bbcc6faa7dcfae436d9c795d306 100644 --- a/libIRDB/include/util/Provenance.hpp +++ b/libIRDB-util/include/Provenance.hpp @@ -3,14 +3,14 @@ #include <bitset> -class Provenance_t +class Provenance_t : public IRDB_SDK::Provenance_t { private: // ProvType enum values are explicit to show they are in bounds of the bitset enum class ProvType { IndJump = 0, IndCall = 1, Ret = 2 }; std::bitset<3> prov; public: - Provenance_t() {prov = bitset<3>();} + Provenance_t() {prov = std::bitset<3>();} virtual ~Provenance_t() {;} void addReturn() diff --git a/libIRDB/include/util/insn_preds.hpp b/libIRDB-util/include/insn_preds.hpp similarity index 58% rename from libIRDB/include/util/insn_preds.hpp rename to libIRDB-util/include/insn_preds.hpp index ac05f41c6c14a1d060714372874c9b6070284d90..3078d25b8272aa235781261306fe033e106f9298 100644 --- a/libIRDB/include/util/insn_preds.hpp +++ b/libIRDB-util/include/insn_preds.hpp @@ -22,21 +22,23 @@ #define insn_preds_h -class InstructionPredecessors_t +class InstructionPredecessors_t : public IRDB_SDK::InstructionPredecessors_t { private: - typedef std::map<const Instruction_t*, InstructionSet_t> PredMap_t; + typedef std::map<const IRDB_SDK::Instruction_t*, InstructionSet_t> PredMap_t; public: - InstructionPredecessors_t(const FileIR_t* f=NULL) {Init(); if(f) AddFile(f);} + InstructionPredecessors_t(const IRDB_SDK::FileIR_t* f=NULL) {Init(); if(f) AddFile(f);} virtual ~InstructionPredecessors_t() {;} - virtual void AddFile(const FileIR_t* ); + virtual void AddFile(const IRDB_SDK::FileIR_t* ); - InstructionSet_t& operator[] (const Instruction_t* i) + virtual const InstructionSet_t& getPredecessors(const IRDB_SDK::Instruction_t* i) const { return (*this)[i]; } + + InstructionSet_t& operator[] (const IRDB_SDK::Instruction_t* i) { return pred_map[i]; } - const InstructionSet_t& operator[] (const Instruction_t* i) const + const InstructionSet_t& operator[] (const IRDB_SDK::Instruction_t* i) const { PredMap_t::const_iterator it=pred_map.find(i); if (it!= pred_map.end()) @@ -50,8 +52,8 @@ class InstructionPredecessors_t private: - virtual void AddPred(const Instruction_t* before, const Instruction_t* after); - virtual void AddPreds(const Instruction_t* before, const InstructionSet_t& after); + virtual void AddPred(const IRDB_SDK::Instruction_t* before, const IRDB_SDK::Instruction_t* after); + virtual void AddPreds(const IRDB_SDK::Instruction_t* before, const IRDB_SDK::InstructionSet_t& after); PredMap_t pred_map; }; diff --git a/libIRDB/include/libIRDB-util.hpp b/libIRDB-util/include/libIRDB-util.hpp similarity index 88% rename from libIRDB/include/libIRDB-util.hpp rename to libIRDB-util/include/libIRDB-util.hpp index c1d852e1ef7df82667b1eba23af7b29c3b844f5e..5b091d1165fab6cc1aa9edf3060a2a88e908c445 100644 --- a/libIRDB/include/libIRDB-util.hpp +++ b/libIRDB-util/include/libIRDB-util.hpp @@ -23,6 +23,8 @@ /* Building a CFG depends on core functionality */ +#include <irdb-core> +#include <irdb-util> #include <libIRDB-core.hpp> #include <vector> @@ -33,9 +35,9 @@ namespace libIRDB { -#include <util/insn_preds.hpp> -#include <util/IBT_Provenance.hpp> -#include <util/params.hpp> +#include <insn_preds.hpp> +#include <IBT_Provenance.hpp> +#include <params.hpp> }; diff --git a/libIRDB-util/include/params.hpp b/libIRDB-util/include/params.hpp new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/libIRDB/src/util/IBT_Provenance.cpp b/libIRDB-util/src/IBT_Provenance.cpp similarity index 56% rename from libIRDB/src/util/IBT_Provenance.cpp rename to libIRDB-util/src/IBT_Provenance.cpp index 9956da0bd03697c51417395a5ad79f3ba4ef9a41..978fdc9d5ffe7df5e151dc4d98554f0a1f3f74a5 100644 --- a/libIRDB/src/util/IBT_Provenance.cpp +++ b/libIRDB-util/src/IBT_Provenance.cpp @@ -2,7 +2,7 @@ #include <bitset> #include <libIRDB-core.hpp> #include <libIRDB-util.hpp> -#include <utils.hpp> +#include <irdb-util> using namespace libIRDB; using namespace std; @@ -11,24 +11,25 @@ using namespace std; Provenance_t IBTProvenance_t::empty; -void IBTProvenance_t::AddFile(const FileIR_t* firp) +void IBTProvenance_t::addFile(const IRDB_SDK::FileIR_t* firp) { - using ICFSProvMap_t = std::map<const ICFS_t*, Provenance_t>; + using ICFSProvMap_t = std::map<const IRDB_SDK::ICFS_t*, Provenance_t>; auto icfs_prov_map = ICFSProvMap_t(); // collect before info for each icfs into icfs_prov_map - for(auto insn : firp->GetInstructions()) + for(auto insn : firp->getInstructions()) { - const auto &ibTargets=insn->GetIBTargets(); + const auto &ibTargets=insn->getIBTargets(); if(!ibTargets) continue; - auto this_prov=Provenance_t(); - const auto IndBranchAsm=DecodedInstruction_t(insn); - const auto isIndJmp = IndBranchAsm.isUnconditionalBranch() && !IndBranchAsm.getOperand(0).isConstant(); - const auto isIndCall = IndBranchAsm.isCall() && !IndBranchAsm.getOperand(0).isConstant(); + libIRDB::Provenance_t this_prov; + const auto p_IndBranchAsm=DecodedInstruction_t::factory(insn); + const auto &IndBranchAsm=*p_IndBranchAsm; + const auto isIndJmp = IndBranchAsm.isUnconditionalBranch() && !IndBranchAsm.getOperand(0)->isConstant(); + const auto isIndCall = IndBranchAsm.isCall() && !IndBranchAsm.getOperand(0)->isConstant(); const auto isRet = IndBranchAsm.isReturn(); if(isIndJmp) @@ -52,7 +53,7 @@ void IBTProvenance_t::AddFile(const FileIR_t* firp) } // deploy info for each target of the icfs - for(const auto &icfs : firp->GetAllICFS()) + for(const auto &icfs : firp->getAllICFS()) { assert(icfs); for(const auto &insn : *icfs) @@ -62,3 +63,8 @@ void IBTProvenance_t::AddFile(const FileIR_t* firp) } } +unique_ptr<IRDB_SDK::IBTProvenance_t> IRDB_SDK::IBTProvenance_t::factory(const IRDB_SDK::FileIR_t* f) +{ + return unique_ptr<IRDB_SDK::IBTProvenance_t>(new libIRDB::IBTProvenance_t(f)); +} + diff --git a/libIRDB/src/util/Makefile b/libIRDB-util/src/Makefile similarity index 100% rename from libIRDB/src/util/Makefile rename to libIRDB-util/src/Makefile diff --git a/libIRDB/src/util/SConscript b/libIRDB-util/src/SConscript similarity index 72% rename from libIRDB/src/util/SConscript rename to libIRDB-util/src/SConscript index 2e773c30efd67175ad565c6105cf6ff741e239f7..b57c532c186b2f609e50620c4dd156e9d720a6bc 100644 --- a/libIRDB/src/util/SConscript +++ b/libIRDB-util/src/SConscript @@ -5,22 +5,24 @@ myenv=env myenv.Replace(SECURITY_TRANSFORMS_HOME=os.environ['SECURITY_TRANSFORMS_HOME']) -libname="IRDB-util" +libname="irdb-util" files= ''' insn_preds.cpp IBT_Provenance.cpp params.cpp ''' cpppath=''' + $IRDB_SDK/include/ $SECURITY_TRANSFORMS_HOME/include/ - $SECURITY_TRANSFORMS_HOME/libIRDB/include/ + $SECURITY_TRANSFORMS_HOME/libIRDB-core/include/ + $SECURITY_TRANSFORMS_HOME/libIRDB-util/include/ ''' #myenv.Append(CCFLAGS=" -Wall -W -Wextra -Wconversion ") myenv=myenv.Clone(CPPPATH=Split(cpppath)) myenv.Append(CXXFLAGS = " -std=c++11 ") -lib=myenv.SharedLibrary(libname, Split(files), LIBS=Split("IRDB-core"), LIBPATH=Split("$SECURITY_TRANSFORMS_HOME/lib")) +lib=myenv.SharedLibrary(libname, Split(files), LIBS=Split("irdb-core"), LIBPATH=Split("$SECURITY_TRANSFORMS_HOME/lib")) install=env.Install("$SECURITY_TRANSFORMS_HOME/lib/", lib) Default(install) diff --git a/tools/dump_map/SConstruct b/libIRDB-util/src/SConstruct similarity index 100% rename from tools/dump_map/SConstruct rename to libIRDB-util/src/SConstruct diff --git a/libIRDB-util/src/insn_preds.cpp b/libIRDB-util/src/insn_preds.cpp new file mode 100644 index 0000000000000000000000000000000000000000..405b737afddce242139f4dc332ba1cb95e633c28 --- /dev/null +++ b/libIRDB-util/src/insn_preds.cpp @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2014-2015 - Zephyr Software LLC + * + * This file may be used and modified for non-commercial purposes as long as + * all copyright, permission, and nonwarranty notices are preserved. + * Redistribution is prohibited without prior written consent from Zephyr + * Software. + * + * Please contact the authors for restrictions applying to commercial use. + * + * THIS SOURCE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * Author: Zephyr Software + * e-mail: jwd@zephyr-software.com + * URL : http://www.zephyr-software.com/ + * + */ + + +#include <map> +#include <libIRDB-core.hpp> +#include <libIRDB-util.hpp> +#include <irdb-util> + +using namespace libIRDB; +using namespace std; + + + +void InstructionPredecessors_t::AddPreds(const IRDB_SDK::Instruction_t* before, const InstructionSet_t& afterset) +{ + for(auto it=afterset.begin(); it!=afterset.end(); ++it) + { + pred_map[*it].insert(const_cast<IRDB_SDK::Instruction_t*>(before)); + } +} + +void InstructionPredecessors_t::AddPred(const IRDB_SDK::Instruction_t* before, const IRDB_SDK::Instruction_t* after) +{ + assert(before); + if(!after) return; + + if(getenv("DUMP_PRED_CREATE")) + cout<<"Found "<<after->getBaseID()<<":"<<after->getDisassembly() << " follows "<< before->getBaseID()<<":"<<before->getDisassembly()<<endl; + pred_map[after].insert(const_cast<IRDB_SDK::Instruction_t*>(before)); + +} + +void InstructionPredecessors_t::AddFile(const IRDB_SDK::FileIR_t* firp2) +{ + auto firp=const_cast<IRDB_SDK::FileIR_t*>(firp2); // discarding const qualifier because we know we won't change the set + for(auto it=firp->getInstructions().begin(); + it!=firp->getInstructions().end(); + ++it) + { + auto insn=*it; + AddPred(insn, insn->getTarget()); + AddPred(insn, insn->getFallthrough()); + + // if we have a complete list, then explicitly add them. + if(insn->getIBTargets() && insn->getIBTargets()->isComplete()) + AddPreds(insn, *insn->getIBTargets()); + + } +} + +unique_ptr<IRDB_SDK::InstructionPredecessors_t> IRDB_SDK::InstructionPredecessors_t::factory(IRDB_SDK::FileIR_t* firp) +{ + return unique_ptr<IRDB_SDK::InstructionPredecessors_t>(new libIRDB::InstructionPredecessors_t(firp)); +} + diff --git a/libIRDB/src/util/params.cpp b/libIRDB-util/src/params.cpp similarity index 53% rename from libIRDB/src/util/params.cpp rename to libIRDB-util/src/params.cpp index 2d344894919536c9436292b398138cdc0b5ba829..68bab5b3aa27ff385ba45e3b893c8eac37eaa7cc 100644 --- a/libIRDB/src/util/params.cpp +++ b/libIRDB-util/src/params.cpp @@ -21,51 +21,39 @@ #include <libIRDB-core.hpp> #include <libIRDB-util.hpp> -#include <utils.hpp> +#include <irdb-util> +#include <algorithm> using namespace libIRDB; using namespace std; // Does instruction potentially write to a parameter to a call? -bool libIRDB::IsParameterWrite(const FileIR_t *firp, Instruction_t* insn, string& output_dst) +bool IRDB_SDK::isParameterWrite(const IRDB_SDK::FileIR_t *firp, IRDB_SDK::Instruction_t* insn, string& output_dst) { -// auto d=DISASM({0}); -// Disassemble(insn,d); - const auto d=DecodedInstruction_t(insn); + const auto p_d=DecodedInstruction_t::factory(insn); + const auto &d=*p_d; -// if(d.Argument1.AccessMode!=WRITE) if(!d.hasOperand(0)) return false; - if(!d.getOperand(0).isWritten()) + if(!d.getOperand(0)->isWritten()) return false; /* 64 bit machines use regs to pass parameters */ - if(firp->GetArchitectureBitWidth()==64) + if(firp->getArchitectureBitWidth()==64) { // if it's a register -// if((d.Argument1.ArgType®ISTER_TYPE)==REGISTER_TYPE) - if(d.getOperand(0).isGeneralPurposeRegister()) + if(d.getOperand(0)->isGeneralPurposeRegister()) { -// int regno=(d.Argument1.ArgType)&0xFFFF; - int regno=d.getOperand(0).getRegNumber(); + int regno=d.getOperand(0)->getRegNumber(); switch(regno) { -/* - case REG7: // rdi - case REG6: // rsi - case REG2: // rdx - case REG1: // rcx - case REG8: // r8 - case REG9: // r9 -*/ case 1: // rcx? case 2: // rdx? case 6: // rsi? case 7: // rdi? case 8: // r8? case 9: // r9? -// output_dst=d.Argument1.ArgMnemonic; - output_dst=d.getOperand(0).getString(); + output_dst=d.getOperand(0)->getString(); return true; // other regsiters == no. @@ -79,36 +67,31 @@ bool libIRDB::IsParameterWrite(const FileIR_t *firp, Instruction_t* insn, string // not a register or not 64-bit. check for [esp+k] // check for memory type -// if((d.Argument1.ArgType&MEMORY_TYPE)!=MEMORY_TYPE) - if(!d.getOperand(0).isMemory()) + if(!d.getOperand(0)->isMemory()) return false; // check that base reg is esp. -// if(d.Argument1.Memory.BaseRegister != REG4) - if(!d.getOperand(0).hasBaseRegister()) + if(!d.getOperand(0)->hasBaseRegister()) return false; - if(d.getOperand(0).getBaseRegister() != 4) + if(d.getOperand(0)->getBaseRegister() != 4) return false; // check that there's no index reg -// if(d.Argument1.Memory.IndexRegister != 0) - if(d.getOperand(0).hasIndexRegister()) + if(d.getOperand(0)->hasIndexRegister()) return false; // get k out of [esp + k ] -// unsigned int k=d.Argument1.Memory.Displacement; - if (!d.getOperand(0).hasMemoryDisplacement()) + if (!d.getOperand(0)->hasMemoryDisplacement()) return false; - const auto k=d.getOperand(0).getMemoryDisplacement(); + const auto k=d.getOperand(0)->getMemoryDisplacement(); // check that we know the frame layout. - if(insn->GetFunction() == NULL) + if(insn->getFunction() == NULL) return false; - if(k < insn->GetFunction()->GetOutArgsRegionSize()) + if(k < insn->getFunction()->getOutArgsRegionSize()) { -// output_dst=string("[")+d.Argument1.ArgMnemonic+string("]"); - output_dst=string("[")+d.getOperand(0).getString()+string("]"); + output_dst=string("[")+d.getOperand(0)->getString()+string("]"); return true; } @@ -121,35 +104,33 @@ bool libIRDB::IsParameterWrite(const FileIR_t *firp, Instruction_t* insn, string // (1) call instruction // (2) call converted to push/jmp pair // -static Instruction_t* IsOrWasCall(const FileIR_t *firp, Instruction_t* insn) +IRDB_SDK::Instruction_t* isOrWasCall(const IRDB_SDK::FileIR_t *firp, IRDB_SDK::Instruction_t* insn) { if (firp == NULL || insn == NULL) return NULL; -// auto d=DISASM({0}); -// Disassemble(insn,d); - const auto d=DecodedInstruction_t(insn); + const auto p_d=DecodedInstruction_t::factory(insn); + const auto &d=*p_d; -// if(d.Instruction.Mnemonic == string("call ")) if(d.isCall()) { - return insn->GetTarget(); + return insn->getTarget(); } else { // look for "push64" or "fix_call_fallthrough" reloc - auto it = std::find_if(insn->GetRelocations().begin(),insn->GetRelocations().end(),[&](const Relocation_t* reloc) + auto it = std::find_if(insn->getRelocations().begin(),insn->getRelocations().end(),[&](const IRDB_SDK::Relocation_t* reloc) { - return (reloc && ((reloc->GetType() == string("push64")) || reloc->GetType() == string("fix_call_fallthrough"))); + return (reloc && ((reloc->getType() == string("push64")) || reloc->getType() == string("fix_call_fallthrough"))); }); // find actual target - if (it != insn->GetRelocations().end()) + if (it != insn->getRelocations().end()) { - if (insn->GetTarget()) - return insn->GetTarget(); - else if (insn->GetFallthrough()) - return insn->GetFallthrough()->GetTarget(); + if (insn->getTarget()) + return insn->getTarget(); + else if (insn->getFallthrough()) + return insn->getFallthrough()->getTarget(); } } @@ -157,7 +138,7 @@ static Instruction_t* IsOrWasCall(const FileIR_t *firp, Instruction_t* insn) } // Does a call follow the instruction? -bool libIRDB::CallFollows(const FileIR_t *firp, Instruction_t* insn, const string& reg_arg_str, const std::string &fn_pattern) +bool IRDB_SDK::callFollows(const IRDB_SDK::FileIR_t *firp, IRDB_SDK::Instruction_t* insn, const string& reg_arg_str, const std::string &fn_pattern) { const std::set<std::string> param_regs = {"rdi", "rsi", "rdx", "rcx", "r8", "r9"}; const bool original_is_param_register = param_regs.find(reg_arg_str) != param_regs.end(); @@ -165,12 +146,11 @@ bool libIRDB::CallFollows(const FileIR_t *firp, Instruction_t* insn, const strin std::set<std::string> live_params; live_params.insert(reg_arg_str); - for(Instruction_t* ptr=insn->GetFallthrough(); ptr!=NULL; ptr=ptr->GetFallthrough()) + for(auto ptr=insn->getFallthrough(); ptr!=NULL; ptr=ptr->getFallthrough()) { -// auto d=DISASM({0}); -// Disassemble(ptr,d); - const auto d=DecodedInstruction_t(ptr); - const auto tgt = IsOrWasCall(firp, ptr); + const auto p_d=DecodedInstruction_t::factory(ptr); + const auto &d=*p_d; + const auto tgt = isOrWasCall(firp, ptr); if (tgt) { @@ -185,10 +165,10 @@ bool libIRDB::CallFollows(const FileIR_t *firp, Instruction_t* insn, const strin // look for specific function // check the target has a function - if(tgt->GetFunction()==NULL) + if(tgt->getFunction()==NULL) return false; - const auto fname = tgt->GetFunction()->GetName(); + const auto fname = tgt->getFunction()->getName(); // std::cout << "CallFollows(): yes, parameter to call: function name: " << fname << endl; return fname.find(fn_pattern)!=string::npos; } @@ -196,13 +176,12 @@ bool libIRDB::CallFollows(const FileIR_t *firp, Instruction_t* insn, const strin // found reference to argstring, original code would just stop the search // need more sophisticated heuristic -// if(string(d.CompleteInstr).find(reg_arg_str)!= string::npos) if(d.getDisassembly().find(reg_arg_str)!= string::npos) { if (original_is_param_register) { std::string arg; - if (IsParameterWrite(firp, ptr, arg)) + if (isParameterWrite(firp, ptr, arg)) { // std::cout << "CallFollows(): " << ptr->getDisassembly() << ": detected write parameter" << std::endl; if (arg == reg_arg_str) @@ -212,8 +191,8 @@ bool libIRDB::CallFollows(const FileIR_t *firp, Instruction_t* insn, const strin } else { -// if (std::string(d.Argument2.ArgMnemonic) == reg_arg_str) { - if (d.hasOperand(1) && d.getOperand(1).getString() == reg_arg_str) { + if (d.hasOperand(1) && d.getOperand(1)->getString() == reg_arg_str) + { // std::cout << "CallFollows(): " << ptr->getDisassembly() << ": copy of original detected: add to live list: " << arg << std::endl; live_params.insert(arg); } @@ -240,48 +219,37 @@ bool libIRDB::CallFollows(const FileIR_t *firp, Instruction_t* insn, const strin return false; } -bool libIRDB::FlowsIntoCall(const FileIR_t *firp, Instruction_t* insn) +bool IRDB_SDK::flowsIntoCall(const IRDB_SDK::FileIR_t *firp, IRDB_SDK::Instruction_t* insn) { - //auto d=DISASM({0}); - //Disassemble(insn,d); - string param_write; - if (!libIRDB::IsParameterWrite(firp, insn, param_write)) + if (!isParameterWrite(firp, insn, param_write)) return false; - return CallFollows(firp, insn, param_write); + return callFollows(firp, insn, param_write); } -bool libIRDB::LeaFlowsIntoCall(const FileIR_t *firp, Instruction_t* insn) +bool IRDB_SDK::leaFlowsIntoCall(const IRDB_SDK::FileIR_t *firp, IRDB_SDK::Instruction_t* insn) { -// auto d=DISASM({0}); -// Disassemble(insn,d); - const auto d=DecodedInstruction_t(insn); + const auto d=DecodedInstruction_t::factory(insn); -// if(string(d.Instruction.Mnemonic)!="lea ") -// return false; - if (d.getMnemonic()!="lea") + if (d->getMnemonic()!="lea") return false; - return FlowsIntoCall(firp, insn); + return flowsIntoCall(firp, insn); } -bool libIRDB::LeaFlowsIntoPrintf(const FileIR_t *firp, Instruction_t* insn) +bool IRDB_SDK::leaFlowsIntoPrintf(const IRDB_SDK::FileIR_t *firp, IRDB_SDK::Instruction_t* insn) { -// auto d=DISASM({0}); -// Disassemble(insn,d); - const auto d=DecodedInstruction_t(insn); + const auto d=DecodedInstruction_t::factory(insn); -// if(string(d.Instruction.Mnemonic)!="lea ") -// return false; - if (d.getMnemonic()!="lea") + if (d->getMnemonic()!="lea") return false; // std::cout << "LeaFlowsIntoCall(): investigating " << insn->getDisassembly() << endl; string param_write; - if (!libIRDB::IsParameterWrite(firp, insn, param_write)) + if (!isParameterWrite(firp, insn, param_write)) return false; - return CallFollows(firp, insn, param_write, "printf"); + return callFollows(firp, insn, param_write, "printf"); } diff --git a/libIRDB/LICENSE.txt b/libIRDB/LICENSE.txt deleted file mode 100644 index 312fba3fce32ba9e8a488ac58885ca41c59c2aa8..0000000000000000000000000000000000000000 --- a/libIRDB/LICENSE.txt +++ /dev/null @@ -1,14 +0,0 @@ -************************************************************************************* -* -* Unless otherwise specified, software artifacts in this directory and its -* subdirectories are subject to: -* -* GOVERNMENT PURPOSE RIGHTS -* -* The Government's rights to use, modify, reproduce, release, perform, display, or -* disclose this software are restricted by GOVERNMENT PURPOSE RIGHTS. -* -* Any reproduction of the software or portions thereof marked with this legend -* must also reproduce the markings. -* -************************************************************************************* diff --git a/libIRDB/Makefile.in b/libIRDB/Makefile.in deleted file mode 100644 index 2eda16e6fe37a49a9356cf509f1b755b6716aae0..0000000000000000000000000000000000000000 --- a/libIRDB/Makefile.in +++ /dev/null @@ -1,13 +0,0 @@ - -CC=@CC@ -CXX=@CXX@ - -all: - cd src;make CC="$(CC)" CXX="$(CXX)" - ./install_libs.sh - cd test;make CC="$(CC)" CXX="$(CXX)" - - -clean: - cd src;make clean - cd test;make clean diff --git a/libIRDB/SConscript b/libIRDB/SConscript deleted file mode 100644 index bd5fcb835edeed5b0f0df7cd9e51407c3efd0919..0000000000000000000000000000000000000000 --- a/libIRDB/SConscript +++ /dev/null @@ -1,11 +0,0 @@ -import os - -Import('env') - - -lib1=SConscript("src/SConscript") -lib2=SConscript("test/SConscript") - - -ret=lib1+lib2 -Return('ret') diff --git a/libIRDB/include/bea_deprecated.hpp b/libIRDB/include/bea_deprecated.hpp deleted file mode 100644 index 6868f1cd1118fe8b01c7c972a49f5191157192cd..0000000000000000000000000000000000000000 --- a/libIRDB/include/bea_deprecated.hpp +++ /dev/null @@ -1,52 +0,0 @@ -#ifndef bea_deprecated_h -#define bea_deprecated_h - - -#include <libIRDB-core.hpp> -#include <beaengine/BeaEngine.h> - - -static inline int Disassemble(const libIRDB::Instruction_t* const insn, DISASM &disasm) -{ - assert(insn); - memset(&disasm, 0, sizeof(DISASM)); - disasm.Options = NasmSyntax + PrefixedNumeral; - disasm.Archi = libIRDB::FileIR_t::GetArchitectureBitWidth(); - disasm.EIP = (UIntPtr) insn->GetDataBits().c_str(); - disasm.VirtualAddr = insn->GetAddress()->GetVirtualOffset(); - int instr_len = Disasm(&disasm); - return instr_len; -} - -static inline bool SetsStackPointer(const ARGTYPE* arg) -{ - if((arg->AccessMode & WRITE ) == 0) - return false; - int access_type=arg->ArgType; - - if(access_type==REGISTER_TYPE + GENERAL_REG +REG4) - return true; - return false; - -} - -static inline bool SetsStackPointer(const DISASM* disasm) -{ - if(strstr(disasm->Instruction.Mnemonic, "push")!=NULL) - return true; - if(strstr(disasm->Instruction.Mnemonic, "pop")!=NULL) - return true; - if(strstr(disasm->Instruction.Mnemonic, "call")!=NULL) - return true; - if(disasm->Instruction.ImplicitModifiedRegs==REGISTER_TYPE+GENERAL_REG+REG4) - return true; - - if(SetsStackPointer(&disasm->Argument1)) return true; - if(SetsStackPointer(&disasm->Argument2)) return true; - if(SetsStackPointer(&disasm->Argument3)) return true; - - return false; - -} - -#endif diff --git a/libIRDB/include/cfg/BasicBlock.hpp b/libIRDB/include/cfg/BasicBlock.hpp deleted file mode 100644 index 7e6475280c497c24c7b082df9985dcb52ad1a7dc..0000000000000000000000000000000000000000 --- a/libIRDB/include/cfg/BasicBlock.hpp +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Copyright (c) 2014 - Zephyr Software LLC - * - * This file may be used and modified for non-commercial purposes as long as - * all copyright, permission, and nonwarranty notices are preserved. - * Redistribution is prohibited without prior written consent from Zephyr - * Software. - * - * Please contact the authors for restrictions applying to commercial use. - * - * THIS SOURCE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF - * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. - * - * Author: Zephyr Software - * e-mail: jwd@zephyr-software.com - * URL : http://www.zephyr-software.com/ - * - */ - - -class BasicBlock_t; -typedef std::set<BasicBlock_t*> BasicBlockSet_t; -typedef std::vector<Instruction_t*> InstructionVector_t; - -class BasicBlock_t -{ - - public: - BasicBlock_t(); - - bool GetIsExitBlock() { return is_exit_block; } - void SetIsExitBlock(bool is_exit) { is_exit_block=is_exit; } - - InstructionVector_t& GetInstructions() { return instructions; } - BasicBlockSet_t& GetPredecessors() { return predecessors; } - BasicBlockSet_t& GetSuccessors() { return successors; } - BasicBlockSet_t& GetIndirectTargets() { return indirect_targets; } - BasicBlock_t* GetFallthrough(); - BasicBlock_t* GetTarget(); - - // for const correctness if you aren't modifying. - const InstructionVector_t& GetInstructions() const { return instructions; } - const BasicBlockSet_t& GetPredecessors() const { return predecessors; } - const BasicBlockSet_t& GetSuccessors() const { return successors; } - const BasicBlockSet_t& GetIndirectTargets() const { return indirect_targets; } - - bool EndsInBranch(); - bool EndsInIndirectBranch(); - bool EndsInConditionalBranch(); - Instruction_t* GetBranchInstruction(); - void dump(std::ostream &os=std::cout) const { os<<*this; } - - protected: - - void BuildBlock( Instruction_t* insn, - const std::map<Instruction_t*,BasicBlock_t*> &insn2block_map - ); - - - private: - - InstructionVector_t instructions; - BasicBlockSet_t predecessors; - BasicBlockSet_t successors; - BasicBlockSet_t indirect_targets; - bool is_exit_block; - - friend std::ostream& operator<<(std::ostream& os, const BasicBlock_t& block); - friend class ControlFlowGraph_t; -}; - -std::ostream& operator<<(std::ostream& os, const BasicBlock_t& block); - diff --git a/libIRDB/include/cfg/CFG.hpp b/libIRDB/include/cfg/CFG.hpp deleted file mode 100644 index ae2c6d0cd18d27dd7e1ee99ba3905430895ee9fe..0000000000000000000000000000000000000000 --- a/libIRDB/include/cfg/CFG.hpp +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright (c) 2014 - Zephyr Software LLC - * - * This file may be used and modified for non-commercial purposes as long as - * all copyright, permission, and nonwarranty notices are preserved. - * Redistribution is prohibited without prior written consent from Zephyr - * Software. - * - * Please contact the authors for restrictions applying to commercial use. - * - * THIS SOURCE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF - * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. - * - * Author: Zephyr Software - * e-mail: jwd@zephyr-software.com - * URL : http://www.zephyr-software.com/ - * - */ - - - -typedef std::set<BasicBlock_t*> BasicBlockSet_t; - -class ControlFlowGraph_t -{ - public: - ControlFlowGraph_t(Function_t* func); - BasicBlock_t* GetEntry() const { return entry; } - Function_t* GetFunction() const { return function; } - BasicBlockSet_t& GetBlocks() { return blocks; } - const BasicBlockSet_t& GetBlocks() const { return blocks; } - void dump(std::ostream &os=std::cout) const { os<<*this; } - - private: - // methods - void Build(Function_t *func); - void alloc_blocks(const InstructionSet_t &starts, map<Instruction_t*,BasicBlock_t*>& insn2block_map); - void build_blocks(const map<Instruction_t*,BasicBlock_t*>& insn2block_map); - void find_unblocked_instructions(InstructionSet_t &starts, Function_t* func); - - // data - BasicBlockSet_t blocks; - BasicBlock_t* entry; - Function_t* function; - - /* friends */ - public: - friend std::ostream& operator<<(std::ostream& os, const ControlFlowGraph_t& cfg); -}; - - -std::ostream& operator<<(std::ostream& os, const ControlFlowGraph_t& cfg); - - diff --git a/libIRDB/include/cfg/callgraph.hpp b/libIRDB/include/cfg/callgraph.hpp deleted file mode 100644 index 7403cfdd4f6da77c985b4ee206a3cd7d34d156e3..0000000000000000000000000000000000000000 --- a/libIRDB/include/cfg/callgraph.hpp +++ /dev/null @@ -1,158 +0,0 @@ -/* - * Copyright (c) 2014-2015 - Zephyr Software LLC - * - * This file may be used and modified for non-commercial purposes as long as - * all copyright, permission, and nonwarranty notices are preserved. - * Redistribution is prohibited without prior written consent from Zephyr - * Software. - * - * Please contact the authors for restrictions applying to commercial use. - * - * THIS SOURCE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF - * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. - * - * Author: Zephyr Software - * e-mail: jwd@zephyr-software.com - * URL : http://www.zephyr-software.com/ - * - */ - -#ifndef irdb_cfg_callgraph_h -#define irdb_cfg_callgraph_h - -// only one type of hell node for now, but leave -// open the possibilty for multiple hell nodes -typedef enum { DEFAULT_HELL_NODE = 0 } HellNodeType; - -class CallGraphNode_t -{ - public: - CallGraphNode_t(libIRDB::Function_t* f = NULL) { - if (f) { - SetFunction(f); - } else { - m_isHellNode = true; - m_node.hellNodeType = DEFAULT_HELL_NODE; - } - } - - bool IsHellnode() const { return m_isHellNode; } - - libIRDB::Function_t* GetFunction() const { - assert(!m_isHellNode); - if (m_isHellNode) - return NULL; - else - return m_node.func; - } - - HellNodeType GetHellNodeType() const { - assert(m_isHellNode); - return m_node.hellNodeType; - } - - bool operator==(const CallGraphNode_t &other) const { - if (this == &other) return true; - if (m_isHellNode) - { - return m_node.hellNodeType == other.m_node.hellNodeType; - } - else - return m_node.func == other.m_node.func; - } - - private: - void SetFunction(Function_t* const f) { - assert(f); - m_node.func = f; - m_isHellNode = false; - } - - private: - bool m_isHellNode; - union { - libIRDB::Function_t* func; - HellNodeType hellNodeType; - } m_node; -}; - -typedef std::pair<CallGraphNode_t*,CallGraphNode_t*> CallGraphEdge_t; -typedef std::set<CallGraphNode_t*> CallGraphNodeSet_t; -typedef libIRDB::Instruction_t* CallSite_t; -typedef std::set<CallSite_t> CallSiteSet_t; - -class Callgraph_t -{ - public: - Callgraph_t(); - ~Callgraph_t(); - void AddFile(libIRDB::FileIR_t* const firp); - - bool EdgeExists(const CallGraphEdge_t& edge) - { - CallGraphNode_t *from=edge.first; - CallGraphNode_t *to=edge.second; - - const CallGraphNodeSet_t& calleeSet = callers[from]; - return calleeSet.find(to)!=calleeSet.end(); - } - bool EdgeExists(CallGraphNode_t& n1, CallGraphNode_t& n2) - { return EdgeExists(CallGraphEdge_t(&n1,&n2));} - - CallGraphNodeSet_t& GetCallersOfNode(CallGraphNode_t* const node) - { return callers[node]; } - CallGraphNodeSet_t& GetCalleesOfNode(CallGraphNode_t* const node) - { return callees[node]; } - - void GetAncestors(Function_t* const fn, CallGraphNodeSet_t& ancestors, bool skipHellNode = false); - void GetAncestors(CallGraphNode_t* const node, CallGraphNodeSet_t& ancestors, bool skipHellNode = false); - - CallSiteSet_t& GetCallSites(CallGraphNode_t* const n1) - { return call_sites[n1]; } - - void Dump(std::ostream& fout); - - std::string GetNodeName(const CallGraphNode_t* const n1) const { - assert(n1); - if (n1->IsHellnode()) { - std::ostringstream s; - s << "HELLNODE" << n1->GetHellNodeType(); - return s.str(); - } else { - assert(n1->GetFunction()); - return n1->GetFunction()->GetName(); - } - } - - std::string GetCallsiteDisassembly(const CallSite_t &c) const - { return c ? c->getDisassembly() : "NOFROMFUNC"; } - - bool Reachable(CallGraphNode_t* const from, CallGraphNode_t* const to, bool skipHellNode = false); - - CallGraphNode_t& GetDefaultHellNode() { return default_hellnode; } - - CallGraphNode_t* FindNode(Function_t* const fn); - - private: - // create nodes from functions - void CreateNodes(libIRDB::FileIR_t *firp); - - // mark the given insn as a call site. - void MarkCallSite(Instruction_t* const insn); - - // traverse graph to retrieve all ancestors - void _GetAncestors(CallGraphNode_t* const node, CallGraphNodeSet_t &ancestors, CallGraphNodeSet_t &visited, bool skipHellNode); - - typedef std::map<CallGraphNode_t*, CallGraphNodeSet_t > CGNodeToCGNodeSetMap_t; - typedef std::map<CallGraphNode_t*, CallSiteSet_t > NodeToCallSiteSetMap_t; - typedef std::map<Function_t*, CallGraphNode_t*> FunctionToCGNodeMap_t; - - CGNodeToCGNodeSetMap_t callers; // map a callee to its callees - CGNodeToCGNodeSetMap_t callees; // map a caller to its callers - NodeToCallSiteSetMap_t call_sites; - CallGraphNode_t default_hellnode; // default hell node - FunctionToCGNodeMap_t nodes; // maps functions to call graph nodes -}; - -#endif diff --git a/libIRDB/include/cfg/domgraph.hpp b/libIRDB/include/cfg/domgraph.hpp deleted file mode 100644 index 087fc4dd604d8458be76de68b188447ffaf68ba9..0000000000000000000000000000000000000000 --- a/libIRDB/include/cfg/domgraph.hpp +++ /dev/null @@ -1,54 +0,0 @@ - - - -typedef std::map<const BasicBlock_t*, BasicBlockSet_t> DominatorMap_t; -typedef std::map<const BasicBlock_t*, BasicBlock_t*> BlockToBlockMap_t; - -class DominatorGraph_t -{ - public: - DominatorGraph_t(const ControlFlowGraph_t* p_cfg, bool needs_postdoms=false, bool needs_idoms=false); - - - // get the (post) dominators for a node - BasicBlockSet_t& GetDominators(const BasicBlock_t* node) { return dom_graph[node]; } - BasicBlockSet_t& GetPostDominators(const BasicBlock_t* node) { return post_dom_graph[node]; } - - const BasicBlockSet_t& GetDominators(const BasicBlock_t* node) const { return dom_graph.at(node); } - const BasicBlockSet_t& GetPostDominators(const BasicBlock_t* node) const { return post_dom_graph.at(node); } - - bool HasWarnings() const { return warn; } - - - // get the immeidate (post) dominators for a node - const BasicBlock_t* GetImmediateDominator(const BasicBlock_t* node) const - { BlockToBlockMap_t::const_iterator it=idom_graph.find(node); return (it!=idom_graph.end()) ? it->second : NULL; } - const BasicBlock_t* GetImmediatePostDominators(const BasicBlock_t* node) const - { BlockToBlockMap_t::const_iterator it=post_idom_graph.find(node); return (it!=post_idom_graph.end()) ? it->second : NULL; } - - - private: - - typedef const BasicBlockSet_t& (*pred_func_ptr_t) (const BasicBlock_t* node); - - DominatorMap_t Dom_Comp(const BasicBlockSet_t& N, pred_func_ptr_t pred_func, BasicBlock_t* r); - BlockToBlockMap_t Idom_Comp(const BasicBlockSet_t& N, const DominatorMap_t &Domin, BasicBlock_t* r); - - - DominatorMap_t dom_graph; - BlockToBlockMap_t idom_graph; - - DominatorMap_t post_dom_graph; - BlockToBlockMap_t post_idom_graph; - - const ControlFlowGraph_t& cfg; // a reference to our cfg. - - bool warn; - - friend std::ostream& operator<<(std::ostream& os, const DominatorGraph_t& cfg); - -}; - -std::ostream& operator<<(std::ostream& os, const DominatorGraph_t& cfg); - - diff --git a/libIRDB/include/core/basetypes.hpp b/libIRDB/include/core/basetypes.hpp deleted file mode 100644 index d47084900d2c1bf6e2dc5faad42bd02d4cc680e8..0000000000000000000000000000000000000000 --- a/libIRDB/include/core/basetypes.hpp +++ /dev/null @@ -1,23 +0,0 @@ -/* - * Copyright (c) 2014 - Zephyr Software LLC - * - * This file may be used and modified for non-commercial purposes as long as - * all copyright, permission, and nonwarranty notices are preserved. - * Redistribution is prohibited without prior written consent from Zephyr - * Software. - * - * Please contact the authors for restrictions applying to commercial use. - * - * THIS SOURCE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF - * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. - * - * Author: Zephyr Software - * e-mail: jwd@zephyr-software.com - * URL : http://www.zephyr-software.com/ - * - */ - -typedef uintptr_t virtual_offset_t; -typedef int db_id_t; -typedef int schema_version_t; diff --git a/libIRDB/include/core/decode.hpp b/libIRDB/include/core/decode.hpp deleted file mode 100644 index 8a59d7d9a109507e2694a09f7045168076cb0dba..0000000000000000000000000000000000000000 --- a/libIRDB/include/core/decode.hpp +++ /dev/null @@ -1,45 +0,0 @@ -#ifndef libdecode_decode_hpp -#define libdecode_decode_hpp - -#define USECS - -#if defined(USEMETA) -#include <core/decode_meta.hpp> -#include <core/operand_meta.hpp> -#elif defined(USECS) -#include <core/decode_cs.hpp> -#include <core/operand_cs.hpp> -#elif defined(USEBEA) -#include <core/decode_bea.hpp> -#include <core/operand_bea.hpp> -#else -#pragma "Error: Source did not adaquately specify a disassembler. " -#endif - - -namespace libIRDB -{ -using namespace std; -using namespace libIRDB; - - - -#if defined(USEMETA) -typedef DecodedInstructionMeta_t DecodedInstruction_t; -typedef DecodedOperandMeta_t DecodedOperand_t; -typedef DecodedOperandMetaVector_t DecodedOperandVector_t; -#elif defined(USECS) -typedef DecodedInstructionCapstone_t DecodedInstruction_t; -typedef DecodedOperandCapstone_t DecodedOperand_t; -typedef DecodedOperandCapstoneVector_t DecodedOperandVector_t; -#elif defined(USEBEA) -typedef DecodedInstructionBea_t DecodedInstruction_t; -typedef DecodedOperandBea_t DecodedOperand_t; -typedef DecodedOperandBeaVector_t DecodedOperandVector_t; -#else -#pragma "Error: Source did not adaquately specify a disassembler. " -#endif - -} - -#endif diff --git a/libIRDB/include/core/decode_bea.hpp b/libIRDB/include/core/decode_bea.hpp deleted file mode 100644 index 800cdd625713e4d882dc7506e93b54939b555386..0000000000000000000000000000000000000000 --- a/libIRDB/include/core/decode_bea.hpp +++ /dev/null @@ -1,62 +0,0 @@ -#ifndef libirdb_decodebea_hpp -#define libirdb_decodebea_hpp - -#include <stdint.h> -#include <vector> - -namespace libIRDB -{ - -using namespace libIRDB; -using namespace std; - -class DecodedOperandBea_t; -typedef std::vector<DecodedOperandBea_t> DecodedOperandBeaVector_t; - -class DecodedInstructionBea_t -{ - public: - DecodedInstructionBea_t()=delete; - DecodedInstructionBea_t(const Instruction_t*); - DecodedInstructionBea_t(const virtual_offset_t start_addr, const void *data, uint32_t max_len); - DecodedInstructionBea_t(const virtual_offset_t start_addr, const void *data, const void* endptr); - DecodedInstructionBea_t(const DecodedInstructionBea_t& copy); - DecodedInstructionBea_t& operator=(const DecodedInstructionBea_t& copy); - - virtual ~DecodedInstructionBea_t(); - - string getDisassembly() const; - bool valid() const; - uint32_t length() const; - bool isBranch() const; - bool isCall() const; - bool isUnconditionalBranch() const; - bool isConditionalBranch() const; - bool isReturn() const; - string getMnemonic() const; - int64_t getImmediate() const; - virtual_offset_t getAddress() const; - bool setsStackPointer() const; - uint32_t getPrefixCount() const; - bool hasRelevantRepPrefix() const; - bool hasRelevantRepnePrefix() const; - bool hasRelevantOperandSizePrefix() const; - bool hasRexWPrefix() const; - bool hasImplicitlyModifiedRegs() const; - virtual_offset_t getMemoryDisplacementOffset(const DecodedOperandBea_t& t, const libIRDB::Instruction_t*) const; - - // 0-based. first operand is numbered 0. - bool hasOperand(const int op_num) const; - DecodedOperandBea_t getOperand(const int op_num) const; - DecodedOperandBeaVector_t getOperands() const; - - private: - - void Disassemble(const virtual_offset_t start_addr, const void *, uint32_t max_len); - void *disasm_data; - uint32_t disasm_length; -}; - -} - -#endif diff --git a/libIRDB/include/core/decode_cs.hpp b/libIRDB/include/core/decode_cs.hpp deleted file mode 100644 index efc71323876e07b5e9d4bfdcb2b0f4b33989a7c6..0000000000000000000000000000000000000000 --- a/libIRDB/include/core/decode_cs.hpp +++ /dev/null @@ -1,100 +0,0 @@ -#ifndef libirdb_decodecsa_hpp -#define libirdb_decodecsa_hpp - -#include <stdint.h> -#include <vector> -#include <memory> - -namespace libIRDB -{ - -using namespace libIRDB; -using namespace std; - -class DecodedOperandCapstone_t; -typedef std::vector<DecodedOperandCapstone_t> DecodedOperandCapstoneVector_t; - -class DecodedInstructionCapstone_t -{ - public: - DecodedInstructionCapstone_t()=delete; - DecodedInstructionCapstone_t(const Instruction_t*); - DecodedInstructionCapstone_t(const virtual_offset_t start_addr, const void *data, uint32_t max_len); - DecodedInstructionCapstone_t(const virtual_offset_t start_addr, const void *data, const void* endptr); - DecodedInstructionCapstone_t(const DecodedInstructionCapstone_t& copy); - DecodedInstructionCapstone_t& operator=(const DecodedInstructionCapstone_t& copy); - - virtual ~DecodedInstructionCapstone_t(); - - string getDisassembly() const; - bool valid() const; - uint32_t length() const; - bool isBranch() const; - bool isCall() const; - bool isUnconditionalBranch() const; - bool isConditionalBranch() const; - bool isReturn() const; - string getMnemonic() const; - int64_t getImmediate() const; - virtual_offset_t getAddress() const; - bool setsStackPointer() const; - uint32_t getPrefixCount() const; - bool hasRelevantRepPrefix() const; - bool hasRelevantRepnePrefix() const; - bool hasRelevantOperandSizePrefix() const; - bool hasRexWPrefix() const; - bool hasImplicitlyModifiedRegs() const; - virtual_offset_t getMemoryDisplacementOffset(const DecodedOperandCapstone_t& t, const Instruction_t* insn) const; - - // 0-based. first operand is numbered 0. - bool hasOperand(const int op_num) const; - DecodedOperandCapstone_t getOperand(const int op_num) const; - DecodedOperandCapstoneVector_t getOperands() const; - - private: - - void Disassemble(const virtual_offset_t start_addr, const void *data, const uint32_t max_len); - - shared_ptr<void> my_insn; - - class CapstoneHandle_t - { - public: - CapstoneHandle_t(FileIR_t* firp=NULL); -#if 0 - { - - const auto width=FileIR_t::GetArchitectureBitWidth(); - const auto mode = (width==64) ? CS_MODE_64: CS_MODE_32; - auto err = cs_open(CS_ARCH_X86, mode, &handle); - - if (err) - { - const auto s=string("Failed on cs_open() with error returned: ")+to_string(err)+"\n"; - throw std::runtime_error(s); - } - cs_option(handle, CS_OPT_DETAIL, CS_OPT_ON); - cs_option(handle, CS_OPT_SYNTAX, CS_OPT_SYNTAX_INTEL); - - - } -#endif - // inline unsigned long getHandle() { return handle; }// this is the real type, but it's an alias and I don't want to export capstone values. - inline unsigned long getHandle() { return handle; } - - private: - // csh handle; // this is the real type, but it's an alias and I don't want to export capstone values. - unsigned long handle; - }; - static CapstoneHandle_t *cs_handle; - - - friend class DecodedOperandCapstone_t; - - DecodedInstructionCapstone_t(const shared_ptr<void> &my_insn); - -}; - -} - -#endif diff --git a/libIRDB/include/core/decode_meta.hpp b/libIRDB/include/core/decode_meta.hpp deleted file mode 100644 index fe62bb089b70b8f89a1e484c05246b7d8ea17b51..0000000000000000000000000000000000000000 --- a/libIRDB/include/core/decode_meta.hpp +++ /dev/null @@ -1,66 +0,0 @@ -#ifndef libirdb_decodemeta_hpp -#define libirdb_decodemeta_hpp - -#include <stdint.h> -#include <vector> -#include <core/decode_bea.hpp> -#include <core/operand_bea.hpp> -#include <core/decode_cs.hpp> -#include <core/operand_cs.hpp> - -namespace libIRDB -{ - -using namespace libIRDB; -using namespace std; - -class DecodedOperandMeta_t; -typedef std::vector<DecodedOperandMeta_t> DecodedOperandMetaVector_t; - -class DecodedInstructionMeta_t -{ - public: - DecodedInstructionMeta_t()=delete; - DecodedInstructionMeta_t(const Instruction_t*); - DecodedInstructionMeta_t(const virtual_offset_t start_addr, const void *data, uint32_t max_len); - DecodedInstructionMeta_t(const virtual_offset_t start_addr, const void *data, const void* endptr); - DecodedInstructionMeta_t(const DecodedInstructionMeta_t& copy); - DecodedInstructionMeta_t& operator=(const DecodedInstructionMeta_t& copy); - - virtual ~DecodedInstructionMeta_t(); - - string getDisassembly() const; - bool valid() const; - uint32_t length() const; - bool isBranch() const; - bool isCall() const; - bool isUnconditionalBranch() const; - bool isConditionalBranch() const; - bool isReturn() const; - string getMnemonic() const; - int64_t getImmediate() const; - virtual_offset_t getAddress() const; - bool setsStackPointer() const; - uint32_t getPrefixCount() const; - bool hasRelevantRepPrefix() const; - bool hasRelevantRepnePrefix() const; - bool hasRelevantOperandSizePrefix() const; - bool hasRexWPrefix() const; - bool hasImplicitlyModifiedRegs() const; - virtual_offset_t getMemoryDisplacementOffset(const DecodedOperandMeta_t& t, const Instruction_t* insn) const; - - // 0-based. first operand is numbered 0. - bool hasOperand(const int op_num) const; - DecodedOperandMeta_t getOperand(const int op_num) const; - DecodedOperandMetaVector_t getOperands() const; - - private: - - DecodedInstructionBea_t bea; - DecodedInstructionCapstone_t cs; - -}; - -} - -#endif diff --git a/libIRDB/include/core/fileir.hpp b/libIRDB/include/core/fileir.hpp deleted file mode 100644 index d0b70244b35a70b1d3a796fb1ac889633840012b..0000000000000000000000000000000000000000 --- a/libIRDB/include/core/fileir.hpp +++ /dev/null @@ -1,182 +0,0 @@ -/* - * Copyright (c) 2014 - Zephyr Software LLC - * - * This file may be used and modified for non-commercial purposes as long as - * all copyright, permission, and nonwarranty notices are preserved. - * Redistribution is prohibited without prior written consent from Zephyr - * Software. - * - * Please contact the authors for restrictions applying to commercial use. - * - * THIS SOURCE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF - * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. - * - * Author: Zephyr Software - * e-mail: jwd@zephyr-software.com - * URL : http://www.zephyr-software.com/ - * - */ - -#include "type.hpp" - - - -typedef std::set<Function_t*> FunctionSet_t; -typedef std::set<AddressID_t*> AddressSet_t; - -// A variant of a problem, this -// may be an original variant -// (i.e., and unmodified Variant) or a modified variant. -class FileIR_t : public BaseObj_t -{ - public: - - // Create a Variant from the database - FileIR_t(const VariantID_t &newprogid, File_t* fid=NULL); - virtual ~FileIR_t(); - - // DB operations - void WriteToDB(std::ostream *verbose_logging=&std::cerr); - - // accessors and mutators in one - FunctionSet_t& GetFunctions() { return funcs; } - const FunctionSet_t& GetFunctions() const { return funcs; } - - InstructionSet_t& GetInstructions() { return insns; } - const InstructionSet_t& GetInstructions() const { return insns; } - - AddressSet_t& GetAddresses() { return addrs; } - const AddressSet_t& GetAddresses() const { return addrs; } - - RelocationSet_t& GetRelocations() { return relocs; } - const RelocationSet_t& GetRelocations() const { return relocs; } - - DataScoopSet_t& GetDataScoops() { return scoops; } - const DataScoopSet_t& GetDataScoops() const { return scoops; } - - ICFSSet_t& GetAllICFS() { return icfs_set; } - const ICFSSet_t& GetAllICFS() const { return icfs_set; } - - EhProgramSet_t& GetAllEhPrograms() { return eh_pgms; } - const EhProgramSet_t& GetAllEhPrograms() const { return eh_pgms; } - - EhCallSiteSet_t& GetAllEhCallSites() { return eh_css; } - const EhCallSiteSet_t& GetAllEhCallSites() const { return eh_css; } - - // generate the spri rules into the output file, fout. - void GenerateSPRI(std::ostream &fout, bool with_ilr=false); - - // generate spri, assume that orig_varirp is the original variant. - void GenerateSPRI(FileIR_t *orig_varirp, std::ostream &fout, bool with_ilr=false); - - void SetBaseIDS(); - db_id_t GetMaxBaseID(); - - File_t* GetFile() const { return fileptr; } - - // Used for modifying a large number of instructions. AssembleRegistry - // assembles the assembly isntructions for each registered instruction - // and clears the registry. RegisterAssembly registers the instruction - // to be assembled later. - void AssembleRegistry(); - void RegisterAssembly(Instruction_t *instr, std::string assembly); - void UnregisterAssembly(Instruction_t *instr); - std::string LookupAssembly(Instruction_t *instr); - - //Needed for inserting assembly before an instruction. - //if orig is not registered, the function returns, otherwise - //the instruction/assembly mapping of orig->assembly is altered to - //updated->assembly - //removes the mapping for orig->assembly from the map. - void ChangeRegistryKey(Instruction_t* orig, Instruction_t* updated); - - static int GetArchitectureBitWidth() ; - static void SetArchitectureBitWidth(const int width); - void SetArchitecture(); - - // Lookup a scoop by address - DataScoop_t* FindScoop(const libIRDB::virtual_offset_t &addr); - - void SplitScoop(DataScoop_t *tosplit, const libIRDB::virtual_offset_t &addr, size_t size, - DataScoop_t* &before,DataScoop_t* &containing, DataScoop_t* &after, db_id_t *max_id=NULL); - - - private: - - static ArchitectureDescription_t *archdesc; - - #define ASM_REG_MAX_SIZE 500000 - - typedef std::map<Instruction_t*,std::string> registry_type; - - // a pointer to the original variants IR, NULL means not yet loaded. - FileIR_t* orig_variant_ir_p; - - registry_type assembly_registry; - - void ReadFromDB(); //accesses DB - - FunctionSet_t funcs; - InstructionSet_t insns; - AddressSet_t addrs; - RelocationSet_t relocs; - TypeSet_t types; - DataScoopSet_t scoops; - VariantID_t& progid; // Not owned by fileIR - ICFSSet_t icfs_set; - File_t* fileptr; // Owned by variant, not fileIR - EhProgramSet_t eh_pgms; - EhCallSiteSet_t eh_css; - - std::map<db_id_t,AddressID_t*> ReadAddrsFromDB(); - std::map<db_id_t,EhProgram_t*> ReadEhPgmsFromDB(); - - std::map<db_id_t,EhCallSite_t*> ReadEhCallSitesFromDB - ( - std::map<EhCallSite_t*,db_id_t> &unresolvedEhCssLandingPads - ); - - std::map<db_id_t,Function_t*> ReadFuncsFromDB - ( - std::map<db_id_t,AddressID_t*> &addrMap, - std::map<db_id_t,Type_t*> &typeMap, - std::map<Function_t*,db_id_t> &entry_points - ); - - std::map<db_id_t,DataScoop_t*> ReadScoopsFromDB - ( - std::map<db_id_t,AddressID_t*> &addrMap, - std::map<db_id_t,Type_t*> &typeMap - ); - - std::map<db_id_t,Instruction_t*> ReadInsnsFromDB - ( - const std::map<db_id_t,Function_t*> &funcMap, - const std::map<db_id_t,AddressID_t*> &addrMap, - const std::map<db_id_t,EhProgram_t*> &ehpgmMap, - const std::map<db_id_t,EhCallSite_t*> &ehcsMap, - std::map<db_id_t,Instruction_t*> &addressToInstructionMap, - std::map<Instruction_t*, db_id_t> &unresolvedICFS - ); - - void ReadRelocsFromDB - ( - std::map<db_id_t,BaseObj_t*> &insnMap - ); - - std::map<db_id_t, Type_t*> ReadTypesFromDB(TypeSet_t& types); - void ReadAllICFSFromDB(std::map<db_id_t,Instruction_t*> &addr2insnMap, - std::map<Instruction_t*, db_id_t> &unresolvedICFS); - - void CleanupICFS(std::ostream *verbose_logging=&std::cerr); - void GarbageCollectICFS(std::ostream *verbose_logging=&std::cerr); - void DedupICFS(std::ostream *verbose_logging=&std::cerr); - - - std::clock_t ReadIRDB_start; - std::clock_t ReadIRDB_end; - - -}; - diff --git a/libIRDB/include/core/instruction.hpp b/libIRDB/include/core/instruction.hpp deleted file mode 100644 index f5ab686084ee38e6584d493ca472812b1b537dba..0000000000000000000000000000000000000000 --- a/libIRDB/include/core/instruction.hpp +++ /dev/null @@ -1,98 +0,0 @@ -/* - * Copyright (c) 2014 - Zephyr Software LLC - * - * This file may be used and modified for non-commercial purposes as long as - * all copyright, permission, and nonwarranty notices are preserved. - * Redistribution is prohibited without prior written consent from Zephyr - * Software. - * - * Please contact the authors for restrictions applying to commercial use. - * - * THIS SOURCE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF - * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. - * - * Author: Zephyr Software - * e-mail: jwd@zephyr-software.com - * URL : http://www.zephyr-software.com/ - * - */ - -class Function_t; // forward decls. -class EhProgram_t; // forward decls. -class EhCallSite_t; // forward decls. - -#define MAX_INSN_SIZE 32 // x86 really declares this as 16, but we'll allow - // for bigger instructions, maybe from other machines? - -typedef std::set<Relocation_t*> RelocationSet_t; - -// The basic instruction of a variant. -class Instruction_t : public BaseObj_t -{ - public: - Instruction_t(); - Instruction_t(db_id_t id, AddressID_t *addr, Function_t *func, db_id_t orig_id, - std::string data, std::string callback, std::string comment, AddressID_t *my_indTarg, db_id_t doip_id); - - AddressID_t* GetAddress() const { return my_address; } - Function_t* GetFunction() const { return my_function; } - db_id_t GetOriginalAddressID() const { return orig_address_id; } - Instruction_t* GetFallthrough() const { return fallthrough; } - Instruction_t* GetTarget() const { return target; } - ICFS_t* GetIBTargets() const { return icfs; } - - // prefer the copy method, since it's inline, compiler will optimize appropriately - // const& rets are just an optimization anyhow.... - //const std::string& GetDataBits() const { return data; } - //const std::string& GetComment() const { return comment; } - //const std::string& GetCallback() const { return callback; } - std::string GetDataBits() const { return data; } - std::string GetCallback() const { return callback; } - std::string GetComment() const { return comment; } - EhProgram_t* GetEhProgram() const { return eh_pgm; } - EhCallSite_t* GetEhCallSite() const { return eh_cs; } - - - void SetAddress(AddressID_t* newaddr) { my_address=newaddr; } - void SetFunction(Function_t* func ) { my_function=func;} - void SetOriginalAddressID(db_id_t origid) { orig_address_id=origid; /* you shouldn't do this, unless you know what you're doing! */} - void SetFallthrough(Instruction_t* i) { fallthrough=i; } - void SetTarget(Instruction_t* i) { target=i; } - void SetIBTargets(ICFS_t *p_icfs) { icfs=p_icfs; } - void SetDataBits(std::string orig) { data=orig; } - void SetCallback(std::string orig) { callback=orig; } - void SetComment(std::string orig) { comment=orig; } - void SetEhProgram(EhProgram_t* orig) { eh_pgm=orig; } - void SetEhCallSite(EhCallSite_t* orig) { eh_cs=orig; } - - AddressID_t* GetIndirectBranchTargetAddress() { return indTarg; } - void SetIndirectBranchTargetAddress(AddressID_t* myIndTarg) { indTarg=myIndTarg; } - - void WriteToDB() { assert(0); } - std::vector<std::string> WriteToDB(File_t *fid, db_id_t newid); - // int Disassemble(DISASM &d) const; - std::string getDisassembly() const; - bool Assemble(std::string assembly); - - bool IsFunctionExit() const; - - //static bool SetsStackPointer(DISASM *disasm); - //static bool SetsStackPointer(ARGTYPE* arg); - - bool IsSyscall() { return getDisassembly().find("int 0x80") != std::string::npos; } - - private: - AddressID_t* my_address; - Function_t* my_function; - db_id_t orig_address_id; // const, should not change. - Instruction_t* fallthrough; - Instruction_t* target; - std::string data; - std::string callback; // name of callback handler (if any) - std::string comment; - AddressID_t* indTarg; - ICFS_t* icfs; - EhProgram_t* eh_pgm; - EhCallSite_t* eh_cs; -}; diff --git a/libIRDB/include/core/operand_bea.hpp b/libIRDB/include/core/operand_bea.hpp deleted file mode 100644 index 2650a18650536c68d52d28e32183a7b8893c5329..0000000000000000000000000000000000000000 --- a/libIRDB/include/core/operand_bea.hpp +++ /dev/null @@ -1,59 +0,0 @@ -#ifndef libRIDB_decodedoperandbea_hpp -#define libRIDB_decodedoperandbea_hpp - -namespace libIRDB -{ - -using namespace std; -using namespace libIRDB; - - -class DecodedOperandBea_t -{ - public: - DecodedOperandBea_t() =delete; - DecodedOperandBea_t& operator=(const DecodedOperandBea_t& copy); - DecodedOperandBea_t(const DecodedOperandBea_t& copy); - virtual ~DecodedOperandBea_t(); - - bool isConstant() const; - string getString() const; - bool isRegister() const; - bool isGeneralPurposeRegister() const; - bool isMmxRegister() const; - bool isFpuRegister() const; - bool isSseRegister() const; - bool isAvxRegister() const; - bool isSpecialRegister() const; - bool isSegmentRegister() const; - uint32_t getRegNumber() const; - bool isMemory() const; - bool hasSegmentRegister() const; - uint32_t getSegmentRegister() const; - bool hasBaseRegister() const; - bool hasIndexRegister() const; - uint32_t getBaseRegister() const; - uint32_t getIndexRegister() const; - bool hasMemoryDisplacement() const; - virtual_offset_t getMemoryDisplacement() const; - bool isPcrel() const; - uint32_t getScaleValue() const; - uint32_t getMemoryDisplacementEncodingSize() const; - uint32_t getArgumentSizeInBytes() const; - uint32_t getArgumentSizeInBits() const; - bool isRead() const; - bool isWritten() const; - - - private: - - - void* arg_data; - DecodedOperandBea_t(void* arg_p); - - friend class DecodedInstructionBea_t; - -}; - -} -#endif diff --git a/libIRDB/include/core/operand_cs.hpp b/libIRDB/include/core/operand_cs.hpp deleted file mode 100644 index 0d4e5e78b7518af34275377b105ca415d200e490..0000000000000000000000000000000000000000 --- a/libIRDB/include/core/operand_cs.hpp +++ /dev/null @@ -1,63 +0,0 @@ -#ifndef libRIDB_decodedoperandcs_hpp -#define libRIDB_decodedoperandcs_hpp - -#include <memory> -namespace libIRDB -{ - -using namespace std; -using namespace libIRDB; - - -class DecodedOperandCapstone_t -{ - public: - DecodedOperandCapstone_t() =delete; - //DecodedOperandCapstone_t& operator=(const DecodedOperandCapstone_t& copy); - //DecodedOperandCapstone_t(const DecodedOperandCapstone_t& copy); - virtual ~DecodedOperandCapstone_t(); - - bool isConstant() const; - uint64_t getConstant() const; - string getString() const; - bool isRegister() const; - bool isGeneralPurposeRegister() const; - bool isMmxRegister() const; - bool isFpuRegister() const; - bool isSseRegister() const; - bool isAvxRegister() const; - bool isZmmRegister() const; - bool isSpecialRegister() const; - bool isSegmentRegister() const; - uint32_t getRegNumber() const; - bool isMemory() const; - bool hasSegmentRegister() const; - uint32_t getSegmentRegister() const; - bool hasBaseRegister() const; - bool hasIndexRegister() const; - uint32_t getBaseRegister() const; - uint32_t getIndexRegister() const; - bool hasMemoryDisplacement() const; - virtual_offset_t getMemoryDisplacement() const; - bool isPcrel() const; - uint32_t getScaleValue() const; - uint32_t getMemoryDisplacementEncodingSize() const; - uint32_t getArgumentSizeInBytes() const; - uint32_t getArgumentSizeInBits() const; - bool isRead() const; - bool isWritten() const; - - - private: - - DecodedOperandCapstone_t( const shared_ptr<void> &my_insn, uint8_t op_num); - - shared_ptr<void> my_insn; - uint8_t op_num; - - friend class DecodedInstructionCapstone_t; - -}; - -} -#endif diff --git a/libIRDB/include/core/type.hpp b/libIRDB/include/core/type.hpp deleted file mode 100644 index 88e83384dd221085e322542c7041cb0855840479..0000000000000000000000000000000000000000 --- a/libIRDB/include/core/type.hpp +++ /dev/null @@ -1,155 +0,0 @@ -/* - * Copyright (c) 2014 - Zephyr Software LLC - * - * This file may be used and modified for non-commercial purposes as long as - * all copyright, permission, and nonwarranty notices are preserved. - * Redistribution is prohibited without prior written consent from Zephyr - * Software. - * - * Please contact the authors for restrictions applying to commercial use. - * - * THIS SOURCE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF - * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. - * - * Author: Zephyr Software - * e-mail: jwd@zephyr-software.com - * URL : http://www.zephyr-software.com/ - * - */ - -#ifndef _IRDB_TYPE_H_ -#define _IRDB_TYPE_H_ - -// add as many types as you want here -// MUST MATCH code in meds2pdb!!! -typedef enum IRDB_Type { - T_UNKNOWN = 0, // must be 0, leave this value alone - T_NUMERIC = 1, T_POINTER = 2, - T_VOID = 10, T_VARIADIC = 11, T_INT = 12, T_CHAR = 13, T_FLOAT = 14, T_DOUBLE = 15, - T_TYPEDEF = 21, T_SUBTYPE = 22, - T_FUNC = 100, T_AGGREGATE = 101 -} IRDB_Type; - -class Type_t; - -typedef std::set<Type_t*> TypeSet_t; -typedef std::vector<Type_t*> TypeVector_t; - -class Type_t : public BaseObj_t -{ - public: - Type_t() : BaseObj_t(NULL) { - typeID = T_UNKNOWN; - } - Type_t(db_id_t dbid, IRDB_Type t, std::string n) : BaseObj_t(NULL) { - SetBaseID(dbid); - typeID = t; - name = n; - } - virtual ~Type_t() {} - - virtual std::string WriteToDB(File_t *fid, db_id_t newid) = 0; - - std::string GetName() const { return name; } - void SetName(std::string newname) { name=newname; } - IRDB_Type GetTypeID() const { return typeID; } - void SetTypeID(IRDB_Type t) { typeID = t; } - - virtual bool IsUnknownType() const { return typeID == T_UNKNOWN; } - virtual bool IsVariadicType() const { return typeID == T_VARIADIC; } - virtual bool IsAggregateType() const { return typeID == T_AGGREGATE; } - virtual bool IsFuncType() const { return typeID == T_FUNC; } - virtual bool IsBasicType() const { return false; } - virtual bool IsPointerType() const { return false; } - virtual bool IsNumericType() const { return false; } - - private: - std::string name; - IRDB_Type typeID; -}; - -class BasicType_t : public Type_t -{ - public: - BasicType_t() : Type_t() {} - BasicType_t(db_id_t id, IRDB_Type type, std::string p_name) : Type_t(id, type, p_name) {} - virtual ~BasicType_t() {} - - virtual bool IsBasicType() const { return true; } - virtual bool IsNumericType() const; - - std::string WriteToDB(File_t *fid, db_id_t newid); -}; - -class PointerType_t : public Type_t -{ - public: - PointerType_t() : Type_t() { SetTypeID(T_POINTER); referentType = NULL; } - PointerType_t(db_id_t id, Type_t* ref, std::string p_name) : Type_t(id, T_POINTER, p_name) { - SetReferentType(ref); - } - virtual ~PointerType_t() {} - virtual bool IsPointerType() const { return true; } - - Type_t* GetReferentType() const { return referentType; } - void SetReferentType(Type_t* r) { referentType = r; } - - std::string WriteToDB(File_t *fid, db_id_t newid); - - private: - Type_t* referentType; -}; - -class AggregateType_t : public Type_t -{ - public: - AggregateType_t() : Type_t() { SetTypeID(T_AGGREGATE); } - AggregateType_t(db_id_t id, std::string p_name) : Type_t(id, T_AGGREGATE, p_name) {} - virtual ~AggregateType_t() {} - virtual bool IsAggregateType() const { return true; } - - void AddAggregatedType(Type_t *t, int pos); - virtual size_t GetNumAggregatedTypes() const { return refTypes.size(); } - Type_t* GetAggregatedType(unsigned int pos) const { - return (pos < (unsigned int)refTypes.size()) ? refTypes.at(pos) : NULL; - } - - std::string toString() { - return GetName(); - } - - std::string WriteToDB(File_t *fid, db_id_t newid); - - private: - TypeVector_t refTypes; -}; - -class FuncType_t : public Type_t -{ - public: - FuncType_t() : Type_t() { SetTypeID(T_FUNC); _init(); } - FuncType_t(db_id_t id, std::string p_name) : Type_t(id, T_FUNC, p_name) { _init(); } - virtual ~FuncType_t() {} - - virtual bool IsFuncType() const { return true; } - - std::string WriteToDB(File_t *fid, db_id_t newid); - - Type_t* GetReturnType() const { return returnType; } - void SetReturnType(Type_t *t) { returnType = t; } - AggregateType_t* GetArgumentsType() const { return argsType; } - void SetArgumentsType(AggregateType_t *t) { argsType = t; } - - private: - void _init() { - returnType = NULL; - argsType = NULL; - } - - private: - Type_t* returnType; - AggregateType_t* argsType; -}; - -#endif diff --git a/libIRDB/include/syscall/syscall.hpp b/libIRDB/include/syscall/syscall.hpp deleted file mode 100644 index 857c1580579d08ecc0f033c00d6741719aff4948..0000000000000000000000000000000000000000 --- a/libIRDB/include/syscall/syscall.hpp +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Copyright (c) 2014 - Zephyr Software - * - * This file may be used and modified for non-commercial purposes as long as - * all copyright, permission, and nonwarranty notices are preserved. - * Redistribution is prohibited without prior written consent from Zephyr - * Software. - * - * Please contact the authors for restrictions applying to commercial use. - * - * THIS SOURCE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF - * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. - * - * Author: Zephyr Software - * e-mail: jwd@zephyr-software.com - * URL : http://www.zephyr-software.com/ - * - */ - -#ifndef irdb_syscall_hpp -#define irdb_syscall_hpp - -typedef enum -{ - SNT_Unknown=-1, -#ifdef CGC - SNT_terminate=1, - SNT_transmit=2, - SNT_receive=3, - SNT_fdwait=4, - SNT_allocate=5, - SNT_deallocate=6, - SNT_random=7 -#else -/* LINUX here? */ -#endif -} SyscallNumber_t; - -class SyscallSite_t -{ - public: - SyscallSite_t(libIRDB::Instruction_t* p_site, libIRDB::SyscallNumber_t p_num) : site(p_site), num(p_num) {} - - bool operator<(const libIRDB::SyscallSite_t& rhs) const { return this->site < rhs.site; } - libIRDB::Instruction_t* GetSyscallSite() { return site; } - libIRDB::Instruction_t* GetSite() const { return site; } - libIRDB::SyscallNumber_t GetSyscallNumber() const { return num; } - private: - libIRDB::Instruction_t* site; - libIRDB::SyscallNumber_t num; -}; -typedef std::set<SyscallSite_t> SyscallSiteSet_t; - -class Syscalls_t -{ - public: - Syscalls_t(FileIR_t *the_firp=NULL) { if(the_firp) FindSystemCalls(the_firp); } - - - bool FindSystemCalls(const libIRDB::FileIR_t* firp); - - const libIRDB::SyscallSiteSet_t& GetSyscalls() {return syscalls;} - protected: - libIRDB::SyscallNumber_t FindSystemCallNumber(libIRDB::Instruction_t* insn, - const libIRDB::InstructionPredecessors_t& preds); - - private: - libIRDB::SyscallSiteSet_t syscalls; -}; - -#endif - diff --git a/libIRDB/include/util/params.hpp b/libIRDB/include/util/params.hpp deleted file mode 100644 index 758ad7241d08b47aafc246322f0e072a5f891e82..0000000000000000000000000000000000000000 --- a/libIRDB/include/util/params.hpp +++ /dev/null @@ -1,10 +0,0 @@ -#ifndef _PARAMS_H -#define _PARAMS_H - -extern bool IsParameterWrite(const libIRDB::FileIR_t *firp, libIRDB::Instruction_t* insn, std::string& output_dst); -extern bool CallFollows(const libIRDB::FileIR_t *firp, libIRDB::Instruction_t* insn, const std::string& arg_str, const std::string & = ""); -extern bool LeaFlowsIntoCall(const libIRDB::FileIR_t *firp, libIRDB::Instruction_t* insn); -extern bool LeaFlowsIntoPrintf(const libIRDB::FileIR_t *firp, libIRDB::Instruction_t* insn); -extern bool FlowsIntoCall(const libIRDB::FileIR_t *firp, libIRDB::Instruction_t* insn); - -#endif diff --git a/libIRDB/include/utils.hpp b/libIRDB/include/utils.hpp deleted file mode 100644 index 6f4a9046e6a03b03bbdc2eb0d320ae03434ba2e2..0000000000000000000000000000000000000000 --- a/libIRDB/include/utils.hpp +++ /dev/null @@ -1,128 +0,0 @@ -/* - * Copyright (c) 2014 - Zephyr Software LLC - * - * This file may be used and modified for non-commercial purposes as long as - * all copyright, permission, and nonwarranty notices are preserved. - * Redistribution is prohibited without prior written consent from Zephyr - * Software. - * - * Please contact the authors for restrictions applying to commercial use. - * - * THIS SOURCE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF - * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. - * - * Author: Zephyr Software - * e-mail: jwd@zephyr-software.com - * URL : http://www.zephyr-software.com/ - * - */ - - -#ifndef _IRDB_UTIL_ -#define _IRDB_UTIL_ - -#include <sstream> -#include <map> -#include <algorithm> -#include <set> -#include <string> -#include <iostream> -#include <sstream> -#include <cstdlib> -#include <iterator> -#include <functional> -#include <utility> -#include <stdint.h> - -template <class T> -inline std::string to_string (const T& t) -{ - std::stringstream ss; - ss << t; - return ss.str(); -} - -template <class T> -inline std::string to_hex_string (const T& t) -{ - std::stringstream ss; - ss << std::hex << t; - return ss.str(); -} - - - -/* - * is_in_container - a handle template function returning whether key S is contained in container T. - */ -template <class T, class S> -inline bool is_in_container(const T& container, const S& key) -{ - bool is_in=container.find(key) != container.end(); - return is_in; -} - -template <class S> -inline bool is_in_set(const std::set<S>& container, const S& key) -{ - return std::find(container.begin(), container.end(), key) != container.end(); -} - -/* - * find_map_object - without modifying the object, return the element - */ -template <class T, class S> -inline S const& find_map_object( const std::map< T , S > &a_map, const T& key) -{ - typename std::map< T , S >::const_iterator it; - - it=a_map.find(key); - - assert(it!=a_map.end()); - - return (*it).second; -} - -typedef uintptr_t virtual_offset_t; - -template<class T> inline T strtoint(std::string s) -{ - std::stringstream str(s); - T off; - - str >> off; - - return off; -} - -// nb: relies on srand() being previously set -template <typename IterType, typename Funct> -inline Funct for_randomOrder_each(const IterType &b, const IterType & e, const Funct &callback) -{ - std::map<int,const typename std::iterator_traits<IterType>::value_type *> m; - for_each(b,e, [&](const typename std::iterator_traits<IterType>::value_type & o) - { - while(true) - { - int rn=rand(); - if(m.find(rn)==m.end()) - { - m[rn]=&o; - break; - } - } - }); - for_each(m.begin(), m.end(), [&](const std::pair<int,const typename std::iterator_traits<IterType>::value_type *> &p) - { - callback(*p.second); - }); - return callback; -} - -int command_to_stream(const std::string& command, std::ostream& stream); - - -#endif - - diff --git a/libIRDB/install_libs.sh b/libIRDB/install_libs.sh deleted file mode 100755 index 96de0964230d4707e30345074732d88da9f3908b..0000000000000000000000000000000000000000 --- a/libIRDB/install_libs.sh +++ /dev/null @@ -1,11 +0,0 @@ -#!/bin/bash - -cd lib; -for i in *; -do - if test ! -f ../../lib/$i -o $i -nt ../../lib/$i ; then - echo Installing $i - cp $i ../../lib/; - fi -done - diff --git a/libIRDB/src/Makefile.in b/libIRDB/src/Makefile.in deleted file mode 100644 index bcf5ef6e803d87ebf6cde5111aee86982f75aca0..0000000000000000000000000000000000000000 --- a/libIRDB/src/Makefile.in +++ /dev/null @@ -1,11 +0,0 @@ - -CC=@CC@ -CXX=@CXX@ - -dirs=core cfg util syscall - -all: - for i in ${dirs}; do echo ${PWD}; cd $$i; make CC="$(CC)" CXX="$(CXX)" || exit 1; cd ..; done - -clean: - for i in ${dirs}; do echo ${PWD}; cd $$i; make clean || exit 1; cd ..; done diff --git a/libIRDB/src/SConscript b/libIRDB/src/SConscript deleted file mode 100644 index 439e5176c06481b34825a2eb2ddcb32f6f81ecd7..0000000000000000000000000000000000000000 --- a/libIRDB/src/SConscript +++ /dev/null @@ -1,17 +0,0 @@ -import os - -Import('env') - -tools=[] - -dirs=''' - cfg - core - syscall - util - ''' - -for i in Split(dirs): - tools=tools + SConscript(os.path.join(i,"SConscript")) - -Return('tools') diff --git a/libIRDB/src/SConstruct b/libIRDB/src/SConstruct deleted file mode 100644 index b5b7b78c5f88640c7e8877a9df76dc9191af7498..0000000000000000000000000000000000000000 --- a/libIRDB/src/SConstruct +++ /dev/null @@ -1,8 +0,0 @@ - - - -env=Environment() -Export('env') -lib=SConscript("SConscript") - -Return('lib') diff --git a/libIRDB/src/cfg/CFG.cpp b/libIRDB/src/cfg/CFG.cpp deleted file mode 100644 index c05723729247c60b0ddfcd700392dd915d69033d..0000000000000000000000000000000000000000 --- a/libIRDB/src/cfg/CFG.cpp +++ /dev/null @@ -1,219 +0,0 @@ -/* - * Copyright (c) 2014 - Zephyr Software LLC - * - * This file may be used and modified for non-commercial purposes as long as - * all copyright, permission, and nonwarranty notices are preserved. - * Redistribution is prohibited without prior written consent from Zephyr - * Software. - * - * Please contact the authors for restrictions applying to commercial use. - * - * THIS SOURCE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF - * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. - * - * Author: Zephyr Software - * e-mail: jwd@zephyr-software.com - * URL : http://www.zephyr-software.com/ - * - */ - - -#include <libIRDB-cfg.hpp> -#include <utils.hpp> - -using namespace std; -using namespace libIRDB; - -#define ALLOF(a) begin(a),end(a) - -/* - * FindTargets - locate all possible instructions that are the target of a jump instruction - */ -static InstructionSet_t FindBlockStarts(Function_t* func) -{ - - InstructionSet_t targets; - InstructionSet_t found_fallthrough_to; - - if(func->GetEntryPoint()) - /* the entry point of the function is a target instruction for this CFG */ - targets.insert(func->GetEntryPoint()); - - /* for each instruction, decide if it's a block start based on whether or not - * it can be indirectly branched to. Also mark direct targets as block starts. - */ - for(InstructionSet_t::iterator it=func->GetInstructions().begin(); - it!=func->GetInstructions().end(); - ++it - ) - { - /* Get the instruction */ - Instruction_t* insn=*it; - - /* If this instruction might be an indirect branch target, then mark it as a block start */ - if(insn->GetIndirectBranchTargetAddress()) - { - targets.insert(insn); - } - - /* get target and fallthrough */ - Instruction_t* target=insn->GetTarget(); - Instruction_t* ft=insn->GetFallthrough(); - - /* if this instruction has a target, and the target is in this function, mark the target as a block start */ - if(target && is_in_container(func->GetInstructions(), target)) - targets.insert(target); - - /* there is a target, and a failthrough, and the fallthrough is in this function */ - if(target && ft && is_in_container(func->GetInstructions(), ft)) - targets.insert(ft); - - // we already found a fallthrough to ft, so we have 2+ fallthroughs to ft. mark it as a control flow merge. - if( ft && is_in_container(found_fallthrough_to, ft)) - targets.insert(ft); - - // if there is a ft, mark that we've seen it now. - if(ft) - found_fallthrough_to.insert(ft); - - } - - return targets; -} - -ControlFlowGraph_t::ControlFlowGraph_t(Function_t* func) : - entry(NULL), function(func) -{ - Build(func); -} - - -void ControlFlowGraph_t::alloc_blocks(const InstructionSet_t &starts, map<Instruction_t*,BasicBlock_t*>& insn2block_map) -{ - /* create a basic block for each instruction that starts a block */ - for(const auto &insn : starts) - { - if(is_in_container(insn2block_map,insn)) // already allocated - continue; - - auto newblock=new BasicBlock_t; - - assert( insn && newblock ); - - blocks.insert(newblock); - insn2block_map[insn]=newblock; - } -} - -void ControlFlowGraph_t::build_blocks(const map<Instruction_t*,BasicBlock_t*>& insn2block_map) -{ - - /* Ask the basic block to set the fields for each block that need to be set */ - for(const auto &it : insn2block_map) - { - const auto insn=it.first; - const auto block=it.second; - - if(block->GetInstructions().size()>0) // already built - continue; - - assert(insn && block); - - block->BuildBlock(insn, insn2block_map); - - } - -} - -void ControlFlowGraph_t::find_unblocked_instructions(InstructionSet_t &starts, Function_t* func) -{ - auto mapped_instructions=InstructionSet_t(); - auto missed_instructions=InstructionSet_t(); - for(const auto block : GetBlocks()) - mapped_instructions.insert(ALLOF(block->GetInstructions())); - - auto my_inserter=inserter(missed_instructions,missed_instructions.end()); - set_difference(ALLOF(func->GetInstructions()), ALLOF(mapped_instructions), my_inserter); - starts.insert(ALLOF(missed_instructions)); -} - - - -void ControlFlowGraph_t::Build(Function_t* func) -{ - auto starts=FindBlockStarts(func); - - auto insn2block_map=map<Instruction_t*,BasicBlock_t*> (); - - alloc_blocks(starts, insn2block_map); - build_blocks(insn2block_map); - /* record the entry block */ - if(func->GetEntryPoint()) - entry=insn2block_map[func->GetEntryPoint()]; - - /* most functions are done now. */ - /* however, if a function has a (direct) side entrance, - * some code may appear unreachable and not be placed in - * a block -- here, we detect that code and create a - * new basic block for every instruction, as any may have a side entrance - */ - /* note: side entrances may miss a block start */ - /* in code that appears reachable from the entrance?! */ - find_unblocked_instructions(starts, func); - alloc_blocks(starts, insn2block_map); - build_blocks(insn2block_map); - - -} - -/* - * output operator - */ -ostream& libIRDB::operator<<(ostream& os, const ControlFlowGraph_t& cfg) -{ - int i=0; - - map<BasicBlock_t*,int> blk_numbers; - for( - set<BasicBlock_t*>::const_iterator it=cfg.blocks.begin(); - it!=cfg.blocks.end(); - ++it - ) - { - blk_numbers[*it]=i++; - } - - - for( - set<BasicBlock_t*>::const_iterator it=cfg.blocks.begin(); - it!=cfg.blocks.end(); - ++it - ) - { - BasicBlock_t *block=*it; - - if(block==cfg.GetEntry()) - os<<"**** Entry "; - else - os<<"---- NotEntry "; - os<<"block "<<std::dec<<blk_numbers[block]<<endl; - os<<"Successors: "; - for_each(block->GetSuccessors().begin(), block->GetSuccessors().end(), [&](BasicBlock_t* succ) - { - os<<blk_numbers[succ]<<", "; - - }); - os<<endl; - os<<"Predecessors: "; - for_each(block->GetPredecessors().begin(), block->GetPredecessors().end(), [&](BasicBlock_t* pred) - { - os<<blk_numbers[pred]<<", "; - }); - os<<endl; - os << *block; - } - - return os; -} - diff --git a/libIRDB/src/cfg/callgraph.cpp b/libIRDB/src/cfg/callgraph.cpp deleted file mode 100644 index 68b0784a53ccd8a40cffba98e2213af3d91737a2..0000000000000000000000000000000000000000 --- a/libIRDB/src/cfg/callgraph.cpp +++ /dev/null @@ -1,271 +0,0 @@ -/* - * Copyright (c) 2014-2015 - Zephyr Software LLC - * - * This file may be used and modified for non-commercial purposes as long as - * all copyright, permission, and nonwarranty notices are preserved. - * Redistribution is prohibited without prior written consent from Zephyr - * Software. - * - * Please contact the authors for restrictions applying to commercial use. - * - * THIS SOURCE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF - * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. - * - * Author: Zephyr Software - * e-mail: jwd@zephyr-software.com - * URL : http://www.zephyr-software.com/ - * - */ - - -#include <map> -#include <ostream> -#include <libIRDB-core.hpp> -#include <libIRDB-cfg.hpp> -#include <utils.hpp> - -using namespace libIRDB; -using namespace std; - - -Callgraph_t::Callgraph_t() : - default_hellnode(NULL) -{ -} - -Callgraph_t::~Callgraph_t() -{ - for (FunctionToCGNodeMap_t::iterator it = nodes.begin(); it != nodes.end(); ++it) - { - CallGraphNode_t* n = it->second; - delete(n); - } - nodes.clear(); -} - -static bool IsCallSite(Instruction_t* insn) -{ - //DISASM insnd; - //Disassemble(insn,insnd); - //return NULL!=(strstr(insnd.Instruction.Mnemonic,"call")); - - const auto d=DecodedInstruction_t(insn); - return d.isCall(); -} - -static bool IsTailJmpSite(Instruction_t* insn) -{ - //DISASM insnd; - //Disassemble(insn,insnd); - const auto d=DecodedInstruction_t(insn); - // if(strstr(insnd.Instruction.Mnemonic,"jmp")==NULL) - if(d.isBranch()) - return false; - - if(insn->GetTarget()==NULL) - return true; - - if(insn->GetFunction() != insn->GetTarget()->GetFunction()) - return true; - return false; -} - -static bool IsPushJmpSite(Instruction_t* insn) -{ - //DISASM insnd; - //Disassemble(insn,insnd); - const auto d=DecodedInstruction_t(insn); - if(d.getMnemonic()!="push" || insn->GetFallthrough()==NULL) - return false; - - if(insn->GetRelocations().size()==0) - return false; - - const auto d2=DecodedInstruction_t(insn->GetFallthrough()); - //if(strstr(insnd.Instruction.Mnemonic,"jmp")==NULL) - if(!d2.isBranch()) - return false; - - return true; -} - -void Callgraph_t::MarkCallSite(Instruction_t* insn) -{ - Function_t* from_func=insn->GetFunction(); - Instruction_t* to_insn=insn->GetTarget(); - Function_t* to_func= to_insn==NULL? NULL : to_insn->GetFunction(); - - CallGraphNode_t* from_node = FindNode(from_func); - CallGraphNode_t* to_node = FindNode(to_func); - - if (!from_node) - from_node = &GetDefaultHellNode(); - - if (!to_node) - to_node = &GetDefaultHellNode(); - - call_sites[from_node].insert(insn); - callees[from_node].insert(to_node); - callers[to_node].insert(from_node); -} - -void Callgraph_t::CreateNodes(libIRDB::FileIR_t *firp) -{ - set<Function_t*> &fns=firp->GetFunctions(); - for(set<Function_t*>::iterator it=fns.begin(); fns.end() != it; ++it) - { - Function_t *fn=*it; - if (fn) { - CallGraphNode_t *newnode = new CallGraphNode_t(fn); - nodes[fn] = newnode; -// cout << "Added CGNode: " << GetNodeName(newnode) << endl; - } - } -} - -void Callgraph_t::AddFile(libIRDB::FileIR_t* const firp) -{ - // Create CG Nodes from functions - CreateNodes(firp); - - // for each instruction - auto &insns=firp->GetInstructions(); - - for(auto it=insns.begin(); insns.end() != it; ++it) - { - auto insn=*it; - if(IsCallSite(insn) || IsTailJmpSite(insn)) - MarkCallSite(insn); - if(IsPushJmpSite(insn)) - MarkCallSite(insn->GetFallthrough()); - - if(insn->GetFunction() && insn->GetFunction()->GetEntryPoint()==insn - && insn->GetIndirectBranchTargetAddress()) - { - auto node = FindNode(insn->GetFunction()); - assert(node); - callees[&GetDefaultHellNode()].insert(node); - callers[node].insert(&GetDefaultHellNode()); - } - } -} - -void Callgraph_t::Dump(std::ostream& fout) -{ - - fout<<"Dumping callgraph ..."<<endl; - - fout<<"Mapping one way ..."<<endl; - for(auto it=callees.begin(); callees.end()!=it; ++it) - { - CallGraphNode_t* node = it->first; - - fout<<"Function "<<GetNodeName(node)<<" calls: "; - CallGraphNodeSet_t &node_callers=it->second; - for(auto it2=node_callers.begin(); node_callers.end()!=it2; ++it2) - { - CallGraphNode_t* the_callee=*it2; - fout<<GetNodeName(the_callee)<<", "; - } - fout<<endl; - for(auto it2=GetCallSites(node).begin(); GetCallSites(node).end() != it2; ++it2) - { - CallSite_t the_call_site=*it2; - fout<<"\t"<<GetCallsiteDisassembly(the_call_site)<<endl; - } - } - - fout<<"Mapping the other way ..."<<endl; - for(auto it=callers.begin(); callers.end()!=it; ++it) - { - CallGraphNode_t* n=it->first; - - fout<<"Function "<<GetNodeName(n)<<" called by: "; - CallGraphNodeSet_t &node_callees=it->second; - for(CallGraphNodeSet_t::iterator it2=node_callees.begin(); - node_callees.end()!=it2; - ++it2) - { - CallGraphNode_t* the_caller=*it2; - fout<<GetNodeName(the_caller)<<", "; - - } - fout<<endl; - } - - - fout<<"Printing call sites..."<<endl; - for(auto it=call_sites.begin(); call_sites.end()!=it; ++it) - { - auto from_node=it->first; - auto &call_sites_for_func=it->second; - - fout<<"Call Sites for "<<GetNodeName(from_node)<<": "; - - for(auto it2=call_sites_for_func.begin(); call_sites_for_func.end() != it2; ++it2) - { - auto the_call_site=*it2; - fout<<GetCallsiteDisassembly(the_call_site)<<", "; - } - fout<<endl; - } - - fout<<"Done!"<<endl; -} - -void Callgraph_t::_GetAncestors(CallGraphNode_t* const node, CallGraphNodeSet_t &ancestors, CallGraphNodeSet_t &visited, bool skipHellNode) -{ - if (!node || visited.count(node) > 0) - return; - -cerr << "visiting node: " << GetNodeName(node) << " visited(size):" << visited.size() << endl; - - // ancestor-traversal(node X) - // mark X visited - // get parents P of X - // if P[i] not visited: - // add P[i] to ancestors - // ancestor-traversal(P[i]) - - visited.insert(node); - - auto directPredecessors = GetCallersOfNode(node); - for (auto it = directPredecessors.begin(); it != directPredecessors.end(); ++it) - { - if (visited.count(*it) == 0) - { - assert(*it); - if ((*it)->IsHellnode() && skipHellNode) continue; - -cerr << "adding " << GetNodeName(*it) << " to ancestor list " << hex << *it << dec << endl; - ancestors.insert(*it); - _GetAncestors(*it, ancestors, visited, skipHellNode); - } - } -} - -CallGraphNode_t* Callgraph_t::FindNode(Function_t* const fn) -{ - return nodes[fn]; -} - -void Callgraph_t::GetAncestors(Function_t* const fn, CallGraphNodeSet_t &ancestors, bool skipHellNode) -{ - auto node = FindNode(fn); - if (node) - GetAncestors(node, ancestors, skipHellNode); -} - -void Callgraph_t::GetAncestors(CallGraphNode_t* const node, CallGraphNodeSet_t &ancestors, bool skipHellNode) -{ - auto visited=CallGraphNodeSet_t(); - _GetAncestors(node, ancestors, visited, skipHellNode); -} - -bool Callgraph_t::Reachable(CallGraphNode_t* const from, CallGraphNode_t* const to, bool skipHellNode) -{ - auto ancestors=CallGraphNodeSet_t(); - GetAncestors(to, ancestors, skipHellNode); - return (ancestors.count(from) > 0); -} diff --git a/libIRDB/src/core/decode_bea.cpp b/libIRDB/src/core/decode_bea.cpp deleted file mode 100644 index 0b7fafb7a2f52aa96eb259b30e56af5ffc440530..0000000000000000000000000000000000000000 --- a/libIRDB/src/core/decode_bea.cpp +++ /dev/null @@ -1,280 +0,0 @@ - -#include <libIRDB-core.hpp> - -#include <bea_deprecated.hpp> -#include <core/decode_bea.hpp> -#include <core/operand_bea.hpp> - -using namespace libIRDB; -using namespace std; - -// static functions -static inline bool my_SetsStackPointer(const ARGTYPE* arg) -{ - if((arg->AccessMode & WRITE ) == 0) - return false; - int access_type=arg->ArgType; - - if(access_type==REGISTER_TYPE + GENERAL_REG +REG4) - return true; - return false; - -} - -// constructors, destructors, operators. - -DecodedInstructionBea_t::DecodedInstructionBea_t(const Instruction_t* i) -{ - disasm_data=static_cast<void*>(new DISASM({})); - DISASM* d=(DISASM*)disasm_data; - disasm_length=::Disassemble(i,*d); -} - -DecodedInstructionBea_t::DecodedInstructionBea_t(const virtual_offset_t start_addr, const void *data, uint32_t max_len) -{ - disasm_data=static_cast<void*>(new DISASM({})); - const auto endptr=data+max_len; - Disassemble(start_addr, data, max_len); -} - -DecodedInstructionBea_t::DecodedInstructionBea_t(const virtual_offset_t start_addr, const void *data, const void* endptr) -{ - disasm_data=static_cast<void*>(new DISASM({})); - const auto length=(char*)endptr-(char*)data + 1; - Disassemble(start_addr,data,length); -} - -DecodedInstructionBea_t::DecodedInstructionBea_t(const DecodedInstructionBea_t& copy) -{ - DISASM* d=static_cast<DISASM*>(copy.disasm_data); - disasm_data=static_cast<void*>(new DISASM(*d)); - disasm_length=copy.disasm_length; -} - -DecodedInstructionBea_t::~DecodedInstructionBea_t() -{ - DISASM* d=static_cast<DISASM*>(disasm_data); - delete d; - disasm_data=NULL; -} - -DecodedInstructionBea_t& DecodedInstructionBea_t::operator=(const DecodedInstructionBea_t& copy) -{ - DISASM* d=static_cast<DISASM*>(disasm_data); - delete d; - disasm_data=NULL; - - d=static_cast<DISASM*>(copy.disasm_data); - disasm_data=static_cast<void*>(new DISASM(*d)); - disasm_length=copy.disasm_length; - return *this; -} - -// private methods - -void DecodedInstructionBea_t::Disassemble(const virtual_offset_t start_addr, const void *data, uint32_t max_len) -{ - DISASM* d=static_cast<DISASM*>(disasm_data); - memset(d, 0, sizeof(DISASM)); - d->Options = NasmSyntax + PrefixedNumeral; - d->Archi = FileIR_t::GetArchitectureBitWidth(); - d->EIP = (UIntPtr)data; - d->SecurityBlock=max_len; - d->VirtualAddr = start_addr; - disasm_length=Disasm(d); - -} - -// public methods - -string DecodedInstructionBea_t::getDisassembly() const -{ - assert(valid()); - DISASM* d=static_cast<DISASM*>(disasm_data); - return string(d->CompleteInstr); -} - -bool DecodedInstructionBea_t::valid() const -{ - return disasm_length>=0; -} - -uint32_t DecodedInstructionBea_t::length() const -{ - assert(valid()); - return disasm_length; -} - - -bool DecodedInstructionBea_t::isBranch() const -{ - DISASM* d=static_cast<DISASM*>(disasm_data); - return d->Instruction.BranchType!=0; -} - -bool DecodedInstructionBea_t::isCall() const -{ - DISASM* d=static_cast<DISASM*>(disasm_data); - return d->Instruction.BranchType==CallType; -} - -bool DecodedInstructionBea_t::isUnconditionalBranch() const -{ - DISASM* d=static_cast<DISASM*>(disasm_data); - return d->Instruction.BranchType==JmpType; -} - -bool DecodedInstructionBea_t::isConditionalBranch() const -{ - DISASM* d=static_cast<DISASM*>(disasm_data); - assert(0); -} - -bool DecodedInstructionBea_t::isReturn() const -{ - DISASM* d=static_cast<DISASM*>(disasm_data); - return d->Instruction.BranchType==RetType; -} - - -bool DecodedInstructionBea_t::hasOperand(const int op_num) const -{ - DISASM* d=static_cast<DISASM*>(disasm_data); - switch(op_num+1) - { - case 1: - return d->Argument1.ArgType!=NO_ARGUMENT; - case 2: - return d->Argument2.ArgType!=NO_ARGUMENT; - case 3: - return d->Argument3.ArgType!=NO_ARGUMENT; - case 4: - return d->Argument4.ArgType!=NO_ARGUMENT; - default: - return false; - } -} - - -// 0-based. first operand is numbered 0. -DecodedOperandBea_t DecodedInstructionBea_t::getOperand(const int op_num) const -{ - if(!hasOperand(op_num)) - throw std::out_of_range("op_num"); - - DISASM* d=static_cast<DISASM*>(disasm_data); - switch(op_num+1) - { - case 1: - return DecodedOperandBea_t(&d->Argument1); - case 2: - return DecodedOperandBea_t(&d->Argument2); - case 3: - return DecodedOperandBea_t(&d->Argument3); - case 4: - return DecodedOperandBea_t(&d->Argument4); - } -} - -DecodedOperandBeaVector_t DecodedInstructionBea_t::getOperands() const -{ - auto ret_val=DecodedOperandBeaVector_t(); - for(auto i=0;i<4;i++) - { - if(hasOperand(i)) - ret_val.push_back(getOperand(i)); - else - break; - } - return ret_val; -} - - -string DecodedInstructionBea_t::getMnemonic() const -{ - DISASM* d=static_cast<DISASM*>(disasm_data); - const auto mnemonic=string(d->Instruction.Mnemonic); - return mnemonic.substr(0,mnemonic.size()-1); -} - -int64_t DecodedInstructionBea_t::getImmediate() const -{ - // find and return an immediate operand from this instruction - DISASM* d=static_cast<DISASM*>(disasm_data); - return d->Instruction.Immediat; -} - - -virtual_offset_t DecodedInstructionBea_t::getAddress() const -{ - // return anything that's explicitly an address, like a jmp/call target - DISASM* d=static_cast<DISASM*>(disasm_data); - return d->Instruction.AddrValue; -} - - -bool DecodedInstructionBea_t::setsStackPointer() const -{ - DISASM* d=static_cast<DISASM*>(disasm_data); - - if(getMnemonic()== "push") - return true; - if(getMnemonic()== "pop") - return true; - if(getMnemonic()== "call") - return true; - if(d->Instruction.ImplicitModifiedRegs==REGISTER_TYPE+GENERAL_REG+REG4) - return true; - - if(my_SetsStackPointer(&d->Argument1)) return true; - if(my_SetsStackPointer(&d->Argument2)) return true; - if(my_SetsStackPointer(&d->Argument3)) return true; - if(my_SetsStackPointer(&d->Argument4)) return true; - - return false; -} - -uint32_t DecodedInstructionBea_t::getPrefixCount() const -{ - DISASM* d=static_cast<DISASM*>(disasm_data); - return d->Prefix.Number; -} - -virtual_offset_t DecodedInstructionBea_t::getMemoryDisplacementOffset(const DecodedOperandBea_t& t, const libIRDB::Instruction_t*) const -{ - DISASM* d=static_cast<DISASM*>(disasm_data); - ARGTYPE* the_arg=static_cast<ARGTYPE*>(t.arg_data); - return the_arg->Memory.DisplacementAddr-d->EIP; -} - - -bool DecodedInstructionBea_t::hasRelevantRepPrefix() const -{ - DISASM* d=static_cast<DISASM*>(disasm_data); - return d->Prefix.RepPrefix==InUsePrefix; -} - -bool DecodedInstructionBea_t::hasRelevantRepnePrefix() const -{ - DISASM* d=static_cast<DISASM*>(disasm_data); - return d->Prefix.RepnePrefix==InUsePrefix; -} - -bool DecodedInstructionBea_t::hasRelevantOperandSizePrefix() const -{ - DISASM* d=static_cast<DISASM*>(disasm_data); - return d->Prefix.OperandSize!=NotUsedPrefix; -} - -bool DecodedInstructionBea_t::hasRexWPrefix() const -{ - DISASM* d=static_cast<DISASM*>(disasm_data); - return d->Prefix.REX.W_; -} - -bool DecodedInstructionBea_t::hasImplicitlyModifiedRegs() const -{ - DISASM* d=static_cast<DISASM*>(disasm_data); - return d->Instruction.ImplicitModifiedRegs!=0; -} - diff --git a/libIRDB/src/core/decode_meta.cpp b/libIRDB/src/core/decode_meta.cpp deleted file mode 100644 index 0bd7a0f2e222a218f05724760640ea2aa269bf29..0000000000000000000000000000000000000000 --- a/libIRDB/src/core/decode_meta.cpp +++ /dev/null @@ -1,167 +0,0 @@ - -#include <libIRDB-core.hpp> -#include <core/decode_meta.hpp> -#include <core/operand_meta.hpp> - -using namespace libIRDB; -using namespace std; - -// constructors, destructors, operators. - -DecodedInstructionMeta_t::DecodedInstructionMeta_t(const Instruction_t* i) : - bea(i), - cs(i) -{ -} - -DecodedInstructionMeta_t::DecodedInstructionMeta_t(const virtual_offset_t start_addr, const void *data, uint32_t max_len) : - bea(start_addr,data,max_len), - cs(start_addr,data,max_len) -{ -} - -DecodedInstructionMeta_t::DecodedInstructionMeta_t(const virtual_offset_t start_addr, const void *data, const void* endptr) : - bea(start_addr,data,endptr), - cs(start_addr,data,endptr) -{ -} - -DecodedInstructionMeta_t::DecodedInstructionMeta_t(const DecodedInstructionMeta_t& copy) : - bea(copy.bea), - cs(copy.cs) -{ -} - -DecodedInstructionMeta_t::~DecodedInstructionMeta_t() -{ -} - -DecodedInstructionMeta_t& DecodedInstructionMeta_t::operator=(const DecodedInstructionMeta_t& copy) -{ - bea=copy.bea; - cs=copy.cs; -} - - -void do_breakpoint(const char* s) { (void)s; } - - -#define passthrough_to_bea(ret_type, method_name) \ - ret_type DecodedInstructionMeta_t::method_name() const \ - { \ - return bea.method_name(); \ - } - - -#define compare_decoders(ret_type, method_name) \ - ret_type DecodedInstructionMeta_t::method_name() const \ - { \ - const auto bea_res= bea.method_name(); \ - const auto cs_res= cs.method_name(); \ - if(bea_res!=cs_res) \ - { \ - cerr<<"Bea/Capstone miscompare: bea='"<<bea_res<<"'" \ - <<" cs='"<<cs_res <<"'"; \ - cerr<<" in bea="<<bea.getDisassembly(); \ - cerr<<" or cs="<<bea.getDisassembly(); \ - cerr<<" at " <<__FUNCTION__<<endl; \ - do_breakpoint(__FUNCTION__); \ - } \ - return cs_res; \ - } - -#define compare_decoders_assert(ret_type, method_name) \ - ret_type DecodedInstructionMeta_t::method_name() const \ - { \ - const auto bea_res= bea.method_name(); \ - const auto cs_res= cs.method_name(); \ - if(bea_res!=cs_res) \ - { \ - cerr<<"Bea/Capstone miscompare: bea='"<<bea_res<<"'" \ - <<" cs='"<<cs_res <<"'"<<endl; \ - cerr<<" in bea="<<bea.getDisassembly(); \ - cerr<<" or cs="<<bea.getDisassembly(); \ - cerr<<" at " <<__FUNCTION__<<endl; \ - abort(); \ - } \ - return cs_res; \ - } - - -#define passthrough_to_cs(ret_type, method_name) \ - ret_type DecodedInstructionMeta_t::method_name() const \ - { \ - return cs.method_name(); \ - } - -// public methods - -/* demonstrating things are the same */ -compare_decoders_assert(bool, valid); -compare_decoders_assert(uint32_t, length); -compare_decoders_assert(bool, isBranch); -compare_decoders_assert(bool, isCall); -compare_decoders_assert(bool, isUnconditionalBranch); -compare_decoders_assert(bool, isConditionalBranch); -compare_decoders_assert(bool, isReturn); -compare_decoders_assert(uint32_t, getPrefixCount); -compare_decoders_assert(bool, hasRexWPrefix); -compare_decoders_assert(bool, setsStackPointer); -compare_decoders_assert(bool, hasRelevantRepPrefix); // rep ret disagreement. -compare_decoders_assert(bool, hasRelevantRepnePrefix); -compare_decoders_assert(bool, hasRelevantOperandSizePrefix); - -/* demonstrating when capstone is better */ -passthrough_to_cs(string, getMnemonic); -passthrough_to_cs(string,getDisassembly); -passthrough_to_cs(virtual_offset_t, getAddress); // bea sometimes calcs this wrong. way wrong. -passthrough_to_cs(int64_t, getImmediate); - -// demonstrating they different and trying to determine which is better. -compare_decoders(bool, hasImplicitlyModifiedRegs); // found div %sil insn that bea gets wrong. - -// not yet completed -// needs more complicated impl. - - -bool DecodedInstructionMeta_t::hasOperand(const int op_num) const -{ - const auto cs_res =cs .hasOperand(op_num); -/* - const auto bea_res=bea.hasOperand(op_num); - if(bea_res!=cs_res) - { - cerr<<"Bea/Capstone miscompare: bea='"<<bea_res<<"'" - <<" cs='"<<cs_res <<"'"<<endl; - cerr<<" in bea="<<bea.getDisassembly(); - cerr<<" or cs="<<bea.getDisassembly(); - cerr<<" at " <<__FUNCTION__<<endl; - abort(); - } - return bea_res; -*/ - return cs_res; -} - -// 0-based. first operand is numbered 0. -DecodedOperandMeta_t DecodedInstructionMeta_t::getOperand(const int op_num) const -{ - return DecodedOperandMeta_t(cs.getOperand(op_num)); -} - -DecodedOperandMetaVector_t DecodedInstructionMeta_t::getOperands() const -{ - auto ret_val=DecodedOperandMetaVector_t(); - auto cs_operands=cs.getOperands(); - for(const auto &op : cs_operands ) - ret_val.push_back(DecodedOperandMeta_t(op)); - return ret_val; -} - -virtual_offset_t DecodedInstructionMeta_t::getMemoryDisplacementOffset(const DecodedOperandMeta_t& t, const Instruction_t* insn) const -{ - return cs.getMemoryDisplacementOffset(t.cs, insn); -} - - - diff --git a/libIRDB/src/core/operand_bea.cpp b/libIRDB/src/core/operand_bea.cpp deleted file mode 100644 index 422752dfc0dc3d02fe5db0cbfa85653549206bc7..0000000000000000000000000000000000000000 --- a/libIRDB/src/core/operand_bea.cpp +++ /dev/null @@ -1,258 +0,0 @@ - -#include <libIRDB-core.hpp> -#include <bea_deprecated.hpp> - -#include <core/decode_bea.hpp> -#include <core/operand_bea.hpp> - -using namespace std; -using namespace libIRDB; - -// static functions -static uint32_t beaRegNoToIRDBRegNo(uint32_t regno) -{ - switch(regno) - { - case 0: return -1; // no reg -> -1 - case REG0+REG2: /* eax:edx pair -- call it reg 0 */ return 0; - case REG0: return 0; - case REG1: return 1; - case REG2: return 2; - case REG3: return 3; - case REG4: return 4; - case REG5: return 5; - case REG6: return 6; - case REG7: return 7; - case REG8: return 8; - case REG9: return 9; - case REG10: return 10; - case REG11: return 11; - case REG12: return 12; - case REG13: return 13; - case REG14: return 14; - case REG15: return 15; - default: assert(0); // odd number from BEA? - }; -} - - -// methods -DecodedOperandBea_t::DecodedOperandBea_t(void* arg_voidptr) -{ - ARGTYPE *arg_ptr=static_cast<ARGTYPE*>(arg_voidptr); - arg_data=(void*)new ARGTYPE(*arg_ptr); -} - -DecodedOperandBea_t::DecodedOperandBea_t(const DecodedOperandBea_t& copy) -{ - ARGTYPE *arg_ptr=static_cast<ARGTYPE*>(copy.arg_data); - arg_data=(void*)new ARGTYPE(*arg_ptr); -} - -DecodedOperandBea_t::~DecodedOperandBea_t() -{ - ARGTYPE *t=static_cast<ARGTYPE*>(arg_data); - delete t; - arg_data=NULL; -} - -DecodedOperandBea_t& DecodedOperandBea_t::operator=(const DecodedOperandBea_t& copy) -{ - ARGTYPE *t=static_cast<ARGTYPE*>(arg_data); - delete t; - arg_data=NULL; - ARGTYPE *arg_ptr=static_cast<ARGTYPE*>(copy.arg_data); - arg_data=(void*)new ARGTYPE(*arg_ptr); - - return *this; -} - -bool DecodedOperandBea_t::isConstant() const -{ - ARGTYPE *t=static_cast<ARGTYPE*>(arg_data); - assert(t); - return (t->ArgType & CONSTANT_TYPE)!=0; -} - -string DecodedOperandBea_t::getString() const -{ - ARGTYPE *t=static_cast<ARGTYPE*>(arg_data); - assert(t); - return t->ArgMnemonic; -} - -bool DecodedOperandBea_t::isRegister() const -{ - ARGTYPE *t=static_cast<ARGTYPE*>(arg_data); - return (t->ArgType®ISTER_TYPE)==REGISTER_TYPE; -} - -bool DecodedOperandBea_t::isGeneralPurposeRegister() const -{ - ARGTYPE *t=static_cast<ARGTYPE*>(arg_data); - return isRegister() && (t->ArgType&GENERAL_REG)==GENERAL_REG; -} - -bool DecodedOperandBea_t::isMmxRegister() const -{ - ARGTYPE *t=static_cast<ARGTYPE*>(arg_data); - return isRegister() && (t->ArgType&MMX_REG)==MMX_REG; -} - -bool DecodedOperandBea_t::isFpuRegister() const -{ - ARGTYPE *t=static_cast<ARGTYPE*>(arg_data); - return isRegister() && (t->ArgType&FPU_REG)==FPU_REG; -} - -bool DecodedOperandBea_t::isSseRegister() const -{ - ARGTYPE *t=static_cast<ARGTYPE*>(arg_data); - return isRegister() && (t->ArgType&SSE_REG)==SSE_REG; -} - -bool DecodedOperandBea_t::isAvxRegister() const -{ - ARGTYPE *t=static_cast<ARGTYPE*>(arg_data); - return isRegister() && (t->ArgType&AVX_REG)==AVX_REG; -} - -bool DecodedOperandBea_t::isSpecialRegister() const -{ - ARGTYPE *t=static_cast<ARGTYPE*>(arg_data); - return isRegister() && (t->ArgType&SPECIAL_REG)==SPECIAL_REG; -} - -bool DecodedOperandBea_t::isSegmentRegister() const -{ - ARGTYPE *t=static_cast<ARGTYPE*>(arg_data); - return isRegister() && (t->ArgType&SEGMENT_REG)==SEGMENT_REG; -} - -uint32_t DecodedOperandBea_t::getRegNumber() const -{ - ARGTYPE *t=static_cast<ARGTYPE*>(arg_data); - if(!isRegister()) - throw std::logic_error("getRegNumber called on not register"); - const auto regno=(t->ArgType)&0xFFFF; - - return beaRegNoToIRDBRegNo(regno); -} - -bool DecodedOperandBea_t::isMemory() const -{ - ARGTYPE *t=static_cast<ARGTYPE*>(arg_data); - return (t->ArgType&MEMORY_TYPE)==MEMORY_TYPE; -} - -bool DecodedOperandBea_t::hasBaseRegister() const -{ - if(!isMemory()) - throw std::logic_error("hasBaseRegister called on not memory operand"); - - ARGTYPE *t=static_cast<ARGTYPE*>(arg_data); - return t->Memory.BaseRegister!=0; -} - -bool DecodedOperandBea_t::hasIndexRegister() const -{ - if(!isMemory()) - throw std::logic_error("hasIndexRegister called on not memory operand"); - - ARGTYPE *t=static_cast<ARGTYPE*>(arg_data); - return t->Memory.IndexRegister!=0; -} - -uint32_t DecodedOperandBea_t::getBaseRegister() const -{ - if(!isMemory() || !hasBaseRegister()) - throw std::logic_error("getBaseRegister called on not memory operand"); - - ARGTYPE *t=static_cast<ARGTYPE*>(arg_data); - return beaRegNoToIRDBRegNo(t->Memory.BaseRegister); -} - -uint32_t DecodedOperandBea_t::getIndexRegister() const -{ - if(!isMemory() || !hasIndexRegister()) - throw std::logic_error("getIndexRegister called on not memory operand"); - - ARGTYPE *t=static_cast<ARGTYPE*>(arg_data); - return beaRegNoToIRDBRegNo(t->Memory.IndexRegister); -} - -uint32_t DecodedOperandBea_t::getScaleValue() const -{ - if(!isMemory()) - throw std::logic_error("getScaleValue called on not memory operand"); - - ARGTYPE *t=static_cast<ARGTYPE*>(arg_data); - return t->Memory.Scale; /* 0 indicates no scale */ -} - -bool DecodedOperandBea_t::hasMemoryDisplacement() const -{ - if(!isMemory()) - throw std::logic_error("GetBaseRegister called on not memory operand"); - ARGTYPE *t=static_cast<ARGTYPE*>(arg_data); - return t->Memory.DisplacementAddr!=0; -} - -virtual_offset_t DecodedOperandBea_t::getMemoryDisplacement() const -{ - if(!isMemory()) - throw std::logic_error("GetBaseRegister called on not memory operand"); - ARGTYPE *t=static_cast<ARGTYPE*>(arg_data); - return (virtual_offset_t)t->Memory.Displacement; -} - -bool DecodedOperandBea_t::isPcrel() const -{ - ARGTYPE *t=static_cast<ARGTYPE*>(arg_data); - return (t->ArgType&RELATIVE_)==RELATIVE_; -} - -uint32_t DecodedOperandBea_t::getMemoryDisplacementEncodingSize() const -{ - ARGTYPE *t=static_cast<ARGTYPE*>(arg_data); - return t->Memory.DisplacementSize; -} - -uint32_t DecodedOperandBea_t::getArgumentSizeInBytes() const -{ - ARGTYPE *t=static_cast<ARGTYPE*>(arg_data); - return t->ArgSize/8; -} - -uint32_t DecodedOperandBea_t::getArgumentSizeInBits() const -{ - ARGTYPE *t=static_cast<ARGTYPE*>(arg_data); - return t->ArgSize; -} - -bool DecodedOperandBea_t::hasSegmentRegister() const -{ - ARGTYPE *t=static_cast<ARGTYPE*>(arg_data); - return t->SegmentReg!=0; - -} - -uint32_t DecodedOperandBea_t::getSegmentRegister() const -{ - if(!hasSegmentRegister()) - throw std::logic_error("getSegmentRegisterNumber called with no segment register"); - ARGTYPE *t=static_cast<ARGTYPE*>(arg_data); - return t->SegmentReg; -} - -bool DecodedOperandBea_t::isRead() const -{ - ARGTYPE *t=static_cast<ARGTYPE*>(arg_data); - return (t->AccessMode&READ)==READ; -} - -bool DecodedOperandBea_t::isWritten() const -{ - ARGTYPE *t=static_cast<ARGTYPE*>(arg_data); - return (t->AccessMode&WRITE)==WRITE; -} diff --git a/libIRDB/src/syscall/Makefile.in b/libIRDB/src/syscall/Makefile.in deleted file mode 100644 index c66e55627c35576039b5d7b9956115284c5f6bb9..0000000000000000000000000000000000000000 --- a/libIRDB/src/syscall/Makefile.in +++ /dev/null @@ -1,29 +0,0 @@ - -LIB=../../lib/libIRDB-syscall.a - -OBJS=syscall.o - -CXX=@CXX@ -EXTRA_CXXFLAGS=-fPIC -g -c -I. -I../../include -I../../../beaengine/include @EXTRA_CXXFLAGS@ - -all: $(OBJS) - --include $(OBJS:.o=.d) - -clean: - rm -f $(OBJS) *.d - -.cpp.o: - ar rc $(LIB) $@ - -%.o: %.cpp - $(CXX) -c $(EXTRA_CXXFLAGS) $*.cpp - $(AR) -r $(LIB) $*.o - @# - @# build dependencies -- http://scottmcpeak.com/autodepend/autodepend.html - @# - $(CXX) -MM $(EXTRA_CXXFLAGS) $*.cpp > $*.d - @cp -f $*.d $*.d.tmp - @sed -e 's/.*://' -e 's/\\$$//' < $*.d.tmp | fmt -1 | sed -e 's/^ *//' -e 's/$$/:/' >> $*.d - @rm -f $*.d.tmp - diff --git a/libIRDB/src/util/insn_preds.cpp b/libIRDB/src/util/insn_preds.cpp deleted file mode 100644 index d50a923a476926054dc07fe2697414d02bda9d7a..0000000000000000000000000000000000000000 --- a/libIRDB/src/util/insn_preds.cpp +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright (c) 2014-2015 - Zephyr Software LLC - * - * This file may be used and modified for non-commercial purposes as long as - * all copyright, permission, and nonwarranty notices are preserved. - * Redistribution is prohibited without prior written consent from Zephyr - * Software. - * - * Please contact the authors for restrictions applying to commercial use. - * - * THIS SOURCE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF - * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. - * - * Author: Zephyr Software - * e-mail: jwd@zephyr-software.com - * URL : http://www.zephyr-software.com/ - * - */ - - -#include <map> -#include <libIRDB-core.hpp> -#include <libIRDB-util.hpp> -#include <utils.hpp> - -using namespace libIRDB; -using namespace std; - - - -void InstructionPredecessors_t::AddPreds(const Instruction_t* before, const InstructionSet_t& afterset) -{ - for(InstructionSet_t::const_iterator it=afterset.begin(); it!=afterset.end(); ++it) - { - pred_map[*it].insert((libIRDB::Instruction_t*)before); - } -} - -void InstructionPredecessors_t::AddPred(const Instruction_t* before, const Instruction_t* after) -{ - assert(before); - if(!after) return; - - if(getenv("DUMP_PRED_CREATE")) - cout<<"Found "<<after->GetBaseID()<<":"<<after->getDisassembly() << " follows "<< before->GetBaseID()<<":"<<before->getDisassembly()<<endl; - pred_map[after].insert((Instruction_t*)before); - -} - -void InstructionPredecessors_t::AddFile(const FileIR_t* firp2) -{ - FileIR_t* firp=(FileIR_t*)firp2; // discarding const qualifier because we know we won't change the set - for(InstructionSet_t::const_iterator it=firp->GetInstructions().begin(); - it!=firp->GetInstructions().end(); - ++it) - { - Instruction_t* insn=*it; - AddPred(insn, insn->GetTarget()); - AddPred(insn, insn->GetFallthrough()); - - // if we have a complete list, then explicitly add them. - if(insn->GetIBTargets() && insn->GetIBTargets()->IsComplete()) - AddPreds(insn, *insn->GetIBTargets()); - - } -} diff --git a/libIRDB/test/SConstruct b/libIRDB/test/SConstruct deleted file mode 100644 index b5b7b78c5f88640c7e8877a9df76dc9191af7498..0000000000000000000000000000000000000000 --- a/libIRDB/test/SConstruct +++ /dev/null @@ -1,8 +0,0 @@ - - - -env=Environment() -Export('env') -lib=SConscript("SConscript") - -Return('lib') diff --git a/libMEDSannotation/include/MEDS_MemoryRangeAnnotation.hpp b/libMEDSannotation/include/MEDS_MemoryRangeAnnotation.hpp index e53c6115ac75bd8d53bb205d670f65f0f89501a7..3dd234fe9e6f4ebb55d6369730b08abea05d475c 100644 --- a/libMEDSannotation/include/MEDS_MemoryRangeAnnotation.hpp +++ b/libMEDSannotation/include/MEDS_MemoryRangeAnnotation.hpp @@ -35,6 +35,7 @@ using namespace MEDS_Annotation; #define MEDS_ANNOT_STATICMEMWRITE "STATICMEMWRITE" #define MEDS_ANNOT_STACKMEMRANGE "STACKMEMRANGE" +#define MEDS_ANNOT_SENTINEL "SENTINEL" // // Class to handle one MEDS memory range annotation @@ -71,6 +72,14 @@ using namespace MEDS_Annotation; // but STARS loop analysis and symbolic analysis have determined that the memory // write is to the range [MIN..LIMIT-1] as seen in the annotation. // +// 4992ea 4 INSTR SENTINEL BASE 43d920 OFFSET -8 ZZ +// Meaning: Address (BASE + OFFSET) is used as a loop sentinel in instruction at 0x4992ea. +// The loop only accesses memory at BASE, so the address of BASE should be used +// as the data scoop referred to by this instruction, e.g. cmp rax,0x43d918 could be +// the instruction, followed by jg top_of_loop. When RAX reaches value 0x43d918, the loop +// exits without using that value except as a sentinel to terminate the loop. 0x43d918 is +// in a different data scoop than 0x43d920, and 0x43d920 is the relevant scoop for the loop. +// class MEDS_MemoryRangeAnnotation : public MEDS_AnnotationBase { @@ -82,23 +91,29 @@ class MEDS_MemoryRangeAnnotation : public MEDS_AnnotationBase uint64_t getRangeMin() const { return m_rangeMin; }; uint64_t getRangeLimit() const { return m_rangeLimit; }; + int64_t getSentinelOffset() const { return m_sentinelOffset; }; const bool isStackRange() const { return m_stackRange; }; const bool isStaticGlobalRange() const { return m_staticGlobalRange; }; + const bool isSentinel() const { return m_sentinel; }; private: // methods void parse(); void setStackRange(const bool p_val) { m_stackRange = p_val; }; void setStaticGlobalRange(const bool p_val) { m_staticGlobalRange = p_val; }; + void setSentinel(const bool p_val) { m_sentinel = p_val; }; void setRangeMin(const uint64_t p_val) { m_rangeMin = p_val; }; void setRangeLimit(const uint64_t p_val) { m_rangeLimit = p_val; }; + void setSentinelOffset(const int64_t p_val) { m_sentinelOffset = p_val; }; private: // data string m_rawInputLine; bool m_stackRange; bool m_staticGlobalRange; + bool m_sentinel; uint64_t m_rangeMin; uint64_t m_rangeLimit; + int64_t m_sentinelOffset; }; } diff --git a/libMEDSannotation/include/MEDS_TakesAddressAnnotation.hpp b/libMEDSannotation/include/MEDS_TakesAddressAnnotation.hpp new file mode 100644 index 0000000000000000000000000000000000000000..524b100ac030bfbba02a15512540e9912d792029 --- /dev/null +++ b/libMEDSannotation/include/MEDS_TakesAddressAnnotation.hpp @@ -0,0 +1,99 @@ +/* + * Copyright (c) 2014 - Zephyr Software LLC + * + * This file may be used and modified for non-commercial purposes as long as + * all copyright, permission, and nonwarranty notices are preserved. + * Redistribution is prohibited without prior written consent from Zephyr + * Software. + * + * Please contact the authors for restrictions applying to commercial use. + * + * THIS SOURCE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * Author: Zephyr Software + * e-mail: jwd@zephyr-software.com + * URL : http://www.zephyr-software.com/ + * + */ + +#ifndef _MEDS_TAKENADDRESSANNOTATION_H_ +#define _MEDS_TAKENADDRESSANNOTATION_H_ + +#include <string> +#include "VirtualOffset.hpp" +#include "MEDS_AnnotationBase.hpp" +#include <iostream> + +namespace MEDS_Annotation +{ + +using namespace std; +using namespace MEDS_Annotation; + +// +// Class to handle one MEDS shadow annotation +// +class MEDS_TakesAddressAnnotation : public MEDS_AnnotationBase +{ + public: + typedef enum { SWITCH, RET, UNKNOWN } ib_type_t; + + MEDS_TakesAddressAnnotation( const string& p_rawLine) : + referenced_address(0), + m_isCode(false) + { + setInvalid(); + parse(p_rawLine); + + }; + + + virtual const std::string toString() const + { + std::string ret="TakesAddress="+to_string(referenced_address); + return ret; + } + + ApplicationAddress GetReferencedAddress() const { return referenced_address; } + bool isCode() const { return m_isCode; } + bool isData() const { return !m_isCode; } + + protected: + + void parse(const string& p_rawLine) + { + const auto tofind=string("INSTR XREF TAKES_ADDRESS_OF "); + const auto codestring=string("CODE"); + const auto pos=p_rawLine.find(tofind); + if(pos==string::npos) + return; + + // she be valid + setValid(); + + m_isCode=(p_rawLine.find(codestring)!=string::npos); + m_virtualOffset = VirtualOffset(p_rawLine); + + // skips over INSTR*{code|data} + const auto rest=p_rawLine.substr(pos+tofind.length()+codestring.length()); + istringstream is(rest); + is >> hex >>referenced_address; /* get the address */ + + // cout<<"Found takes_address of "<<m_virtualOffset.to_string() << " to " + // << hex << referenced_address<< " from '" << rest << "'"<<endl; + + + } + + + private: + + ApplicationAddress referenced_address; + bool m_isCode; +}; + +} + +#endif diff --git a/libMEDSannotation/include/libMEDSAnnotation.h b/libMEDSannotation/include/libMEDSAnnotation.h index a4bb39f5d2ed179b79fb0d0d83d8dc444d899d03..a4f17f37c494c7f2e0d8b5279b617ecc553999e0 100644 --- a/libMEDSannotation/include/libMEDSAnnotation.h +++ b/libMEDSannotation/include/libMEDSAnnotation.h @@ -10,6 +10,8 @@ #include "MEDS_FuncAnnotation.hpp" #include "MEDS_FuncPrototypeAnnotation.hpp" #include "MEDS.hpp" +#include "MEDS_TakesAddressAnnotation.hpp" +#include "MEDS_IBAnnotation.hpp" #include "MEDS_IBAnnotation.hpp" #include "MEDS_IBTAnnotation.hpp" #include "MEDS_InstructionCheckAnnotation.hpp" diff --git a/libMEDSannotation/src/MEDS_AnnotationParser.cpp b/libMEDSannotation/src/MEDS_AnnotationParser.cpp index de2b10055a40425ad299441e89b7f1b3ad249a6a..85e85a2e4cba5465bf6f576786d1e5c518754329 100644 --- a/libMEDSannotation/src/MEDS_AnnotationParser.cpp +++ b/libMEDSannotation/src/MEDS_AnnotationParser.cpp @@ -30,6 +30,7 @@ #include "MEDS_FRSafeAnnotation.hpp" #include "MEDS_FPTRShadowAnnotation.hpp" #include "MEDS_DeadRegAnnotation.hpp" +#include "MEDS_TakesAddressAnnotation.hpp" #include "MEDS_IBAnnotation.hpp" #include "MEDS_IBTAnnotation.hpp" #include "MEDS_MemoryRangeAnnotation.hpp" @@ -87,26 +88,24 @@ template <class type> bool MEDS_AnnotationParser::add_if_valid(string line) void MEDS_AnnotationParser::parseFile(istream &p_inputStream) { - string line; - while (!p_inputStream.eof()) { + auto line=string(); getline(p_inputStream, line); if (line.empty()) continue; - - if(add_if_valid<MEDS_DeadRegAnnotation>(line)) continue; - if(add_if_valid<MEDS_FPTRShadowAnnotation>(line)) continue; - if(add_if_valid<MEDS_InstructionCheckAnnotation>(line)) continue; - if(add_if_valid<MEDS_FuncPrototypeAnnotation>(line)) continue; - if(add_if_valid<MEDS_SafeFuncAnnotation>(line)) continue; - if(add_if_valid<MEDS_ProblemFuncAnnotation>(line)) continue; - if(add_if_valid<MEDS_FRSafeAnnotation>(line)) continue; - if(add_if_valid<MEDS_FuncExitAnnotation>(line)) continue; - if(add_if_valid<MEDS_IBAnnotation>(line)) continue; - if(add_if_valid<MEDS_IBTAnnotation>(line)) continue; - if (add_if_valid<MEDS_MemoryRangeAnnotation>(line)) continue; - + if(add_if_valid<MEDS_DeadRegAnnotation> (line)) continue; + if(add_if_valid<MEDS_FPTRShadowAnnotation> (line)) continue; + if(add_if_valid<MEDS_InstructionCheckAnnotation> (line)) continue; + if(add_if_valid<MEDS_FuncPrototypeAnnotation> (line)) continue; + if(add_if_valid<MEDS_SafeFuncAnnotation> (line)) continue; + if(add_if_valid<MEDS_ProblemFuncAnnotation> (line)) continue; + if(add_if_valid<MEDS_FRSafeAnnotation> (line)) continue; + if(add_if_valid<MEDS_FuncExitAnnotation> (line)) continue; + if(add_if_valid<MEDS_TakesAddressAnnotation> (line)) continue; + if(add_if_valid<MEDS_IBAnnotation> (line)) continue; + if(add_if_valid<MEDS_IBTAnnotation> (line)) continue; + if(add_if_valid<MEDS_MemoryRangeAnnotation> (line)) continue; } } diff --git a/libMEDSannotation/src/MEDS_MemoryRangeAnnotation.cpp b/libMEDSannotation/src/MEDS_MemoryRangeAnnotation.cpp index 8548def683e60c60527ae534779057222ba513f2..d3475148d00396c1de0ed0da0f9512464cb95e7e 100644 --- a/libMEDSannotation/src/MEDS_MemoryRangeAnnotation.cpp +++ b/libMEDSannotation/src/MEDS_MemoryRangeAnnotation.cpp @@ -35,6 +35,7 @@ using namespace MEDS_Annotation; 417748 12 INSTR STATICMEMWRITE MIN 3c60320 LIMIT 4e53730 ZZ 4992ea 4 INSTR STACKMEMRANGE MIN RSP-568 LIMIT RSP-48 INSTRSPDELTA -592 ZZ + 4992ea 4 INSTR SENTINEL BASE 43d920 OFFSET -8 ZZ See explanations in the header file MEDS_MemoryRangeAnnotation.hpp. @@ -45,6 +46,7 @@ MEDS_MemoryRangeAnnotation::MEDS_MemoryRangeAnnotation() : MEDS_AnnotationBase() this->setInvalid(); this->setStackRange(false); this->setStaticGlobalRange(false); + this->setSentinel(false); } MEDS_MemoryRangeAnnotation::MEDS_MemoryRangeAnnotation(const string &p_rawLine) : MEDS_AnnotationBase() @@ -52,6 +54,7 @@ MEDS_MemoryRangeAnnotation::MEDS_MemoryRangeAnnotation(const string &p_rawLine) this->setInvalid(); this->setStackRange(false); this->setStaticGlobalRange(false); + this->setSentinel(false); this->m_rawInputLine = p_rawLine; this->parse(); } @@ -71,7 +74,12 @@ void MEDS_MemoryRangeAnnotation::parse() this->setStackRange(true); } - if (!this->isStackRange() && !this->isStaticGlobalRange()) + if (this->m_rawInputLine.find(MEDS_ANNOT_SENTINEL) != string::npos) + { + this->setSentinel(true); + } + + if (!this->isStackRange() && !this->isStaticGlobalRange() && !this->isSentinel()) { /* invalid annotation */ this->setInvalid(); @@ -83,6 +91,7 @@ void MEDS_MemoryRangeAnnotation::parse() this->setVirtualOffset(vo); // in base class uint64_t MinVal, LimitVal; + int64_t OffsetVal; int instrSize; // 417748 12 INSTR STATICMEMWRITE MIN 3c60320 LIMIT 4e53730 ZZ @@ -98,7 +107,7 @@ void MEDS_MemoryRangeAnnotation::parse() cerr << "Parsed STATICMEMWRITE annotation: MIN = " << hex << MinVal << " LIMIT = " << LimitVal << endl; } } - else { + else if (this->isStackRange()) { #if 0 int ItemsFilled = sscanf(m_rawInputLine.c_str(), "%*x %d %*s %*s MIN %" SCNx64 " LIMIT %" SCNx64, &instrSize, &MinVal, &LimitVal); if (3 != ItemsFilled) { @@ -112,21 +121,39 @@ void MEDS_MemoryRangeAnnotation::parse() return; #endif } + else { // SENTINEL + int ItemsFilled = sscanf(m_rawInputLine.c_str(), "%*x %d %*s %*s BASE %" SCNx64 " OFFSET %" SCNd64, &instrSize, &MinVal, &OffsetVal); + if (3 != ItemsFilled) { + this->setInvalid(); + cerr << "Error on sscanf of annotation: ItemsFilled = " << ItemsFilled << " line: " << m_rawInputLine << endl; + return; + } + } this->setInstructionSize(instrSize); // in base class this->setRangeMin(MinVal); - this->setRangeLimit(LimitVal); + if (this->isSentinel()) { + this->setSentinelOffset(OffsetVal); + } + else { + this->setRangeLimit(LimitVal); + } cout << "virtual offset: " << hex << this->getVirtualOffset().getOffset() << dec << endl; cout << "size: " << this->getInstructionSize() << endl; cout << "min: " << this->getRangeMin() << endl; - cout << "limit: " << this->getRangeLimit() << endl; + if (this->isSentinel()) { + cout << "offset: " << this->getSentinelOffset() << endl; + } + else { + cout << "limit: " << this->getRangeLimit() << endl; - if (LimitVal <= MinVal) - { - setInvalid(); - cerr << "invalid range limit" << endl; - return; + if (LimitVal <= MinVal) + { + setInvalid(); + cerr << "invalid range limit" << endl; + return; + } } cout << "valid annotation" << endl; diff --git a/libehp b/libehp index 844394fefeb8197007510824e71c905dafb0e5d9..87294a3b4c9f07be3a0bedbed90f89744e728376 160000 --- a/libehp +++ b/libehp @@ -1 +1 @@ -Subproject commit 844394fefeb8197007510824e71c905dafb0e5d9 +Subproject commit 87294a3b4c9f07be3a0bedbed90f89744e728376 diff --git a/libtransform/src/Rewrite_Utility.cpp b/libtransform/src/Rewrite_Utility.cpp deleted file mode 100644 index 6df1334214ea74d19a915aaf4a0ab2af7401f8ea..0000000000000000000000000000000000000000 --- a/libtransform/src/Rewrite_Utility.cpp +++ /dev/null @@ -1,264 +0,0 @@ -/* - * Copyright (c) 2013, 2014 - University of Virginia - * - * This file may be used and modified for non-commercial purposes as long as - * all copyright, permission, and nonwarranty notices are preserved. - * Redistribution is prohibited without prior written consent from the University - * of Virginia. - * - * Please contact the authors for restrictions applying to commercial use. - * - * THIS SOURCE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF - * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. - * - * Author: University of Virginia - * e-mail: jwd@virginia.com - * URL : http://www.cs.virginia.edu/ - * - */ - -#include "Rewrite_Utility.hpp" - -// Copied from PnTransform -// @todo: create a utility library with the one interface - -using namespace std; -using namespace libIRDB; - -using namespace IRDBUtility; - -namespace IRDBUtility { -map<Function_t*, set<Instruction_t*> > inserted_instr; //used to undo inserted instructions -map<Function_t*, set<AddressID_t*> > inserted_addr; //used to undo inserted addresses - - -void setExitCode(FileIR_t* virp, Instruction_t* exit_code); - - - -void setInstructionDataBits(FileIR_t* virp, Instruction_t *p_instr, string p_dataBits, Instruction_t *p_fallThrough, Instruction_t *p_target) -{ - if (p_instr == NULL) return; - - p_instr->SetDataBits(p_dataBits); - p_instr->SetComment(p_instr->getDisassembly()); - p_instr->SetFallthrough(p_fallThrough); - p_instr->SetTarget(p_target); - - virp->GetAddresses().insert(p_instr->GetAddress()); - virp->GetInstructions().insert(p_instr); -} - - -//For all insertBefore functions: -//The "first" instruction will have its contents replaced and a duplicate of "first" will be in the follow of first. -//This duplicate is returned since the user already has a pointer to first. -//To insert before an instruction is the same as modifying the original instruction, and inserting after it -//a copy of the original instruction -Instruction_t* insertAssemblyBefore(FileIR_t* virp, Instruction_t* first, string assembly, Instruction_t *target) -{ - Instruction_t* next = copyInstruction(virp,first); - - //In case the fallthrough is null, generate spri has to have a - //place to jump, which is determined by the original address. - //This code is not placed in copyInstruction since this is only needed - //when inserting before - next->SetOriginalAddressID(first->GetOriginalAddressID()); - //"Null" out the original address (it should be as if the instruction was not in the database). - first->SetOriginalAddressID(BaseObj_t::NOT_IN_DATABASE); - first->GetRelocations().clear(); - first->SetIBTargets(NULL); - //Note that the instruction just inserted should have the same exception handling - //info as the instructions immediately around it. - //Thus the exception handling information (EhCallSite and EhProgram) are kept the - //same from the copy of first (unlike with relocations and IBT's). - - virp->ChangeRegistryKey(first,next); - setInstructionAssembly(virp,first,assembly,next,target); - - return next; -} - -Instruction_t* insertAssemblyBefore(FileIR_t* virp, Instruction_t* first, string assembly) -{ - return insertAssemblyBefore(virp,first,assembly,NULL); -} - - -Instruction_t* insertDataBitsBefore(FileIR_t* virp, Instruction_t* first, string dataBits) -{ - return insertDataBitsBefore(virp,first,dataBits,NULL); -} - -Instruction_t* insertDataBitsBefore(FileIR_t* virp, Instruction_t* first, string dataBits, Instruction_t *target) -{ - Instruction_t* next = copyInstruction(virp,first); - - //In case the fallthrough is null, generate spri has to have a - //place to jump, which is determined by the original address. - //This code is not placed in copyInstruction since this is only needed - //when inserting before - next->SetOriginalAddressID(first->GetOriginalAddressID()); - //"Null" out the original address (it should be as if the instruction was not in the database). - first->SetOriginalAddressID(BaseObj_t::NOT_IN_DATABASE); - first->GetRelocations().clear(); - first->SetIBTargets(NULL); - //Note that the instruction just inserted should have the same exception handling - //info as the instructions immediately around it. - //Thus the exception handling information (EhCallSite and EhProgram) are kept the - //same from the copy of first (unlike with relocations and IBT's). - - virp->ChangeRegistryKey(first,next); - setInstructionDataBits(virp,first,dataBits,next,target); - - return next; -} - -Instruction_t* insertAssemblyAfter(FileIR_t* virp, Instruction_t* first, string assembly, Instruction_t *target) -{ - Instruction_t *new_instr = allocateNewInstruction(virp,first); - setInstructionAssembly(virp,new_instr,assembly,first->GetFallthrough(), target); - first->SetFallthrough(new_instr); - return new_instr; -} - -Instruction_t* insertAssemblyAfter(FileIR_t* virp, Instruction_t* first, string assembly) -{ - return insertAssemblyAfter(virp,first,assembly,NULL); - -} - -Instruction_t* insertDataBitsAfter(FileIR_t* virp, Instruction_t* first, string dataBits, Instruction_t *target) -{ - Instruction_t *new_instr = allocateNewInstruction(virp,first); - setInstructionDataBits(virp,new_instr,dataBits,first->GetFallthrough(), target); - first->SetFallthrough(new_instr); - - return new_instr; -} - -Instruction_t* insertDataBitsAfter(FileIR_t* virp, Instruction_t* first, string dataBits) -{ - return insertDataBitsAfter(virp,first,dataBits,NULL); -} - -Instruction_t* addNewDatabits(FileIR_t* firp, Instruction_t *p_instr, string p_bits) -{ - Instruction_t* newinstr; - if (p_instr) - newinstr = allocateNewInstruction(firp,p_instr->GetAddress()->GetFileID(), p_instr->GetFunction()); - else - newinstr = allocateNewInstruction(firp,firp->GetFile()->GetFileID(), NULL); - - newinstr->SetDataBits(p_bits); - - if (p_instr) - { - newinstr->SetFallthrough(p_instr->GetFallthrough()); - p_instr->SetFallthrough(newinstr); - } - - return newinstr; -} - -Instruction_t* addNewAssembly(FileIR_t* firp, Instruction_t *p_instr, string p_asm) -{ - Instruction_t* newinstr; - if (p_instr) - newinstr = allocateNewInstruction(firp,p_instr->GetAddress()->GetFileID(), p_instr->GetFunction()); - else - newinstr = allocateNewInstruction(firp,firp->GetFile()->GetFileID(), NULL); - - firp->RegisterAssembly(newinstr, p_asm); - - if (p_instr) - { - newinstr->SetFallthrough(p_instr->GetFallthrough()); - p_instr->SetFallthrough(newinstr); - } - - return newinstr; -} - - - - - - -//Does not insert into any variant -Instruction_t* copyInstruction(Instruction_t* instr) -{ - Instruction_t* cpy = new Instruction_t(); - - copyInstruction(instr,cpy); - - return cpy; -} - -Instruction_t* copyInstruction(FileIR_t* virp, Instruction_t* instr) -{ - Instruction_t* cpy = allocateNewInstruction(virp,instr); - - copyInstruction(instr,cpy); - - return cpy; -} - -void copyInstruction(Instruction_t* src, Instruction_t* dest) -{ - dest->SetDataBits(src->GetDataBits()); - dest->SetComment(src->GetComment()); - dest->SetCallback(src->GetCallback()); - dest->SetFallthrough(src->GetFallthrough()); - dest->SetTarget(src->GetTarget()); - dest->SetIBTargets(src->GetIBTargets()); - dest->GetRelocations()=src->GetRelocations(); - dest->SetEhProgram(src->GetEhProgram()); - dest->SetEhCallSite(src->GetEhCallSite()); -} - -Instruction_t* allocateNewInstruction(FileIR_t* virp, db_id_t p_fileID,Function_t* func) -{ - Instruction_t *instr = new Instruction_t(); - AddressID_t *a =new AddressID_t(); - - a->SetFileID(p_fileID); - - instr->SetFunction(func); - instr->SetAddress(a); - if(func) - func->GetInstructions().insert(instr); - - virp->GetInstructions().insert(instr); - virp->GetAddresses().insert(a); - - inserted_instr[func].insert(instr); - inserted_addr[func].insert(a); - - return instr; -} - -Instruction_t* allocateNewInstruction(FileIR_t* virp, Instruction_t *template_instr) -{ - Function_t *func = template_instr->GetFunction(); - db_id_t fileID = template_instr->GetAddress()->GetFileID(); - return allocateNewInstruction(virp, fileID, func); -} - -void setInstructionAssembly(FileIR_t* virp,Instruction_t *p_instr, string p_assembly, Instruction_t *p_fallThrough, Instruction_t *p_target) -{ - if (p_instr == NULL) return; - - ///TODO: what if bad assembly? - virp->RegisterAssembly(p_instr,p_assembly); - p_instr->SetComment(p_assembly); - p_instr->SetFallthrough(p_fallThrough); - p_instr->SetTarget(p_target); - - virp->GetAddresses().insert(p_instr->GetAddress()); - virp->GetInstructions().insert(p_instr); -} - - -} diff --git a/libtransform/tests/bin/ls_O3.exe b/libtransform/tests/bin/ls_O3.exe deleted file mode 100755 index cdbe0931c2b49ff1bcab208272a0508748ecfb2a..0000000000000000000000000000000000000000 Binary files a/libtransform/tests/bin/ls_O3.exe and /dev/null differ diff --git a/tools/meds2pdb/SConscript b/meds2pdb/SConscript similarity index 72% rename from tools/meds2pdb/SConscript rename to meds2pdb/SConscript index 5869a82157de1c8d0bef4bd845b3a28c4aa2c68c..ca7f560339534ff8749ed39cf64c61fe4aa62cff 100644 --- a/tools/meds2pdb/SConscript +++ b/meds2pdb/SConscript @@ -7,22 +7,21 @@ myenv=env.Clone() myenv.Replace(SECURITY_TRANSFORMS_HOME=os.environ['SECURITY_TRANSFORMS_HOME']) cpppath=''' + $IRDB_SDK/include $SECURITY_TRANSFORMS_HOME/include - $SECURITY_TRANSFORMS_HOME/xform + $SECURITY_TRANSFORMS_HOME/libIRDB-core/include $SECURITY_TRANSFORMS_HOME/libEXEIO/include - $SECURITY_TRANSFORMS_HOME/libIRDB/include $SECURITY_TRANSFORMS_HOME/libMEDSannotation/include - $SECURITY_TRANSFORMS_HOME/libtransform/include ''' -files=Glob( Dir('.').srcnode().abspath+"/*.cpp") +files=Glob( Dir('.').srcnode().abspath+"/*.cpp") + Glob(Dir('.').srcnode().abspath+"/*.c") pgm="meds2pdb" myenv.Append(CXXFLAGS = " -std=c++11 ") LIBPATH="$SECURITY_TRANSFORMS_HOME/lib" -LIBS=Split(" IRDB-cfg IRDB-util xform transform MEDSannotation "+env.subst('$BASE_IRDB_LIBS')) +LIBS=Split(" irdb-cfg irdb-util irdb-transform EXEIO MEDSannotation "+env.subst('$BASE_IRDB_LIBS')) myenv=myenv.Clone(CPPPATH=Split(cpppath)) pgm=myenv.Program(pgm, files, LIBPATH=LIBPATH, LIBS=LIBS) install1=myenv.Install("$SECURITY_TRANSFORMS_HOME/bin/", pgm) diff --git a/tools/meds2pdb/SConstruct b/meds2pdb/SConstruct similarity index 100% rename from tools/meds2pdb/SConstruct rename to meds2pdb/SConstruct diff --git a/xform/aspri.h b/meds2pdb/aspri.h similarity index 97% rename from xform/aspri.h rename to meds2pdb/aspri.h index 70cc78ce27d4923d4d95c26b09b7001c43e7321e..0da73ac38278996f05b96385b1601619145e8327 100644 --- a/xform/aspri.h +++ b/meds2pdb/aspri.h @@ -34,7 +34,7 @@ typedef struct aspri_address aspri_address_t; struct aspri_address { char *library_name; - app_iaddr_t offset; + VirtualOffset_t offset; bool isCurrentPC; }; diff --git a/xform/bitvector.c b/meds2pdb/bitvector.cpp similarity index 92% rename from xform/bitvector.c rename to meds2pdb/bitvector.cpp index 9660878fbf8104821f0f5c50028569254284021a..e3c627724516c9570e1b49a364595222cbac4fe8 100644 --- a/xform/bitvector.c +++ b/meds2pdb/bitvector.cpp @@ -28,7 +28,7 @@ */ -#include "all.h" +#include "meds_all.h" /* @@ -40,13 +40,13 @@ bitvector_t * allocate_bitvector(int num_fields, int num_data_chunks) /* round number of bits up to 8 then convert to bytes */ int num_bytes_to_allocate=(((num_fields*num_data_chunks) + 7) &~7)/8; - bitvector_t * the_bitvector = spri_allocate_type(sizeof(bitvector_t)); + bitvector_t * the_bitvector = (bitvector_t*)spri_allocate_type(sizeof(bitvector_t)); /* allocate the_bits * the number of bits needed is num_fields * num_data_chunks * rounded to nearest 8 (num bits in a char) * to get bytes, need to divide by 8 bits */ - the_bitvector->the_bits = spri_allocate_type(num_bytes_to_allocate*sizeof(char)); + the_bitvector->the_bits = (char*)spri_allocate_type(num_bytes_to_allocate*sizeof(char)); the_bitvector->size = num_fields*num_data_chunks; the_bitvector->num_bytes = num_bytes_to_allocate; @@ -57,7 +57,7 @@ bitvector_t * allocate_bitvector(int num_fields, int num_data_chunks) void free_bitvector(bitvector_t *the_bitvector_to_be_freed) { #ifndef NDEBUG - STRATA_LOG("profile_fields_allocate","bitvector address: 0x%x size: %d\n", the_bitvector_to_be_freed, the_bitvector_to_be_freed->size); +// STRATA_LOG("profile_fields_allocate","bitvector address: 0x%x size: %d\n", the_bitvector_to_be_freed, the_bitvector_to_be_freed->size); #endif /* first free the_bits vector */ spri_deallocate_type((void *)the_bitvector_to_be_freed->the_bits, ((the_bitvector_to_be_freed->size+7)&~7)/8); diff --git a/xform/bitvector.h b/meds2pdb/bitvector.h similarity index 100% rename from xform/bitvector.h rename to meds2pdb/bitvector.h diff --git a/xform/constant_hash.c b/meds2pdb/constant_hash.cpp similarity index 89% rename from xform/constant_hash.c rename to meds2pdb/constant_hash.cpp index 9b4b210cfa78f08089a5e11e07c065b202845b2d..368ccbeb3da3e624c8d42b24081d6c17f2f2f5b6 100644 --- a/xform/constant_hash.c +++ b/meds2pdb/constant_hash.cpp @@ -21,7 +21,7 @@ * */ -#include "all.h" +#include "meds_all.h" Hashtable *constants_hash=NULL; @@ -48,7 +48,7 @@ long constants_key_compare(void* key1, void* key2) } -constant_hash_value_t * add_constant_ref(app_iaddr_t pc,int the_const, constant_hash_field_t the_field, constant_hash_type_t the_type) +constant_hash_value_t * add_constant_ref(VirtualOffset_t pc,int the_const, constant_hash_field_t the_field, constant_hash_type_t the_type) { constant_hash_key_t *chk=(constant_hash_key_t*)spri_allocate_type(sizeof(constant_hash_key_t )); constant_hash_value_t *chv=(constant_hash_value_t*)spri_allocate_type(sizeof(constant_hash_value_t )); @@ -60,10 +60,11 @@ constant_hash_value_t * add_constant_ref(app_iaddr_t pc,int the_const, constant_ chv->type=the_type; Hashtable_put(constants_hash, chk, chv); + return chv; } -constant_hash_value_t * get_constant_ref(app_iaddr_t pc, int the_const, constant_hash_field_t the_field) +constant_hash_value_t * get_constant_ref(VirtualOffset_t pc, int the_const, constant_hash_field_t the_field) { constant_hash_key_t chk={pc, the_const, the_field}; constant_hash_value_t *chv=(constant_hash_value_t*)Hashtable_get(constants_hash, &chk); diff --git a/xform/constant_hash.h b/meds2pdb/constant_hash.h similarity index 85% rename from xform/constant_hash.h rename to meds2pdb/constant_hash.h index b439b9f860f3ff24950059dc53b15ff1e51c1729..2159265286a583ab50e80984b3d908189489bb3a 100644 --- a/xform/constant_hash.h +++ b/meds2pdb/constant_hash.h @@ -33,7 +33,7 @@ typedef enum constant_hash_field constant_hash_field_t; extern Hashtable *constants_hash; struct constant_hash_key { - app_iaddr_t pc; + VirtualOffset_t pc; int the_const; constant_hash_field_t field; }; @@ -49,9 +49,9 @@ long constants_compute_hash(void* key1); long constants_key_compare(void* key1, void* key2); -constant_hash_value_t * add_constant_ref(app_iaddr_t pc,int the_const, constant_hash_field_t the_field, constant_hash_type_t the_type); +constant_hash_value_t * add_constant_ref(VirtualOffset_t pc,int the_const, constant_hash_field_t the_field, constant_hash_type_t the_type); -constant_hash_value_t * get_constant_ref(app_iaddr_t pc, int the_const, constant_hash_field_t the_field); +constant_hash_value_t * get_constant_ref(VirtualOffset_t pc, int the_const, constant_hash_field_t the_field); const char* constant_hash_type_to_string(constant_hash_type_t type); diff --git a/xform/elfreader.cpp b/meds2pdb/elfreader.cpp similarity index 81% rename from xform/elfreader.cpp rename to meds2pdb/elfreader.cpp index 799533edb7c353485bacfbb33518a31bcbdee2a6..51f10cecea32d236fba283975abc44cf1b47f029 100644 --- a/xform/elfreader.cpp +++ b/meds2pdb/elfreader.cpp @@ -20,19 +20,13 @@ #include <iostream> #include <string.h> -#include "targ-config.h" - #include <stdio.h> - -/* -#include "elfio/elfio.hpp" -#include "elfio/elfio_dump.hpp" - -*/ +#include <irdb-core> +#include <libIRDB-core.hpp> #include "elfreader.h" using namespace std; -//using namespace ELFIO; +using namespace IRDB_SDK; using namespace EXEIO; ElfReader::ElfReader(char *p_elfFile) @@ -86,7 +80,7 @@ ElfReader::~ElfReader() /* * Read <p_numBytes> from ELF file for location <p_pc> */ -string ElfReader::read(app_iaddr_t p_pc, unsigned p_numBytes) +string ElfReader::read(VirtualOffset_t p_pc, unsigned p_numBytes) const { for ( int i = 0; i < m_reader->sections.size(); ++i ) { @@ -109,7 +103,7 @@ string ElfReader::read(app_iaddr_t p_pc, unsigned p_numBytes) * No bounds checking is done on <p_buf> * Return false if address not in valid sections */ -bool ElfReader::read(app_iaddr_t p_pc, unsigned p_numBytes, char* p_buf) +bool ElfReader::read(VirtualOffset_t p_pc, unsigned p_numBytes, char* p_buf) const { for ( int i = 0; i < m_reader->sections.size(); ++i ) { @@ -130,7 +124,7 @@ bool ElfReader::read(app_iaddr_t p_pc, unsigned p_numBytes, char* p_buf) /* * Return buffer for instruction off the ELF file */ -char* ElfReader::getInstructionBuffer(app_iaddr_t p_pc) +const char* ElfReader::getInstructionBuffer(VirtualOffset_t p_pc) const { for ( int i = 0; i < m_reader->sections.size(); ++i ) { @@ -147,3 +141,17 @@ char* ElfReader::getInstructionBuffer(app_iaddr_t p_pc) return NULL; } +void ElfReader::SetArchitecture() +{ + const auto width = + (isElf32() || isPe32()) ? 32 : + (isElf64() || isPe64()) ? 64 : + throw std::invalid_argument("Unknown architecture."); + const auto mt = m_reader->getMachineType() == EXEIO::mtI386 ? IRDB_SDK::admtI386 : + m_reader->getMachineType() == EXEIO::mtX86_64 ? IRDB_SDK::admtX86_64 : + m_reader->getMachineType() == EXEIO::mtAarch64 ? IRDB_SDK::admtAarch64 : + throw std::invalid_argument("Unknown architecture."); + + libIRDB::FileIR_t::setArchitecture(width,mt); +} + diff --git a/meds2pdb/elfreader.h b/meds2pdb/elfreader.h new file mode 100644 index 0000000000000000000000000000000000000000..87b4ac4a71b303008e96b265d1885f5828c49804 --- /dev/null +++ b/meds2pdb/elfreader.h @@ -0,0 +1,38 @@ +#ifndef _elfreader_H_ +#define _elfreader_H_ + +#include <vector> +#include "exeio.h" +#include <irdb-core> +#include <assert.h> +#include <exception> +#include <irdb-core> + + +// doing this is very bad. +// using namespace std; +// using namespace ELFIO; + +class ElfReader +{ + public: + + ElfReader(char *); + virtual ~ElfReader(); + + std::string read(IRDB_SDK::VirtualOffset_t p_pc, unsigned p_numBytes) const ; + bool read(IRDB_SDK::VirtualOffset_t p_pc, unsigned p_numBytes, char* p_buf) const ; + const char* getInstructionBuffer(IRDB_SDK::VirtualOffset_t p_pc) const ; + + bool isElf32() const { assert(m_reader); return m_reader->get_class()==EXEIO::ELF32; } + bool isElf64() const { assert(m_reader); return m_reader->get_class()==EXEIO::ELF64; } + bool isPe32() const { assert(m_reader); return m_reader->get_class()==EXEIO::PE32; } + bool isPe64() const { assert(m_reader); return m_reader->get_class()==EXEIO::PE64; } + void SetArchitecture() ; + + private: + EXEIO::exeio* m_reader; + +}; + +#endif diff --git a/xform/framerestore_hash.c b/meds2pdb/framerestore_hash.cpp similarity index 92% rename from xform/framerestore_hash.c rename to meds2pdb/framerestore_hash.cpp index 5c3ef8960afe583cf84680317f8b0635b13a3258..d7c2d400fda6c41c9a0d98b81706bcb22c7a1230 100644 --- a/xform/framerestore_hash.c +++ b/meds2pdb/framerestore_hash.cpp @@ -45,7 +45,7 @@ long framerestores_key_compare(void* key1, void* key2) /* * frame_restore_set_return_address - set the offset of the return address for this frame */ -void frame_restore_set_return_address(app_iaddr_t pc, int offset) +void frame_restore_set_return_address(VirtualOffset_t pc, int offset) { instrmap_hash_value_t *imhv=(instrmap_hash_value_t*)Hashtable_get(instrmaps_hash,&pc); @@ -75,7 +75,7 @@ void frame_restore_set_return_address(app_iaddr_t pc, int offset) /* * frame_restore_hash_add_reg_restore - add info to the frame restore hash about the type and offset of saved registers */ -void frame_restore_hash_add_reg_restore(app_iaddr_t addr, int reg_num, int reg_offset, int reg_type) +void frame_restore_hash_add_reg_restore(VirtualOffset_t addr, int reg_num, int reg_offset, int reg_type) { framerestore_hash_value_t *frhv=(framerestore_hash_value_t*) Hashtable_get(framerestores_hash,&addr); @@ -104,7 +104,7 @@ void frame_restore_hash_add_reg_restore(app_iaddr_t addr, int reg_num, int reg_o } -void frame_restore_hash_set_safe_bit(app_iaddr_t addr, int is_safe) +void frame_restore_hash_set_safe_bit(VirtualOffset_t addr, int is_safe) { framerestore_hash_value_t *frhv=(framerestore_hash_value_t*)Hashtable_get(framerestores_hash,&addr); @@ -126,7 +126,7 @@ void frame_restore_hash_set_safe_bit(app_iaddr_t addr, int is_safe) frhv->static_analyzer_believes_safe=is_safe; } -int is_safe_function(app_iaddr_t pc) +int is_safe_function(VirtualOffset_t pc) { instrmap_hash_value_t *imhv=(instrmap_hash_value_t*)Hashtable_get(instrmaps_hash,&pc); diff --git a/xform/framerestore_hash.h b/meds2pdb/framerestore_hash.h similarity index 81% rename from xform/framerestore_hash.h rename to meds2pdb/framerestore_hash.h index b6caf515c6c29fbf9aec1f4c663ecf4cd13746de..df466ba832ce3990f077e541ef9897650ffbd4ec 100644 --- a/xform/framerestore_hash.h +++ b/meds2pdb/framerestore_hash.h @@ -24,7 +24,7 @@ #ifndef framerestore_hash_h #define framerestore_hash_h -#include "all.h" +#include "meds_all.h" extern Hashtable *framerestores_hash; @@ -50,12 +50,12 @@ long framerestores_compute_hash(void* key1); long framerestores_key_compare(void* key1, void* key2); -void frame_restore_hash_add_reg_restore(app_iaddr_t addr, int reg_num, int reg_offset, int reg_type); +void frame_restore_hash_add_reg_restore(VirtualOffset_t addr, int reg_num, int reg_offset, int reg_type); -void frame_restore_hash_set_safe_bit(app_iaddr_t addr, int is_safe); +void frame_restore_hash_set_safe_bit(VirtualOffset_t addr, int is_safe); -void frame_restore_hash_set_frame_size(app_iaddr_t addr, int is_safe); -void frame_restore_set_return_address(app_iaddr_t pc, int offset); +void frame_restore_hash_set_frame_size(VirtualOffset_t addr, int is_safe); +void frame_restore_set_return_address(VirtualOffset_t pc, int offset); #endif diff --git a/xform/framesize_hash.c b/meds2pdb/framesize_hash.cpp similarity index 67% rename from xform/framesize_hash.c rename to meds2pdb/framesize_hash.cpp index b8b0c8069af628bebd6c8bceda5307c0ea388378..e6f3a8de4c64fdf4bdcdaabe32cb9502f1286f5a 100644 --- a/xform/framesize_hash.c +++ b/meds2pdb/framesize_hash.cpp @@ -17,10 +17,10 @@ long framesizes_key_compare(void* key1, void* key2) return a_key->pc == b_key->pc; } -int set_frame_size(int pc, int frame_size) +void set_frame_size(int pc, int frame_size) { framesize_hash_key_t fshk={pc}; - framesize_hash_value_t *fshv=Hashtable_get(framesizes_hash, &fshk); + framesize_hash_value_t *fshv=(framesize_hash_value_t*)Hashtable_get(framesizes_hash, &fshk); if(fshv) { @@ -31,8 +31,8 @@ int set_frame_size(int pc, int frame_size) return; } - framesize_hash_key_t *fshk2=spri_allocate_type(sizeof(*fshk2)); - framesize_hash_value_t *fshv2=spri_allocate_type(sizeof(*fshv2)); + framesize_hash_key_t *fshk2=(framesize_hash_key_t*)spri_allocate_type(sizeof(*fshk2)); + framesize_hash_value_t *fshv2=(framesize_hash_value_t*)spri_allocate_type(sizeof(*fshv2)); *fshk2=fshk; fshv2->frame_size=frame_size; @@ -46,7 +46,7 @@ int set_frame_size(int pc, int frame_size) int is_var_sized_frame(int pc) { framesize_hash_key_t fshk={pc}; - framesize_hash_value_t *fshv=Hashtable_get(framesizes_hash, &fshk); + framesize_hash_value_t *fshv=(framesize_hash_value_t*)Hashtable_get(framesizes_hash, &fshk); if(fshv) { diff --git a/xform/framesize_hash.h b/meds2pdb/framesize_hash.h similarity index 87% rename from xform/framesize_hash.h rename to meds2pdb/framesize_hash.h index 4a2af6206ddceaa513107b02a07388282096b7a9..a379e485217426b6ed8c38c6a578fc8d6fec67ac 100644 --- a/xform/framesize_hash.h +++ b/meds2pdb/framesize_hash.h @@ -1,7 +1,7 @@ #ifndef framesize_hash_h #define framesize_hash_h -#include "all.h" +#include "meds_all.h" extern Hashtable *framesizes_hash; @@ -22,7 +22,7 @@ long framesizes_compute_hash(void* key1); long framesizes_key_compare(void* key1, void* key2); -int set_frame_size(int pc, int frame_size); +void set_frame_size(int pc, int frame_size); int is_var_sized_frame(int pc); diff --git a/xform/funclist_hash.c b/meds2pdb/funclist_hash.cpp similarity index 100% rename from xform/funclist_hash.c rename to meds2pdb/funclist_hash.cpp diff --git a/xform/funclist_hash.h b/meds2pdb/funclist_hash.h similarity index 98% rename from xform/funclist_hash.h rename to meds2pdb/funclist_hash.h index 52d3f416bb8dc5dec6a62b7ddcf619b5e79fc634..7e3f618e398120c2850bb46be237d09c74f65baa 100644 --- a/xform/funclist_hash.h +++ b/meds2pdb/funclist_hash.h @@ -24,7 +24,7 @@ #ifndef funclist_hash_h #define funclist_hash_h -#include "all.h" +#include "meds_all.h" extern Hashtable *funclists_hash; diff --git a/xform/function_descriptor.cpp b/meds2pdb/function_descriptor.cpp similarity index 91% rename from xform/function_descriptor.cpp rename to meds2pdb/function_descriptor.cpp index c2dec6d5c6cdc050548262db9e26936be661f18e..e81dd459c053143cb97465f05c4595cc3dd6f6c1 100644 --- a/xform/function_descriptor.cpp +++ b/meds2pdb/function_descriptor.cpp @@ -22,6 +22,7 @@ #include <cstdio> #include "function_descriptor.h" +using namespace IRDB_SDK; void wahoo::Function::_init() { @@ -40,13 +41,13 @@ wahoo::Function::Function() _init(); } -wahoo::Function::Function(app_iaddr_t p_start) +wahoo::Function::Function(VirtualOffset_t p_start) { _init(); setAddress(p_start); } -wahoo::Function::Function(string p_name, app_iaddr_t p_start, int p_size) +wahoo::Function::Function(string p_name, VirtualOffset_t p_start, int p_size) { _init(); setName(p_name); @@ -63,7 +64,7 @@ bool wahoo::Function::operator == (const Function &other) return (other.m_name == this->m_name && other.m_address == this->m_address); } -bool wahoo::Function::operator == (const app_iaddr_t p_addr) +bool wahoo::Function::operator == (const VirtualOffset_t p_addr) { return (this->m_address == p_addr); } @@ -73,7 +74,7 @@ bool wahoo::Function::operator != (const Function &other) return (other.m_name != this->m_name || other.m_address != this->m_address); } -bool wahoo::Function::operator != (const app_iaddr_t p_addr) +bool wahoo::Function::operator != (const VirtualOffset_t p_addr) { return (this->m_address != p_addr); } diff --git a/xform/function_descriptor.h b/meds2pdb/function_descriptor.h similarity index 64% rename from xform/function_descriptor.h rename to meds2pdb/function_descriptor.h index 32b4c429feffb0bf7e0b3f145d321fd0c177b8a2..502c175e6c7ebc4898260b25c4adc6b99ec257ce 100644 --- a/xform/function_descriptor.h +++ b/meds2pdb/function_descriptor.h @@ -2,7 +2,8 @@ #include <vector> #include <string> -#include "targ-config.h" +#include <irdb-core> +#include <irdb-core> #include "instruction_descriptor.h" //class wahoo::Instruction; @@ -15,26 +16,26 @@ class Function { public: Function(); - Function(app_iaddr_t); - Function(string, app_iaddr_t, int); + Function(IRDB_SDK::VirtualOffset_t); + Function(string, IRDB_SDK::VirtualOffset_t, int); ~Function(); - string getName() const { return m_name; } - void setName(const string p_name) { m_name = p_name; } - app_iaddr_t getAddress() const { return m_address; } - void setAddress(const app_iaddr_t p_address) { m_address = p_address; } - int getSize() const { return m_size; } - void setSize(const int p_size) { m_size = p_size; } - int getFrameSize() const { return m_frameSize; } - void setFrameSize(const int p_size) { m_frameSize = p_size; } - int getFunctionID() const { return m_functionID; } - void setFunctionID(const int id) { m_functionID = id; } + string getName() const { return m_name; } + void setName(const string p_name) { m_name = p_name; } + IRDB_SDK::VirtualOffset_t getAddress() const { return m_address; } + void setAddress(const IRDB_SDK::VirtualOffset_t p_address) { m_address = p_address; } + int getSize() const { return m_size; } + void setSize(const int p_size) { m_size = p_size; } + int getFrameSize() const { return m_frameSize; } + void setFrameSize(const int p_size) { m_frameSize = p_size; } + int getFunctionID() const { return m_functionID; } + void setFunctionID(const int id) { m_functionID = id; } bool operator == (const Function &); - bool operator == (const app_iaddr_t); + bool operator == (const IRDB_SDK::VirtualOffset_t); bool operator != (const Function &); - bool operator != (const app_iaddr_t); + bool operator != (const IRDB_SDK::VirtualOffset_t); bool isSafe() const { return m_isSafe; } void setSafe() { m_isSafe = true; } @@ -67,7 +68,7 @@ class Function int m_functionID; string m_name; - app_iaddr_t m_address; + IRDB_SDK::VirtualOffset_t m_address; int m_size; int m_frameSize; bool m_isSafe; diff --git a/xform/gen_hash.c b/meds2pdb/gen_hash.cpp similarity index 98% rename from xform/gen_hash.c rename to meds2pdb/gen_hash.cpp index 1b1c9d885d9f066a01188d266af86634ce93ec94..358bc720969e11ff30bdc90e00b9399ac41c655b 100644 --- a/xform/gen_hash.c +++ b/meds2pdb/gen_hash.cpp @@ -111,7 +111,7 @@ void Hashtable_rehash( Hashtable *h ) void Hashtable_put( Hashtable *h, void *key, void *value ) { struct entry *e; - long hash = (long)key; + // long hash = (long)key; long index = h->hash_func(key) & (h->tableLength-1); // make sure the key isn't already present @@ -195,7 +195,7 @@ struct entry* Hashtable_get_next(Hashtable_iterator &iterator) if (iterator.idx < 0) { - int i; + int i=0; // first time, find the first real entry for (i = 0; i < iterator.ht->tableLength; ++i) { @@ -220,7 +220,7 @@ struct entry* Hashtable_get_next(Hashtable_iterator &iterator) } else { - int i; + int i=0; // get the next entry for (i = iterator.idx + 1; i < iterator.ht->tableLength; ++i) { @@ -234,6 +234,7 @@ struct entry* Hashtable_get_next(Hashtable_iterator &iterator) return NULL; // we're done } } + return NULL; // empty table, no keys found } } diff --git a/xform/gen_hash.h b/meds2pdb/gen_hash.h similarity index 100% rename from xform/gen_hash.h rename to meds2pdb/gen_hash.h diff --git a/xform/instrmap_hash.c b/meds2pdb/instrmap_hash.cpp similarity index 100% rename from xform/instrmap_hash.c rename to meds2pdb/instrmap_hash.cpp diff --git a/xform/instrmap_hash.h b/meds2pdb/instrmap_hash.h similarity index 98% rename from xform/instrmap_hash.h rename to meds2pdb/instrmap_hash.h index 8b802fcb8c57469d0c3f51a70626d0c1e8a7e46e..1b6239596186a4c99fb3c9a99e39f25c8b0738c0 100644 --- a/xform/instrmap_hash.h +++ b/meds2pdb/instrmap_hash.h @@ -24,7 +24,7 @@ #ifndef instrmap_hash_h #define instrmap_hash_h -#include "all.h" +#include "meds_all.h" extern Hashtable *instrmaps_hash; diff --git a/xform/instruction_descriptor.cpp b/meds2pdb/instruction_descriptor.cpp similarity index 94% rename from xform/instruction_descriptor.cpp rename to meds2pdb/instruction_descriptor.cpp index 50595f6cff2fa228f98820ef1f94693439ac4b3c..d01255f9196ab43ce70ecae5a651bb6bedece10e 100644 --- a/xform/instruction_descriptor.cpp +++ b/meds2pdb/instruction_descriptor.cpp @@ -21,6 +21,8 @@ #include "instruction_descriptor.h" #include "function_descriptor.h" +using namespace IRDB_SDK; + wahoo::Instruction::Instruction() { m_address = 0; @@ -36,7 +38,7 @@ wahoo::Instruction::Instruction() m_data = NULL; } -wahoo::Instruction::Instruction(app_iaddr_t p_address, int p_size, Function* p_func) +wahoo::Instruction::Instruction(VirtualOffset_t p_address, int p_size, Function* p_func) { m_address = p_address; m_size = p_size; diff --git a/xform/instruction_descriptor.h b/meds2pdb/instruction_descriptor.h similarity index 86% rename from xform/instruction_descriptor.h rename to meds2pdb/instruction_descriptor.h index 5efdf3b65a647011e8293b2c5a7215b506868058..2cb5bfd2ec7d8dece2253460aee4e4df8f7ba761 100644 --- a/xform/instruction_descriptor.h +++ b/meds2pdb/instruction_descriptor.h @@ -3,8 +3,9 @@ #include <string> #include <set> +#include <irdb-core> -#include "targ-config.h" +#include <irdb-core> using namespace std; @@ -17,7 +18,7 @@ class Function; class Instruction { public: Instruction(); - Instruction(app_iaddr_t, int p_size = -1, Function* = NULL); + Instruction(IRDB_SDK::VirtualOffset_t, int p_size = -1, Function* = NULL); ~Instruction(); void setSize(int p_size) { m_size = p_size; } @@ -28,7 +29,7 @@ class Instruction { void markStackRef(); void markVarStackRef(); - app_iaddr_t getAddress() const { return m_address; } + IRDB_SDK::VirtualOffset_t getAddress() const { return m_address; } int getSize() const { return m_size; } Function* getFunction() const { return m_function; } string getAsm() const { return m_asm; } @@ -47,7 +48,7 @@ class Instruction { bool isVisited() const { return m_isVisited; } private: - app_iaddr_t m_address; + IRDB_SDK::VirtualOffset_t m_address; int m_size; Function* m_function; string m_asm; diff --git a/xform/instrument.h b/meds2pdb/instrument.h similarity index 82% rename from xform/instrument.h rename to meds2pdb/instrument.h index 77a310ffc9d8b66fb36f083b3c808c08d509036e..80f85f760bbcfb1a967dd9bb1e1f28b6a908e296 100644 --- a/xform/instrument.h +++ b/meds2pdb/instrument.h @@ -31,8 +31,8 @@ /* no needed for SPRI -void add_smp_instrumentation(strata_fragment_t *frag, app_iaddr_t PC, insn_t *insn); -void add_smp_postinstrumentation(strata_fragment_t *frag, app_iaddr_t PC, insn_t *insn); +void add_smp_instrumentation(strata_fragment_t *frag, VirtualOffset_t PC, insn_t *insn); +void add_smp_postinstrumentation(strata_fragment_t *frag, VirtualOffset_t PC, insn_t *insn); */ @@ -58,7 +58,7 @@ struct reg_values /* no needed for SPRI -app_iaddr_t targ_watched_called_instrument(app_iaddr_t next_PC, watch *w, strata_fragment_t *frag); +VirtualOffset_t targ_watched_called_instrument(VirtualOffset_t next_PC, watch *w, strata_fragment_t *frag); */ diff --git a/tools/meds2pdb/meds2pdb.cpp b/meds2pdb/meds2pdb.cpp similarity index 95% rename from tools/meds2pdb/meds2pdb.cpp rename to meds2pdb/meds2pdb.cpp index 3eb03a6e14240be1f723371e3bf604766a7dfa24..67539ea7bb64632efcce1d1181cb76e190bc4ed7 100644 --- a/tools/meds2pdb/meds2pdb.cpp +++ b/meds2pdb/meds2pdb.cpp @@ -29,11 +29,11 @@ #include <stdlib.h> #include "MEDS_AnnotationParser.hpp" #include "MEDS_FuncPrototypeAnnotation.hpp" -#include "libIRDB-core.hpp" +#include <irdb-core> using namespace std; using namespace pqxx; -using namespace libIRDB; +using namespace IRDB_SDK; using namespace MEDS_Annotation; #include <sstream> @@ -58,7 +58,7 @@ inline std::string my_to_string (const T& t) int next_address_id=0; -map<app_iaddr_t,int> address_to_instructionid_map; +map<VirtualOffset_t,int> address_to_instructionid_map; map<wahoo::Instruction*,int> instruction_to_addressid_map; // extract the file id from the md5 hash and the program name @@ -104,7 +104,7 @@ void insert_instructions(int fileID, const vector<wahoo::Instruction*> &instruct char buf[128]; wahoo::Instruction *instruction = instructions[i]; - app_iaddr_t addr = instruction->getAddress(); + auto addr = instruction->getAddress(); // assign an instruction id address_to_instructionid_map[addr]=next_address_id++; @@ -204,7 +204,6 @@ void insert_functions(int fileID, const vector<wahoo::Function*> &functions ) if (j >= functions.size()) break; wahoo::Function *f = functions[j]; string functionName = f->getName(); - //app_iaddr_t functionAddress = f->getAddress(); int functionFrameSize = f->getFrameSize(); int function_id = j; @@ -249,7 +248,7 @@ void update_functions(int fileID, const vector<wahoo::Function*> &functions ) if (j >= functions.size()) break; wahoo::Function *f = functions[j]; string functionName = f->getName(); - app_iaddr_t functionAddress = f->getAddress(); + auto functionAddress = f->getAddress(); //int functionSize = f->getSize(); int function_id = f->getFunctionID(); //int outArgsRegionSize = f->getOutArgsRegionSize(); @@ -347,7 +346,7 @@ void update_function_prototype(const vector<wahoo::Function*> &functions, char* if (j >= functions.size()) break; wahoo::Function *f = functions[j]; int function_id = f->getFunctionID(); - app_iaddr_t functionAddress = f->getAddress(); + auto functionAddress = f->getAddress(); VirtualOffset vo(functionAddress); //MEDS_FuncPrototypeAnnotation* fn_prototype_annot = NULL; @@ -385,33 +384,33 @@ void update_function_prototype(const vector<wahoo::Function*> &functions, char* // (3) define new function type (combo (1) + (2)) int aggregate_type_id = getNewTypeId(); int func_type_id = getNewTypeId(); - int basic_type_id = T_UNKNOWN; + int basic_type_id = IRDB_SDK::itUnknown; for (auto i = 0U; i < args->size(); ++i) { if ((*args)[i].isNumericType()) - basic_type_id = T_NUMERIC; + basic_type_id = itNumeric; else if ((*args)[i].isPointerType()) - basic_type_id = T_POINTER; + basic_type_id = itPointer; q += "INSERT into " + typesTable + " (type_id, type, name, ref_type_id, pos) VALUES ("; q += txn.quote(my_to_string(aggregate_type_id)) + ","; - q += txn.quote(my_to_string(T_AGGREGATE)) + ","; + q += txn.quote(my_to_string(itAggregate)) + ","; q += txn.quote(string(f->getName()) + "_arg") + ","; q += txn.quote(my_to_string(basic_type_id)) + ","; q += txn.quote(my_to_string(i)) + ");"; } - int return_type_id = T_UNKNOWN; + int return_type_id = itUnknown; if (returnArg) { if (returnArg->isNumericType()) - return_type_id = T_NUMERIC; + return_type_id = itNumeric; else if (returnArg->isPointerType()) - return_type_id = T_POINTER; + return_type_id = itPointer; else - return_type_id = T_UNKNOWN; + return_type_id = itUnknown; } // new function type id (ok to have duplicate prototypes) @@ -421,7 +420,7 @@ void update_function_prototype(const vector<wahoo::Function*> &functions, char* q += "INSERT into " + typesTable + " (type_id, type, name, ref_type_id, ref_type_id2) VALUES ("; q += txn.quote(my_to_string(func_type_id)) + ","; - q += txn.quote(my_to_string(T_FUNC)) + ","; + q += txn.quote(my_to_string(itFunc)) + ","; q += txn.quote(string(f->getName()) + "_func") + ","; q += txn.quote(my_to_string(return_type_id)) + ","; q += txn.quote(my_to_string(aggregate_type_id)) + ");"; diff --git a/xform/all.h b/meds2pdb/meds_all.h similarity index 93% rename from xform/all.h rename to meds2pdb/meds_all.h index e670cbb1038453259eab667842f78ff7c4e4dc53..f551ac1dc631a6bd446d07de7c1fb21b087f8454 100644 --- a/xform/all.h +++ b/meds2pdb/meds_all.h @@ -1,5 +1,5 @@ /* - * all.h + * meds_all.h * * Copyright (c) 2011 - University of Virginia * @@ -29,10 +29,13 @@ #include <string.h> #include <assert.h> +#include <irdb-core> + +using namespace IRDB_SDK; + #include "strata_defines.h" /* x86_32-specific headers */ -#include "targ-config.h" #include "instrument.h" #include "spri_alloc.h" @@ -46,4 +49,6 @@ #include "funclist_hash.h" #include "constant_hash.h" +#include <inttypes.h> + #endif diff --git a/xform/null_transform.cpp b/meds2pdb/null_transform.cpp similarity index 95% rename from xform/null_transform.cpp rename to meds2pdb/null_transform.cpp index 491fda4b42ed2e7145df522e489f4bb5f4402598..c675d20ce826ae346d1a3faa35ce524f010faec9 100644 --- a/xform/null_transform.cpp +++ b/meds2pdb/null_transform.cpp @@ -20,7 +20,7 @@ #include <iostream> -//#include "targ-config.h" +#include <irdb-core> // #include "elfio/elfio.hpp" @@ -49,9 +49,9 @@ using namespace wahoo; void NullTransform::rewrite() { // only transform instructions contained in well-defined functions - for (map<app_iaddr_t, wahoo::Function*>::iterator it = m_functions.begin(); it != m_functions.end(); ++it) + for (map<VirtualOffset_t, wahoo::Function*>::iterator it = m_functions.begin(); it != m_functions.end(); ++it) { - app_iaddr_t addr = it->first; + VirtualOffset_t addr = it->first; wahoo::Function* f = it->second; if (!f) { diff --git a/xform/null_transform.h b/meds2pdb/null_transform.h similarity index 100% rename from xform/null_transform.h rename to meds2pdb/null_transform.h diff --git a/xform/read_annot_file.c b/meds2pdb/read_annot_file.cpp similarity index 86% rename from xform/read_annot_file.c rename to meds2pdb/read_annot_file.cpp index 0be85b60804bb6d3aaf0ed5b1eaba294cd3a1b0a..10508f2376e63d09e0886e3a9c9d18789470994a 100644 --- a/xform/read_annot_file.c +++ b/meds2pdb/read_annot_file.cpp @@ -35,23 +35,27 @@ // #include <stdio.h> // #include <string.h> -#include "all.h" +#include "meds_all.h" + +template <class T> +void ignore_result(const T& v) { (void)v; } /* * read_annot_file - read the annotations file provided by IDA Pro. */ void read_annot_file(char fn[]) { - FILE* fin; - app_iaddr_t addr; + FILE* fin=nullptr; + VirtualOffset_t addr=0; union { int size, type;} size_type_u; char type[200]; char scope[200]; char remainder[200000]; - char * objname; + /*char * objname; int pid=0; - int var_length=0; + int var_length=0; int bitvector_size_bits=0; + */ int line=0; @@ -76,12 +80,14 @@ void read_annot_file(char fn[]) do { - fscanf(fin, "%x %d\n", &addr, &size_type_u); + unsigned int tmp=0; + ignore_result(fscanf(fin, "%x %d\n", &tmp, &size_type_u.size)); + addr=tmp; if(feof(fin)) // deal with blank lines at the EOF break; - fscanf(fin, "%s%s", type,scope); + ignore_result(fscanf(fin, "%s%s", type,scope)); int annot_type; int is_spec_annot=FALSE; @@ -100,7 +106,7 @@ void read_annot_file(char fn[]) if(is_spec_annot) { /* skip this annotation */ - fgets(remainder, sizeof(remainder), fin); + ignore_result(fgets(remainder, sizeof(remainder), fin)); line++; continue; } @@ -117,7 +123,7 @@ void read_annot_file(char fn[]) funclist_hash_key_t *flhk=(funclist_hash_key_t*)spri_allocate_type(sizeof(funclist_hash_key_t)); funclist_hash_value_t *flhv=(funclist_hash_value_t*)spri_allocate_type(sizeof(funclist_hash_value_t)); - fscanf(fin,"%s", name); + ignore_result(fscanf(fin,"%s", name)); flhk->name=spri_strdup(name); flhv->pc=addr; // STRATA_LOG("annot","Adding name=%s pc=%x to funclist hash table\n", flhk->name, flhv->pc); @@ -131,17 +137,17 @@ void read_annot_file(char fn[]) int reg=0; for( ; reg<8;reg++) { - fscanf(fin, "%d %d %d", ®_num, ®_offset, ®_type); + ignore_result(fscanf(fin, "%d %d %d", ®_num, ®_offset, ®_type)); assert(reg_num==reg); frame_restore_hash_add_reg_restore(addr,reg_num,reg_offset,reg_type); } - fscanf(fin, "%s", zz); + ignore_result(fscanf(fin, "%s", zz)); assert(strcmp("ZZ", zz)==0); } else if(strcmp(scope,"MMSAFENESS")==0) { char safeness[1000]; - fscanf(fin, "%s", &safeness); + ignore_result(fscanf(fin, "%s", safeness)); if(strcmp(safeness, "SAFE")) frame_restore_hash_set_safe_bit(addr,TRUE); else if(strcmp(safeness, "SPECSAFE")) @@ -164,14 +170,14 @@ void read_annot_file(char fn[]) /* found function declaration */ assert(strcmp(scope,"STACK")==0); /* remaining parameters are "esp + <const> <name>" */ - fscanf(fin, "%s%s%d%s", esp, plus, &offset, name); + ignore_result(fscanf(fin, "%s%s%d%s", esp, plus, &offset, name)); if(strcmp(name, "ReturnAddress")==0) { frame_restore_set_return_address(addr,offset); } - printf("MEMORYHOLE, pc=%x offset=%d\n", addr, offset); + //printf("MEMORYHOLE, pc=%x offset=%d\n", addr, offset); /* ignoring for now */ } else if(strcmp(type,"LOCALFRAME")==0 || strcmp(type,"INARGS")==0) @@ -185,7 +191,7 @@ void read_annot_file(char fn[]) /* add to hashtable, a name would be nice someday */ sshk->pc=addr; sshv->size=size_type_u.size; - printf("Adding pc=%x size=%d to stackref hash table\n", sshk->pc, sshv->size); + // printf("Adding pc=%x size=%d to stackref hash table\n", sshk->pc, sshv->size); // STRATA_LOG("annot","Adding pc=%x size=%d to stackref hash table\n", sshk->pc, sshv->size); Hashtable_put(stackrefs_hash, sshk,sshv); @@ -205,12 +211,12 @@ void read_annot_file(char fn[]) } else if (strcmp(scope, "DEADREGS") == 0) { - stackref_hash_key_t sshk; - stackref_hash_value_t *sshv; - sshk.pc = addr; + // stackref_hash_key_t sshk; + // stackref_hash_value_t *sshv; + // sshk.pc = addr; if (Hashtable_get(stackrefs_hash, &addr)) { - printf("STACK ALLOC INSTRUCTION CONFIRMED AT pc=0x%x size=%d\n", sshk.pc, size_type_u); + // printf("STACK ALLOC INSTRUCTION CONFIRMED AT pc=0x%x size=%d\n", sshk.pc, size_type_u); } #ifdef OLD_MEDS @@ -218,7 +224,7 @@ void read_annot_file(char fn[]) int value = SAVE_EBP | SAVE_EDI | SAVE_ESI | SAVE_EDX | SAVE_ECX | SAVE_EBX | SAVE_EAX | SAVE_EFLAGS; do { - fscanf(fin, "%s", ®name); + ignore_result(fscanf(fin, "%s", ®name)); if (strcmp(regname, "EFLAGS") == 0) value ^= SAVE_EFLAGS; else if (strcmp(regname, "EAX") == 0) @@ -251,7 +257,7 @@ void read_annot_file(char fn[]) else if (strcmp(scope, "FAULT") == 0) { int count; - fscanf(fin, "%d", &count); + ignore_result(fscanf(fin, "%d", &count)); recordfault_add_fault(addr,count); } else if (strcmp(scope, "CHILDACCESS") == 0) @@ -261,10 +267,10 @@ void read_annot_file(char fn[]) int istart, iend; do { - fscanf(fin, "%s", start); + ignore_result(fscanf(fin, "%s", start)); if(strcmp(start,"ZZ")==0) break; - fscanf(fin, "%s", end); + ignore_result(fscanf(fin, "%s", end)); istart=atoi(start); iend=atoi(end); add_fgrange(addr, istart, istart+iend-1); @@ -275,8 +281,10 @@ void read_annot_file(char fn[]) #endif else if (strcmp(scope, "BELONGTO") == 0) { - app_iaddr_t func_addr; - fscanf(fin, "%x", &func_addr); + VirtualOffset_t func_addr; + unsigned int tmp=0; + ignore_result(fscanf(fin, "%x", &tmp)); + func_addr=tmp; instrmap_hash_key_t* key = (instrmap_hash_key_t*)spri_allocate_type(sizeof(instrmap_hash_key_t)); instrmap_hash_value_t* val = (instrmap_hash_value_t*)spri_allocate_type(sizeof(instrmap_hash_value_t)); key->pc = addr; @@ -302,7 +310,7 @@ void read_annot_file(char fn[]) */ /* copy scope to objname */ - fscanf(fin, "%s", temp_obj_name); + ignore_result(fscanf(fin, "%s", temp_obj_name)); objname=spri_strdup(temp_obj_name); /* lookup in hash table */ @@ -312,10 +320,10 @@ void read_annot_file(char fn[]) /* FIXME: if bit vector dumped as hex */ /* allocate memory for the bitvector */ - fscanf(fin, "%d%d", &pid, &var_length); + ignore_result(fscanf(fin, "%d%d", &pid, &var_length)); if(var_length>0) { - fscanf(fin, "%d%d", &bitvector_size_bits, &num_elems_in_hex_rep); + ignore_result(fscanf(fin, "%d%d", &bitvector_size_bits, &num_elems_in_hex_rep)); the_bitvector= spri_allocate_type(((bitvector_size_bits/8)+1)*sizeof(char) + 4); @@ -323,7 +331,7 @@ void read_annot_file(char fn[]) for(i=0, j=0; i < num_elems_in_hex_rep; i++, j+=4) { /* read an int */ - fscanf(fin, "%x", &the_bitvector[j]); + ignore_result(fscanf(fin, "%x", &the_bitvector[j])); } /* create a bitvector structure to hold the info */ @@ -399,12 +407,12 @@ void read_annot_file(char fn[]) reg_buffer[0]=0; int reg_map=0; - fscanf(fin, "%s", n_buffer); + ignore_result(fscanf(fin, "%s", n_buffer)); assert(strcmp(n_buffer,"n")==0); while(1) // loop until we find a ZZ { - fscanf(fin, "%s", reg_buffer); + ignore_result(fscanf(fin, "%s", reg_buffer)); if(strcmp(reg_buffer,"EAX")==0 || strcmp(reg_buffer,"AL")==0 || strcmp(reg_buffer,"AH")==0 || strcmp(reg_buffer,"AX")==0) { @@ -500,11 +508,11 @@ void read_annot_file(char fn[]) assert(strcmp(scope,"STACK")==0 || strcmp(scope,"GLOBAL")==0); /* remaining params are <const> <field> <real_const_if_global> <comment> */ - fscanf(fin, "%d %s", &the_const, field); + ignore_result(fscanf(fin, "%d %s", &the_const, field)); if( strcmp(type,"PTRIMMEDESP2")==0 || strcmp(type,"PTRIMMEDABSOLUTE")==0 ) - fscanf(fin, "%x", &real_const); + ignore_result(fscanf(fin, "%x", &real_const)); else real_const=the_const; @@ -535,8 +543,8 @@ void read_annot_file(char fn[]) } else if(strcmp(type,"DATAREF")==0) { - char name[1000], parent_child[1000], offset_str[1000]; - int id, parent_id, offset, parent_offset; + char /* name[1000], */ parent_child[1000], offset_str[1000]; + int id /*, parent_id, offset, parent_offset*/; if(size_type_u.size<=0) { // STRATA_LOG("warn", "Found DATAREF of size <=0 at line %d of annot file\n", line); @@ -544,12 +552,14 @@ void read_annot_file(char fn[]) else if(strcmp(scope,"GLOBAL")==0) { /* remaining params id, addr, parent/child, name */ - fscanf(fin, "%d%x%s%s", &id, &addr, parent_child); + unsigned int tmp=0; + ignore_result(fscanf(fin, "%d%x%s%s", &id, &tmp, parent_child, offset_str)); + addr=tmp; if(strcmp(parent_child, "PARENT")==0) { #ifdef OLD_MEDS - fscanf(fin, "%s", name); + ignore_result(fscanf(fin, "%s", name)); add_referent(spri_strdup(name),addr,size_type_u.size, 0, 0); if(strata_opt_do_smp_fine_grain && !STRATA_LOG_IS_ON("no_fine_grain_static")) @@ -562,7 +572,7 @@ void read_annot_file(char fn[]) if(strata_opt_do_smp_fine_grain && !STRATA_LOG_IS_ON("no_fine_grain_static")) { referent_object_t* new_ref; - fscanf(fin, "%d%s%d", &parent_id, offset_str, &parent_offset); + ignore_result(fscanf(fin, "%d%s%d", &parent_id, offset_str, parent_offset)); assert(strcmp("OFFSET", offset_str)==0); referent_object_t *refnt=get_referent_from_id_map(parent_id); new_ref=add_referent_field(refnt, parent_offset, addr, size_type_u.size); @@ -576,11 +586,11 @@ void read_annot_file(char fn[]) } else if(strcmp(scope,"STACK")==0) { - char esp[1000], plus[1000], offset_str[1000]; + char esp[1000], plus[1000]; // , offset_str[1000]; int esp_offset; /* remaining params id, addr, parent/child, name */ - fscanf(fin, "%d%s%s%d%s", &id, &esp, &plus, &esp_offset, parent_child); + ignore_result(fscanf(fin, "%d%s%s%d%s", &id, esp, plus, &esp_offset, parent_child)); assert(strcmp(esp, "esp")==0 && strcmp(plus,"+")==0); @@ -589,17 +599,17 @@ void read_annot_file(char fn[]) /* add to the stackref hashtable, also record the id->stackref mapping so we can * can easily lookup the id for any fields we find. */ - stackref_hash_value_t *sshv=add_stack_ref(addr,size_type_u.size, esp_offset); + /*stackref_hash_value_t *sshv=(stackref_hash_value_t *)*/(void)add_stack_ref(addr,size_type_u.size, esp_offset); - printf("New stack frame at: pc=0x%x size=0x%x\n", addr, sshv->size); + // printf("New stack frame at: pc=0x%x size=0x%x\n", addr, sshv->size); #ifdef OLD_MEDS //if(strata_opt_do_smp_fine_grain && !STRATA_LOG_IS_ON("no_fine_grain_stack")) - if(!STRATA_LOG_IS_ON("no_fine_grain_stack")) - add_to_stackref_id_map(id,sshv); + // if(!STRATA_LOG_IS_ON("no_fine_grain_stack")) + // add_to_stackref_id_map(id,sshv); /* add to hashtable, a name would be nice someday */ - STRATA_LOG("annot","Adding pc=%x size=%d to stackref hash table\n", addr, sshv->size); + // STRATA_LOG("annot","Adding pc=%x size=%d to stackref hash table\n", addr, sshv->size); #endif } else if(strcmp(parent_child, "CHILDOF")==0) @@ -607,7 +617,7 @@ void read_annot_file(char fn[]) #ifdef OLD_MEDS if(strata_opt_do_smp_fine_grain && !STRATA_LOG_IS_ON("no_fine_grain_stack")) { - fscanf(fin, "%d%s%d", &parent_id, offset_str, &parent_offset); + ignore_result(fscanf(fin, "%d%s%d", &parent_id, offset_str, &parent_offset)); assert(strcmp("OFFSET", offset_str)==0); stackref_hash_value_t *sshv=get_stackref_from_id_map(parent_id); stackref_hash_value_t *new_sshv=add_stack_ref_field(sshv, addr, @@ -674,7 +684,7 @@ void read_annot_file(char fn[]) fprintf(stderr, "Fatal, Unknown type at line %d\n", line); } - fgets(remainder, sizeof(remainder), fin); + ignore_result(fgets(remainder, sizeof(remainder), fin)); line++; } while(!feof(fin)); fclose(fin); diff --git a/xform/rewriter.cpp b/meds2pdb/rewriter.cpp similarity index 94% rename from xform/rewriter.cpp rename to meds2pdb/rewriter.cpp index c5fe4c302d3ccae6fb1b237a3ee64d143a8ea3e3..f95a60ec44e918c040210dc63aa0e11b0bc118e2 100644 --- a/xform/rewriter.cpp +++ b/meds2pdb/rewriter.cpp @@ -23,11 +23,11 @@ #include <string> #include <set> #include <stdlib.h> -#include <libIRDB-core.hpp> +#include <irdb-core> -#include "all.h" -//#include "targ-config.h" +#include "meds_all.h" +#include <irdb-core> //#include "elfio/elfio.hpp" @@ -35,7 +35,7 @@ using namespace std; -using namespace libIRDB; +using namespace IRDB_SDK; template <class T> void ignore_result(T /* res */) { } @@ -54,7 +54,7 @@ Rewriter::~Rewriter() { } -wahoo::Function* Rewriter::ensureFunctionExists(const app_iaddr_t p_addr) +wahoo::Function* Rewriter::ensureFunctionExists(const VirtualOffset_t p_addr) { if (m_functions.count(p_addr) > 0) return m_functions[p_addr]; @@ -65,7 +65,7 @@ wahoo::Function* Rewriter::ensureFunctionExists(const app_iaddr_t p_addr) return fn; } -wahoo::Instruction* Rewriter::ensureInstructionExists(const app_iaddr_t p_addr) +wahoo::Instruction* Rewriter::ensureInstructionExists(const VirtualOffset_t p_addr) { if (m_instructions.count(p_addr) > 0) return m_instructions[p_addr]; @@ -82,7 +82,7 @@ wahoo::Instruction* Rewriter::ensureInstructionExists(const app_iaddr_t p_addr) void Rewriter::readAnnotationFile(char p_filename[]) { FILE* fin=NULL; - app_iaddr_t addr = 0, prevStackDeallocPC = 0; + VirtualOffset_t addr = 0, prevStackDeallocPC = 0; union { int size, type;} size_type_u; char type[200]; char scope[200]; @@ -323,7 +323,7 @@ void Rewriter::readAnnotationFile(char p_filename[]) } else if (strcmp(scope, "BELONGTO") == 0) { - app_iaddr_t func_addr; + VirtualOffset_t func_addr; ignore_result(fscanf(fin, "%p", (void**)&func_addr)); instrmap_hash_key_t* key = (instrmap_hash_key_t*)spri_allocate_type(sizeof(instrmap_hash_key_t)); instrmap_hash_value_t* val = (instrmap_hash_value_t*)spri_allocate_type(sizeof(instrmap_hash_value_t)); @@ -639,22 +639,26 @@ void Rewriter::readElfFile(char p_filename[]) if(!objdump) objdump=strdup("objdump"); sprintf(buf, "%s -d --prefix-addresses %s | grep \"^[0-9]\"", objdump, p_filename); + printf("Running objdump, like so: %s\n", buf); FILE* pin=popen(buf, "r"); - app_iaddr_t addr; + VirtualOffset_t addr; assert(pin); void* tmp=NULL; ignore_result(fscanf(pin, "%p", &tmp)); - addr=(app_iaddr_t)tmp; + addr=(VirtualOffset_t)tmp; ignore_result(fgets(buf,sizeof(buf),pin)); do { if(m_instructions[addr]==NULL) + { + cout<<"Found instruction from objdump at "<<hex<<addr<<endl; m_instructions[addr]=new wahoo::Instruction(addr,-1,NULL); + } ignore_result(fscanf(pin,"%p", &tmp)); - addr=(app_iaddr_t)tmp; + addr=(VirtualOffset_t)tmp; ignore_result(fgets(buf,sizeof(buf),pin)); } while(!feof(pin)); @@ -669,10 +673,13 @@ void Rewriter::readElfFile(char p_filename[]) */ void Rewriter::disassemble() { + getElfReader()->SetArchitecture(); + /* if(getElfReader()->isElf64() || getElfReader()->isPe64()) FileIR_t::SetArchitectureBitWidth(64); else FileIR_t::SetArchitectureBitWidth(32); + */ // for every instruction, grab from ELF // disassemble @@ -686,7 +693,8 @@ void Rewriter::disassemble() wahoo::Instruction *instr = instructions[j]; const auto instr_data=(void*)(getElfReader()->getInstructionBuffer(instr->getAddress())); - const auto disasm=DecodedInstruction_t(instr->getAddress(), instr_data, 16); + const auto p_disasm=DecodedInstruction_t::factory(instr->getAddress(), instr_data, 16); + const auto &disasm=*p_disasm; /* maybe this isn't in a section so getInstructionBuffer returns 0 */ @@ -711,7 +719,7 @@ void Rewriter::disassemble() } } -void Rewriter::addSimpleRewriteRule(wahoo::Function* p_func, char *p_origInstr, int p_origSize, app_iaddr_t p_origAddress, char *p_newInstr) +void Rewriter::addSimpleRewriteRule(wahoo::Function* p_func, char *p_origInstr, int p_origSize, VirtualOffset_t p_origAddress, char *p_newInstr) { char buf[1024]; char aspri[2048]; @@ -746,7 +754,7 @@ void Rewriter::commitFn2SPRI(wahoo::Function *p_func, FILE *p_fp) vector<wahoo::Function*> Rewriter::getCandidateFunctions() { vector<wahoo::Function*> candidates; - for (map<app_iaddr_t, wahoo::Function*>::iterator it = m_functions.begin(); it != m_functions.end(); ++it) + for (map<VirtualOffset_t, wahoo::Function*>::iterator it = m_functions.begin(); it != m_functions.end(); ++it) { wahoo::Function* f = it->second; @@ -762,7 +770,7 @@ vector<wahoo::Function*> Rewriter::getCandidateFunctions() vector<wahoo::Function*> Rewriter::getNonCandidateFunctions() { vector<wahoo::Function*> nonCandidates; - for (map<app_iaddr_t, wahoo::Function*>::iterator it = m_functions.begin(); it != m_functions.end(); ++it) + for (map<VirtualOffset_t, wahoo::Function*>::iterator it = m_functions.begin(); it != m_functions.end(); ++it) { wahoo::Function* f = it->second; @@ -779,7 +787,7 @@ vector<wahoo::Function*> Rewriter::getAllFunctions() { vector<wahoo::Function*> allFunctions; - for (map<app_iaddr_t, wahoo::Function*>::iterator it = m_functions.begin(); it != m_functions.end(); ++it) + for (map<VirtualOffset_t, wahoo::Function*>::iterator it = m_functions.begin(); it != m_functions.end(); ++it) { wahoo::Function* f = it->second; @@ -795,7 +803,7 @@ vector<wahoo::Instruction*> Rewriter::getAllInstructions() { vector<wahoo::Instruction*> allInstructions; - for (map<app_iaddr_t, wahoo::Instruction*>::iterator it = m_instructions.begin(); it != m_instructions.end(); ++it) + for (map<VirtualOffset_t, wahoo::Instruction*>::iterator it = m_instructions.begin(); it != m_instructions.end(); ++it) { wahoo::Instruction* instr = it->second; @@ -820,7 +828,7 @@ map<wahoo::Function*, double> Rewriter::getFunctionCoverage(char *p_instructionF return coverage; } - set<app_iaddr_t> visitedInstructions; + set<VirtualOffset_t> visitedInstructions; infile.seekg(0,ios::end); size_t size = infile.tellg(); @@ -837,7 +845,7 @@ map<wahoo::Function*, double> Rewriter::getFunctionCoverage(char *p_instructionF infile>>hex>>address; - visitedInstructions.insert((app_iaddr_t) address); + visitedInstructions.insert((VirtualOffset_t) address); } vector<wahoo::Instruction*> allInstructions = getAllInstructions(); diff --git a/xform/rewriter.h b/meds2pdb/rewriter.h similarity index 74% rename from xform/rewriter.h rename to meds2pdb/rewriter.h index acaa03664aef6753da5079f6ff2ae3c212daf48b..9614dbcedbd4eb3b826efca2e7056c7a2615882f 100644 --- a/xform/rewriter.h +++ b/meds2pdb/rewriter.h @@ -1,6 +1,6 @@ #include <map> #include <set> -//#include "targ-config.h" +#include <irdb-core> // #include "elfio/elfio.hpp" //#include "elfio/elfio_dump.hpp" @@ -35,18 +35,18 @@ class Rewriter void disassemble(); // one instruction modification - void addSimpleRewriteRule(wahoo::Function* p_func, char *p_origInstr, int p_origSize, app_iaddr_t p_origAddress, char *p_newInstr); + void addSimpleRewriteRule(wahoo::Function* p_func, char *p_origInstr, int p_origSize, IRDB_SDK::VirtualOffset_t p_origAddress, char *p_newInstr); // commit function to AsmSPRI file void commitFn2SPRI(wahoo::Function* p_func, FILE *p_file); protected: - map<app_iaddr_t, wahoo::Function*> m_functions; - map<app_iaddr_t, wahoo::Instruction*> m_instructions; + map<IRDB_SDK::VirtualOffset_t, wahoo::Function*> m_functions; + map<IRDB_SDK::VirtualOffset_t, wahoo::Instruction*> m_instructions; private: - wahoo::Function* ensureFunctionExists(const app_iaddr_t); - wahoo::Instruction* ensureInstructionExists(const app_iaddr_t); + wahoo::Function* ensureFunctionExists(const IRDB_SDK::VirtualOffset_t); + wahoo::Instruction* ensureInstructionExists(const IRDB_SDK::VirtualOffset_t); private: ElfReader* m_elfReader; diff --git a/xform/spri_alloc.c b/meds2pdb/spri_alloc.cpp similarity index 100% rename from xform/spri_alloc.c rename to meds2pdb/spri_alloc.cpp diff --git a/xform/spri_alloc.h b/meds2pdb/spri_alloc.h similarity index 100% rename from xform/spri_alloc.h rename to meds2pdb/spri_alloc.h diff --git a/xform/stackref_hash.c b/meds2pdb/stackref_hash.cpp similarity index 94% rename from xform/stackref_hash.c rename to meds2pdb/stackref_hash.cpp index 232032968dbe26805c9b6d4bcbec4a135410ec9a..baba2498166443b3f7780e44300f271f3e0f7d18 100644 --- a/xform/stackref_hash.c +++ b/meds2pdb/stackref_hash.cpp @@ -21,7 +21,7 @@ * */ -#include "all.h" +#include "meds_all.h" #include "stackref_hash.h" /* @@ -47,7 +47,7 @@ long stackrefs_key_compare(void* key1, void* key2) /* add something to the stackrefs_hash hashtable */ -stackref_hash_value_t *add_stack_ref(app_iaddr_t pc,int size, int offset) +stackref_hash_value_t *add_stack_ref(VirtualOffset_t pc,int size, int offset) { stackref_hash_key_t *sshk=(stackref_hash_key_t*)spri_allocate_type(sizeof(stackref_hash_key_t )); stackref_hash_value_t *sshv=(stackref_hash_value_t*)spri_allocate_type(sizeof(stackref_hash_value_t )); @@ -64,7 +64,7 @@ stackref_hash_value_t *add_stack_ref(app_iaddr_t pc,int size, int offset) return sshv; } -stackref_hash_value_t *add_stack_ref_field(stackref_hash_value_t* parent, app_iaddr_t pc, int size, int offset) +stackref_hash_value_t *add_stack_ref_field(stackref_hash_value_t* parent, VirtualOffset_t pc, int size, int offset) { stackref_hash_key_t *sshk=(stackref_hash_key_t*)spri_allocate_type(sizeof(stackref_hash_key_t )); stackref_hash_value_t *sshv=(stackref_hash_value_t*)spri_allocate_type(sizeof(stackref_hash_value_t )); diff --git a/xform/stackref_hash.h b/meds2pdb/stackref_hash.h similarity index 89% rename from xform/stackref_hash.h rename to meds2pdb/stackref_hash.h index 64e272f8fdce8c868136400ce175486d11c19291..b5f526aa3e01c5083edb4e6a6c0651224a78ea05 100644 --- a/xform/stackref_hash.h +++ b/meds2pdb/stackref_hash.h @@ -24,7 +24,7 @@ #ifndef stackref_hash_h #define stackref_hash_h -#include "all.h" +#include "meds_all.h" /* @@ -35,7 +35,7 @@ extern Hashtable *stackrefs_hash; typedef struct stackref_hash_key stackref_hash_key_t; struct stackref_hash_key { - app_iaddr_t pc; + VirtualOffset_t pc; }; typedef struct stackref_hash_value stackref_hash_value_t; @@ -52,8 +52,8 @@ long stackrefs_compute_hash(void* key1); long stackrefs_key_compare(void* key1, void* key2); -stackref_hash_value_t *add_stack_ref(app_iaddr_t pc,int size, int offset); -stackref_hash_value_t *add_stack_ref_field(stackref_hash_value_t *parent, app_iaddr_t pc,int size, int offset); +stackref_hash_value_t *add_stack_ref(VirtualOffset_t pc,int size, int offset); +stackref_hash_value_t *add_stack_ref_field(stackref_hash_value_t *parent, VirtualOffset_t pc,int size, int offset); #endif diff --git a/xform/strata_defines.h b/meds2pdb/strata_defines.h similarity index 100% rename from xform/strata_defines.h rename to meds2pdb/strata_defines.h diff --git a/tools/rida/SConscript b/rida/SConscript similarity index 100% rename from tools/rida/SConscript rename to rida/SConscript diff --git a/tools/rida/SConstruct b/rida/SConstruct similarity index 100% rename from tools/rida/SConstruct rename to rida/SConstruct diff --git a/tools/rida/rida.cpp b/rida/rida.cpp similarity index 89% rename from tools/rida/rida.cpp rename to rida/rida.cpp index 08f9a9b1d9c191971f036be757a74168404c0593..91833dfb11270b5bd8f1a98f657d3fb5223054bf 100644 --- a/tools/rida/rida.cpp +++ b/rida/rida.cpp @@ -9,7 +9,6 @@ #include <string> #include "capstone/capstone.h" #include <fstream> -//#include <elfio/elfio.hpp> #include <elf.h> #include <functional> @@ -48,6 +47,7 @@ class CreateFunctions_t csh cshandle; ofstream outfile; execlass_t file_class; + MachineType_t machine_type; friend ostream& operator<<(ostream& os, const CreateFunctions_t::RangeSet_t& rs); public: CreateFunctions_t(const string &input_pgm, const string &output_annot, const bool p_verbose) @@ -55,7 +55,8 @@ class CreateFunctions_t verbose(p_verbose), exeio(input_pgm), cshandle(), - file_class(exeio.get_class()) + file_class(exeio.get_class()), + machine_type(exeio.getMachineType()) { outfile.open(output_annot.c_str(), ofstream::out); if(!outfile.is_open()) @@ -73,8 +74,19 @@ class CreateFunctions_t exit(1); } - const auto cs_mode= file_class==ELF64 ? CS_MODE_64 : CS_MODE_32 ; - if (cs_open(CS_ARCH_X86, cs_mode , &cshandle) != CS_ERR_OK) + const auto cs_mode= + machine_type==mtAarch64 ? CS_MODE_LITTLE_ENDIAN : + file_class==ELF64 ? CS_MODE_64 : + file_class==ELF32 ? CS_MODE_32 : + throw std::runtime_error("Cannot handle ELF class"); + + const auto my_cs_arch = + machine_type == mtX86_64 ? CS_ARCH_X86 : + machine_type == mtI386 ? CS_ARCH_X86 : + machine_type == mtAarch64 ? CS_ARCH_ARM64 : + throw std::runtime_error("Cannot handle architecture"); + + if (cs_open(my_cs_arch, cs_mode , &cshandle) != CS_ERR_OK) { cerr<<"Cannot initialize capstone"<<endl; exit(1); @@ -349,33 +361,65 @@ class CreateFunctions_t }; const auto pltSec=exeio.sections[pltSecName]; - assert(pltSec!=NULL); + if(pltSec==NULL) return; + const auto startAddr=pltSec->get_address(); const auto endAddr=pltSec->get_address()+pltSec->get_size(); if(verbose) cout<<"Found plt function range is "<<hex<<startAddr<<"-"<<endAddr<<endl; - auto pltRange_it=find_if(ALLOF(sccs), [&](const RangeSet_t& s) + const auto pltRange_it=find_if(ALLOF(sccs), [&](const RangeSet_t& s) { return find_if(ALLOF(s), [&](const Range_t& r) { return r.contains(startAddr); }) != s.end(); }); - assert(pltRange_it!=sccs.end()); - sccs.erase(pltRange_it); // invalidates all iterators + // erase startAddr if found. + if(pltRange_it!=sccs.end()) + sccs.erase(pltRange_it); // invalidates all iterators - const auto plt_skip=16; - const auto plt_header_size=12; - const auto plt_entry_size=16; - const auto plt_entry_size_first_part=6; - - addRange(startAddr,plt_header_size); auto dynsymEntryIndex=0; - for(auto i=startAddr+plt_skip; i<endAddr; i+=plt_skip) + + const auto handle_x86_plt=[&]() { - addRange(i,plt_entry_size_first_part); - addRange(i+6,plt_entry_size-plt_entry_size_first_part); - addName(i,dynsymEntryIndex++); - } + const auto plt_skip=16; + const auto plt_header_size=12; + const auto plt_entry_size=16; + const auto plt_entry_size_first_part=6; + + addRange(startAddr,plt_header_size); + for(auto i=startAddr+plt_skip; i<endAddr; i+=plt_skip) + { + addRange(i,plt_entry_size_first_part); + addRange(i+6,plt_entry_size-plt_entry_size_first_part); + addName(i,dynsymEntryIndex++); + } + }; + const auto handle_arm_plt=[&]() + { + const auto plt_entry_size=16; + const auto plt_header_size=8*4; + + addRange(startAddr,plt_header_size); + for(auto i=startAddr+plt_header_size; i<endAddr; i+=plt_entry_size) + { + addRange(i,plt_entry_size); + addName(i,dynsymEntryIndex++); + } + }; + + switch(machine_type) + { + case mtX86_64: + case mtI386: + handle_x86_plt(); + break; + case mtAarch64: + handle_arm_plt(); + break; + default: + assert(0); + + }; cout<<"#ATTRIBUTE plt_entries="<<dec<<dynsymEntryIndex<<endl; diff --git a/tools/thanos/SConscript b/thanos/SConscript similarity index 60% rename from tools/thanos/SConscript rename to thanos/SConscript index 32e69a3b73e7aa730dec4997eb6fa438c3e8603c..ed7ad18ccbdec2248fb96d7f5fcef85375cac017 100644 --- a/tools/thanos/SConscript +++ b/thanos/SConscript @@ -7,11 +7,8 @@ myenv=env.Clone() myenv.Replace(SECURITY_TRANSFORMS_HOME=os.environ['SECURITY_TRANSFORMS_HOME']) cpppath=''' - $SECURITY_TRANSFORMS_HOME/include - $SECURITY_TRANSFORMS_HOME/libIRDB/include - $SECURITY_TRANSFORMS_HOME/libMEDSannotation/include - $SECURITY_TRANSFORMS_HOME/libtransform/include - $SECURITY_TRANSFORMS_HOME/libEXEIO/include + $IRDB_SDK/include + $SECURITY_TRANSFORMS_HOME/libIRDB-core/include ''' @@ -22,7 +19,7 @@ myenv.Append(CXXFLAGS = " -std=c++11 -Wall ") pgm="thanos.exe" LIBPATH="$SECURITY_TRANSFORMS_HOME/lib" -LIBS=Split( env.subst('$BASE_IRDB_LIBS')+ " IRDB-cfg IRDB-util IRDB-core transform MEDSannotation pqxx pq dl") +LIBS=Split( env.subst('$BASE_IRDB_LIBS')+ " irdb-transform dl") myenv=myenv.Clone(CPPPATH=Split(cpppath)) pgm=myenv.Program(pgm, files, LIBPATH=LIBPATH, LIBS=LIBS) install=myenv.Install("$SECURITY_TRANSFORMS_HOME/plugins_install", pgm) diff --git a/tools/thanos/SConstruct b/thanos/SConstruct similarity index 100% rename from tools/thanos/SConstruct rename to thanos/SConstruct diff --git a/tools/thanos/thanos.cpp b/thanos/thanos.cpp similarity index 97% rename from tools/thanos/thanos.cpp rename to thanos/thanos.cpp index a5523b239d9bc8acb235532b6747c45ac9e095d3..e336c3307ff9e4ab7a1e3387c74943f9c3fea7fe 100644 --- a/tools/thanos/thanos.cpp +++ b/thanos/thanos.cpp @@ -1,3 +1,4 @@ +#include <irdb-core> #include <libIRDB-core.hpp> #include <dlfcn.h> #include <vector> @@ -14,8 +15,7 @@ using namespace std; -using namespace libIRDB; -using namespace Transform_SDK; +using namespace IRDB_SDK; #define ALLOF(a) begin(a),end(a) @@ -67,7 +67,7 @@ class ThanosPlugin_t static const unique_ptr<IRDBObjects_t> shared_objects; }; // initialize private static data member -const unique_ptr<IRDBObjects_t> ThanosPlugin_t::shared_objects(new IRDBObjects_t()); +const unique_ptr<IRDBObjects_t> ThanosPlugin_t::shared_objects(new libIRDB::IRDBObjects_t()); using PluginList_t = vector<unique_ptr<ThanosPlugin_t>>; PluginList_t getPlugins(const int argc, char const *const argv[]); @@ -240,11 +240,11 @@ int ThanosPlugin_t::runPlugin() return -1; } - const void *const sym = dlsym(dlhdl, "GetTransformStep"); + const void *const sym = dlsym(dlhdl, "getTransformStep"); if(sym == NULL) { const auto err=dlerror(); - *thanos_log<<"Cannot find GetTransformStep in "<<step_name<<": "<<err<<endl; + *thanos_log<<"Cannot find getTransformStep in "<<step_name<<": "<<err<<endl; return -1; } @@ -351,7 +351,7 @@ int ThanosPlugin_t::executeStep(TransformStep_t& the_step, const bool are_debugg else { // commit changes (in case this step fails) and reset interface - pqxx_interface->Commit(); + pqxx_interface->commit(); pqxx_interface = shared_objects->resetDBInterface(); } } @@ -392,7 +392,7 @@ int ThanosPlugin_t::executeStep(TransformStep_t& the_step, const bool are_debugg else if(are_debugging) { // commit changes (in case next step fails) and reset interface - pqxx_interface->Commit(); + pqxx_interface->commit(); pqxx_interface = shared_objects->resetDBInterface(); } } @@ -407,7 +407,7 @@ int ThanosPlugin_t::executeStep(TransformStep_t& the_step, const bool are_debugg else { // commit changes (in case next step fails) and reset interface - pqxx_interface->Commit(); + pqxx_interface->commit(); pqxx_interface = shared_objects->resetDBInterface(); } } @@ -427,7 +427,7 @@ int ThanosPlugin_t::saveChanges() else { // commit changes and reset interface - pqxx_interface->Commit(); + pqxx_interface->commit(); pqxx_interface = shared_objects->resetDBInterface(); return 0; } diff --git a/tools/SConscript b/tools/SConscript index a83cce77deeaf23e7148b274442ab2013ad11a4a..bfaf22cb663796d08a40b295fd31525d2965b6c0 100644 --- a/tools/SConscript +++ b/tools/SConscript @@ -5,20 +5,15 @@ Import('env') tools=[] dirs=''' + selective_cfi + ''' + +nobuild_dirs=''' cover fix_rets - meds2pdb safefr - selective_cfi spasm - dump_map - dump_insns hook_start - rida - thanos - ''' - -nobuild_dirs=''' cookbook simple_cdi ret_shadow_stack diff --git a/tools/safefn/fill_in_safefn.cpp b/tools/safefn/fill_in_safefn.cpp index ef6b7008207567d5a10a8eccbde0955fb0e0bca9..a2d6f66c47907aae124df8d77257d239f3f97d2a 100644 --- a/tools/safefn/fill_in_safefn.cpp +++ b/tools/safefn/fill_in_safefn.cpp @@ -28,8 +28,6 @@ #include <assert.h> #include <libgen.h> -#include "targ-config.h" - #include "MEDS_AnnotationParser.hpp" #include "MEDS_SafeFuncAnnotation.hpp" diff --git a/tools/safefr/fill_in_safefr.cpp b/tools/safefr/fill_in_safefr.cpp index 9ba1b5674d49e7e5b23b063ad78cab46744a1c9b..ea4a5afd15bf6166830868bd291caffc3a30fb5b 100644 --- a/tools/safefr/fill_in_safefr.cpp +++ b/tools/safefr/fill_in_safefr.cpp @@ -28,8 +28,6 @@ #include <assert.h> #include <libgen.h> -#include "targ-config.h" - #include "MEDS_AnnotationParser.hpp" #include "MEDS_FRSafeAnnotation.hpp" diff --git a/tools/selective_cfi/SConscript b/tools/selective_cfi/SConscript index e27170815e742a87bf0e7991180b0454513eaf44..e31c252dba16b2503f78dad564fe638ac33ff522 100644 --- a/tools/selective_cfi/SConscript +++ b/tools/selective_cfi/SConscript @@ -7,6 +7,7 @@ myenv=env.Clone() myenv.Replace(SECURITY_TRANSFORMS_HOME=os.environ['SECURITY_TRANSFORMS_HOME']) cpppath=''' + $IRDB_SDK/include $SECURITY_TRANSFORMS_HOME/include $SECURITY_TRANSFORMS_HOME/libIRDB/include $SECURITY_TRANSFORMS_HOME/libMEDSannotation/include @@ -22,16 +23,17 @@ myenv.Append(CXXFLAGS = " -std=c++11 -Wall ") pgm="selective_cfi.exe" LIBPATH="$SECURITY_TRANSFORMS_HOME/lib" -LIBS=Split( env.subst('$BASE_IRDB_LIBS')+ " IRDB-cfg IRDB-util IRDB-core transform MEDSannotation pqxx pq") +LIBS=Split( env.subst('$BASE_IRDB_LIBS')+ " irdb-cfg irdb-util irdb-core irdb-transform MEDSannotation ") myenv=myenv.Clone(CPPPATH=Split(cpppath)) pgm=myenv.Program(pgm, files, LIBPATH=LIBPATH, LIBS=LIBS) install=myenv.Install("$SECURITY_TRANSFORMS_HOME/plugins_install/", pgm) Default(install) +ret=[]+install #lib32=SConscript("zest_cfi_runtime/SConscript", variant_dir="build32") -zestcfi_lib=SConscript("zest_cfi_runtime/SConscript") # , variant_dir="build64") - -ret=[]+install+zestcfi_lib +if 'ZEST_RUNTIME' in os.environ: + zestcfi_lib=SConscript("zest_cfi_runtime/SConscript") # , variant_dir="build64") + ret=ret+zestcfi_lib Return('ret') diff --git a/tools/selective_cfi/color_map.cpp b/tools/selective_cfi/color_map.cpp index 9a050f4bd6e1d3d023b26e27c556035a1294cfc3..587ea203500c2271da0ddb0745b060df6d174ef0 100644 --- a/tools/selective_cfi/color_map.cpp +++ b/tools/selective_cfi/color_map.cpp @@ -2,7 +2,7 @@ #include "color_map.hpp" using namespace std; -using namespace libIRDB; +using namespace IRDB_SDK; bool ColoredInstructionNonces_t::create() @@ -10,7 +10,7 @@ bool ColoredInstructionNonces_t::create() UniqueICFSSet_t unique_icfs; assert(firp); - const ICFSSet_t& all_icfs=firp->GetAllICFS(); + const ICFSSet_t& all_icfs=firp->getAllICFS(); for(ICFSSet_t::iterator it=all_icfs.begin(); it!=all_icfs.end(); ++it) { ICFS_t* p=*it; @@ -19,9 +19,10 @@ bool ColoredInstructionNonces_t::create() } ColoredSlotValue_t v; - for(UniqueICFSSet_t::iterator it=unique_icfs.begin(); it!=unique_icfs.end(); ++it) + for(auto the_icfs : unique_icfs) { - const ICFS_t& the_icfs=*it; + // const ICFS_t& the_icfs=*it; + // const auto the_icfs=*it; for(auto slot_no=0U; /* loop until break */ ; slot_no++) { @@ -39,9 +40,8 @@ bool ColoredInstructionNonces_t::create() } // check if any of the targets for this branch already have a slot filled. - for(ICFS_t::iterator it2=the_icfs.begin(); it2!=the_icfs.end(); ++it2) + for(auto target : the_icfs) { - Instruction_t* target=*it2; if(color_assignments[target][slot_no].IsValid()) goto next_slot; } @@ -56,7 +56,7 @@ bool ColoredInstructionNonces_t::create() Instruction_t* target=*it2; color_assignments[target][slot_no]=v; cout<<"Setting slot[-"<<hex<<v.GetPosition()<<"]=color["<<hex<<v.GetNonceValue()<<dec<<"]" - << " for "<<hex<<target->GetBaseID()<<":"<<target->getDisassembly() + << " for "<<hex<<target->getBaseID()<<":"<<target->getDisassembly() << endl; } @@ -74,16 +74,15 @@ bool ColoredInstructionNonces_t::create() #if 1 /* debug code */ UniqueICFSSet_t used_icfs; - for(InstructionSet_t::iterator it=firp->GetInstructions().begin(); it!=firp->GetInstructions().end(); ++it) + for(auto insn : firp->getInstructions()) { - Instruction_t* insn=*it; - if(insn->GetIBTargets()) + if(insn->getIBTargets()) { v=GetColorOfIB(insn); cout<<"IB assigned " <<"slot[-"<<v.GetPosition()<<"]=color["<<hex<<v.GetNonceValue()<<dec<<"]" - << " for "<<insn->GetBaseID()<<":"<<insn->getDisassembly() << endl; + << " for "<<insn->getBaseID()<<":"<<insn->getDisassembly() << endl; - used_icfs.insert(*insn->GetIBTargets()); + used_icfs.insert(*insn->getIBTargets()); } } diff --git a/tools/selective_cfi/color_map.hpp b/tools/selective_cfi/color_map.hpp index 2ffb0992de1f55ef5f8517fefeffe522a3b54361..2f78675d33dd1e858b8e9ae4ea563f55353e54bd 100644 --- a/tools/selective_cfi/color_map.hpp +++ b/tools/selective_cfi/color_map.hpp @@ -21,7 +21,7 @@ #ifndef color_map_hpp #define color_map_hpp -#include <libIRDB-core.hpp> +#include <irdb-core> #include <stdint.h> @@ -73,16 +73,16 @@ typedef std::map<int,ColoredSlotValue_t> ColoredSlotValues_t; class ColoredInstructionNonces_t { public: - ColoredInstructionNonces_t(libIRDB::FileIR_t *the_firp) + ColoredInstructionNonces_t(IRDB_SDK::FileIR_t *the_firp) : firp(the_firp), slot_size(1), slot_values(255) { } - ColoredInstructionNonces_t(libIRDB::FileIR_t *the_firp, int the_slot_size) + ColoredInstructionNonces_t(IRDB_SDK::FileIR_t *the_firp, int the_slot_size) : firp(the_firp), slot_size(the_slot_size), slot_values(MaxNonceValForSlotSize(the_slot_size)) { } - ColoredSlotValues_t GetColorsOfIBT (libIRDB::Instruction_t* i) + ColoredSlotValues_t GetColorsOfIBT (IRDB_SDK::Instruction_t* i) { return color_assignments[i]; } - ColoredSlotValue_t GetColorOfIB (libIRDB::Instruction_t* i) - { assert(i->GetIBTargets()); return slot_assignments[*i->GetIBTargets()]; } + ColoredSlotValue_t GetColorOfIB (IRDB_SDK::Instruction_t* i) + { assert(i->getIBTargets()); return slot_assignments[*i->getIBTargets()]; } int NumberSlotsUsed() { return slots_used.size(); } @@ -94,7 +94,7 @@ class ColoredInstructionNonces_t bool create(); // the IR we're working on. - libIRDB::FileIR_t* firp; + IRDB_SDK::FileIR_t* firp; // used to describe how big a nonce slot is. for now, 1 byte. const int slot_size; @@ -106,11 +106,11 @@ class ColoredInstructionNonces_t // information for each IBT. // a map for each instruction, which contains a ColorSlotValue_t for each slot used. // instruction -> ( int-> slot_value ) - std::map<libIRDB::Instruction_t*, ColoredSlotValues_t> color_assignments; + std::map<IRDB_SDK::Instruction_t*, ColoredSlotValues_t> color_assignments; // information for each IB (as indexed by the IBs ICFS). // the slot that each IB uses. ICFS_t -> slot_value - std::map<libIRDB::ICFS_t, ColoredSlotValue_t> slot_assignments; + std::map<IRDB_SDK::InstructionSet_t, ColoredSlotValue_t> slot_assignments; NonceValueType_t MaxNonceValForSlotSize(int slot_size) { @@ -128,12 +128,12 @@ class ColoredInstructionNonces_t // a simple way to sort ICFS. class UniqueICFSSetSorter_t; -typedef std::set<libIRDB::ICFS_t, UniqueICFSSetSorter_t> UniqueICFSSet_t; +typedef std::set<IRDB_SDK::InstructionSet_t, UniqueICFSSetSorter_t> UniqueICFSSet_t; class UniqueICFSSetSorter_t { public: - bool operator() (const libIRDB::ICFS_t& a, const libIRDB::ICFS_t& b) const + bool operator() (const IRDB_SDK::InstructionSet_t& a, const IRDB_SDK::InstructionSet_t& b) const { if(a.size() == b.size()) return a<b; return a.size() < b.size() ; diff --git a/tools/selective_cfi/scfi_driver.cpp b/tools/selective_cfi/scfi_driver.cpp index 0bd71b6d0e37b7f2434c1cec006d175564909b37..2e5d796074e9d9b32b041692cae3ac01d56b2c09 100644 --- a/tools/selective_cfi/scfi_driver.cpp +++ b/tools/selective_cfi/scfi_driver.cpp @@ -20,13 +20,13 @@ #include <stdlib.h> #include <fstream> -#include <libIRDB-core.hpp> +#include <irdb-core> #include <libgen.h> #include "scfi_instr.hpp" using namespace std; -using namespace libIRDB; +using namespace IRDB_SDK; #define BINARY_NAME "a.ncexe" @@ -206,59 +206,53 @@ int main(int argc, char **argv) string programName(argv[0]); int variantID = atoi(argv[1]); - VariantID_t *pidp=NULL; - /* setup the interface to the sql server */ - pqxxDB_t pqxx_interface; - BaseObj_t::SetInterface(&pqxx_interface); + auto pqxx_interface=pqxxDB_t::factory(); + BaseObj_t::setInterface(pqxx_interface.get()); - pidp=new VariantID_t(variantID); - assert(pidp->IsRegistered()==true); + auto pidp=VariantID_t::factory(variantID); + assert(pidp->isRegistered()==true); cout<<"selective_cfi.exe started\n"; bool one_success = false; bool seen_failures = false; - for(set<File_t*>::iterator it=pidp->GetFiles().begin(); - it!=pidp->GetFiles().end(); - ++it) + for(auto this_file : pidp->getFiles()) { - File_t* this_file = *it; - FileIR_t *firp = new FileIR_t(*pidp, this_file); + auto firp = FileIR_t::factory(pidp.get(), this_file); - cout<<"Transforming "<<this_file->GetURL()<<endl; + cout<<"Transforming "<<this_file->getURL()<<endl; assert(firp && pidp); try { - SCFI_Instrument scfii(firp, nonce_size, exe_nonce_size, do_coloring, do_color_exe_nonces, do_common_slow_path, do_jumps, do_calls, do_rets, do_safefn, do_multimodule, do_exe_nonce_for_call); + SCFI_Instrument scfii(firp.get(), nonce_size, exe_nonce_size, do_coloring, do_color_exe_nonces, do_common_slow_path, do_jumps, do_calls, do_rets, do_safefn, do_multimodule, do_exe_nonce_for_call); int success=scfii.execute(); if (success) { - cout<<"Writing changes for "<<this_file->GetURL()<<endl; + cout<<"Writing changes for "<<this_file->getURL()<<endl; one_success = true; - firp->WriteToDB(); - delete firp; + firp->writeToDB(); } else { seen_failures = true; - cout<<"Skipping (no changes) "<<this_file->GetURL()<<endl; + cout<<"Skipping (no changes) "<<this_file->getURL()<<endl; } } catch (DatabaseError_t pnide) { seen_failures = true; - cerr << programName << ": Unexpected database error: " << pnide << "file url: " << this_file->GetURL() << endl; + cerr << programName << ": Unexpected database error: " << pnide << "file url: " << this_file->getURL() << endl; } catch (...) { seen_failures = true; - cerr << programName << ": Unexpected error file url: " << this_file->GetURL() << endl; + cerr << programName << ": Unexpected error file url: " << this_file->getURL() << endl; } } // end file iterator @@ -266,7 +260,7 @@ int main(int argc, char **argv) if (one_success) { cout<<"Commiting changes...\n"; - pqxx_interface.Commit(); + pqxx_interface->commit(); } if(seen_failures) diff --git a/tools/selective_cfi/scfi_instr.cpp b/tools/selective_cfi/scfi_instr.cpp index 1d968ae4c74b251a4b4b8cf1054964d342fe884e..25dd3f27e29a118c3c7099dba6d8c6d658ea27d0 100644 --- a/tools/selective_cfi/scfi_instr.cpp +++ b/tools/selective_cfi/scfi_instr.cpp @@ -19,24 +19,18 @@ */ -#include "utils.hpp" +#include <algorithm> #include "scfi_instr.hpp" -#include "Rewrite_Utility.hpp" #include "color_map.hpp" #include <stdlib.h> #include <memory> #include <math.h> #include <exeio.h> #include <elf.h> -//#include "elfio/elfio.hpp" -//#include "elfio/elfio_dump.hpp" - - using namespace std; -using namespace libIRDB; -using namespace IRDBUtility; +using namespace IRDB_SDK; string getRetDataBits() { @@ -51,10 +45,10 @@ string getRetDataBits() Relocation_t* SCFI_Instrument::FindRelocation(Instruction_t* insn, string type) { RelocationSet_t::iterator rit; - for( rit=insn->GetRelocations().begin(); rit!=insn->GetRelocations().end(); ++rit) + for( rit=insn->getRelocations().begin(); rit!=insn->getRelocations().end(); ++rit) { Relocation_t& reloc=*(*rit); - if(reloc.GetType()==type) + if(reloc.getType()==type) { return &reloc; } @@ -64,22 +58,22 @@ Relocation_t* SCFI_Instrument::FindRelocation(Instruction_t* insn, string type) bool SCFI_Instrument::isSafeFunction(Instruction_t* insn) { - return (insn && insn->GetFunction() && insn->GetFunction()->IsSafe()); + return (insn && insn->getFunction() && insn->getFunction()->isSafe()); } bool SCFI_Instrument::isCallToSafeFunction(Instruction_t* insn) { - if (insn && insn->GetTarget() && insn->GetTarget()->GetFunction()) + if (insn && insn->getTarget() && insn->getTarget()->getFunction()) { if(getenv("SCFI_VERBOSE")!=NULL) { - if (insn->GetTarget()->GetFunction()->IsSafe()) + if (insn->getTarget()->getFunction()->isSafe()) { - cout << "Function " << insn->GetTarget()->GetFunction()->GetName() << " is deemed safe" << endl; + cout << "Function " << insn->getTarget()->getFunction()->getName() << " is deemed safe" << endl; } } - return insn->GetTarget()->GetFunction()->IsSafe(); + return insn->getTarget()->getFunction()->isSafe(); } return false; @@ -87,9 +81,12 @@ bool SCFI_Instrument::isCallToSafeFunction(Instruction_t* insn) Relocation_t* SCFI_Instrument::create_reloc(Instruction_t* insn) { - Relocation_t* reloc=new Relocation_t; - insn->GetRelocations().insert(reloc); - firp->GetRelocations().insert(reloc); + /* + * Relocation_t* reloc=new Relocation_t; + insn->getRelocations().insert(reloc); + firp->getRelocations().insert(reloc); + */ + auto reloc=firp->addNewRelocation(insn,0,"error-if-seen"); // will update offset and type in caller return reloc; } @@ -116,7 +113,7 @@ unsigned int SCFI_Instrument::GetExeNonceOffset(Instruction_t* insn) { if(exe_nonce_color_map) { - assert(insn->GetIBTargets()); + assert(insn->getIBTargets()); // We can't know the offset yet because this nonce may need to get // shoved into multiple exe nonces, so just return the position. cout << "EXE NONCE OFFSET IS: "<< exe_nonce_color_map->GetColorOfIB(insn).GetPosition() << endl; @@ -130,7 +127,7 @@ NonceValueType_t SCFI_Instrument::GetExeNonce(Instruction_t* insn) { if(exe_nonce_color_map) { - assert(insn->GetIBTargets()); + assert(insn->getIBTargets()); return exe_nonce_color_map->GetColorOfIB(insn).GetNonceValue(); } // Otherwise, all nonces are the same @@ -158,7 +155,7 @@ unsigned int SCFI_Instrument::GetNonceOffset(Instruction_t* insn) { if(color_map) { - assert(insn->GetIBTargets()); + assert(insn->getIBTargets()); return (color_map->GetColorOfIB(insn).GetPosition()+1) * GetNonceSize(insn); } return GetNonceSize(insn); @@ -170,7 +167,7 @@ NonceValueType_t SCFI_Instrument::GetNonce(Instruction_t* insn) /* for now, it's just f4 as the nonce */ if(color_map) { - assert(insn->GetIBTargets()); + assert(insn->getIBTargets()); return color_map->GetColorOfIB(insn).GetNonceValue(); } // Otherwise, all nonces are the same @@ -198,32 +195,28 @@ bool SCFI_Instrument::mark_targets() { int targets=0, ind_targets=0, exe_nonce_targets=0; // Make sure no unresolved instructions are in the insn set - firp->AssembleRegistry(); - firp->SetBaseIDS(); + firp->assembleRegistry(); + firp->setBaseIDS(); // create new preds (we've added instructions) - InstructionPredecessors_t newPreds; - newPreds.AddFile(firp); + auto newPredsp=InstructionPredecessors_t::factory(firp); + auto &newPreds=*newPredsp; // Make sure the new insns added in this loop are not processed in this loop // (ok since none of the them should receive nonces) - auto insn_set = firp->GetInstructions(); - for(InstructionSet_t::iterator it=insn_set.begin(); - it!=insn_set.end(); - ++it) + auto insn_set = firp->getInstructions(); + for(auto insn : insn_set) { targets++; - Instruction_t* insn=*it; - if(insn->GetIndirectBranchTargetAddress()) + if(insn->getIndirectBranchTargetAddress()) { // make sure there are no fallthroughs to nonces. - for(InstructionSet_t::iterator pred_it=newPreds[insn].begin(); pred_it!=newPreds[insn].end(); ++pred_it) + for(auto the_pred : newPreds[insn]) { - Instruction_t* the_pred=*pred_it; - if(the_pred->GetFallthrough()==insn) + if(the_pred->getFallthrough()==insn) { - Instruction_t* jmp=addNewAssembly(firp,NULL, "jmp 0x0"); - the_pred->SetFallthrough(jmp); - jmp->SetTarget(insn); + Instruction_t* jmp=addNewAssembly("jmp 0x0"); + the_pred->setFallthrough(jmp); + jmp->setTarget(insn); } } @@ -249,9 +242,9 @@ bool SCFI_Instrument::mark_targets() type=string("cfi_nonce=(pos=") + to_string(position) + ",nv=" + to_string(noncevalue) + ",sz="+ to_string(size)+ ")"; Relocation_t* reloc=create_reloc(insn); - reloc->SetOffset(-position*size); - reloc->SetType(type); - cout<<"Created reloc='"+type+"' for "<<std::hex<<insn->GetBaseID()<<":"<<insn->getDisassembly()<<endl; + reloc->setOffset(-position*size); + reloc->setType(type); + cout<<"Created reloc='"+type+"' for "<<std::hex<<insn->getBaseID()<<":"<<insn->getDisassembly()<<endl; } } else @@ -259,26 +252,26 @@ bool SCFI_Instrument::mark_targets() type=string("cfi_nonce=(pos=") + to_string(-((int) GetNonceOffset(insn))) + ",nv=" + to_string(GetNonce(insn)) + ",sz="+ to_string(GetNonceSize(insn))+ ")"; Relocation_t* reloc=create_reloc(insn); - reloc->SetOffset(-((int) GetNonceOffset(insn))); - reloc->SetType(type); - cout<<"Created reloc='"+type+"' for "<<std::hex<<insn->GetBaseID()<<":"<<insn->getDisassembly()<<endl; + reloc->setOffset(-((int) GetNonceOffset(insn))); + reloc->setType(type); + cout<<"Created reloc='"+type+"' for "<<std::hex<<insn->getBaseID()<<":"<<insn->getDisassembly()<<endl; } } - if(do_exe_nonce_for_call && DecodedInstruction_t(insn).isCall()) + if(do_exe_nonce_for_call && DecodedInstruction_t::factory(insn)->isCall()) { ++exe_nonce_targets; if(do_color_exe_nonces) { // The colors we want are not on the call, but on its return target. - ColoredSlotValues_t v=exe_nonce_color_map->GetColorsOfIBT(insn->GetFallthrough()); + ColoredSlotValues_t v=exe_nonce_color_map->GetColorsOfIBT(insn->getFallthrough()); // The return target gets a regular nonce as well, so there may be an inserted jmp // in the way of the original IBT that has our colors. if(v.size() == 0) { - v=exe_nonce_color_map->GetColorsOfIBT(insn->GetFallthrough()->GetTarget()); + v=exe_nonce_color_map->GetColorsOfIBT(insn->getFallthrough()->getTarget()); } int nonceSz=GetExeNonceSize(insn); //Multiple sizes not yet supported @@ -345,9 +338,9 @@ void SCFI_Instrument::CreateExeNonceReloc(Instruction_t* insn, NonceValueType_t string type=string("cfi_exe_nonce=(pos=") + to_string(bytePos) + ",nv=" + to_string(nonceVal) + ",sz="+ to_string(nonceSz)+ ")"; Relocation_t* reloc=create_reloc(insn); - reloc->SetOffset(bytePos); - reloc->SetType(type); - cout<<"Created reloc='"+type+"' for "<<std::hex<<insn->GetBaseID()<<":"<<insn->getDisassembly()<<endl; + reloc->setOffset(bytePos); + reloc->setType(type); + cout<<"Created reloc='"+type+"' for "<<std::hex<<insn->getBaseID()<<":"<<insn->getDisassembly()<<endl; } @@ -448,19 +441,14 @@ void SCFI_Instrument::PlaceExeNonceReloc(Instruction_t* insn, NonceValueType_t n */ static string change_to_push(Instruction_t *insn) { - string newbits=insn->GetDataBits(); + string newbits=insn->getDataBits(); - //DISASM d; - //Disassemble(insn,d); - const auto d=DecodedInstruction_t(insn); + const auto dp=DecodedInstruction_t::factory(insn); + const auto &d=*dp; int opcode_offset=0; - - // FIXME: assumes REX is only prefix on jmp insn. - // does not assume rex exists. - //if(d.Prefix.REX.state == InUsePrefix) - opcode_offset=d.getPrefixCount(); + opcode_offset=d.getPrefixCount(); unsigned char modregrm = (newbits[1+opcode_offset]); modregrm &= 0xc7; @@ -472,51 +460,35 @@ static string change_to_push(Instruction_t *insn) } -void mov_reloc(Instruction_t* from, Instruction_t* to, string type ) +void SCFI_Instrument::mov_reloc(Instruction_t* from, Instruction_t* to, string type ) { - for( - /* start */ - RelocationSet_t::iterator it=from->GetRelocations().begin(); - - /* continue */ - it!=from->GetRelocations().end(); - - /* increment */ - /* empty */ - ) + // need to copy because moveReloc will destroy the iterator used for copying + auto copy_of_relocs=from->getRelocations(); + for(auto reloc : copy_of_relocs) { - Relocation_t* reloc=*it; - if(reloc->GetType()==type) + if(reloc->getType()==type) { - to->GetRelocations().insert(reloc); - + firp->moveRelocation(reloc,from,to); // odd standards-conforming way to delete object while iterating. - from->GetRelocations().erase(it++); - } - else - { - it++; + //to->getRelocations().insert(reloc); + //from->getRelocations().erase(it++); } } } -static void move_relocs(Instruction_t* from, Instruction_t* to) +void SCFI_Instrument::move_relocs(Instruction_t* from, Instruction_t* to) { - for(auto it=from->GetRelocations().begin(); it!=from->GetRelocations().end(); ) + auto copy_of_relocs=from->getRelocations(); + for(auto reloc : copy_of_relocs) { - auto current=it++; - Relocation_t* reloc=*current; - if(reloc->GetType()=="fix_call_fallthrough") - { - // don't move it. - } - else + if(reloc->getType()!="fix_call_fallthrough") { - to->GetRelocations().insert(reloc); - from->GetRelocations().erase(current); + firp->moveRelocation(reloc,from,to); + // to->getRelocations().insert(reloc); + // from->getRelocations().erase(current); } } } @@ -527,10 +499,10 @@ void SCFI_Instrument::AddJumpCFI(Instruction_t* insn) string pushbits=change_to_push(insn); cout<<"Converting ' "<<insn->getDisassembly()<<"' to '"; - Instruction_t* after=insertDataBitsBefore(firp,insn,pushbits); + Instruction_t* after=insertDataBitsBefore(insn,pushbits); move_relocs(after,insn); - after->SetDataBits(getRetDataBits()); + after->setDataBits(getRetDataBits()); cout <<insn->getDisassembly()<<" + ret' "<<endl ; // move any pc-rel relocation bits to the push, which will access memory now @@ -555,7 +527,7 @@ void SCFI_Instrument::AddJumpCFI(Instruction_t* insn) void SCFI_Instrument::AddCallCFIWithExeNonce(Instruction_t* insn) { string reg="ecx"; // 32-bit reg - if(firp->GetArchitectureBitWidth()==64) + if(firp->getArchitectureBitWidth()==64) reg="r11"; // 64-bit reg. Instruction_t* call=NULL, *stub=NULL; @@ -573,17 +545,17 @@ void SCFI_Instrument::AddCallCFIWithExeNonce(Instruction_t* insn) // insert the pop/checking code. string pushbits=change_to_push(insn); - call=insertDataBitsBefore(firp, insn, pushbits); - insertAssemblyAfter(firp,insn,string("pop ")+reg); + call=insertDataBitsBefore(insn, pushbits); + insertAssemblyAfter(insn,string("pop ")+reg); // keep any relocs on the push instruction, as those may need updating. - insn->GetRelocations()=call->GetRelocations(); - call->GetRelocations().clear(); + insn->setRelocations(call->getRelocations()); + call->setRelocations({}); // Jump to non-exe nonce check code - stub = addNewAssembly(firp, NULL, string("push ")+reg); - Instruction_t* ret = insertDataBitsAfter(firp, stub, getRetDataBits()); - ret->SetIBTargets(call->GetIBTargets()); + stub = addNewAssembly(string("push ")+reg); + Instruction_t* ret = insertDataBitsAfter(stub, getRetDataBits()); + ret->setIBTargets(call->getIBTargets()); if(do_exe_nonce_for_call) { @@ -598,13 +570,13 @@ void SCFI_Instrument::AddCallCFIWithExeNonce(Instruction_t* insn) } // convert the indirct call to a direct call to the stub. - string call_bits=call->GetDataBits(); + string call_bits=call->getDataBits(); call_bits.resize(5); call_bits[0]=0xe8; - call->SetTarget(stub); - call->SetDataBits(call_bits); - call->SetComment("Direct call to cfi stub"); - call->SetIBTargets(NULL); // lose info about branch targets. + call->setTarget(stub); + call->setDataBits(call_bits); + call->setComment("Direct call to cfi stub"); + call->setIBTargets(NULL); // lose info about branch targets. return; } @@ -619,8 +591,8 @@ void SCFI_Instrument::AddExecutableNonce(Instruction_t* insn) Instruction_t* SCFI_Instrument::GetExeNonceSlowPath(Instruction_t* insn) { // Jump to non-exe nonce check code - Instruction_t* ret = addNewDatabits(firp, NULL, getRetDataBits()); - ret->SetIBTargets(insn->GetIBTargets()); + Instruction_t* ret = addNewDataBits(getRetDataBits()); + ret->setIBTargets(insn->getIBTargets()); AddReturnCFI(ret); return ret; } @@ -641,7 +613,7 @@ void SCFI_Instrument::InsertExeNonceComparisons(Instruction_t* insn, noncePartSz = nonceSz; string reg="ecx"; // 32-bit reg - if(firp->GetArchitectureBitWidth()==64) + if(firp->getArchitectureBitWidth()==64) reg="r11"; // 64-bit reg. string decoration=""; @@ -674,10 +646,10 @@ void SCFI_Instrument::InsertExeNonceComparisons(Instruction_t* insn, { NoncePart_t theNoncePart = *it; cout << "ADDING CMP FOR BYTE POS: " << theNoncePart.bytePos << "FOR NONCE WITH POSITION: " << noncePos << "AND SIZE: " << nonceSz << endl; - tmp=insertAssemblyAfter(firp,tmp,string("cmp ")+decoration+ + tmp=insertAssemblyAfter(tmp,string("cmp ")+decoration+ " ["+reg+"+"+to_string(theNoncePart.bytePos)+"], "+to_string(theNoncePart.val)); - jne=tmp=insertAssemblyAfter(firp,tmp,"jne 0"); - jne->SetTarget(exeNonceSlowPath); + jne=tmp=insertAssemblyAfter(tmp,"jne 0"); + jne->setTarget(exeNonceSlowPath); } } @@ -689,29 +661,28 @@ void SCFI_Instrument::AddReturnCFIForExeNonce(Instruction_t* insn, ColoredSlotVa return; string reg="ecx"; // 32-bit reg - if(firp->GetArchitectureBitWidth()==64) + if(firp->getArchitectureBitWidth()==64) reg="r11"; // 64-bit reg. string rspreg="esp"; // 32-bit reg - if(firp->GetArchitectureBitWidth()==64) + if(firp->getArchitectureBitWidth()==64) rspreg="rsp"; // 64-bit reg. string worddec="dword"; // 32-bit reg - if(firp->GetArchitectureBitWidth()==64) + if(firp->getArchitectureBitWidth()==64) worddec="qword"; // 64-bit reg. - //DISASM d; - //Disassemble(insn,d); - const auto d=DecodedInstruction_t(insn); + const auto dp=DecodedInstruction_t::factory(insn); + const auto &d=*dp; - if(d.hasOperand(0)) // d.Argument1.ArgType!=NO_ARGUMENT) + if(d.hasOperand(0)) { - unsigned int sp_adjust=d.getImmediate() /*d.Instruction.Immediat*/-firp->GetArchitectureBitWidth()/8; - cout<<"Found relatively rare ret_with_pop insn: "<<d.getDisassembly() /*CompleteInstr*/<<endl; + unsigned int sp_adjust=d.getImmediate() -firp->getArchitectureBitWidth()/8; + cout<<"Found relatively rare ret_with_pop insn: "<<d.getDisassembly() <<endl; char buf[30]; sprintf(buf, "pop %s [%s+%d]", worddec.c_str(), rspreg.c_str(), sp_adjust); - Instruction_t* newafter=insertAssemblyBefore(firp,insn,buf); + Instruction_t* newafter=insertAssemblyBefore(insn,buf); if(sp_adjust>0) { @@ -722,7 +693,7 @@ void SCFI_Instrument::AddReturnCFIForExeNonce(Instruction_t* insn, ColoredSlotVa insn=newafter; //Needed b/c AddReturnCFI may be called on this ret insn //But also clean up and change ret_with_pop to ret (as it should be now) to be safe - setInstructionAssembly(firp,insn, string("ret"), insn->GetFallthrough(), insn->GetTarget()); + setInstructionAssembly(insn, string("ret"), insn->getFallthrough(), insn->getTarget()); } //TODO: Handle uncommon slow path @@ -741,7 +712,7 @@ void SCFI_Instrument::AddReturnCFIForExeNonce(Instruction_t* insn, ColoredSlotVa // ret ; ignore race condition for now // insert the mov/checking code. - insertAssemblyBefore(firp,insn,string("mov ")+reg+string(", [")+rspreg+string("]")); + insertAssemblyBefore(insn,string("mov ")+reg+string(", [")+rspreg+string("]")); InsertExeNonceComparisons(insn, nonce, nonce_size, nonce_pos, exeNonceSlowPath); // leave the ret instruction (risk of successful race condition exploit << performance benefit) @@ -763,28 +734,26 @@ void SCFI_Instrument::AddReturnCFI(Instruction_t* insn, ColoredSlotValue_t *v) string reg="ecx"; // 32-bit reg - if(firp->GetArchitectureBitWidth()==64) + if(firp->getArchitectureBitWidth()==64) reg="r11"; // 64-bit reg. string rspreg="esp"; // 32-bit reg - if(firp->GetArchitectureBitWidth()==64) + if(firp->getArchitectureBitWidth()==64) rspreg="rsp"; // 64-bit reg. string worddec="dword"; // 32-bit reg - if(firp->GetArchitectureBitWidth()==64) + if(firp->getArchitectureBitWidth()==64) worddec="qword"; // 64-bit reg. - - //DISASM d; - //Disassemble(insn,d); - const auto d=DecodedInstruction_t(insn); + const auto dp=DecodedInstruction_t::factory(insn); + const auto &d=*dp; if(d.hasOperand(0)) // d.Argument1.ArgType!=NO_ARGUMENT) { - unsigned int sp_adjust=d.getImmediate() /* Instruction.Immediat*/-firp->GetArchitectureBitWidth()/8; + unsigned int sp_adjust=d.getImmediate() /* Instruction.Immediat*/-firp->getArchitectureBitWidth()/8; cout<<"Found relatively rare ret_with_pop insn: "<<d.getDisassembly()<<endl; char buf[30]; sprintf(buf, "pop %s [%s+%d]", worddec.c_str(), rspreg.c_str(), sp_adjust); - Instruction_t* newafter=insertAssemblyBefore(firp,insn,buf); + Instruction_t* newafter=insertAssemblyBefore(insn,buf); if(sp_adjust>0) { @@ -794,7 +763,7 @@ void SCFI_Instrument::AddReturnCFI(Instruction_t* insn, ColoredSlotValue_t *v) // rewrite the "old" isntruction, as that's what insertAssemblyBefore returns insn=newafter; //Clean up and change ret_with_pop to ret (as it should be now) to be safe - setInstructionAssembly(firp,insn, string("ret"), insn->GetFallthrough(), insn->GetTarget()); + setInstructionAssembly(insn, string("ret"), insn->getFallthrough(), insn->getTarget()); } int size=1; @@ -857,37 +826,37 @@ void SCFI_Instrument::AddReturnCFI(Instruction_t* insn, ColoredSlotValue_t *v) } // insert the pop/checking code. - insertAssemblyBefore(firp,insn,string("pop ")+reg); + insertAssemblyBefore(insn,string("pop ")+reg); if(nonce_size != 8) { - tmp=insertAssemblyAfter(firp,insn,string("cmp ")+decoration+ + tmp=insertAssemblyAfter(insn,string("cmp ")+decoration+ " ["+reg+"-"+to_string(nonce_offset)+"], "+to_string(nonce)); } else { - tmp=insertAssemblyAfter(firp,insn,string("cmp ")+decoration+ + tmp=insertAssemblyAfter(insn,string("cmp ")+decoration+ " ["+reg+"-"+to_string(nonce_offset)+"], "+to_string((uint32_t) nonce)); // upper 32 bits chopped off by cast - jne=tmp=insertAssemblyAfter(firp,tmp,"jne 0"); - tmp=insertAssemblyAfter(firp,tmp,string("cmp ")+decoration+ + jne=tmp=insertAssemblyAfter(tmp,"jne 0"); + tmp=insertAssemblyAfter(tmp,string("cmp ")+decoration+ " ["+reg+"-"+to_string(nonce_offset - 4)+"], "+to_string((uint32_t) (nonce >> 32))); // set the jne's target to itself, and create a reloc that zipr/strata will have to resolve. - jne->SetTarget(jne); // needed so spri/spasm/irdb don't freak out about missing target for new insn. + jne->setTarget(jne); // needed so spri/spasm/irdb don't freak out about missing target for new insn. Relocation_t* reloc=create_reloc(jne); - reloc->SetType(slow_cfi_path_reloc_string); - reloc->SetOffset(0); + reloc->setType(slow_cfi_path_reloc_string); + reloc->setOffset(0); cout<<"Setting slow path for: "<<slow_cfi_path_reloc_string<<endl; } - jne=tmp=insertAssemblyAfter(firp,tmp,"jne 0"); + jne=tmp=insertAssemblyAfter(tmp,"jne 0"); // convert the ret instruction to a jmp ecx - cout<<"Converting "<<hex<<tmp->GetFallthrough()->GetBaseID()<<":"<<tmp->GetFallthrough()->getDisassembly()<<"to jmp+reg"<<endl; - setInstructionAssembly(firp,tmp->GetFallthrough(), string("jmp ")+reg, NULL,NULL); + cout<<"Converting "<<hex<<tmp->getFallthrough()->getBaseID()<<":"<<tmp->getFallthrough()->getDisassembly()<<"to jmp+reg"<<endl; + setInstructionAssembly(tmp->getFallthrough(), string("jmp ")+reg, NULL,NULL); // set the jne's target to itself, and create a reloc that zipr/strata will have to resolve. - jne->SetTarget(jne); // needed so spri/spasm/irdb don't freak out about missing target for new insn. + jne->setTarget(jne); // needed so spri/spasm/irdb don't freak out about missing target for new insn. Relocation_t* reloc=create_reloc(jne); - reloc->SetType(slow_cfi_path_reloc_string); - reloc->SetOffset(0); + reloc->setType(slow_cfi_path_reloc_string); + reloc->setOffset(0); cout<<"Setting slow path for: "<<slow_cfi_path_reloc_string<<endl; return; @@ -914,13 +883,10 @@ static void display_histogram(std::ostream& out, std::string attr_label, std::ma bool SCFI_Instrument::is_plt_style_jmp(Instruction_t* insn) { - //DISASM d; - //Disassemble(insn,d); - const auto d=DecodedInstruction_t(insn); - if(d.getOperand(0).isMemory()) // (d.Argument1.ArgType&MEMORY_TYPE)==MEMORY_TYPE) + const auto d=DecodedInstruction_t::factory(insn); + if(d->getOperand(0)->isMemory()) { - //if(d.Argument1.Memory.BaseRegister == 0 && d.Argument1.Memory.IndexRegister == 0) - if(!d.getOperand(0).hasBaseRegister() && !d.getOperand(0).hasIndexRegister() ) + if(!d->getOperand(0)->hasBaseRegister() && !d->getOperand(0)->hasIndexRegister() ) return true; return false; } @@ -935,7 +901,7 @@ bool SCFI_Instrument::is_jmp_a_fixed_call(Instruction_t* insn) Instruction_t* pred=*(preds[insn].begin()); assert(pred); - if(pred->GetDataBits()[0]==0x68) + if(pred->getDataBits()[0]==0x68) return true; return false; } @@ -966,15 +932,9 @@ bool SCFI_Instrument::instrument_jumps() // for each instruction // But make sure the new insns added in this loop are not processed in this loop // (ok since none of the them should need to be protected) - auto insn_set = firp->GetInstructions(); - for(InstructionSet_t::iterator it=insn_set.begin(); - it!=insn_set.end(); - ++it) + auto insn_set = firp->getInstructions(); + for(auto insn : insn_set) { - Instruction_t* insn=*it; - //DISASM d; - //Disassemble(insn,d); - // we always have to protect the zestcfi dispatcher, that we just added. if(zestcfi_function_entry==insn) @@ -985,17 +945,18 @@ bool SCFI_Instrument::instrument_jumps() continue; } - if(insn->GetBaseID()==BaseObj_t::NOT_IN_DATABASE) + if(insn->getBaseID()==BaseObj_t::NOT_IN_DATABASE) continue; - const auto d=DecodedInstruction_t(insn); + const auto dp=DecodedInstruction_t::factory(insn); + const auto &d=*dp; - if (insn->GetFunction()) - cerr<<"Looking at: "<<insn->getDisassembly()<< " from func: " << insn->GetFunction()->GetName() << endl; + if (insn->getFunction()) + cerr<<"Looking at: "<<insn->getDisassembly()<< " from func: " << insn->getFunction()->getName() << endl; else cerr<<"Looking at: "<<insn->getDisassembly()<< " but no associated function" << endl; - if(d.isCall() /*string(d.Instruction.Mnemonic)==string("call ")*/ && (protect_safefn && !do_exe_nonce_for_call)) + if(d.isCall() && (protect_safefn && !do_exe_nonce_for_call)) { cerr<<"Fatal Error: Found call instruction!"<<endl; cerr<<"FIX_CALLS_FIX_ALL_CALLS=1 should be set in the environment, or"<<endl; @@ -1010,29 +971,25 @@ bool SCFI_Instrument::instrument_jumps() bool safefn = isSafeFunction(insn); if (safefn) { - if (insn->GetFunction()) - cerr << insn->GetFunction()->GetName() << " is safe" << endl; + if (insn->getFunction()) + cerr << insn->getFunction()->getName() << " is safe" << endl; } - //switch(d.Instruction.BranchType) - //{ - //case JmpType: if(d.isUnconditionalBranch()) { - //if((d.Argument1.ArgType&CONSTANT_TYPE)!=CONSTANT_TYPE) - if(!d.getOperand(0).isConstant()) + if(!d.getOperand(0)->isConstant()) { bool is_fixed_call=is_jmp_a_fixed_call(insn); bool is_plt_style=is_plt_style_jmp(insn); bool is_any_call_style = (is_fixed_call || is_plt_style); if(do_jumps && !is_any_call_style) { - if (insn->GetIBTargets() && insn->GetIBTargets()->IsComplete()) + if (insn->getIBTargets() && insn->getIBTargets()->isComplete()) { cfi_branch_jmp_complete++; - jmps[insn->GetIBTargets()->size()]++; + jmps[insn->getIBTargets()->size()]++; } cfi_checks++; @@ -1042,10 +999,10 @@ bool SCFI_Instrument::instrument_jumps() } else if(do_calls && is_any_call_style) { - if (insn->GetIBTargets() && insn->GetIBTargets()->IsComplete()) + if (insn->getIBTargets() && insn->getIBTargets()->isComplete()) { cfi_branch_call_complete++; - calls[insn->GetIBTargets()->size()]++; + calls[insn->getIBTargets()->size()]++; } cfi_checks++; @@ -1064,7 +1021,6 @@ bool SCFI_Instrument::instrument_jumps() } } } - // case CallType: else if(d.isCall()) { @@ -1073,9 +1029,7 @@ bool SCFI_Instrument::instrument_jumps() // (1) --no-fix-safefn in fixcalls leaves call as call (instead of push/jmp) // (2) and here, we don't plop down a nonce // see (3) below where we don't instrument returns for safe functions - - // bool isDirectCall = (d.Argument1.ArgType&CONSTANT_TYPE)==CONSTANT_TYPE; - bool isDirectCall = d.getOperand(0).isConstant(); + bool isDirectCall = d.getOperand(0)->isConstant(); if (!protect_safefn) { @@ -1087,23 +1041,22 @@ bool SCFI_Instrument::instrument_jumps() } AddExecutableNonce(insn); // for all calls - if(!isDirectCall) // (d.Argument1.ArgType&CONSTANT_TYPE)!=CONSTANT_TYPE) + if(!isDirectCall) { // for indirect calls. AddCallCFIWithExeNonce(insn); } } - // case RetType: else if (d.isReturn()) { - if (insn->GetFunction()) - cerr << "found ret type protect_safefn: " << protect_safefn << " safefn: " << safefn << " function: " << insn->GetFunction()->GetName() << endl; + if (insn->getFunction()) + cerr << "found ret type protect_safefn: " << protect_safefn << " safefn: " << safefn << " function: " << insn->getFunction()->getName() << endl; else cerr << "found ret type protect_safefn: " << protect_safefn << " safefn: " << safefn << " no functions associated with instruction!! wtf???" << endl; - if (insn->GetIBTargets() && insn->GetIBTargets()->IsComplete()) + if (insn->getIBTargets() && insn->getIBTargets()->isComplete()) { cfi_branch_ret_complete++; - rets[insn->GetIBTargets()->size()]++; + rets[insn->getIBTargets()->size()]++; } // (3) and here, we don't instrument returns for safe function @@ -1123,10 +1076,9 @@ bool SCFI_Instrument::instrument_jumps() AddReturnCFI(insn); } } - else // default: + else { } - //} } cout<<"# ATTRIBUTE Selective_Control_Flow_Integrity::cfi_jmp_checks="<<std::dec<<cfi_branch_jmp_checks<<endl; @@ -1184,14 +1136,14 @@ static struct ScoopFinder : binary_function<const DataScoop_t*,const string,bool // declare a simple scoop finder function that finds scoops by name bool operator()(const DataScoop_t* scoop, const string& name) const { - return (scoop->GetName() == name); + return (scoop->getName() == name); }; } finder; static DataScoop_t* find_scoop(FileIR_t *firp,const string &name) { - auto it=find_if(firp->GetDataScoops().begin(), firp->GetDataScoops().end(), bind2nd(finder, name)) ; - if( it != firp->GetDataScoops().end() ) + auto it=find_if(firp->getDataScoops().begin(), firp->getDataScoops().end(), bind2nd(finder, name)) ; + if( it != firp->getDataScoops().end() ) return *it; return NULL; }; @@ -1199,12 +1151,12 @@ static DataScoop_t* find_scoop(FileIR_t *firp,const string &name) static unsigned int add_to_scoop(const string &str, DataScoop_t* scoop) { // assert that this scoop is unpinned. may need to enable --step move_globals --step-option move_globals:--elftables-only - assert(scoop->GetStart()->GetVirtualOffset()==0); + assert(scoop->getStart()->getVirtualOffset()==0); int len=str.length(); - scoop->SetContents(scoop->GetContents()+str); - virtual_offset_t oldend=scoop->GetEnd()->GetVirtualOffset(); - virtual_offset_t newend=oldend+len; - scoop->GetEnd()->SetVirtualOffset(newend); + scoop->setContents(scoop->getContents()+str); + auto oldend=scoop->getEnd()->getVirtualOffset(); + auto newend=oldend+len; + scoop->getEnd()->setVirtualOffset(newend); return oldend+1; }; @@ -1212,73 +1164,73 @@ template<int ptrsize> static void insert_into_scoop_at(const string &str, DataScoop_t* scoop, FileIR_t* firp, const unsigned int at) { // assert that this scoop is unpinned. may need to enable --step move_globals --step-option move_globals:--cfi - assert(scoop->GetStart()->GetVirtualOffset()==0); + assert(scoop->getStart()->getVirtualOffset()==0); int len=str.length(); - string new_scoop_contents=scoop->GetContents(); + string new_scoop_contents=scoop->getContents(); new_scoop_contents.insert(at,str); - scoop->SetContents(new_scoop_contents); + scoop->setContents(new_scoop_contents); - virtual_offset_t oldend=scoop->GetEnd()->GetVirtualOffset(); - virtual_offset_t newend=oldend+len; - scoop->GetEnd()->SetVirtualOffset(newend); + auto oldend=scoop->getEnd()->getVirtualOffset(); + auto newend=oldend+len; + scoop->getEnd()->setVirtualOffset(newend); // update each reloc to point to the new location. - for_each(scoop->GetRelocations().begin(), scoop->GetRelocations().end(), [str,at](Relocation_t* reloc) + for_each(scoop->getRelocations().begin(), scoop->getRelocations().end(), [str,at](Relocation_t* reloc) { - if((unsigned int)reloc->GetOffset()>=at) - reloc->SetOffset(reloc->GetOffset()+str.size()); + if((unsigned int)reloc->getOffset()>=at) + reloc->setOffset(reloc->getOffset()+str.size()); }); // check relocations for pointers to this object. // we'll update dataptr_to_scoop relocs, but nothing else // so assert if we find something else - for_each(firp->GetRelocations().begin(), firp->GetRelocations().end(), [scoop](Relocation_t* reloc) + for_each(firp->getRelocations().begin(), firp->getRelocations().end(), [scoop](Relocation_t* reloc) { - DataScoop_t* wrt=dynamic_cast<DataScoop_t*>(reloc->GetWRT()); - assert(wrt != scoop || reloc->GetType()=="dataptr_to_scoop"); + DataScoop_t* wrt=dynamic_cast<DataScoop_t*>(reloc->getWRT()); + assert(wrt != scoop || reloc->getType()=="dataptr_to_scoop"); }); // for each scoop - for_each(firp->GetDataScoops().begin(), firp->GetDataScoops().end(), [&str,scoop,firp,at](DataScoop_t* scoop_to_update) + for_each(firp->getDataScoops().begin(), firp->getDataScoops().end(), [&str,scoop,firp,at](DataScoop_t* scoop_to_update) { // for each relocation for that scoop - for_each(scoop_to_update->GetRelocations().begin(), scoop_to_update->GetRelocations().end(), [&str,scoop,firp,scoop_to_update,at](Relocation_t* reloc) + for_each(scoop_to_update->getRelocations().begin(), scoop_to_update->getRelocations().end(), [&str,scoop,firp,scoop_to_update,at](Relocation_t* reloc) { // if it's a reloc that's wrt scoop - DataScoop_t* wrt=dynamic_cast<DataScoop_t*>(reloc->GetWRT()); + DataScoop_t* wrt=dynamic_cast<DataScoop_t*>(reloc->getWRT()); if(wrt==scoop) { // then we need to update the scoop - if(reloc->GetType()=="dataptr_to_scoop") + if(reloc->getType()=="dataptr_to_scoop") { - string contents=scoop_to_update->GetContents(); + string contents=scoop_to_update->getContents(); // subtract the stringsize from the (implicitly stored) addend // taking pointer size into account. switch(ptrsize) { case 4: { - unsigned int val=*((unsigned int*)&contents.c_str()[reloc->GetOffset()]); + unsigned int val=*((unsigned int*)&contents.c_str()[reloc->getOffset()]); if(val>=at) val +=str.size(); - contents.replace(reloc->GetOffset(), ptrsize, (const char*)&val, ptrsize); + contents.replace(reloc->getOffset(), ptrsize, (const char*)&val, ptrsize); break; } case 8: { - unsigned long long val=*((long long*)&contents.c_str()[reloc->GetOffset()]); + unsigned long long val=*((long long*)&contents.c_str()[reloc->getOffset()]); if(val>=at) val +=str.size(); - contents.replace(reloc->GetOffset(), ptrsize, (const char*)&val, ptrsize); + contents.replace(reloc->getOffset(), ptrsize, (const char*)&val, ptrsize); break; } default: assert(0); } - scoop_to_update->SetContents(contents); + scoop_to_update->setContents(contents); } } @@ -1308,18 +1260,18 @@ template<typename T_Elf_Sym, typename T_Elf_Rela, typename T_Elf_Dyn, int reloc_ Instruction_t* SCFI_Instrument::find_runtime_resolve(DataScoop_t* gotplt_scoop) { // find any data_to_insn_ptr reloc for the gotplt scoop - auto it=find_if(gotplt_scoop->GetRelocations().begin(), gotplt_scoop->GetRelocations().end(), [](Relocation_t* reloc) + auto it=find_if(gotplt_scoop->getRelocations().begin(), gotplt_scoop->getRelocations().end(), [](Relocation_t* reloc) { - return reloc->GetType()=="data_to_insn_ptr"; + return reloc->getType()=="data_to_insn_ptr"; }); // there _should_ be one. - assert(it!=gotplt_scoop->GetRelocations().end()); + assert(it!=gotplt_scoop->getRelocations().end()); Relocation_t* reloc=*it; - Instruction_t* wrt=dynamic_cast<Instruction_t*>(reloc->GetWRT()); + Instruction_t* wrt=dynamic_cast<Instruction_t*>(reloc->getWRT()); assert(wrt); // should be a WRT assert(wrt->getDisassembly().find("push ") != string::npos); // should be push K insn - return wrt->GetFallthrough(); // jump to the jump, or not.. doesn't matter. zopt will fix + return wrt->getFallthrough(); // jump to the jump, or not.. doesn't matter. zopt will fix } template<typename T_Elf_Sym, typename T_Elf_Rela, typename T_Elf_Dyn, int reloc_type, int rela_shift, int ptrsize> @@ -1332,20 +1284,32 @@ void SCFI_Instrument::add_got_entry(const std::string& name) auto relaplt_scoop=find_scoop(firp,".rela.dyn coalesced w/.rela.plt"); auto relplt_scoop=find_scoop(firp,".rel.dyn coalesced w/.rel.plt"); auto relscoop=relaplt_scoop!=NULL ? relaplt_scoop : relplt_scoop; + auto gnu_version_scoop=find_scoop(firp,".gnu.version"); + assert(gnu_version_scoop); + assert(gnu_version_scoop->getStart()->getVirtualOffset()==0); // add 0-init'd pointer to table string new_got_entry_str(ptrsize,0); // zero-init a pointer-sized string // create a new, unpinned, rw+relro scoop that's an empty pointer. - AddressID_t* start_addr=new AddressID_t(BaseObj_t::NOT_IN_DATABASE, firp->GetFile()->GetBaseID(), 0); - AddressID_t* end_addr=new AddressID_t(BaseObj_t::NOT_IN_DATABASE, firp->GetFile()->GetBaseID(), ptrsize-1); - DataScoop_t* external_func_addr_scoop=new DataScoop_t(BaseObj_t::NOT_IN_DATABASE, - name, start_addr,end_addr, NULL, 6, true, new_got_entry_str); - + /* + AddressID_t* start_addr=new AddressID_t(BaseObj_t::NOT_IN_DATABASE, firp->getFile()->getBaseID(), 0); firp->GetAddresses().insert(start_addr); + */ + auto start_addr=firp->addNewAddress(firp->getFile()->getBaseID(), 0); + /* + AddressID_t* end_addr=new AddressID_t(BaseObj_t::NOT_IN_DATABASE, firp->getFile()->getBaseID(), ptrsize-1); firp->GetAddresses().insert(end_addr); - firp->GetDataScoops().insert(external_func_addr_scoop); + */ + auto end_addr=firp->addNewAddress(firp->getFile()->getBaseID(), ptrsize-1); + + /* + DataScoop_t* external_func_addr_scoop=new DataScoop_t(BaseObj_t::NOT_IN_DATABASE, + name, start_addr,end_addr, NULL, 6, true, new_got_entry_str); + firp->getDataScoops().insert(external_func_addr_scoop); + */ + auto external_func_addr_scoop=firp->addNewDataScoop(name, start_addr,end_addr, NULL, 6, true, new_got_entry_str); // add string to string table auto dl_str_pos=add_to_scoop(name+'\0', dynstr_scoop); @@ -1358,11 +1322,15 @@ void SCFI_Instrument::add_got_entry(const std::string& name) string dl_sym_str((const char*)&dl_sym, sizeof(T_Elf_Sym)); unsigned int dl_pos=add_to_scoop(dl_sym_str,dynsym_scoop); + // update the gnu.version section so that the new symbol has a version. + const auto new_version_str=string("\0\0", 2); // \0\0 means *local*, as in, don't index the gnu.verneeded array. + add_to_scoop(new_version_str,gnu_version_scoop); + // find the rela count. can't insert before that. int rela_count=0; - for(int i=0;i+sizeof(T_Elf_Dyn)<dynamic_scoop->GetSize(); i+=sizeof(T_Elf_Dyn)) + for(int i=0;i+sizeof(T_Elf_Dyn)<dynamic_scoop->getSize(); i+=sizeof(T_Elf_Dyn)) { - T_Elf_Dyn &dyn_entry=*(T_Elf_Dyn*)&dynamic_scoop->GetContents().c_str()[i]; + T_Elf_Dyn &dyn_entry=*(T_Elf_Dyn*)&dynamic_scoop->getContents().c_str()[i]; if(dyn_entry.d_tag==DT_RELACOUNT) // diff than rela size. { // add to the size @@ -1382,15 +1350,19 @@ void SCFI_Instrument::add_got_entry(const std::string& name) unsigned int at=rela_count*sizeof(T_Elf_Rela); insert_into_scoop_at<ptrsize>(dl_rel_str, relscoop, firp, at); - Relocation_t* dl_reloc=new Relocation_t(BaseObj_t::NOT_IN_DATABASE, at+((uintptr_t)&dl_rel.r_offset -(uintptr_t)&dl_rel), "dataptr_to_scoop", external_func_addr_scoop); - relscoop->GetRelocations().insert(dl_reloc); - firp->GetRelocations().insert(dl_reloc); - - for(int i=0;i+sizeof(T_Elf_Dyn)<dynamic_scoop->GetSize(); i+=sizeof(T_Elf_Dyn)) + /* + * Relocation_t* dl_reloc=new Relocation_t(BaseObj_t::NOT_IN_DATABASE, at+((uintptr_t)&dl_rel.r_offset -(uintptr_t)&dl_rel), "dataptr_to_scoop", external_func_addr_scoop); + relscoop->getRelocations().insert(dl_reloc); + firp->getRelocations().insert(dl_reloc); + */ + auto dl_reloc=firp->addNewRelocation(relscoop,at+((uintptr_t)&dl_rel.r_offset -(uintptr_t)&dl_rel), "dataptr_to_scoop", external_func_addr_scoop); + (void)dl_reloc; + + for(int i=0;i+sizeof(T_Elf_Dyn)<dynamic_scoop->getSize(); i+=sizeof(T_Elf_Dyn)) { // cast the index'd c_str to an Elf_Dyn pointer and deref it to assign to a // reference structure. That way editing the structure directly edits the string. - T_Elf_Dyn &dyn_entry=*(T_Elf_Dyn*)&dynamic_scoop->GetContents().c_str()[i]; + T_Elf_Dyn &dyn_entry=*(T_Elf_Dyn*)&dynamic_scoop->getContents().c_str()[i]; if(dyn_entry.d_tag==DT_RELASZ) // add to the size dyn_entry.d_un.d_val+=sizeof(T_Elf_Rela); @@ -1439,34 +1411,39 @@ bool SCFI_Instrument::add_got_entries() // add "function" for zestcfi" // for now, return that the target is allowed. the nonce plugin will have to have a slow path for this later. - assert(firp->GetArchitectureBitWidth()==64); // fixme for 32-bit, should jmp to ecx. - zestcfi_function_entry=addNewAssembly(firp,NULL,"jmp r11"); + assert(firp->getArchitectureBitWidth()==64); // fixme for 32-bit, should jmp to ecx. + zestcfi_function_entry=addNewAssembly("jmp r11"); // this jump can target any IBT in the module. - ICFS_t *newicfs=new ICFS_t; - for_each(firp->GetInstructions().begin(), firp->GetInstructions().end(), [&](Instruction_t* insn) + // ICFS_t *newicfs=new ICFS_t; + // firp->GetAllICFS().insert(newicfs); + auto newicfs=firp->addNewICFS(); + for_each(firp->getInstructions().begin(), firp->getInstructions().end(), [&](Instruction_t* insn) { - if(insn->GetIndirectBranchTargetAddress() != NULL ) + if(insn->getIndirectBranchTargetAddress() != NULL ) newicfs->insert(insn); }); - zestcfi_function_entry->SetIBTargets(newicfs); - firp->GetAllICFS().insert(newicfs); - firp->AssembleRegistry(); + zestcfi_function_entry->setIBTargets(newicfs); + firp->assembleRegistry(); // add a relocation so that the zest_cfi "function" gets pointed to by the symbol + /* Relocation_t* zestcfi_reloc=new Relocation_t(BaseObj_t::NOT_IN_DATABASE, zestcfi_pos+((uintptr_t)&zestcfi_sym.st_value - (uintptr_t)&zestcfi_sym), "data_to_insn_ptr", zestcfi_function_entry); - dynsym_scoop->GetRelocations().insert(zestcfi_reloc); - firp->GetRelocations().insert(zestcfi_reloc); + dynsym_scoop->getRelocations().insert(zestcfi_reloc); + firp->getRelocations().insert(zestcfi_reloc); + */ + auto zestcfi_reloc=firp->addNewRelocation(dynsym_scoop,zestcfi_pos+((uintptr_t)&zestcfi_sym.st_value - (uintptr_t)&zestcfi_sym), "data_to_insn_ptr", zestcfi_function_entry); + (void)zestcfi_reloc; // update strtabsz after got/etc entries are added. - for(int i=0;i+sizeof(T_Elf_Dyn)<dynamic_scoop->GetSize(); i+=sizeof(T_Elf_Dyn)) + for(int i=0;i+sizeof(T_Elf_Dyn)<dynamic_scoop->getSize(); i+=sizeof(T_Elf_Dyn)) { - T_Elf_Dyn &dyn_entry=*(T_Elf_Dyn*)&dynamic_scoop->GetContents().c_str()[i]; + T_Elf_Dyn &dyn_entry=*(T_Elf_Dyn*)&dynamic_scoop->getContents().c_str()[i]; if(dyn_entry.d_tag==DT_STRSZ) { - dyn_entry.d_un.d_val=dynstr_scoop->GetContents().size(); + dyn_entry.d_un.d_val=dynstr_scoop->getContents().size(); } } @@ -1527,9 +1504,9 @@ bool SCFI_Instrument::add_libdl_as_needed_support() while(1) { // assert we don't run off the end. - assert((index+1)*sizeof(T_Elf_Dyn) <= dynamic_scoop->GetContents().size()); + assert((index+1)*sizeof(T_Elf_Dyn) <= dynamic_scoop->getContents().size()); - T_Elf_Dyn* dyn_ptr=(T_Elf_Dyn*) & dynamic_scoop->GetContents().c_str()[index*sizeof(T_Elf_Dyn)]; + T_Elf_Dyn* dyn_ptr=(T_Elf_Dyn*) & dynamic_scoop->getContents().c_str()[index*sizeof(T_Elf_Dyn)]; if(memcmp(dyn_ptr,&null_dynamic_entry,sizeof(T_Elf_Dyn)) == 0 ) { @@ -1538,14 +1515,16 @@ bool SCFI_Instrument::add_libdl_as_needed_support() for(unsigned int i=0; i<sizeof(T_Elf_Dyn); i++) { // copy new_dynamic_entry ontop of null entry. - dynamic_scoop->GetContents()[index*sizeof(T_Elf_Dyn) + i ] = ((char*)&new_dynamic_entry)[i]; + auto str=dynamic_scoop->getContents(); + str[index*sizeof(T_Elf_Dyn) + i ] = ((char*)&new_dynamic_entry)[i]; + dynamic_scoop->setContents(str); } // check if there's room for the new null entry - if((index+2)*sizeof(T_Elf_Dyn) <= dynamic_scoop->GetContents().size()) + if((index+2)*sizeof(T_Elf_Dyn) <= dynamic_scoop->getContents().size()) { /* yes */ - T_Elf_Dyn* next_entry=(T_Elf_Dyn*)&dynamic_scoop->GetContents().c_str()[(index+1)*sizeof(T_Elf_Dyn)]; + T_Elf_Dyn* next_entry=(T_Elf_Dyn*)&dynamic_scoop->getContents().c_str()[(index+1)*sizeof(T_Elf_Dyn)]; // assert it's actually null assert(memcmp(next_entry,&null_dynamic_entry,sizeof(T_Elf_Dyn)) == 0 ); } @@ -1562,7 +1541,7 @@ bool SCFI_Instrument::add_libdl_as_needed_support() #if 0 cout<<".dynamic contents after scfi update:"<<hex<<endl; - const string &dynstr_contents=dynamic_scoop->GetContents(); + const string &dynstr_contents=dynamic_scoop->getContents(); for(unsigned int i=0;i<dynstr_contents.size(); i+=16) { cout<<*(long long*) &dynstr_contents.c_str()[i] <<" " @@ -1585,7 +1564,7 @@ bool SCFI_Instrument::execute() // do not move later. if(do_multimodule) { - if(firp->GetArchitectureBitWidth()==64) + if(firp->getArchitectureBitWidth()==64) success = success && add_dl_support<Elf64_Sym, Elf64_Rela, Elf64_Dyn, R_X86_64_GLOB_DAT, 32, 8>(); else success = success && add_dl_support<Elf32_Sym, Elf32_Rel, Elf32_Dyn, R_386_GLOB_DAT, 8, 4>(); diff --git a/tools/selective_cfi/scfi_instr.hpp b/tools/selective_cfi/scfi_instr.hpp index 93f3568fca18686e1410de5e95e36a42929e5414..caf95929b526732b345bf6bf58e11980273ab2f6 100644 --- a/tools/selective_cfi/scfi_instr.hpp +++ b/tools/selective_cfi/scfi_instr.hpp @@ -21,8 +21,9 @@ #ifndef scfi_instrument_hpp #define scfi_instrument_hpp -#include <libIRDB-core.hpp> -#include <libIRDB-util.hpp> +#include <irdb-core> +#include <irdb-util> +#include <irdb-transform> #include "color_map.hpp" #include <iostream> #include <iomanip> @@ -30,10 +31,10 @@ -class SCFI_Instrument +class SCFI_Instrument : public IRDB_SDK::Transform { public: - SCFI_Instrument(libIRDB::FileIR_t *the_firp, + SCFI_Instrument(IRDB_SDK::FileIR_t *the_firp, int p_nonce_size=1, int p_exe_nonce_size=4, bool p_do_coloring=true, @@ -47,6 +48,7 @@ class SCFI_Instrument bool p_do_exe_nonce_for_call=false ) : + Transform(the_firp), firp(the_firp), nonce_size(p_nonce_size), exe_nonce_size(p_exe_nonce_size), @@ -61,7 +63,10 @@ class SCFI_Instrument do_exe_nonce_for_call(p_do_exe_nonce_for_call), ret_shared(NULL), zestcfi_function_entry(NULL), - ExecutableNonceValue("\x90", 1) + ExecutableNonceValue("\x90", 1), + predsp(IRDB_SDK::InstructionPredecessors_t::factory(firp)), + preds(*predsp) + { std::cout<<std::boolalpha; std::cout<<"# ATTRIBUTE Selective_Control_Flow_Integrity::do_coloring="<<p_do_coloring<<std::endl; @@ -72,7 +77,6 @@ class SCFI_Instrument std::cout<<"# ATTRIBUTE Selective_Control_Flow_Integrity::do_rets="<<p_do_rets<<std::endl; std::cout<<"# ATTRIBUTE Selective_Control_Flow_Integrity::do_safefn="<<p_do_safefn<<std::endl; std::cout<<"# ATTRIBUTE Selective_Control_Flow_Integrity::do_multimodule="<<p_do_multimodule<<std::endl; - preds.AddFile(the_firp); } bool execute(); @@ -90,7 +94,7 @@ class SCFI_Instrument bool add_got_entries(); template<typename T_Elf_Sym, typename T_Elf_Rela, typename T_Elf_Dyn, int reloc_type, int rela_shift, int ptrsize> - libIRDB::Instruction_t* find_runtime_resolve(libIRDB::DataScoop_t* gotplt_scoop); + IRDB_SDK::Instruction_t* find_runtime_resolve(IRDB_SDK::DataScoop_t* gotplt_scoop); template<typename T_Elf_Sym, typename T_Elf_Rela, typename T_Elf_Dyn, int reloc_type, int rela_shift, int ptrsize> void add_got_entry(const std::string& name); @@ -103,47 +107,46 @@ class SCFI_Instrument bool instrument_jumps(); // helper - libIRDB::Instruction_t* GetExeNonceSlowPath(libIRDB::Instruction_t* insn); - libIRDB::Relocation_t* create_reloc(libIRDB::Instruction_t* insn); - libIRDB::Relocation_t* FindRelocation(libIRDB::Instruction_t* insn, std::string type); - bool isSafeFunction(libIRDB::Instruction_t* insn); - bool isCallToSafeFunction(libIRDB::Instruction_t* insn); - bool is_jmp_a_fixed_call(libIRDB::Instruction_t* insn); - bool is_plt_style_jmp(libIRDB::Instruction_t* insn); + IRDB_SDK::Instruction_t* GetExeNonceSlowPath(IRDB_SDK::Instruction_t* insn); + IRDB_SDK::Relocation_t* create_reloc(IRDB_SDK::Instruction_t* insn); + IRDB_SDK::Relocation_t* FindRelocation(IRDB_SDK::Instruction_t* insn, std::string type); + bool isSafeFunction(IRDB_SDK::Instruction_t* insn); + bool isCallToSafeFunction(IRDB_SDK::Instruction_t* insn); + bool is_jmp_a_fixed_call(IRDB_SDK::Instruction_t* insn); + bool is_plt_style_jmp(IRDB_SDK::Instruction_t* insn); // add instrumentation - bool add_scfi_instrumentation(libIRDB::Instruction_t* insn); - bool needs_scfi_instrumentation(libIRDB::Instruction_t* insn); + bool add_scfi_instrumentation(IRDB_SDK::Instruction_t* insn); + bool needs_scfi_instrumentation(IRDB_SDK::Instruction_t* insn); // return instrumentation - void AddReturnCFI(libIRDB::Instruction_t* insn, ColoredSlotValue_t *v=NULL); - void AddReturnCFIForExeNonce(libIRDB::Instruction_t* insn, ColoredSlotValue_t *v=NULL); + void AddReturnCFI(IRDB_SDK::Instruction_t* insn, ColoredSlotValue_t *v=NULL); + void AddReturnCFIForExeNonce(IRDB_SDK::Instruction_t* insn, ColoredSlotValue_t *v=NULL); // jump instrumentation - void AddJumpCFI(libIRDB::Instruction_t* insn); + void AddJumpCFI(IRDB_SDK::Instruction_t* insn); // call instrumentation with executable nonce - void AddCallCFIWithExeNonce(libIRDB::Instruction_t* insn); + void AddCallCFIWithExeNonce(IRDB_SDK::Instruction_t* insn); // for all calls - void AddExecutableNonce(libIRDB::Instruction_t* insn); + void AddExecutableNonce(IRDB_SDK::Instruction_t* insn); // Nonce Manipulation. - NonceValueType_t GetNonce(libIRDB::Instruction_t* insn); - unsigned int GetNonceSize(libIRDB::Instruction_t* insn); - unsigned int GetNonceOffset(libIRDB::Instruction_t*); + NonceValueType_t GetNonce(IRDB_SDK::Instruction_t* insn); + unsigned int GetNonceSize(IRDB_SDK::Instruction_t* insn); + unsigned int GetNonceOffset(IRDB_SDK::Instruction_t*); - unsigned int GetExeNonceOffset(libIRDB::Instruction_t* insn); - NonceValueType_t GetExeNonce(libIRDB::Instruction_t* insn); - unsigned int GetExeNonceSize(libIRDB::Instruction_t* insn); + unsigned int GetExeNonceOffset(IRDB_SDK::Instruction_t* insn); + NonceValueType_t GetExeNonce(IRDB_SDK::Instruction_t* insn); + unsigned int GetExeNonceSize(IRDB_SDK::Instruction_t* insn); private: // data // predecessors of instructions. - libIRDB::InstructionPredecessors_t preds; - libIRDB::FileIR_t* firp; + IRDB_SDK::FileIR_t* firp; const int nonce_size; const int exe_nonce_size; const bool do_coloring; @@ -157,8 +160,8 @@ class SCFI_Instrument const bool do_exe_nonce_for_call; std::unique_ptr<ColoredInstructionNonces_t> color_map; std::unique_ptr<ColoredInstructionNonces_t> exe_nonce_color_map; - const libIRDB::Instruction_t *ret_shared; - libIRDB::Instruction_t *zestcfi_function_entry; + const IRDB_SDK::Instruction_t *ret_shared; + IRDB_SDK::Instruction_t *zestcfi_function_entry; std::string ExecutableNonceValue; // Exe Nonce helpers @@ -188,10 +191,18 @@ class SCFI_Instrument */ std::vector<NoncePart_t> GetExeNonceFit(NonceValueType_t nonceVal, int nonceSz, int noncePos); int GetNonceBytePos(int nonceSz, int noncePos); - void CreateExeNonceReloc(libIRDB::Instruction_t* insn, NonceValueType_t nonceVal, int nonceSz, int bytePos); - void PlaceExeNonceReloc(libIRDB::Instruction_t* insn, NonceValueType_t nonceVal, int nonceSz, int noncePos); - void InsertExeNonceComparisons(libIRDB::Instruction_t* insn, NonceValueType_t nonceVal, int nonceSz, - int noncePos, libIRDB::Instruction_t* exeNonceSlowPath ); + void CreateExeNonceReloc(IRDB_SDK::Instruction_t* insn, NonceValueType_t nonceVal, int nonceSz, int bytePos); + void PlaceExeNonceReloc(IRDB_SDK::Instruction_t* insn, NonceValueType_t nonceVal, int nonceSz, int noncePos); + void InsertExeNonceComparisons(IRDB_SDK::Instruction_t* insn, NonceValueType_t nonceVal, int nonceSz, + int noncePos, IRDB_SDK::Instruction_t* exeNonceSlowPath ); + + + void mov_reloc(IRDB_SDK::Instruction_t* from, IRDB_SDK::Instruction_t* to, std::string type ); + void move_relocs(IRDB_SDK::Instruction_t* from, IRDB_SDK::Instruction_t* to); + + std::unique_ptr<IRDB_SDK::InstructionPredecessors_t> predsp; + IRDB_SDK::InstructionPredecessors_t &preds; + }; #endif diff --git a/tools/selective_cfi/tests/cfi_all_configs.sh b/tools/selective_cfi/tests/cfi_all_configs.sh index 44eaa1343a544c3021145253844e37adf292d386..33767757cbd3ca28e898fc2e03d9549586701445 100644 --- a/tools/selective_cfi/tests/cfi_all_configs.sh +++ b/tools/selective_cfi/tests/cfi_all_configs.sh @@ -75,370 +75,370 @@ configs=(do_cfi do_cfi() { - $PS $1 $2 --backend zipr --critical-step move_globals=on --critical-step selective_cfi=on --step-option selective_cfi:--multimodule --step-option move_globals:--elftables-only --step-option fix_calls:--fix-all --step-option zipr:"--add-sections false" + (set -x; $PS $1 $2 --backend zipr --critical-step move_globals=on --critical-step selective_cfi=on --step-option selective_cfi:--multimodule --step-option move_globals:--elftables-only --step-option fix_calls:--fix-all --step-option zipr:"--add-sections false") } do_cfi_2_byte() { - $PS $1 $2 --backend zipr --critical-step move_globals=on --critical-step selective_cfi=on --step-option selective_cfi:--multimodule --step-option move_globals:--elftables-only --step-option fix_calls:--fix-all --step-option zipr:"--add-sections false" --step-option selective_cfi:"--nonce-size 2" + (set -x; $PS $1 $2 --backend zipr --critical-step move_globals=on --critical-step selective_cfi=on --step-option selective_cfi:--multimodule --step-option move_globals:--elftables-only --step-option fix_calls:--fix-all --step-option zipr:"--add-sections false" --step-option selective_cfi:"--nonce-size 2") } do_cfi_4_byte() { - $PS $1 $2 --backend zipr --critical-step move_globals=on --critical-step selective_cfi=on --step-option selective_cfi:--multimodule --step-option move_globals:--elftables-only --step-option fix_calls:--fix-all --step-option zipr:"--add-sections false" --step-option selective_cfi:"--nonce-size 4" + (set -x; $PS $1 $2 --backend zipr --critical-step move_globals=on --critical-step selective_cfi=on --step-option selective_cfi:--multimodule --step-option move_globals:--elftables-only --step-option fix_calls:--fix-all --step-option zipr:"--add-sections false" --step-option selective_cfi:"--nonce-size 4") } do_cfi_8_byte() { - $PS $1 $2 --backend zipr --critical-step move_globals=on --critical-step selective_cfi=on --step-option selective_cfi:--multimodule --step-option move_globals:--elftables-only --step-option fix_calls:--fix-all --step-option zipr:"--add-sections false" --step-option selective_cfi:"--nonce-size 8" + (set -x; $PS $1 $2 --backend zipr --critical-step move_globals=on --critical-step selective_cfi=on --step-option selective_cfi:--multimodule --step-option move_globals:--elftables-only --step-option fix_calls:--fix-all --step-option zipr:"--add-sections false" --step-option selective_cfi:"--nonce-size 8") } ############################################################################### do_coloring_cfi() { - $PS $1 $2 --backend zipr --critical-step move_globals=on --critical-step selective_cfi=on --step-option selective_cfi:--multimodule --step-option move_globals:--elftables-only --step-option fix_calls:--fix-all --step-option selective_cfi:--color --step-option zipr:"--add-sections false" + (set -x; $PS $1 $2 --backend zipr --critical-step move_globals=on --critical-step selective_cfi=on --step-option selective_cfi:--multimodule --step-option move_globals:--elftables-only --step-option fix_calls:--fix-all --step-option selective_cfi:--color --step-option zipr:"--add-sections false") } do_coloring_cfi_2_byte() { - $PS $1 $2 --backend zipr --critical-step move_globals=on --critical-step selective_cfi=on --step-option selective_cfi:--multimodule --step-option move_globals:--elftables-only --step-option fix_calls:--fix-all --step-option selective_cfi:--color --step-option zipr:"--add-sections false" --step-option selective_cfi:"--nonce-size 2" + (set -x; $PS $1 $2 --backend zipr --critical-step move_globals=on --critical-step selective_cfi=on --step-option selective_cfi:--multimodule --step-option move_globals:--elftables-only --step-option fix_calls:--fix-all --step-option selective_cfi:--color --step-option zipr:"--add-sections false" --step-option selective_cfi:"--nonce-size 2") } do_coloring_cfi_4_byte() { - $PS $1 $2 --backend zipr --critical-step move_globals=on --critical-step selective_cfi=on --step-option selective_cfi:--multimodule --step-option move_globals:--elftables-only --step-option fix_calls:--fix-all --step-option selective_cfi:--color --step-option zipr:"--add-sections false" --step-option selective_cfi:"--nonce-size 4" + (set -x; $PS $1 $2 --backend zipr --critical-step move_globals=on --critical-step selective_cfi=on --step-option selective_cfi:--multimodule --step-option move_globals:--elftables-only --step-option fix_calls:--fix-all --step-option selective_cfi:--color --step-option zipr:"--add-sections false" --step-option selective_cfi:"--nonce-size 4") } do_coloring_cfi_8_byte() { - $PS $1 $2 --backend zipr --critical-step move_globals=on --critical-step selective_cfi=on --step-option selective_cfi:--multimodule --step-option move_globals:--elftables-only --step-option fix_calls:--fix-all --step-option selective_cfi:--color --step-option zipr:"--add-sections false" --step-option selective_cfi:"--nonce-size 8" + (set -x; $PS $1 $2 --backend zipr --critical-step move_globals=on --critical-step selective_cfi=on --step-option selective_cfi:--multimodule --step-option move_globals:--elftables-only --step-option fix_calls:--fix-all --step-option selective_cfi:--color --step-option zipr:"--add-sections false" --step-option selective_cfi:"--nonce-size 8") } ############################################################################### do_cfi_exe_nonces() { - $PS $1 $2 --backend zipr --critical-step move_globals=on --critical-step selective_cfi=on --step-option selective_cfi:--multimodule --step-option move_globals:--elftables-only --step-option fix_calls:--no-fix-safefn --step-option selective_cfi:--exe-nonce-for-call --step-option zipr:"--add-sections false" + (set -x; $PS $1 $2 --backend zipr --critical-step move_globals=on --critical-step selective_cfi=on --step-option selective_cfi:--multimodule --step-option move_globals:--elftables-only --step-option fix_calls:--no-fix-safefn --step-option selective_cfi:--exe-nonce-for-call --step-option zipr:"--add-sections false") } do_cfi_exe_nonces_1_byte() { - $PS $1 $2 --backend zipr --critical-step move_globals=on --critical-step selective_cfi=on --step-option selective_cfi:--multimodule --step-option move_globals:--elftables-only --step-option fix_calls:--no-fix-safefn --step-option selective_cfi:--exe-nonce-for-call --step-option zipr:"--add-sections false" --step-option selective_cfi:"--exe-nonce-size 1" + (set -x; $PS $1 $2 --backend zipr --critical-step move_globals=on --critical-step selective_cfi=on --step-option selective_cfi:--multimodule --step-option move_globals:--elftables-only --step-option fix_calls:--no-fix-safefn --step-option selective_cfi:--exe-nonce-for-call --step-option zipr:"--add-sections false" --step-option selective_cfi:"--exe-nonce-size 1") } do_cfi_exe_nonces_2_byte() { - $PS $1 $2 --backend zipr --critical-step move_globals=on --critical-step selective_cfi=on --step-option selective_cfi:--multimodule --step-option move_globals:--elftables-only --step-option fix_calls:--no-fix-safefn --step-option selective_cfi:--exe-nonce-for-call --step-option zipr:"--add-sections false" --step-option selective_cfi:"--exe-nonce-size 2" + (set -x; $PS $1 $2 --backend zipr --critical-step move_globals=on --critical-step selective_cfi=on --step-option selective_cfi:--multimodule --step-option move_globals:--elftables-only --step-option fix_calls:--no-fix-safefn --step-option selective_cfi:--exe-nonce-for-call --step-option zipr:"--add-sections false" --step-option selective_cfi:"--exe-nonce-size 2") } do_cfi_exe_nonces_8_byte() { - $PS $1 $2 --backend zipr --critical-step move_globals=on --critical-step selective_cfi=on --step-option selective_cfi:--multimodule --step-option move_globals:--elftables-only --step-option fix_calls:--no-fix-safefn --step-option selective_cfi:--exe-nonce-for-call --step-option zipr:"--add-sections false" --step-option selective_cfi:"--exe-nonce-size 8" + (set -x; $PS $1 $2 --backend zipr --critical-step move_globals=on --critical-step selective_cfi=on --step-option selective_cfi:--multimodule --step-option move_globals:--elftables-only --step-option fix_calls:--no-fix-safefn --step-option selective_cfi:--exe-nonce-for-call --step-option zipr:"--add-sections false" --step-option selective_cfi:"--exe-nonce-size 8") } do_cfi_exe_nonces_2_byte_non_exe() { - $PS $1 $2 --backend zipr --critical-step move_globals=on --critical-step selective_cfi=on --step-option selective_cfi:--multimodule --step-option move_globals:--elftables-only --step-option fix_calls:--no-fix-safefn --step-option selective_cfi:--exe-nonce-for-call --step-option zipr:"--add-sections false" --step-option selective_cfi:"--nonce-size 2" + (set -x; $PS $1 $2 --backend zipr --critical-step move_globals=on --critical-step selective_cfi=on --step-option selective_cfi:--multimodule --step-option move_globals:--elftables-only --step-option fix_calls:--no-fix-safefn --step-option selective_cfi:--exe-nonce-for-call --step-option zipr:"--add-sections false" --step-option selective_cfi:"--nonce-size 2") } do_cfi_exe_nonces_4_byte_non_exe() { - $PS $1 $2 --backend zipr --critical-step move_globals=on --critical-step selective_cfi=on --step-option selective_cfi:--multimodule --step-option move_globals:--elftables-only --step-option fix_calls:--no-fix-safefn --step-option selective_cfi:--exe-nonce-for-call --step-option zipr:"--add-sections false" --step-option selective_cfi:"--nonce-size 4" + (set -x; $PS $1 $2 --backend zipr --critical-step move_globals=on --critical-step selective_cfi=on --step-option selective_cfi:--multimodule --step-option move_globals:--elftables-only --step-option fix_calls:--no-fix-safefn --step-option selective_cfi:--exe-nonce-for-call --step-option zipr:"--add-sections false" --step-option selective_cfi:"--nonce-size 4") } do_cfi_exe_nonces_8_byte_non_exe() { - $PS $1 $2 --backend zipr --critical-step move_globals=on --critical-step selective_cfi=on --step-option selective_cfi:--multimodule --step-option move_globals:--elftables-only --step-option fix_calls:--no-fix-safefn --step-option selective_cfi:--exe-nonce-for-call --step-option zipr:"--add-sections false" --step-option selective_cfi:"--nonce-size 8" + (set -x; $PS $1 $2 --backend zipr --critical-step move_globals=on --critical-step selective_cfi=on --step-option selective_cfi:--multimodule --step-option move_globals:--elftables-only --step-option fix_calls:--no-fix-safefn --step-option selective_cfi:--exe-nonce-for-call --step-option zipr:"--add-sections false" --step-option selective_cfi:"--nonce-size 8") } do_cfi_exe_nonces_1_byte_2_byte_non_exe() { - $PS $1 $2 --backend zipr --critical-step move_globals=on --critical-step selective_cfi=on --step-option selective_cfi:--multimodule --step-option move_globals:--elftables-only --step-option fix_calls:--no-fix-safefn --step-option selective_cfi:--exe-nonce-for-call --step-option zipr:"--add-sections false" --step-option selective_cfi:"--exe-nonce-size 1" --step-option selective_cfi:"--nonce-size 2" + (set -x; $PS $1 $2 --backend zipr --critical-step move_globals=on --critical-step selective_cfi=on --step-option selective_cfi:--multimodule --step-option move_globals:--elftables-only --step-option fix_calls:--no-fix-safefn --step-option selective_cfi:--exe-nonce-for-call --step-option zipr:"--add-sections false" --step-option selective_cfi:"--exe-nonce-size 1" --step-option selective_cfi:"--nonce-size 2") } do_cfi_exe_nonces_1_byte_4_byte_non_exe() { - $PS $1 $2 --backend zipr --critical-step move_globals=on --critical-step selective_cfi=on --step-option selective_cfi:--multimodule --step-option move_globals:--elftables-only --step-option fix_calls:--no-fix-safefn --step-option selective_cfi:--exe-nonce-for-call --step-option zipr:"--add-sections false" --step-option selective_cfi:"--exe-nonce-size 1" --step-option selective_cfi:"--nonce-size 4" + (set -x; $PS $1 $2 --backend zipr --critical-step move_globals=on --critical-step selective_cfi=on --step-option selective_cfi:--multimodule --step-option move_globals:--elftables-only --step-option fix_calls:--no-fix-safefn --step-option selective_cfi:--exe-nonce-for-call --step-option zipr:"--add-sections false" --step-option selective_cfi:"--exe-nonce-size 1" --step-option selective_cfi:"--nonce-size 4") } do_cfi_exe_nonces_1_byte_8_byte_non_exe() { - $PS $1 $2 --backend zipr --critical-step move_globals=on --critical-step selective_cfi=on --step-option selective_cfi:--multimodule --step-option move_globals:--elftables-only --step-option fix_calls:--no-fix-safefn --step-option selective_cfi:--exe-nonce-for-call --step-option zipr:"--add-sections false" --step-option selective_cfi:"--exe-nonce-size 1" --step-option selective_cfi:"--nonce-size 8" + (set -x; $PS $1 $2 --backend zipr --critical-step move_globals=on --critical-step selective_cfi=on --step-option selective_cfi:--multimodule --step-option move_globals:--elftables-only --step-option fix_calls:--no-fix-safefn --step-option selective_cfi:--exe-nonce-for-call --step-option zipr:"--add-sections false" --step-option selective_cfi:"--exe-nonce-size 1" --step-option selective_cfi:"--nonce-size 8") } do_cfi_exe_nonces_2_byte_2_byte_non_exe() { - $PS $1 $2 --backend zipr --critical-step move_globals=on --critical-step selective_cfi=on --step-option selective_cfi:--multimodule --step-option move_globals:--elftables-only --step-option fix_calls:--no-fix-safefn --step-option selective_cfi:--exe-nonce-for-call --step-option zipr:"--add-sections false" --step-option selective_cfi:"--exe-nonce-size 2" --step-option selective_cfi:"--nonce-size 2" + (set -x; $PS $1 $2 --backend zipr --critical-step move_globals=on --critical-step selective_cfi=on --step-option selective_cfi:--multimodule --step-option move_globals:--elftables-only --step-option fix_calls:--no-fix-safefn --step-option selective_cfi:--exe-nonce-for-call --step-option zipr:"--add-sections false" --step-option selective_cfi:"--exe-nonce-size 2" --step-option selective_cfi:"--nonce-size 2") } do_cfi_exe_nonces_2_byte_4_byte_non_exe() { - $PS $1 $2 --backend zipr --critical-step move_globals=on --critical-step selective_cfi=on --step-option selective_cfi:--multimodule --step-option move_globals:--elftables-only --step-option fix_calls:--no-fix-safefn --step-option selective_cfi:--exe-nonce-for-call --step-option zipr:"--add-sections false" --step-option selective_cfi:"--exe-nonce-size 2" --step-option selective_cfi:"--nonce-size 4" + (set -x; $PS $1 $2 --backend zipr --critical-step move_globals=on --critical-step selective_cfi=on --step-option selective_cfi:--multimodule --step-option move_globals:--elftables-only --step-option fix_calls:--no-fix-safefn --step-option selective_cfi:--exe-nonce-for-call --step-option zipr:"--add-sections false" --step-option selective_cfi:"--exe-nonce-size 2" --step-option selective_cfi:"--nonce-size 4") } do_cfi_exe_nonces_2_byte_8_byte_non_exe() { - $PS $1 $2 --backend zipr --critical-step move_globals=on --critical-step selective_cfi=on --step-option selective_cfi:--multimodule --step-option move_globals:--elftables-only --step-option fix_calls:--no-fix-safefn --step-option selective_cfi:--exe-nonce-for-call --step-option zipr:"--add-sections false" --step-option selective_cfi:"--exe-nonce-size 2" --step-option selective_cfi:"--nonce-size 8" + (set -x; $PS $1 $2 --backend zipr --critical-step move_globals=on --critical-step selective_cfi=on --step-option selective_cfi:--multimodule --step-option move_globals:--elftables-only --step-option fix_calls:--no-fix-safefn --step-option selective_cfi:--exe-nonce-for-call --step-option zipr:"--add-sections false" --step-option selective_cfi:"--exe-nonce-size 2" --step-option selective_cfi:"--nonce-size 8") } do_cfi_exe_nonces_8_byte_2_byte_non_exe() { - $PS $1 $2 --backend zipr --critical-step move_globals=on --critical-step selective_cfi=on --step-option selective_cfi:--multimodule --step-option move_globals:--elftables-only --step-option fix_calls:--no-fix-safefn --step-option selective_cfi:--exe-nonce-for-call --step-option zipr:"--add-sections false" --step-option selective_cfi:"--exe-nonce-size 8" --step-option selective_cfi:"--nonce-size 2" + (set -x; $PS $1 $2 --backend zipr --critical-step move_globals=on --critical-step selective_cfi=on --step-option selective_cfi:--multimodule --step-option move_globals:--elftables-only --step-option fix_calls:--no-fix-safefn --step-option selective_cfi:--exe-nonce-for-call --step-option zipr:"--add-sections false" --step-option selective_cfi:"--exe-nonce-size 8" --step-option selective_cfi:"--nonce-size 2") } do_cfi_exe_nonces_8_byte_4_byte_non_exe() { - $PS $1 $2 --backend zipr --critical-step move_globals=on --critical-step selective_cfi=on --step-option selective_cfi:--multimodule --step-option move_globals:--elftables-only --step-option fix_calls:--no-fix-safefn --step-option selective_cfi:--exe-nonce-for-call --step-option zipr:"--add-sections false" --step-option selective_cfi:"--exe-nonce-size 8" --step-option selective_cfi:"--nonce-size 4" + (set -x; $PS $1 $2 --backend zipr --critical-step move_globals=on --critical-step selective_cfi=on --step-option selective_cfi:--multimodule --step-option move_globals:--elftables-only --step-option fix_calls:--no-fix-safefn --step-option selective_cfi:--exe-nonce-for-call --step-option zipr:"--add-sections false" --step-option selective_cfi:"--exe-nonce-size 8" --step-option selective_cfi:"--nonce-size 4") } do_cfi_exe_nonces_8_byte_8_byte_non_exe() { - $PS $1 $2 --backend zipr --critical-step move_globals=on --critical-step selective_cfi=on --step-option selective_cfi:--multimodule --step-option move_globals:--elftables-only --step-option fix_calls:--no-fix-safefn --step-option selective_cfi:--exe-nonce-for-call --step-option zipr:"--add-sections false" --step-option selective_cfi:"--exe-nonce-size 8" --step-option selective_cfi:"--nonce-size 8" + (set -x; $PS $1 $2 --backend zipr --critical-step move_globals=on --critical-step selective_cfi=on --step-option selective_cfi:--multimodule --step-option move_globals:--elftables-only --step-option fix_calls:--no-fix-safefn --step-option selective_cfi:--exe-nonce-for-call --step-option zipr:"--add-sections false" --step-option selective_cfi:"--exe-nonce-size 8" --step-option selective_cfi:"--nonce-size 8") } ############################################################################### do_cfi_exe_nonces_color_non_exe() { - $PS $1 $2 --backend zipr --critical-step move_globals=on --critical-step selective_cfi=on --step-option selective_cfi:--multimodule --step-option move_globals:--elftables-only --step-option fix_calls:--no-fix-safefn --step-option selective_cfi:--exe-nonce-for-call --step-option zipr:"--add-sections false" --step-option selective_cfi:--color + (set -x; $PS $1 $2 --backend zipr --critical-step move_globals=on --critical-step selective_cfi=on --step-option selective_cfi:--multimodule --step-option move_globals:--elftables-only --step-option fix_calls:--no-fix-safefn --step-option selective_cfi:--exe-nonce-for-call --step-option zipr:"--add-sections false" --step-option selective_cfi:--color) } do_cfi_exe_nonces_1_byte_color_non_exe() { - $PS $1 $2 --backend zipr --critical-step move_globals=on --critical-step selective_cfi=on --step-option selective_cfi:--multimodule --step-option move_globals:--elftables-only --step-option fix_calls:--no-fix-safefn --step-option selective_cfi:--exe-nonce-for-call --step-option zipr:"--add-sections false" --step-option selective_cfi:"--exe-nonce-size 1" --step-option selective_cfi:--color + (set -x; $PS $1 $2 --backend zipr --critical-step move_globals=on --critical-step selective_cfi=on --step-option selective_cfi:--multimodule --step-option move_globals:--elftables-only --step-option fix_calls:--no-fix-safefn --step-option selective_cfi:--exe-nonce-for-call --step-option zipr:"--add-sections false" --step-option selective_cfi:"--exe-nonce-size 1" --step-option selective_cfi:--color) } do_cfi_exe_nonces_2_byte_color_non_exe() { - $PS $1 $2 --backend zipr --critical-step move_globals=on --critical-step selective_cfi=on --step-option selective_cfi:--multimodule --step-option move_globals:--elftables-only --step-option fix_calls:--no-fix-safefn --step-option selective_cfi:--exe-nonce-for-call --step-option zipr:"--add-sections false" --step-option selective_cfi:"--exe-nonce-size 2" --step-option selective_cfi:--color + (set -x; $PS $1 $2 --backend zipr --critical-step move_globals=on --critical-step selective_cfi=on --step-option selective_cfi:--multimodule --step-option move_globals:--elftables-only --step-option fix_calls:--no-fix-safefn --step-option selective_cfi:--exe-nonce-for-call --step-option zipr:"--add-sections false" --step-option selective_cfi:"--exe-nonce-size 2" --step-option selective_cfi:--color) } do_cfi_exe_nonces_8_byte_color_non_exe() { - $PS $1 $2 --backend zipr --critical-step move_globals=on --critical-step selective_cfi=on --step-option selective_cfi:--multimodule --step-option move_globals:--elftables-only --step-option fix_calls:--no-fix-safefn --step-option selective_cfi:--exe-nonce-for-call --step-option zipr:"--add-sections false" --step-option selective_cfi:"--exe-nonce-size 8" --step-option selective_cfi:--color + (set -x; $PS $1 $2 --backend zipr --critical-step move_globals=on --critical-step selective_cfi=on --step-option selective_cfi:--multimodule --step-option move_globals:--elftables-only --step-option fix_calls:--no-fix-safefn --step-option selective_cfi:--exe-nonce-for-call --step-option zipr:"--add-sections false" --step-option selective_cfi:"--exe-nonce-size 8" --step-option selective_cfi:--color) } do_cfi_exe_nonces_2_byte_non_exe_color_non_exe() { - $PS $1 $2 --backend zipr --critical-step move_globals=on --critical-step selective_cfi=on --step-option selective_cfi:--multimodule --step-option move_globals:--elftables-only --step-option fix_calls:--no-fix-safefn --step-option selective_cfi:--exe-nonce-for-call --step-option zipr:"--add-sections false" --step-option selective_cfi:"--nonce-size 2" --step-option selective_cfi:--color + (set -x; $PS $1 $2 --backend zipr --critical-step move_globals=on --critical-step selective_cfi=on --step-option selective_cfi:--multimodule --step-option move_globals:--elftables-only --step-option fix_calls:--no-fix-safefn --step-option selective_cfi:--exe-nonce-for-call --step-option zipr:"--add-sections false" --step-option selective_cfi:"--nonce-size 2" --step-option selective_cfi:--color) } do_cfi_exe_nonces_4_byte_non_exe_color_non_exe() { - $PS $1 $2 --backend zipr --critical-step move_globals=on --critical-step selective_cfi=on --step-option selective_cfi:--multimodule --step-option move_globals:--elftables-only --step-option fix_calls:--no-fix-safefn --step-option selective_cfi:--exe-nonce-for-call --step-option zipr:"--add-sections false" --step-option selective_cfi:"--nonce-size 4" --step-option selective_cfi:--color + (set -x; $PS $1 $2 --backend zipr --critical-step move_globals=on --critical-step selective_cfi=on --step-option selective_cfi:--multimodule --step-option move_globals:--elftables-only --step-option fix_calls:--no-fix-safefn --step-option selective_cfi:--exe-nonce-for-call --step-option zipr:"--add-sections false" --step-option selective_cfi:"--nonce-size 4" --step-option selective_cfi:--color) } do_cfi_exe_nonces_8_byte_non_exe_color_non_exe() { - $PS $1 $2 --backend zipr --critical-step move_globals=on --critical-step selective_cfi=on --step-option selective_cfi:--multimodule --step-option move_globals:--elftables-only --step-option fix_calls:--no-fix-safefn --step-option selective_cfi:--exe-nonce-for-call --step-option zipr:"--add-sections false" --step-option selective_cfi:"--nonce-size 8" --step-option selective_cfi:--color + (set -x; $PS $1 $2 --backend zipr --critical-step move_globals=on --critical-step selective_cfi=on --step-option selective_cfi:--multimodule --step-option move_globals:--elftables-only --step-option fix_calls:--no-fix-safefn --step-option selective_cfi:--exe-nonce-for-call --step-option zipr:"--add-sections false" --step-option selective_cfi:"--nonce-size 8" --step-option selective_cfi:--color) } do_cfi_exe_nonces_1_byte_2_byte_non_exe_color_non_exe() { - $PS $1 $2 --backend zipr --critical-step move_globals=on --critical-step selective_cfi=on --step-option selective_cfi:--multimodule --step-option move_globals:--elftables-only --step-option fix_calls:--no-fix-safefn --step-option selective_cfi:--exe-nonce-for-call --step-option zipr:"--add-sections false" --step-option selective_cfi:"--exe-nonce-size 1" --step-option selective_cfi:"--nonce-size 2" --step-option selective_cfi:--color + (set -x; $PS $1 $2 --backend zipr --critical-step move_globals=on --critical-step selective_cfi=on --step-option selective_cfi:--multimodule --step-option move_globals:--elftables-only --step-option fix_calls:--no-fix-safefn --step-option selective_cfi:--exe-nonce-for-call --step-option zipr:"--add-sections false" --step-option selective_cfi:"--exe-nonce-size 1" --step-option selective_cfi:"--nonce-size 2" --step-option selective_cfi:--color) } do_cfi_exe_nonces_1_byte_4_byte_non_exe_color_non_exe() { - $PS $1 $2 --backend zipr --critical-step move_globals=on --critical-step selective_cfi=on --step-option selective_cfi:--multimodule --step-option move_globals:--elftables-only --step-option fix_calls:--no-fix-safefn --step-option selective_cfi:--exe-nonce-for-call --step-option zipr:"--add-sections false" --step-option selective_cfi:"--exe-nonce-size 1" --step-option selective_cfi:"--nonce-size 4" --step-option selective_cfi:--color + (set -x; $PS $1 $2 --backend zipr --critical-step move_globals=on --critical-step selective_cfi=on --step-option selective_cfi:--multimodule --step-option move_globals:--elftables-only --step-option fix_calls:--no-fix-safefn --step-option selective_cfi:--exe-nonce-for-call --step-option zipr:"--add-sections false" --step-option selective_cfi:"--exe-nonce-size 1" --step-option selective_cfi:"--nonce-size 4" --step-option selective_cfi:--color) } do_cfi_exe_nonces_1_byte_8_byte_non_exe_color_non_exe() { - $PS $1 $2 --backend zipr --critical-step move_globals=on --critical-step selective_cfi=on --step-option selective_cfi:--multimodule --step-option move_globals:--elftables-only --step-option fix_calls:--no-fix-safefn --step-option selective_cfi:--exe-nonce-for-call --step-option zipr:"--add-sections false" --step-option selective_cfi:"--exe-nonce-size 1" --step-option selective_cfi:"--nonce-size 8" --step-option selective_cfi:--color + (set -x; $PS $1 $2 --backend zipr --critical-step move_globals=on --critical-step selective_cfi=on --step-option selective_cfi:--multimodule --step-option move_globals:--elftables-only --step-option fix_calls:--no-fix-safefn --step-option selective_cfi:--exe-nonce-for-call --step-option zipr:"--add-sections false" --step-option selective_cfi:"--exe-nonce-size 1" --step-option selective_cfi:"--nonce-size 8" --step-option selective_cfi:--color) } do_cfi_exe_nonces_2_byte_2_byte_non_exe_color_non_exe() { - $PS $1 $2 --backend zipr --critical-step move_globals=on --critical-step selective_cfi=on --step-option selective_cfi:--multimodule --step-option move_globals:--elftables-only --step-option fix_calls:--no-fix-safefn --step-option selective_cfi:--exe-nonce-for-call --step-option zipr:"--add-sections false" --step-option selective_cfi:"--exe-nonce-size 2" --step-option selective_cfi:"--nonce-size 2" --step-option selective_cfi:--color + (set -x; $PS $1 $2 --backend zipr --critical-step move_globals=on --critical-step selective_cfi=on --step-option selective_cfi:--multimodule --step-option move_globals:--elftables-only --step-option fix_calls:--no-fix-safefn --step-option selective_cfi:--exe-nonce-for-call --step-option zipr:"--add-sections false" --step-option selective_cfi:"--exe-nonce-size 2" --step-option selective_cfi:"--nonce-size 2" --step-option selective_cfi:--color) } do_cfi_exe_nonces_2_byte_4_byte_non_exe_color_non_exe() { - $PS $1 $2 --backend zipr --critical-step move_globals=on --critical-step selective_cfi=on --step-option selective_cfi:--multimodule --step-option move_globals:--elftables-only --step-option fix_calls:--no-fix-safefn --step-option selective_cfi:--exe-nonce-for-call --step-option zipr:"--add-sections false" --step-option selective_cfi:"--exe-nonce-size 2" --step-option selective_cfi:"--nonce-size 4" --step-option selective_cfi:--color + (set -x; $PS $1 $2 --backend zipr --critical-step move_globals=on --critical-step selective_cfi=on --step-option selective_cfi:--multimodule --step-option move_globals:--elftables-only --step-option fix_calls:--no-fix-safefn --step-option selective_cfi:--exe-nonce-for-call --step-option zipr:"--add-sections false" --step-option selective_cfi:"--exe-nonce-size 2" --step-option selective_cfi:"--nonce-size 4" --step-option selective_cfi:--color) } do_cfi_exe_nonces_2_byte_8_byte_non_exe_color_non_exe() { - $PS $1 $2 --backend zipr --critical-step move_globals=on --critical-step selective_cfi=on --step-option selective_cfi:--multimodule --step-option move_globals:--elftables-only --step-option fix_calls:--no-fix-safefn --step-option selective_cfi:--exe-nonce-for-call --step-option zipr:"--add-sections false" --step-option selective_cfi:"--exe-nonce-size 2" --step-option selective_cfi:"--nonce-size 8" --step-option selective_cfi:--color + (set -x; $PS $1 $2 --backend zipr --critical-step move_globals=on --critical-step selective_cfi=on --step-option selective_cfi:--multimodule --step-option move_globals:--elftables-only --step-option fix_calls:--no-fix-safefn --step-option selective_cfi:--exe-nonce-for-call --step-option zipr:"--add-sections false" --step-option selective_cfi:"--exe-nonce-size 2" --step-option selective_cfi:"--nonce-size 8" --step-option selective_cfi:--color) } do_cfi_exe_nonces_8_byte_2_byte_non_exe_color_non_exe() { - $PS $1 $2 --backend zipr --critical-step move_globals=on --critical-step selective_cfi=on --step-option selective_cfi:--multimodule --step-option move_globals:--elftables-only --step-option fix_calls:--no-fix-safefn --step-option selective_cfi:--exe-nonce-for-call --step-option zipr:"--add-sections false" --step-option selective_cfi:"--exe-nonce-size 8" --step-option selective_cfi:"--nonce-size 2" --step-option selective_cfi:--color + (set -x; $PS $1 $2 --backend zipr --critical-step move_globals=on --critical-step selective_cfi=on --step-option selective_cfi:--multimodule --step-option move_globals:--elftables-only --step-option fix_calls:--no-fix-safefn --step-option selective_cfi:--exe-nonce-for-call --step-option zipr:"--add-sections false" --step-option selective_cfi:"--exe-nonce-size 8" --step-option selective_cfi:"--nonce-size 2" --step-option selective_cfi:--color) } do_cfi_exe_nonces_8_byte_4_byte_non_exe_color_non_exe() { - $PS $1 $2 --backend zipr --critical-step move_globals=on --critical-step selective_cfi=on --step-option selective_cfi:--multimodule --step-option move_globals:--elftables-only --step-option fix_calls:--no-fix-safefn --step-option selective_cfi:--exe-nonce-for-call --step-option zipr:"--add-sections false" --step-option selective_cfi:"--exe-nonce-size 8" --step-option selective_cfi:"--nonce-size 4" --step-option selective_cfi:--color + (set -x; $PS $1 $2 --backend zipr --critical-step move_globals=on --critical-step selective_cfi=on --step-option selective_cfi:--multimodule --step-option move_globals:--elftables-only --step-option fix_calls:--no-fix-safefn --step-option selective_cfi:--exe-nonce-for-call --step-option zipr:"--add-sections false" --step-option selective_cfi:"--exe-nonce-size 8" --step-option selective_cfi:"--nonce-size 4" --step-option selective_cfi:--color) } do_cfi_exe_nonces_8_byte_8_byte_non_exe_color_non_exe() { - $PS $1 $2 --backend zipr --critical-step move_globals=on --critical-step selective_cfi=on --step-option selective_cfi:--multimodule --step-option move_globals:--elftables-only --step-option fix_calls:--no-fix-safefn --step-option selective_cfi:--exe-nonce-for-call --step-option zipr:"--add-sections false" --step-option selective_cfi:"--exe-nonce-size 8" --step-option selective_cfi:"--nonce-size 8" --step-option selective_cfi:--color + (set -x; $PS $1 $2 --backend zipr --critical-step move_globals=on --critical-step selective_cfi=on --step-option selective_cfi:--multimodule --step-option move_globals:--elftables-only --step-option fix_calls:--no-fix-safefn --step-option selective_cfi:--exe-nonce-for-call --step-option zipr:"--add-sections false" --step-option selective_cfi:"--exe-nonce-size 8" --step-option selective_cfi:"--nonce-size 8" --step-option selective_cfi:--color) } ############################################################################### do_cfi_exe_nonces_color_exe() { - $PS $1 $2 --backend zipr --critical-step move_globals=on --critical-step selective_cfi=on --step-option selective_cfi:--multimodule --step-option move_globals:--elftables-only --step-option fix_calls:--no-fix-safefn --step-option selective_cfi:--exe-nonce-for-call --step-option zipr:"--add-sections false" --step-option selective_cfi:--color-exe-nonces + (set -x; $PS $1 $2 --backend zipr --critical-step move_globals=on --critical-step selective_cfi=on --step-option selective_cfi:--multimodule --step-option move_globals:--elftables-only --step-option fix_calls:--no-fix-safefn --step-option selective_cfi:--exe-nonce-for-call --step-option zipr:"--add-sections false" --step-option selective_cfi:--color-exe-nonces) } do_cfi_exe_nonces_1_byte_color_exe() { - $PS $1 $2 --backend zipr --critical-step move_globals=on --critical-step selective_cfi=on --step-option selective_cfi:--multimodule --step-option move_globals:--elftables-only --step-option fix_calls:--no-fix-safefn --step-option selective_cfi:--exe-nonce-for-call --step-option zipr:"--add-sections false" --step-option selective_cfi:"--exe-nonce-size 1" --step-option selective_cfi:--color-exe-nonces + (set -x; $PS $1 $2 --backend zipr --critical-step move_globals=on --critical-step selective_cfi=on --step-option selective_cfi:--multimodule --step-option move_globals:--elftables-only --step-option fix_calls:--no-fix-safefn --step-option selective_cfi:--exe-nonce-for-call --step-option zipr:"--add-sections false" --step-option selective_cfi:"--exe-nonce-size 1" --step-option selective_cfi:--color-exe-nonces) } do_cfi_exe_nonces_2_byte_color_exe() { - $PS $1 $2 --backend zipr --critical-step move_globals=on --critical-step selective_cfi=on --step-option selective_cfi:--multimodule --step-option move_globals:--elftables-only --step-option fix_calls:--no-fix-safefn --step-option selective_cfi:--exe-nonce-for-call --step-option zipr:"--add-sections false" --step-option selective_cfi:"--exe-nonce-size 2" --step-option selective_cfi:--color-exe-nonces + (set -x; $PS $1 $2 --backend zipr --critical-step move_globals=on --critical-step selective_cfi=on --step-option selective_cfi:--multimodule --step-option move_globals:--elftables-only --step-option fix_calls:--no-fix-safefn --step-option selective_cfi:--exe-nonce-for-call --step-option zipr:"--add-sections false" --step-option selective_cfi:"--exe-nonce-size 2" --step-option selective_cfi:--color-exe-nonces) } do_cfi_exe_nonces_8_byte_color_exe() { - $PS $1 $2 --backend zipr --critical-step move_globals=on --critical-step selective_cfi=on --step-option selective_cfi:--multimodule --step-option move_globals:--elftables-only --step-option fix_calls:--no-fix-safefn --step-option selective_cfi:--exe-nonce-for-call --step-option zipr:"--add-sections false" --step-option selective_cfi:"--exe-nonce-size 8" --step-option selective_cfi:--color-exe-nonces + (set -x; $PS $1 $2 --backend zipr --critical-step move_globals=on --critical-step selective_cfi=on --step-option selective_cfi:--multimodule --step-option move_globals:--elftables-only --step-option fix_calls:--no-fix-safefn --step-option selective_cfi:--exe-nonce-for-call --step-option zipr:"--add-sections false" --step-option selective_cfi:"--exe-nonce-size 8" --step-option selective_cfi:--color-exe-nonces) } do_cfi_exe_nonces_2_byte_non_exe_color_exe() { - $PS $1 $2 --backend zipr --critical-step move_globals=on --critical-step selective_cfi=on --step-option selective_cfi:--multimodule --step-option move_globals:--elftables-only --step-option fix_calls:--no-fix-safefn --step-option selective_cfi:--exe-nonce-for-call --step-option zipr:"--add-sections false" --step-option selective_cfi:"--nonce-size 2" --step-option selective_cfi:--color-exe-nonces + (set -x; $PS $1 $2 --backend zipr --critical-step move_globals=on --critical-step selective_cfi=on --step-option selective_cfi:--multimodule --step-option move_globals:--elftables-only --step-option fix_calls:--no-fix-safefn --step-option selective_cfi:--exe-nonce-for-call --step-option zipr:"--add-sections false" --step-option selective_cfi:"--nonce-size 2" --step-option selective_cfi:--color-exe-nonces) } do_cfi_exe_nonces_4_byte_non_exe_color_exe() { - $PS $1 $2 --backend zipr --critical-step move_globals=on --critical-step selective_cfi=on --step-option selective_cfi:--multimodule --step-option move_globals:--elftables-only --step-option fix_calls:--no-fix-safefn --step-option selective_cfi:--exe-nonce-for-call --step-option zipr:"--add-sections false" --step-option selective_cfi:"--nonce-size 4" --step-option selective_cfi:--color-exe-nonces + (set -x; $PS $1 $2 --backend zipr --critical-step move_globals=on --critical-step selective_cfi=on --step-option selective_cfi:--multimodule --step-option move_globals:--elftables-only --step-option fix_calls:--no-fix-safefn --step-option selective_cfi:--exe-nonce-for-call --step-option zipr:"--add-sections false" --step-option selective_cfi:"--nonce-size 4" --step-option selective_cfi:--color-exe-nonces) } do_cfi_exe_nonces_8_byte_non_exe_color_exe() { - $PS $1 $2 --backend zipr --critical-step move_globals=on --critical-step selective_cfi=on --step-option selective_cfi:--multimodule --step-option move_globals:--elftables-only --step-option fix_calls:--no-fix-safefn --step-option selective_cfi:--exe-nonce-for-call --step-option zipr:"--add-sections false" --step-option selective_cfi:"--nonce-size 8" --step-option selective_cfi:--color-exe-nonces + (set -x; $PS $1 $2 --backend zipr --critical-step move_globals=on --critical-step selective_cfi=on --step-option selective_cfi:--multimodule --step-option move_globals:--elftables-only --step-option fix_calls:--no-fix-safefn --step-option selective_cfi:--exe-nonce-for-call --step-option zipr:"--add-sections false" --step-option selective_cfi:"--nonce-size 8" --step-option selective_cfi:--color-exe-nonces) } do_cfi_exe_nonces_1_byte_2_byte_non_exe_color_exe() { - $PS $1 $2 --backend zipr --critical-step move_globals=on --critical-step selective_cfi=on --step-option selective_cfi:--multimodule --step-option move_globals:--elftables-only --step-option fix_calls:--no-fix-safefn --step-option selective_cfi:--exe-nonce-for-call --step-option zipr:"--add-sections false" --step-option selective_cfi:"--exe-nonce-size 1" --step-option selective_cfi:"--nonce-size 2" --step-option selective_cfi:--color-exe-nonces + (set -x; $PS $1 $2 --backend zipr --critical-step move_globals=on --critical-step selective_cfi=on --step-option selective_cfi:--multimodule --step-option move_globals:--elftables-only --step-option fix_calls:--no-fix-safefn --step-option selective_cfi:--exe-nonce-for-call --step-option zipr:"--add-sections false" --step-option selective_cfi:"--exe-nonce-size 1" --step-option selective_cfi:"--nonce-size 2" --step-option selective_cfi:--color-exe-nonces) } do_cfi_exe_nonces_1_byte_4_byte_non_exe_color_exe() { - $PS $1 $2 --backend zipr --critical-step move_globals=on --critical-step selective_cfi=on --step-option selective_cfi:--multimodule --step-option move_globals:--elftables-only --step-option fix_calls:--no-fix-safefn --step-option selective_cfi:--exe-nonce-for-call --step-option zipr:"--add-sections false" --step-option selective_cfi:"--exe-nonce-size 1" --step-option selective_cfi:"--nonce-size 4" --step-option selective_cfi:--color-exe-nonces + (set -x; $PS $1 $2 --backend zipr --critical-step move_globals=on --critical-step selective_cfi=on --step-option selective_cfi:--multimodule --step-option move_globals:--elftables-only --step-option fix_calls:--no-fix-safefn --step-option selective_cfi:--exe-nonce-for-call --step-option zipr:"--add-sections false" --step-option selective_cfi:"--exe-nonce-size 1" --step-option selective_cfi:"--nonce-size 4" --step-option selective_cfi:--color-exe-nonces) } do_cfi_exe_nonces_1_byte_8_byte_non_exe_color_exe() { - $PS $1 $2 --backend zipr --critical-step move_globals=on --critical-step selective_cfi=on --step-option selective_cfi:--multimodule --step-option move_globals:--elftables-only --step-option fix_calls:--no-fix-safefn --step-option selective_cfi:--exe-nonce-for-call --step-option zipr:"--add-sections false" --step-option selective_cfi:"--exe-nonce-size 1" --step-option selective_cfi:"--nonce-size 8" --step-option selective_cfi:--color-exe-nonces + (set -x; $PS $1 $2 --backend zipr --critical-step move_globals=on --critical-step selective_cfi=on --step-option selective_cfi:--multimodule --step-option move_globals:--elftables-only --step-option fix_calls:--no-fix-safefn --step-option selective_cfi:--exe-nonce-for-call --step-option zipr:"--add-sections false" --step-option selective_cfi:"--exe-nonce-size 1" --step-option selective_cfi:"--nonce-size 8" --step-option selective_cfi:--color-exe-nonces) } do_cfi_exe_nonces_2_byte_2_byte_non_exe_color_exe() { - $PS $1 $2 --backend zipr --critical-step move_globals=on --critical-step selective_cfi=on --step-option selective_cfi:--multimodule --step-option move_globals:--elftables-only --step-option fix_calls:--no-fix-safefn --step-option selective_cfi:--exe-nonce-for-call --step-option zipr:"--add-sections false" --step-option selective_cfi:"--exe-nonce-size 2" --step-option selective_cfi:"--nonce-size 2" --step-option selective_cfi:--color-exe-nonces + (set -x; $PS $1 $2 --backend zipr --critical-step move_globals=on --critical-step selective_cfi=on --step-option selective_cfi:--multimodule --step-option move_globals:--elftables-only --step-option fix_calls:--no-fix-safefn --step-option selective_cfi:--exe-nonce-for-call --step-option zipr:"--add-sections false" --step-option selective_cfi:"--exe-nonce-size 2" --step-option selective_cfi:"--nonce-size 2" --step-option selective_cfi:--color-exe-nonces) } do_cfi_exe_nonces_2_byte_4_byte_non_exe_color_exe() { - $PS $1 $2 --backend zipr --critical-step move_globals=on --critical-step selective_cfi=on --step-option selective_cfi:--multimodule --step-option move_globals:--elftables-only --step-option fix_calls:--no-fix-safefn --step-option selective_cfi:--exe-nonce-for-call --step-option zipr:"--add-sections false" --step-option selective_cfi:"--exe-nonce-size 2" --step-option selective_cfi:"--nonce-size 4" --step-option selective_cfi:--color-exe-nonces + (set -x; $PS $1 $2 --backend zipr --critical-step move_globals=on --critical-step selective_cfi=on --step-option selective_cfi:--multimodule --step-option move_globals:--elftables-only --step-option fix_calls:--no-fix-safefn --step-option selective_cfi:--exe-nonce-for-call --step-option zipr:"--add-sections false" --step-option selective_cfi:"--exe-nonce-size 2" --step-option selective_cfi:"--nonce-size 4" --step-option selective_cfi:--color-exe-nonces) } do_cfi_exe_nonces_2_byte_8_byte_non_exe_color_exe() { - $PS $1 $2 --backend zipr --critical-step move_globals=on --critical-step selective_cfi=on --step-option selective_cfi:--multimodule --step-option move_globals:--elftables-only --step-option fix_calls:--no-fix-safefn --step-option selective_cfi:--exe-nonce-for-call --step-option zipr:"--add-sections false" --step-option selective_cfi:"--exe-nonce-size 2" --step-option selective_cfi:"--nonce-size 8" --step-option selective_cfi:--color-exe-nonces + (set -x; $PS $1 $2 --backend zipr --critical-step move_globals=on --critical-step selective_cfi=on --step-option selective_cfi:--multimodule --step-option move_globals:--elftables-only --step-option fix_calls:--no-fix-safefn --step-option selective_cfi:--exe-nonce-for-call --step-option zipr:"--add-sections false" --step-option selective_cfi:"--exe-nonce-size 2" --step-option selective_cfi:"--nonce-size 8" --step-option selective_cfi:--color-exe-nonces) } do_cfi_exe_nonces_8_byte_2_byte_non_exe_color_exe() { - $PS $1 $2 --backend zipr --critical-step move_globals=on --critical-step selective_cfi=on --step-option selective_cfi:--multimodule --step-option move_globals:--elftables-only --step-option fix_calls:--no-fix-safefn --step-option selective_cfi:--exe-nonce-for-call --step-option zipr:"--add-sections false" --step-option selective_cfi:"--exe-nonce-size 8" --step-option selective_cfi:"--nonce-size 2" --step-option selective_cfi:--color-exe-nonces + (set -x; $PS $1 $2 --backend zipr --critical-step move_globals=on --critical-step selective_cfi=on --step-option selective_cfi:--multimodule --step-option move_globals:--elftables-only --step-option fix_calls:--no-fix-safefn --step-option selective_cfi:--exe-nonce-for-call --step-option zipr:"--add-sections false" --step-option selective_cfi:"--exe-nonce-size 8" --step-option selective_cfi:"--nonce-size 2" --step-option selective_cfi:--color-exe-nonces) } do_cfi_exe_nonces_8_byte_4_byte_non_exe_color_exe() { - $PS $1 $2 --backend zipr --critical-step move_globals=on --critical-step selective_cfi=on --step-option selective_cfi:--multimodule --step-option move_globals:--elftables-only --step-option fix_calls:--no-fix-safefn --step-option selective_cfi:--exe-nonce-for-call --step-option zipr:"--add-sections false" --step-option selective_cfi:"--exe-nonce-size 8" --step-option selective_cfi:"--nonce-size 4" --step-option selective_cfi:--color-exe-nonces + (set -x; $PS $1 $2 --backend zipr --critical-step move_globals=on --critical-step selective_cfi=on --step-option selective_cfi:--multimodule --step-option move_globals:--elftables-only --step-option fix_calls:--no-fix-safefn --step-option selective_cfi:--exe-nonce-for-call --step-option zipr:"--add-sections false" --step-option selective_cfi:"--exe-nonce-size 8" --step-option selective_cfi:"--nonce-size 4" --step-option selective_cfi:--color-exe-nonces) } do_cfi_exe_nonces_8_byte_8_byte_non_exe_color_exe() { - $PS $1 $2 --backend zipr --critical-step move_globals=on --critical-step selective_cfi=on --step-option selective_cfi:--multimodule --step-option move_globals:--elftables-only --step-option fix_calls:--no-fix-safefn --step-option selective_cfi:--exe-nonce-for-call --step-option zipr:"--add-sections false" --step-option selective_cfi:"--exe-nonce-size 8" --step-option selective_cfi:"--nonce-size 8" --step-option selective_cfi:--color-exe-nonces + (set -x; $PS $1 $2 --backend zipr --critical-step move_globals=on --critical-step selective_cfi=on --step-option selective_cfi:--multimodule --step-option move_globals:--elftables-only --step-option fix_calls:--no-fix-safefn --step-option selective_cfi:--exe-nonce-for-call --step-option zipr:"--add-sections false" --step-option selective_cfi:"--exe-nonce-size 8" --step-option selective_cfi:"--nonce-size 8" --step-option selective_cfi:--color-exe-nonces) } ############################################################################### do_cfi_exe_nonces_color_both() { - $PS $1 $2 --backend zipr --critical-step move_globals=on --critical-step selective_cfi=on --step-option selective_cfi:--multimodule --step-option move_globals:--elftables-only --step-option fix_calls:--no-fix-safefn --step-option selective_cfi:--exe-nonce-for-call --step-option zipr:"--add-sections false" --step-option selective_cfi:--color-exe-nonces --step-option selective_cfi:--color + (set -x; $PS $1 $2 --backend zipr --critical-step move_globals=on --critical-step selective_cfi=on --step-option selective_cfi:--multimodule --step-option move_globals:--elftables-only --step-option fix_calls:--no-fix-safefn --step-option selective_cfi:--exe-nonce-for-call --step-option zipr:"--add-sections false" --step-option selective_cfi:--color-exe-nonces --step-option selective_cfi:--color) } do_cfi_exe_nonces_1_byte_color_both() { - $PS $1 $2 --backend zipr --critical-step move_globals=on --critical-step selective_cfi=on --step-option selective_cfi:--multimodule --step-option move_globals:--elftables-only --step-option fix_calls:--no-fix-safefn --step-option selective_cfi:--exe-nonce-for-call --step-option zipr:"--add-sections false" --step-option selective_cfi:"--exe-nonce-size 1" --step-option selective_cfi:--color-exe-nonces --step-option selective_cfi:--color + (set -x; $PS $1 $2 --backend zipr --critical-step move_globals=on --critical-step selective_cfi=on --step-option selective_cfi:--multimodule --step-option move_globals:--elftables-only --step-option fix_calls:--no-fix-safefn --step-option selective_cfi:--exe-nonce-for-call --step-option zipr:"--add-sections false" --step-option selective_cfi:"--exe-nonce-size 1" --step-option selective_cfi:--color-exe-nonces --step-option selective_cfi:--color) } do_cfi_exe_nonces_2_byte_color_both() { - $PS $1 $2 --backend zipr --critical-step move_globals=on --critical-step selective_cfi=on --step-option selective_cfi:--multimodule --step-option move_globals:--elftables-only --step-option fix_calls:--no-fix-safefn --step-option selective_cfi:--exe-nonce-for-call --step-option zipr:"--add-sections false" --step-option selective_cfi:"--exe-nonce-size 2" --step-option selective_cfi:--color-exe-nonces --step-option selective_cfi:--color + (set -x; $PS $1 $2 --backend zipr --critical-step move_globals=on --critical-step selective_cfi=on --step-option selective_cfi:--multimodule --step-option move_globals:--elftables-only --step-option fix_calls:--no-fix-safefn --step-option selective_cfi:--exe-nonce-for-call --step-option zipr:"--add-sections false" --step-option selective_cfi:"--exe-nonce-size 2" --step-option selective_cfi:--color-exe-nonces --step-option selective_cfi:--color) } do_cfi_exe_nonces_8_byte_color_both() { - $PS $1 $2 --backend zipr --critical-step move_globals=on --critical-step selective_cfi=on --step-option selective_cfi:--multimodule --step-option move_globals:--elftables-only --step-option fix_calls:--no-fix-safefn --step-option selective_cfi:--exe-nonce-for-call --step-option zipr:"--add-sections false" --step-option selective_cfi:"--exe-nonce-size 8" --step-option selective_cfi:--color-exe-nonces --step-option selective_cfi:--color + (set -x; $PS $1 $2 --backend zipr --critical-step move_globals=on --critical-step selective_cfi=on --step-option selective_cfi:--multimodule --step-option move_globals:--elftables-only --step-option fix_calls:--no-fix-safefn --step-option selective_cfi:--exe-nonce-for-call --step-option zipr:"--add-sections false" --step-option selective_cfi:"--exe-nonce-size 8" --step-option selective_cfi:--color-exe-nonces --step-option selective_cfi:--color) } do_cfi_exe_nonces_2_byte_non_exe_color_both() { - $PS $1 $2 --backend zipr --critical-step move_globals=on --critical-step selective_cfi=on --step-option selective_cfi:--multimodule --step-option move_globals:--elftables-only --step-option fix_calls:--no-fix-safefn --step-option selective_cfi:--exe-nonce-for-call --step-option zipr:"--add-sections false" --step-option selective_cfi:"--nonce-size 2" --step-option selective_cfi:--color-exe-nonces --step-option selective_cfi:--color + (set -x; $PS $1 $2 --backend zipr --critical-step move_globals=on --critical-step selective_cfi=on --step-option selective_cfi:--multimodule --step-option move_globals:--elftables-only --step-option fix_calls:--no-fix-safefn --step-option selective_cfi:--exe-nonce-for-call --step-option zipr:"--add-sections false" --step-option selective_cfi:"--nonce-size 2" --step-option selective_cfi:--color-exe-nonces --step-option selective_cfi:--color) } do_cfi_exe_nonces_4_byte_non_exe_color_both() { - $PS $1 $2 --backend zipr --critical-step move_globals=on --critical-step selective_cfi=on --step-option selective_cfi:--multimodule --step-option move_globals:--elftables-only --step-option fix_calls:--no-fix-safefn --step-option selective_cfi:--exe-nonce-for-call --step-option zipr:"--add-sections false" --step-option selective_cfi:"--nonce-size 4" --step-option selective_cfi:--color-exe-nonces --step-option selective_cfi:--color + (set -x; $PS $1 $2 --backend zipr --critical-step move_globals=on --critical-step selective_cfi=on --step-option selective_cfi:--multimodule --step-option move_globals:--elftables-only --step-option fix_calls:--no-fix-safefn --step-option selective_cfi:--exe-nonce-for-call --step-option zipr:"--add-sections false" --step-option selective_cfi:"--nonce-size 4" --step-option selective_cfi:--color-exe-nonces --step-option selective_cfi:--color) } do_cfi_exe_nonces_8_byte_non_exe_color_both() { - $PS $1 $2 --backend zipr --critical-step move_globals=on --critical-step selective_cfi=on --step-option selective_cfi:--multimodule --step-option move_globals:--elftables-only --step-option fix_calls:--no-fix-safefn --step-option selective_cfi:--exe-nonce-for-call --step-option zipr:"--add-sections false" --step-option selective_cfi:"--nonce-size 8" --step-option selective_cfi:--color-exe-nonces --step-option selective_cfi:--color + (set -x; $PS $1 $2 --backend zipr --critical-step move_globals=on --critical-step selective_cfi=on --step-option selective_cfi:--multimodule --step-option move_globals:--elftables-only --step-option fix_calls:--no-fix-safefn --step-option selective_cfi:--exe-nonce-for-call --step-option zipr:"--add-sections false" --step-option selective_cfi:"--nonce-size 8" --step-option selective_cfi:--color-exe-nonces --step-option selective_cfi:--color) } do_cfi_exe_nonces_1_byte_2_byte_non_exe_color_both() { - $PS $1 $2 --backend zipr --critical-step move_globals=on --critical-step selective_cfi=on --step-option selective_cfi:--multimodule --step-option move_globals:--elftables-only --step-option fix_calls:--no-fix-safefn --step-option selective_cfi:--exe-nonce-for-call --step-option zipr:"--add-sections false" --step-option selective_cfi:"--exe-nonce-size 1" --step-option selective_cfi:"--nonce-size 2" --step-option selective_cfi:--color-exe-nonces --step-option selective_cfi:--color + (set -x; $PS $1 $2 --backend zipr --critical-step move_globals=on --critical-step selective_cfi=on --step-option selective_cfi:--multimodule --step-option move_globals:--elftables-only --step-option fix_calls:--no-fix-safefn --step-option selective_cfi:--exe-nonce-for-call --step-option zipr:"--add-sections false" --step-option selective_cfi:"--exe-nonce-size 1" --step-option selective_cfi:"--nonce-size 2" --step-option selective_cfi:--color-exe-nonces --step-option selective_cfi:--color) } do_cfi_exe_nonces_1_byte_4_byte_non_exe_color_both() { - $PS $1 $2 --backend zipr --critical-step move_globals=on --critical-step selective_cfi=on --step-option selective_cfi:--multimodule --step-option move_globals:--elftables-only --step-option fix_calls:--no-fix-safefn --step-option selective_cfi:--exe-nonce-for-call --step-option zipr:"--add-sections false" --step-option selective_cfi:"--exe-nonce-size 1" --step-option selective_cfi:"--nonce-size 4" --step-option selective_cfi:--color-exe-nonces --step-option selective_cfi:--color + (set -x; $PS $1 $2 --backend zipr --critical-step move_globals=on --critical-step selective_cfi=on --step-option selective_cfi:--multimodule --step-option move_globals:--elftables-only --step-option fix_calls:--no-fix-safefn --step-option selective_cfi:--exe-nonce-for-call --step-option zipr:"--add-sections false" --step-option selective_cfi:"--exe-nonce-size 1" --step-option selective_cfi:"--nonce-size 4" --step-option selective_cfi:--color-exe-nonces --step-option selective_cfi:--color) } do_cfi_exe_nonces_1_byte_8_byte_non_exe_color_both() { - $PS $1 $2 --backend zipr --critical-step move_globals=on --critical-step selective_cfi=on --step-option selective_cfi:--multimodule --step-option move_globals:--elftables-only --step-option fix_calls:--no-fix-safefn --step-option selective_cfi:--exe-nonce-for-call --step-option zipr:"--add-sections false" --step-option selective_cfi:"--exe-nonce-size 1" --step-option selective_cfi:"--nonce-size 8" --step-option selective_cfi:--color-exe-nonces --step-option selective_cfi:--color + (set -x; $PS $1 $2 --backend zipr --critical-step move_globals=on --critical-step selective_cfi=on --step-option selective_cfi:--multimodule --step-option move_globals:--elftables-only --step-option fix_calls:--no-fix-safefn --step-option selective_cfi:--exe-nonce-for-call --step-option zipr:"--add-sections false" --step-option selective_cfi:"--exe-nonce-size 1" --step-option selective_cfi:"--nonce-size 8" --step-option selective_cfi:--color-exe-nonces --step-option selective_cfi:--color) } do_cfi_exe_nonces_2_byte_2_byte_non_exe_color_both() { - $PS $1 $2 --backend zipr --critical-step move_globals=on --critical-step selective_cfi=on --step-option selective_cfi:--multimodule --step-option move_globals:--elftables-only --step-option fix_calls:--no-fix-safefn --step-option selective_cfi:--exe-nonce-for-call --step-option zipr:"--add-sections false" --step-option selective_cfi:"--exe-nonce-size 2" --step-option selective_cfi:"--nonce-size 2" --step-option selective_cfi:--color-exe-nonces --step-option selective_cfi:--color + (set -x; $PS $1 $2 --backend zipr --critical-step move_globals=on --critical-step selective_cfi=on --step-option selective_cfi:--multimodule --step-option move_globals:--elftables-only --step-option fix_calls:--no-fix-safefn --step-option selective_cfi:--exe-nonce-for-call --step-option zipr:"--add-sections false" --step-option selective_cfi:"--exe-nonce-size 2" --step-option selective_cfi:"--nonce-size 2" --step-option selective_cfi:--color-exe-nonces --step-option selective_cfi:--color) } do_cfi_exe_nonces_2_byte_4_byte_non_exe_color_both() { - $PS $1 $2 --backend zipr --critical-step move_globals=on --critical-step selective_cfi=on --step-option selective_cfi:--multimodule --step-option move_globals:--elftables-only --step-option fix_calls:--no-fix-safefn --step-option selective_cfi:--exe-nonce-for-call --step-option zipr:"--add-sections false" --step-option selective_cfi:"--exe-nonce-size 2" --step-option selective_cfi:"--nonce-size 4" --step-option selective_cfi:--color-exe-nonces --step-option selective_cfi:--color + (set -x; $PS $1 $2 --backend zipr --critical-step move_globals=on --critical-step selective_cfi=on --step-option selective_cfi:--multimodule --step-option move_globals:--elftables-only --step-option fix_calls:--no-fix-safefn --step-option selective_cfi:--exe-nonce-for-call --step-option zipr:"--add-sections false" --step-option selective_cfi:"--exe-nonce-size 2" --step-option selective_cfi:"--nonce-size 4" --step-option selective_cfi:--color-exe-nonces --step-option selective_cfi:--color) } do_cfi_exe_nonces_2_byte_8_byte_non_exe_color_both() { - $PS $1 $2 --backend zipr --critical-step move_globals=on --critical-step selective_cfi=on --step-option selective_cfi:--multimodule --step-option move_globals:--elftables-only --step-option fix_calls:--no-fix-safefn --step-option selective_cfi:--exe-nonce-for-call --step-option zipr:"--add-sections false" --step-option selective_cfi:"--exe-nonce-size 2" --step-option selective_cfi:"--nonce-size 8" --step-option selective_cfi:--color-exe-nonces --step-option selective_cfi:--color + (set -x; $PS $1 $2 --backend zipr --critical-step move_globals=on --critical-step selective_cfi=on --step-option selective_cfi:--multimodule --step-option move_globals:--elftables-only --step-option fix_calls:--no-fix-safefn --step-option selective_cfi:--exe-nonce-for-call --step-option zipr:"--add-sections false" --step-option selective_cfi:"--exe-nonce-size 2" --step-option selective_cfi:"--nonce-size 8" --step-option selective_cfi:--color-exe-nonces --step-option selective_cfi:--color) } do_cfi_exe_nonces_8_byte_2_byte_non_exe_color_both() { - $PS $1 $2 --backend zipr --critical-step move_globals=on --critical-step selective_cfi=on --step-option selective_cfi:--multimodule --step-option move_globals:--elftables-only --step-option fix_calls:--no-fix-safefn --step-option selective_cfi:--exe-nonce-for-call --step-option zipr:"--add-sections false" --step-option selective_cfi:"--exe-nonce-size 8" --step-option selective_cfi:"--nonce-size 2" --step-option selective_cfi:--color-exe-nonces --step-option selective_cfi:--color + (set -x; $PS $1 $2 --backend zipr --critical-step move_globals=on --critical-step selective_cfi=on --step-option selective_cfi:--multimodule --step-option move_globals:--elftables-only --step-option fix_calls:--no-fix-safefn --step-option selective_cfi:--exe-nonce-for-call --step-option zipr:"--add-sections false" --step-option selective_cfi:"--exe-nonce-size 8" --step-option selective_cfi:"--nonce-size 2" --step-option selective_cfi:--color-exe-nonces --step-option selective_cfi:--color) } do_cfi_exe_nonces_8_byte_4_byte_non_exe_color_both() { - $PS $1 $2 --backend zipr --critical-step move_globals=on --critical-step selective_cfi=on --step-option selective_cfi:--multimodule --step-option move_globals:--elftables-only --step-option fix_calls:--no-fix-safefn --step-option selective_cfi:--exe-nonce-for-call --step-option zipr:"--add-sections false" --step-option selective_cfi:"--exe-nonce-size 8" --step-option selective_cfi:"--nonce-size 4" --step-option selective_cfi:--color-exe-nonces --step-option selective_cfi:--color + (set -x; $PS $1 $2 --backend zipr --critical-step move_globals=on --critical-step selective_cfi=on --step-option selective_cfi:--multimodule --step-option move_globals:--elftables-only --step-option fix_calls:--no-fix-safefn --step-option selective_cfi:--exe-nonce-for-call --step-option zipr:"--add-sections false" --step-option selective_cfi:"--exe-nonce-size 8" --step-option selective_cfi:"--nonce-size 4" --step-option selective_cfi:--color-exe-nonces --step-option selective_cfi:--color) } do_cfi_exe_nonces_8_byte_8_byte_non_exe_color_both() { - $PS $1 $2 --backend zipr --critical-step move_globals=on --critical-step selective_cfi=on --step-option selective_cfi:--multimodule --step-option move_globals:--elftables-only --step-option fix_calls:--no-fix-safefn --step-option selective_cfi:--exe-nonce-for-call --step-option zipr:"--add-sections false" --step-option selective_cfi:"--exe-nonce-size 8" --step-option selective_cfi:"--nonce-size 8" --step-option selective_cfi:--color-exe-nonces --step-option selective_cfi:--color + (set -x; $PS $1 $2 --backend zipr --critical-step move_globals=on --critical-step selective_cfi=on --step-option selective_cfi:--multimodule --step-option move_globals:--elftables-only --step-option fix_calls:--no-fix-safefn --step-option selective_cfi:--exe-nonce-for-call --step-option zipr:"--add-sections false" --step-option selective_cfi:"--exe-nonce-size 8" --step-option selective_cfi:"--nonce-size 8" --step-option selective_cfi:--color-exe-nonces --step-option selective_cfi:--color) } diff --git a/tools/selective_cfi/tests/test_fib.sh b/tools/selective_cfi/tests/test_fib.sh index 396988bf4219529c880ce5592545ff827f729078..4cb29073dd4790c9409e5ba1ccbf56cdb2f64e5a 100755 --- a/tools/selective_cfi/tests/test_fib.sh +++ b/tools/selective_cfi/tests/test_fib.sh @@ -71,12 +71,12 @@ protect() clean() { - rm out - rm correct + rm -f out + rm -f correct rm -Rf fib.exe* peasoup_exe* lib*.so* for config in "${configs[@]}"; do - rm *."$config" + rm -f *."$config" done } diff --git a/xform/Makefile.in b/xform/Makefile.in deleted file mode 100644 index 04547b0f217c6a22d816f1c7f1f43d10901778e6..0000000000000000000000000000000000000000 --- a/xform/Makefile.in +++ /dev/null @@ -1,46 +0,0 @@ -# -# Makefile.in - DESCRIPTION. -# -# Copyright (c) 2011 - University of Virginia -# -# This file may be used and modified for non-commercial purposes as long as -# all copyright, permission, and nonwarranty notices are preserved. -# -# Please contact the authors for restrictions applying to commercial use. -# -# THIS SOURCE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED -# WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF -# MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. -# - -CC=@CXX@ -CFLAGS= -DUBUNTU -g -DIR=.. -INCLUDEDIR=${DIR}/include -INCLUDE=-I${INCLUDEDIR} -I. -I${DIR}/beaengine/include -LIB=libxform.a - -OBJS= instruction_descriptor.o function_descriptor.o elfreader.o null_transform.o rewriter.o spri_alloc.o gen_hash.o constant_hash.o funclist_hash.o instrmap_hash.o framerestore_hash.o stackref_hash.o - -.SUFFIXES: .o .c .cpp - -.cpp.o .c.o: - $(CC) $(CFLAGS) $(INCLUDE) -c $< - - -all: ../lib/$(LIB) - echo $(LIB) build complete - -$(LIB): $(OBJS) - ar -r $(LIB) $(OBJS) - -../lib/$(LIB): $(LIB) - cp $(LIB) ../lib/ - -clean: - rm -f *.o core *.a - -stackref_hash.o gen_hash.o: *.h stackref_hash.c gen_hash.c - $(CC) $(CFLAGS) $(INCLUDE) -fomit-frame-pointer -c $*.c - -$(OBJS): *.h diff --git a/xform/elfreader.h b/xform/elfreader.h deleted file mode 100644 index 23ae15bd471132ab08312d8c6898e72d8aea9fff..0000000000000000000000000000000000000000 --- a/xform/elfreader.h +++ /dev/null @@ -1,38 +0,0 @@ -#ifndef _elfreader_H_ -#define _elfreader_H_ - -#include <vector> -// #include "elfio/elfio.hpp" -#include "exeio.h" -#include "targ-config.h" -#include <assert.h> - - -// doing this is very bad. -// using namespace std; -// using namespace ELFIO; - -class ElfReader -{ - public: - ElfReader(char *); - virtual ~ElfReader(); - - std::string read(app_iaddr_t p_pc, unsigned p_numBytes); - bool read(app_iaddr_t p_pc, unsigned p_numBytes, char* p_buf); - char* getInstructionBuffer(app_iaddr_t p_pc); - - bool isElf32() { assert(m_reader); return m_reader->get_class()==EXEIO::ELF32; } - bool isElf64() { assert(m_reader); return m_reader->get_class()==EXEIO::ELF64; } - bool isPe32() { assert(m_reader); return m_reader->get_class()==EXEIO::PE32; } - bool isPe64() { assert(m_reader); return m_reader->get_class()==EXEIO::PE64; } - - private: -// ELFIO::elfio* m_reader; - EXEIO::exeio* m_reader; - -// std::vector < const ELFIO::section* > m_sections; - -}; - -#endif