diff --git a/.gitattributes b/.gitattributes index 7c99ab9ae1853e07fbdd6764251d51cf1d989137..35aa5c324058ca9252db405ab8b97e5d61a38996 100644 --- a/.gitattributes +++ b/.gitattributes @@ -234,16 +234,20 @@ libIRDB/test/read_variantir.cpp -text libIRDB/test/unfix_calls.cpp -text libIRDB/test/unwind-pe.h -text libMEDSannotation/Makefile -text +libMEDSannotation/include/FuncExitAnnotation.hpp -text libMEDSannotation/include/MEDS.hpp -text libMEDSannotation/include/MEDS_AnnotationBase.hpp -text libMEDSannotation/include/MEDS_AnnotationParser.hpp -text +libMEDSannotation/include/MEDS_FRSafeAnnotation.hpp -text libMEDSannotation/include/MEDS_FuncAnnotation.hpp -text libMEDSannotation/include/MEDS_InstructionCheckAnnotation.hpp -text libMEDSannotation/include/MEDS_ProblemFuncAnnotation.hpp -text libMEDSannotation/include/MEDS_Register.hpp -text libMEDSannotation/include/MEDS_SafeFuncAnnotation.hpp -text libMEDSannotation/include/VirtualOffset.hpp -text +libMEDSannotation/src/FuncExitAnnotation.cpp -text libMEDSannotation/src/MEDS_AnnotationParser.cpp -text +libMEDSannotation/src/MEDS_FRSafeAnnotation.cpp -text libMEDSannotation/src/MEDS_InstructionCheckAnnotation.cpp -text libMEDSannotation/src/MEDS_ProblemFuncAnnotation.cpp -text libMEDSannotation/src/MEDS_Register.cpp -text @@ -401,6 +405,8 @@ tools/ret_shadow_stack/Makefile -text tools/ret_shadow_stack/rss_driver.cpp -text tools/ret_shadow_stack/rss_instrument.cpp -text tools/ret_shadow_stack/rss_instrument.hpp -text +tools/safefr/Makefile -text +tools/safefr/fill_in_safefr.cpp -text tools/spasm/Makefile -text tools/spasm/ben_lib.cpp -text tools/spasm/ben_lib.h -text diff --git a/libIRDB/test/fix_calls.cpp b/libIRDB/test/fix_calls.cpp index c8406a6fa3956a89cb3314ab06394a58d1772d44..00a179dea7ee2bdc908f37b29b9bb7118ba4f9f7 100644 --- a/libIRDB/test/fix_calls.cpp +++ b/libIRDB/test/fix_calls.cpp @@ -58,6 +58,16 @@ bool check_entry(bool &found, ControlFlowGraph_t* cfg) bool call_needs_fix(Instruction_t* insn) { + + for(set<Relocation_t*>::iterator it=insn->GetRelocations().begin(); + it!=insn->GetRelocations().end(); + ++it + ) + { + Relocation_t* reloc=*it; + if(string("safefr") == reloc->GetType()) + return false; + } Instruction_t *target=insn->GetTarget(); Instruction_t *fallthru=insn->GetFallthrough(); DISASM disasm; @@ -698,6 +708,29 @@ void fix_other_pcrel(FileIR_t* firp, Instruction_t *insn, UIntPtr virt_offset) } } +void fix_safefr(FileIR_t* firp, Instruction_t *insn, UIntPtr virt_offset) +{ + /* if this has already been fixed, we can skip it */ + if(virt_offset==0 || virt_offset==-1) + return; + + for(set<Relocation_t*>::iterator it=insn->GetRelocations().begin(); + it!=insn->GetRelocations().end(); + ++it) + { + Relocation_t* reloc=*it; + assert(reloc); + if(string("safefr") == reloc->GetType()) + { + AddressID_t* addr =new AddressID_t; + addr->SetFileID(insn->GetAddress()->GetFileID()); + firp->GetAddresses().insert(addr); + insn->SetAddress(addr); + } + } +} + + void fix_other_pcrel(FileIR_t* firp) { @@ -709,6 +742,7 @@ void fix_other_pcrel(FileIR_t* firp) { Instruction_t* insn=*it; fix_other_pcrel(firp,insn, insn->GetAddress()->GetVirtualOffset()); + fix_safefr(firp,insn, insn->GetAddress()->GetVirtualOffset()); } } diff --git a/libMEDSannotation/include/FuncExitAnnotation.hpp b/libMEDSannotation/include/FuncExitAnnotation.hpp new file mode 100644 index 0000000000000000000000000000000000000000..b02764e71e93c3fc34517e78d399de60cc51cc52 --- /dev/null +++ b/libMEDSannotation/include/FuncExitAnnotation.hpp @@ -0,0 +1,37 @@ +#ifndef _FUNCEXITANNOTATION_H_ +#define _FUNCEXITANNOTATION_H_ + +#include <string> +#include "VirtualOffset.hpp" +#include "MEDS_Register.hpp" +#include "MEDS_AnnotationBase.hpp" + + +namespace MEDS_Annotation +{ + +using namespace std; +using namespace MEDS_Annotation; + +// +// Class to handle one MEDS annotation +// +class MEDS_FuncExitAnnotation : public MEDS_AnnotationBase +{ + public: + MEDS_FuncExitAnnotation() {}; + MEDS_FuncExitAnnotation(const string &p_rawLine); + virtual ~MEDS_FuncExitAnnotation(){} + + virtual const string toString() const { return "tail call: "+m_rawInputLine; } + + private: + void init(); + void parse(); + + private: + std::string m_rawInputLine; +}; + +} +#endif diff --git a/libMEDSannotation/include/MEDS_AnnotationParser.hpp b/libMEDSannotation/include/MEDS_AnnotationParser.hpp index 8305b4f3c0e0a05224a8f6782e8f0e8d3e8e2983..d353a2f4148449853ee74a179d8ad17f8fedd6fc 100644 --- a/libMEDSannotation/include/MEDS_AnnotationParser.hpp +++ b/libMEDSannotation/include/MEDS_AnnotationParser.hpp @@ -23,8 +23,8 @@ class MEDS_AnnotationParser MEDS_AnnotationParser(std::istream &); /* pass opened file */ void parseFile(std::istream &); void parseFile(const std::string &); /* pass filename */ - MEDS_Annotations_t getAnnotations() { return m_annotations; } - MEDS_FuncAnnotations_t getFuncAnnotations() { return m_func_annotations; } + MEDS_Annotations_t & getAnnotations() { return m_annotations; } + MEDS_FuncAnnotations_t & getFuncAnnotations() { return m_func_annotations; } private: MEDS_Annotations_t m_annotations; diff --git a/libMEDSannotation/include/MEDS_FRSafeAnnotation.hpp b/libMEDSannotation/include/MEDS_FRSafeAnnotation.hpp new file mode 100644 index 0000000000000000000000000000000000000000..1a43102af73dba6429c3c9a8994bc102dc2d0bab --- /dev/null +++ b/libMEDSannotation/include/MEDS_FRSafeAnnotation.hpp @@ -0,0 +1,37 @@ +#ifndef _MEDS_FRSAFEANNOTATION_H_ +#define _MEDS_FRSAFEANNOTATION_H_ + +#include <string> +#include "VirtualOffset.hpp" +#include "MEDS_Register.hpp" +#include "MEDS_AnnotationBase.hpp" + + +namespace MEDS_Annotation +{ + +using namespace std; +using namespace MEDS_Annotation; + +// +// Class to handle one MEDS (integer vulnerability) annotation +// +class MEDS_FRSafeAnnotation : public MEDS_AnnotationBase +{ + public: + MEDS_FRSafeAnnotation() {}; + MEDS_FRSafeAnnotation(const string &p_rawLine); + virtual ~MEDS_FRSafeAnnotation(){} + + virtual const string toString() const { return "fr safe func: "+m_rawInputLine; } + + private: + void init(); + void parse(); + + private: + std::string m_rawInputLine; +}; + +} +#endif diff --git a/libMEDSannotation/src/FuncExitAnnotation.cpp b/libMEDSannotation/src/FuncExitAnnotation.cpp new file mode 100644 index 0000000000000000000000000000000000000000..a213c4dfb2483c2cb84c53ceba579efb1aa567b0 --- /dev/null +++ b/libMEDSannotation/src/FuncExitAnnotation.cpp @@ -0,0 +1,61 @@ +#include <stdlib.h> + +#include <iostream> +#include <cstdio> +#include <string> +#include <string.h> + +#include "MEDS_Register.hpp" +#include "FuncExitAnnotation.hpp" + +using namespace std; +using namespace MEDS_Annotation; + + + + + +MEDS_FuncExitAnnotation::MEDS_FuncExitAnnotation(const string &p_rawLine) +{ + init(); + m_rawInputLine=p_rawLine; + parse(); +} + +void MEDS_FuncExitAnnotation::init() +{ +} + + +/* + Example format -- subject to change: + 804925b 5 INSTR CALL TAILCALL jmp check_one_fd + + +*/ +void MEDS_FuncExitAnnotation::parse() +{ + + if (m_rawInputLine.find(" INSTR ")==string::npos) + return; + + if ( + m_rawInputLine.find(" INSTR RETURN ")==string::npos && + m_rawInputLine.find(" INSTR CALL TAILCALL ")==string::npos + ) + { + /* INSTR that's not for a safe fast return */ + return; + } + + // get offset + VirtualOffset vo(m_rawInputLine); + m_virtualOffset = vo; + + setValid(); // no additional info recorded for right now. + +// if(getenv("VERBOSE")!=NULL) + cout<<"Found TAILCALL annotation for "<<vo.to_string()<<endl; + +} + diff --git a/libMEDSannotation/src/MEDS_AnnotationParser.cpp b/libMEDSannotation/src/MEDS_AnnotationParser.cpp index f9cea504a134b9c75cfa6d3f19b5913b5f80c832..79aab05acd774b3166b2bdc197a78ea9dadd663d 100644 --- a/libMEDSannotation/src/MEDS_AnnotationParser.cpp +++ b/libMEDSannotation/src/MEDS_AnnotationParser.cpp @@ -3,8 +3,10 @@ #include "MEDS_AnnotationParser.hpp" #include "MEDS_InstructionCheckAnnotation.hpp" +#include "FuncExitAnnotation.hpp" #include "MEDS_SafeFuncAnnotation.hpp" #include "MEDS_ProblemFuncAnnotation.hpp" +#include "MEDS_FRSafeAnnotation.hpp" // @todo: multiple annotation per instruction @@ -62,6 +64,8 @@ void MEDS_AnnotationParser::parseFile(istream &p_inputStream) ADD_AND_CONTINUE_IF_VALID(MEDS_InstructionCheckAnnotation); ADD_AND_CONTINUE_IF_VALID(MEDS_SafeFuncAnnotation); ADD_AND_CONTINUE_IF_VALID(MEDS_ProblemFuncAnnotation); + ADD_AND_CONTINUE_IF_VALID(MEDS_FRSafeAnnotation); + ADD_AND_CONTINUE_IF_VALID(MEDS_FuncExitAnnotation); // cout<<"Found annotation: "<<annot->toString()<<endl;\ diff --git a/libMEDSannotation/src/MEDS_FRSafeAnnotation.cpp b/libMEDSannotation/src/MEDS_FRSafeAnnotation.cpp new file mode 100644 index 0000000000000000000000000000000000000000..2d4ba01a12c9ff117029bb161216e0cb7d992b1a --- /dev/null +++ b/libMEDSannotation/src/MEDS_FRSafeAnnotation.cpp @@ -0,0 +1,65 @@ +#include <stdlib.h> + +#include <iostream> +#include <cstdio> +#include <string> +#include <string.h> + +#include "MEDS_Register.hpp" +#include "MEDS_FRSafeAnnotation.hpp" + +using namespace std; +using namespace MEDS_Annotation; + + + + + +MEDS_FRSafeAnnotation::MEDS_FRSafeAnnotation(const string &p_rawLine) +{ + init(); + m_rawInputLine=p_rawLine; + parse(); +} + +void MEDS_FRSafeAnnotation::init() +{ +} + + +/* + Example format (as of July 31, 2014 ) -- subject to change: + + 804b3a6 5 INSTR CALL NOFASTRETURN RAUNSAFE ZZ call frame_dummy + 804c941 5 INSTR CALL FASTRETURN ZZ call _ZN7GString3cmpEPKc; GString::cmp(char const*) + 804c511 3 INSTR INDIRCALL NOFASTRETURN INDIRECT ZZ call dword ptr [eax+8] + 804c6fa 1 INSTR RETURN NOFASTRETURN NOCALLERS ZZ retn + +*/ +void MEDS_FRSafeAnnotation::parse() +{ + + if (m_rawInputLine.find(" INSTR ")==string::npos) + return; + + if ( + m_rawInputLine.find(" INSTR CALL FASTRETURN ")==string::npos && + m_rawInputLine.find(" INSTR INDCALL FASTRETURN ")==string::npos && + m_rawInputLine.find(" INSTR RETURN FASTRETURN ")==string::npos + ) + { + /* INSTR that's not for a safe fast return */ + return; + } + + // get offset + VirtualOffset vo(m_rawInputLine); + m_virtualOffset = vo; + + setValid(); // no additional info recorded for right now. + +// if(getenv("VERBOSE")!=NULL) + cout<<"Found FASTRETURN annotation for "<<vo.to_string()<<endl; + +} + diff --git a/libMEDSannotation/src/Makefile b/libMEDSannotation/src/Makefile index cb8d4eb0f935f5316aad68f751e3b1c9f860d69d..ef9151510c66861995edad75d06c7c9795c4927f 100644 --- a/libMEDSannotation/src/Makefile +++ b/libMEDSannotation/src/Makefile @@ -1,7 +1,7 @@ LIB=../lib/libMEDSannotation.a -OBJS=VirtualOffset.o MEDS_Register.o MEDS_AnnotationParser.o MEDS_InstructionCheckAnnotation.o MEDS_SafeFuncAnnotation.o MEDS_ProblemFuncAnnotation.o +OBJS=VirtualOffset.o MEDS_Register.o MEDS_AnnotationParser.o MEDS_InstructionCheckAnnotation.o MEDS_SafeFuncAnnotation.o MEDS_ProblemFuncAnnotation.o MEDS_FRSafeAnnotation.o FuncExitAnnotation.o all: $(OBJS) diff --git a/tools/ret_shadow_stack/rss_driver.cpp b/tools/ret_shadow_stack/rss_driver.cpp index 1401c37a3cba5b45086b7620a60d0f2e732178ff..cbc6442826727a6329a4b1a5213b0bdab0378514 100644 --- a/tools/ret_shadow_stack/rss_driver.cpp +++ b/tools/ret_shadow_stack/rss_driver.cpp @@ -72,6 +72,7 @@ int main(int argc, char **argv) cerr << "annotation file: " << annotationFilename << endl; annotationParser.parseFile(annotationFilename+".annot"); annotationParser.parseFile(annotationFilename+".infoannot"); + annotationParser.parseFile(annotationFilename+".STARScallreturn"); RSS_Instrument rssi(firp, &annotationParser); diff --git a/tools/ret_shadow_stack/rss_instrument.cpp b/tools/ret_shadow_stack/rss_instrument.cpp index cb8b9b6e0d1a624b73e7faa3f43f6cbcae36e937..7596db788df58959ccb6c723d7e3ce4b22be1507 100644 --- a/tools/ret_shadow_stack/rss_instrument.cpp +++ b/tools/ret_shadow_stack/rss_instrument.cpp @@ -1,6 +1,7 @@ #include "rss_instrument.hpp" #include "MEDS_SafeFuncAnnotation.hpp" +#include "FuncExitAnnotation.hpp" #include "MEDS_ProblemFuncAnnotation.hpp" #include "Rewrite_Utility.hpp" #include <stdlib.h> @@ -279,7 +280,24 @@ static bool add_rss_pop(FileIR_t* firp, Instruction_t* insn) tmp=insertAssemblyAfter(firp,tmp,"mov rcx, [fs:0x12345678] "); create_tls_reloc(firp,tmp); tmp=insertAssemblyAfter(firp,tmp,"lea rcx, [rcx-8]"); tmp=insertAssemblyAfter(firp,tmp,"mov [fs:0x12345678], rcx "); create_tls_reloc(firp,tmp); + + /* if tss_print_stack is on, we want to zero the old location just for easy printing. */ + /* doing so requires an extra register */ + if(getenv("tss_print_stack")!=NULL) + { + tmp=insertAssemblyAfter(firp,tmp,"push rax"); + tmp=insertAssemblyAfter(firp,tmp,"mov rax, rcx"); + } + + // load the old value tmp=insertAssemblyAfter(firp,tmp,"mov rcx, [rcx]"); + + /* if tss_print_stack is on, we want to zero the old location just for easy printing. */ + if(getenv("tss_print_stack")!=NULL) + { + tmp=insertAssemblyAfter(firp,tmp,"mov dword [rax], 0"); + tmp=insertAssemblyAfter(firp,tmp,"pop rax"); + } tmp=insertAssemblyAfter(firp,tmp,"sub rcx, [rsp+16]"); jmp_insn=tmp=insertDataBitsAfter(firp,tmp,getJecxzDataBits()); // jecxz L1 tmp=insertAssemblyAfter(firp,tmp,"hlt"); @@ -298,16 +316,46 @@ static bool add_rss_pop(FileIR_t* firp, Instruction_t* insn) return true; } -static bool is_exit_instruction(Instruction_t *insn) +static bool is_exit_instruction(Instruction_t *insn, MEDS_AnnotationParser *meds_ap) { DISASM d; insn->Disassemble(d); if(strstr(d.CompleteInstr,"ret")!=0) return true; + + assert(meds_ap); + std::pair<MEDS_Annotations_t::iterator,MEDS_Annotations_t::iterator> ret; + + virtual_offset_t irdb_vo = insn->GetAddress()->GetVirtualOffset(); + VirtualOffset vo(irdb_vo); + + /* find it in the annotations */ + ret = meds_ap->getAnnotations().equal_range(vo); + MEDS_FuncExitAnnotation annotation; + MEDS_FuncExitAnnotation* p_annotation; + + /* for each annotation for this instruction */ + for (MEDS_Annotations_t::iterator it = ret.first; it != ret.second; ++it) + { + /* is this annotation a funcSafe annotation? */ + p_annotation=dynamic_cast<MEDS_FuncExitAnnotation*>(it->second); + if(p_annotation==NULL) + continue; + + annotation = *p_annotation; + + /* bad annotation? */ + if(!annotation.isValid()) + continue; + + return true; + } + + /* couldn't find this insn as a function exit. */ return false; } -static bool add_rss_instrumentation(FileIR_t* firp, Function_t* func) +static bool add_rss_instrumentation(FileIR_t* firp, Function_t* func, MEDS_AnnotationParser *meds_ap) { bool success=true; if(func->GetEntryPoint()==NULL) @@ -316,8 +364,6 @@ static bool add_rss_instrumentation(FileIR_t* firp, Function_t* func) if(getenv("RSS_VERBOSE")!=NULL) cout<<"Transforming function "<<func->GetName()<<endl; - success&=add_rss_push(firp, func->GetEntryPoint()); - for( set<Instruction_t*>::iterator it=func->GetInstructions().begin(); @@ -326,10 +372,13 @@ static bool add_rss_instrumentation(FileIR_t* firp, Function_t* func) ) { Instruction_t* insn=*it; - if(is_exit_instruction(insn)) + if(is_exit_instruction(insn, meds_ap)) success&=add_rss_pop(firp, insn); } + /* need to do this second, as the function entry may actually change due to popping that may happen */ + success&=add_rss_push(firp, func->GetEntryPoint()); + return success; } @@ -446,7 +495,7 @@ bool RSS_Instrument::execute() if(func->GetEntryPoint()) cout<<"( "<<std::hex<<func->GetEntryPoint()->GetAddress()->GetVirtualOffset()<<")"; cout<<endl; - success|=add_rss_instrumentation(firp,func); + success|=add_rss_instrumentation(firp,func, meds_ap); } else { diff --git a/tools/safefr/Makefile b/tools/safefr/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..8b08b2f9bc3049391c662a1dc93cd06f91da3d48 --- /dev/null +++ b/tools/safefr/Makefile @@ -0,0 +1,23 @@ + + +INCLUDES= -I $(SECURITY_TRANSFORMS_HOME)/include -I$(SECURITY_TRANSFORMS_HOME)/beaengine/include -I $(SECURITY_TRANSFORMS_HOME)/libIRDB/include/ -I$(SECURITY_TRANSFORMS_HOME)/libMEDSannotation/include/ +LIBS= -L$(SECURITY_TRANSFORMS_HOME)/lib -lIRDB-core -lIRDB-cfg -lpqxx -L $(SECURITY_TRANSFORMS_HOME)/beaengine/lib/Linux.gnu.Debug -lBeaEngine_s_d -lMEDSannotation + +OPT=-g +.SUFFIXES: .exe .cpp + +PROGS=fill_in_safefr.exe + +all: $(PROGS) + +$(PROGS): ../../lib/* + + +.o.exe: $< $(SECURITY_TRANSFORMS_HOME)/lib/*.a + g++ $< $(INCLUDES) $(LIBS) $(OPT) -o $@ + +.cpp.o: $< + g++ $< $(INCLUDES) $(LIBS) $(OPT) -o $@ -c + +clean: + rm -f $(PROGS) *.o diff --git a/tools/safefr/fill_in_safefr.cpp b/tools/safefr/fill_in_safefr.cpp new file mode 100644 index 0000000000000000000000000000000000000000..6f705260bfc94ba1339fee39c38f399e1c2bc83c --- /dev/null +++ b/tools/safefr/fill_in_safefr.cpp @@ -0,0 +1,142 @@ + + +#include <libIRDB-core.hpp> +#include <iostream> +#include <fstream> +#include <stdlib.h> +#include <cctype> +#include <assert.h> + +#include "targ-config.h" + +#include "MEDS_AnnotationParser.hpp" +#include "MEDS_FRSafeAnnotation.hpp" + +using namespace libIRDB; +using namespace std; +using namespace MEDS_Annotation; + + +#define BINARY_NAME "a.ncexe" +#define SHARED_OBJECTS_DIR "shared_objects" + +static void add_annotations(FileIR_t* firp) +{ + char *fileBasename = basename((char*)firp->GetFile()->GetURL().c_str()); + + cout<<"Adding FR annotations to "<<firp->GetFile()->GetURL()<<endl; + + + MEDS_AnnotationParser annotationParser; + string annotationFilename; + // 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 (strcmp(fileBasename, BINARY_NAME) == 0) + annotationFilename = string(BINARY_NAME); + else + annotationFilename = string(SHARED_OBJECTS_DIR) + "/" + fileBasename ; + + cerr << "annotation file: " << annotationFilename << endl; + annotationParser.parseFile(annotationFilename+".STARScallreturn"); + + // now, look through each instruction and match the insn to the annotation. + + cout<< "Annot size is "<<std::dec<< annotationParser.getAnnotations().size() << endl; + + for(set<Instruction_t*>::iterator it=firp->GetInstructions().begin(); + it!=firp->GetInstructions().end(); + ++it + ) + { + Instruction_t* insn=*it; + assert(insn); + + + /* find annotations for this insn */ + std::pair<MEDS_Annotations_t::iterator,MEDS_Annotations_t::iterator> ret; + VirtualOffset vo(insn->GetAddress()->GetVirtualOffset()); + + cout<<"Checking annotations for "<<std::hex<<vo.to_string()<<endl; + + /* find it in the annotations */ + ret = annotationParser.getAnnotations().equal_range(vo); + MEDS_FRSafeAnnotation* p_annotation; + + /* for each annotation for this instruction */ + for (MEDS_Annotations_t::iterator it2 = ret.first; it2 != ret.second; ++it2) + { + p_annotation=dynamic_cast<MEDS_FRSafeAnnotation*>(it2->second); + if(p_annotation==NULL) + continue; + + cout<<"Found safe FR annotation for "<<std::hex<<insn->GetAddress()->GetVirtualOffset()<<endl; + Relocation_t* reloc=new Relocation_t; + reloc->SetOffset(0); + reloc->SetType("safefr"); + insn->GetRelocations().insert(reloc); + firp->GetRelocations().insert(reloc); + } + } +} + + +main(int argc, char* argv[]) +{ + + if(argc!=2) + { + cerr<<"Usage: ilr <id>"<<endl; + exit(-1); + } + + VariantID_t *pidp=NULL; + FileIR_t *firp=NULL; + + /* setup the interface to the sql server */ + pqxxDB_t pqxx_interface; + BaseObj_t::SetInterface(&pqxx_interface); + + cout<<"Reading variant "<<string(argv[1])<<" from database." << endl; + try + { + + pidp=new VariantID_t(atoi(argv[1])); + assert(pidp->IsRegistered()==true); + + + for(set<File_t*>::iterator it=pidp->GetFiles().begin(); + it!=pidp->GetFiles().end(); + ++it + ) + { + File_t* this_file=*it; + assert(this_file); + + // read the db + firp=new FileIR_t(*pidp,this_file); + + add_annotations(firp); + + firp->WriteToDB(); + + delete firp; + } + + + pqxx_interface.Commit(); + + } + catch (DatabaseError_t pnide) + { + cout<<"Unexpected database error: "<<pnide<<endl; + exit(-1); + } + + cout<<"Done!"<<endl; + + delete pidp; +} +