diff --git a/libintegertransform/include/integertransform.hpp b/libintegertransform/include/integertransform.hpp index 8391344a4ec13fa3713232c80acaefd57cd230ef..3ff8048a1a3ffd4f12d2f3fd7af9a5ac499c5c03 100644 --- a/libintegertransform/include/integertransform.hpp +++ b/libintegertransform/include/integertransform.hpp @@ -19,9 +19,14 @@ class IntegerTransform int execute(); private: - void addOverflowCheck(libIRDB::Instruction_t *p_instruction, std::string p_handlerName); + void addOverflowCheck(Instruction_t *p_instruction, const MEDS_InstructionCheckAnnotation& p_annotation); + virtual_offset_t getAvailableAddress(VariantIR_t *p_virp); + // utility functions + bool isMultiplyInstruction32(libIRDB::Instruction_t*); + bool isAddSubNonEspInstruction32(libIRDB::Instruction_t*); + private: VariantID_t *m_variantID; VariantIR_t *m_variantIR; @@ -29,4 +34,11 @@ class IntegerTransform set<std::string> *m_filteredFunctions; }; +// make sure these match the function names in $STRATA/src/posix/x86_linux/detector_number_handling/overflow_detector.c + +#define INTEGER_OVERFLOW_DETECTOR "integer_overflow_detector" +#define ADDSUB_OVERFLOW_DETECTOR_SIGNED_32 "addsub_overflow_detector_signed_32" +#define ADDSUB_OVERFLOW_DETECTOR_UNSIGNED_32 "addsub_overflow_detector_unsigned_32" +#define MUL_OVERFLOW_DETECTOR_32 "mul_overflow_detector_32" + #endif diff --git a/libintegertransform/src/integertransform.cpp b/libintegertransform/src/integertransform.cpp index edc08e5d4921c86438f54de0fed7cd6c75d6ad49..c00dec0b814f2f13365f56ffe276192953a20582 100644 --- a/libintegertransform/src/integertransform.cpp +++ b/libintegertransform/src/integertransform.cpp @@ -23,6 +23,8 @@ int IntegerTransform::execute() { Function_t* func=*itf; + cerr << "integertransform: looking at function: " << func->GetName() << endl; + if (m_filteredFunctions->find(func->GetName()) != m_filteredFunctions->end()) continue; @@ -33,20 +35,49 @@ int IntegerTransform::execute() { Instruction_t* insn=*it; - // lookup address - // see if there's an annotation - // if so perform the instrumentation check - + if (insn && insn->GetAddress()) + { + virtual_offset_t irdb_vo = insn->GetAddress()->GetVirtualOffset(); + if (irdb_vo == 0) continue; + + VirtualOffset vo(irdb_vo); + + MEDS_InstructionCheckAnnotation annotation = (*m_annotations)[vo]; + if (!annotation.isValid()) continue; + + if (annotation.isOverflow()) + { + cerr << "integertransform: overflow annotation" << annotation.toString(); + addOverflowCheck(insn, annotation); + } + else if (annotation.isUnderflow()) + { + cerr << "integertransform: underflow annotation" << annotation.toString(); + } + else if (annotation.isTruncation()) + { + cerr << "integertransform: truncation annotation" << annotation.toString(); + + } + else if (annotation.isSignedness()) + { + cerr << "integertransform: signedness annotation" << annotation.toString(); + } + else + cerr << "integertransform: unknown annotation" << annotation.toString(); + } } // end iterate over all instructions in a function } // end iterate over all functions - m_variantIR->WriteToDB(); + cerr << "integertransform: testing: do not write new variant to DB" << endl; +// m_variantIR->WriteToDB(); // for now just be happy return 0; } // +// <instruction to instrument> // jno <originalFallthroughInstruction> // pusha // pushf @@ -57,15 +88,15 @@ int IntegerTransform::execute() // popf // popa // -void IntegerTransform::addOverflowCheck(Instruction_t *p_instruction, std::string p_detector) +void IntegerTransform::addOverflowCheck(Instruction_t *p_instruction, const MEDS_InstructionCheckAnnotation& p_annotation) { +cerr << "void IntegerTransform::addOverflowCheck(): enter: " << p_instruction->GetComment() << endl; assert(m_variantIR && p_instruction); + string detector; // name of SPRI/STRATA callback handler function string dataBits; - AddressID_t *jno_a =new AddressID_t; - AddressID_t *jo_a =new AddressID_t; - AddressID_t *jmporigfallthrough_a =new AddressID_t; + AddressID_t *jncond_a =new AddressID_t; AddressID_t *pusha_a =new AddressID_t; AddressID_t *pushf_a =new AddressID_t; AddressID_t *pusharg_a =new AddressID_t; @@ -74,8 +105,7 @@ void IntegerTransform::addOverflowCheck(Instruction_t *p_instruction, std::strin AddressID_t *popf_a =new AddressID_t; AddressID_t *popa_a =new AddressID_t; - jno_a->SetFileID(p_instruction->GetAddress()->GetFileID()); - jmporigfallthrough_a->SetFileID(p_instruction->GetAddress()->GetFileID()); + jncond_a->SetFileID(p_instruction->GetAddress()->GetFileID()); pusha_a->SetFileID(p_instruction->GetAddress()->GetFileID()); pushf_a->SetFileID(p_instruction->GetAddress()->GetFileID()); pusharg_a->SetFileID(p_instruction->GetAddress()->GetFileID()); @@ -84,8 +114,7 @@ void IntegerTransform::addOverflowCheck(Instruction_t *p_instruction, std::strin popf_a->SetFileID(p_instruction->GetAddress()->GetFileID()); popa_a->SetFileID(p_instruction->GetAddress()->GetFileID()); - Instruction_t* jno_i = new Instruction_t; - Instruction_t* jmporigfallthrough_i = new Instruction_t; + Instruction_t* jncond_i = new Instruction_t; Instruction_t* pusha_i = new Instruction_t; Instruction_t* pushf_i = new Instruction_t; Instruction_t* pusharg_i = new Instruction_t; @@ -96,8 +125,7 @@ void IntegerTransform::addOverflowCheck(Instruction_t *p_instruction, std::strin Function_t* origFunction = p_instruction->GetFunction(); - jno_i->SetFunction(origFunction); - jmporigfallthrough_i->SetFunction(origFunction); + jncond_i->SetFunction(origFunction); pusha_i->SetFunction(origFunction); pushf_i->SetFunction(origFunction); pusharg_i->SetFunction(origFunction); @@ -110,8 +138,7 @@ void IntegerTransform::addOverflowCheck(Instruction_t *p_instruction, std::strin virtual_offset_t postDetectorReturn = getAvailableAddress(m_variantIR); poparg_a->SetVirtualOffset(postDetectorReturn); - jno_i->SetAddress(jno_a); - jmporigfallthrough_i->SetAddress(jmporigfallthrough_a); + jncond_i->SetAddress(jncond_a); pusha_i->SetAddress(pusha_a); pushf_i->SetAddress(pushf_a); pusharg_i->SetAddress(pusharg_a); @@ -122,23 +149,48 @@ void IntegerTransform::addOverflowCheck(Instruction_t *p_instruction, std::strin // set fallthrough for the original instruction Instruction_t* nextOrig_i = p_instruction->GetFallthrough(); - p_instruction->SetFallthrough(jno_i); + p_instruction->SetFallthrough(jncond_i); - // jno IO + + // jncond dataBits.resize(2); - dataBits[0] = 0x71; - dataBits[1] = 0x15; // value doesn't matter, we will fill it in later - jno_i->SetDataBits(dataBits); - jno_i->SetComment(jno_i->getDisassembly()); - jno_i->SetFallthrough(pusha_i); - jno_i->SetTarget(nextOrig_i); + if (isMultiplyInstruction32(p_instruction)) + { + dataBits[0] = 0x71; // jno + dataBits[1] = 0x00; // value doesn't matter, we will fill it in later + detector = string(MUL_OVERFLOW_DETECTOR_32); + cerr << "integertransform: MUL OVERFLOW 32" << endl; + } + else if (p_annotation.isSigned()) + { + dataBits[0] = 0x71; // jno + dataBits[1] = 0x00; // value doesn't matter, we will fill it in later + + detector = string(ADDSUB_OVERFLOW_DETECTOR_SIGNED_32); + cerr << "integertransform: ADD/SUB OVERFLOW SIGNED 32" << endl; + } + else if (p_annotation.isUnsigned()) + { + dataBits[0] = 0x73; // jnc + dataBits[1] = 0x00; // value doesn't matter, we will fill it in later + + detector = string(ADDSUB_OVERFLOW_DETECTOR_UNSIGNED_32); + cerr << "integertransform: ADD/SUB OVERFLOW UNSIGNED 32" << endl; + } + + + jncond_i->SetDataBits(dataBits); + jncond_i->SetComment(jncond_i->getDisassembly()); + jncond_i->SetFallthrough(pusha_i); + jncond_i->SetTarget(nextOrig_i); + p_instruction->SetFallthrough(jncond_i); // pusha dataBits.resize(1); dataBits[0] = 0x60; pusha_i->SetDataBits(dataBits); pusha_i->SetComment(pusha_i->getDisassembly()); - pusha_i->SetFallthrough(pusharg_i); + pusha_i->SetFallthrough(pushf_i); // pushf dataBits.resize(1); @@ -169,10 +221,10 @@ void IntegerTransform::addOverflowCheck(Instruction_t *p_instruction, std::strin 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->SetComment(poparg_i->getDisassembly() + " -- with callback to " + detector + " orig: " + p_instruction->GetComment()) ; poparg_i->SetFallthrough(popa_i); poparg_i->SetIndirectBranchTargetAddress(poparg_a); - poparg_i->SetCallback(p_detector); + poparg_i->SetCallback(detector); // popf dataBits.resize(1); @@ -189,8 +241,7 @@ void IntegerTransform::addOverflowCheck(Instruction_t *p_instruction, std::strin popa_i->SetFallthrough(nextOrig_i); // add new address to IR - m_variantIR->GetAddresses().insert(jno_a); - m_variantIR->GetAddresses().insert(jmporigfallthrough_a); + m_variantIR->GetAddresses().insert(jncond_a); m_variantIR->GetAddresses().insert(pusha_a); m_variantIR->GetAddresses().insert(pusharg_a); m_variantIR->GetAddresses().insert(pushf_a); @@ -200,8 +251,7 @@ void IntegerTransform::addOverflowCheck(Instruction_t *p_instruction, std::strin m_variantIR->GetAddresses().insert(popa_a); // add new instructions to IR - m_variantIR->GetInstructions().insert(jno_i); - m_variantIR->GetInstructions().insert(jmporigfallthrough_i); + m_variantIR->GetInstructions().insert(jncond_i); m_variantIR->GetInstructions().insert(pusha_i); m_variantIR->GetInstructions().insert(pusharg_i); m_variantIR->GetInstructions().insert(pushf_i); @@ -209,6 +259,7 @@ void IntegerTransform::addOverflowCheck(Instruction_t *p_instruction, std::strin m_variantIR->GetInstructions().insert(popf_i); m_variantIR->GetInstructions().insert(poparg_i); m_variantIR->GetInstructions().insert(popa_i); +cerr << "void IntegerTransform::addOverflowCheck(): exit" << endl; } virtual_offset_t IntegerTransform::getAvailableAddress(VariantIR_t *p_virp) @@ -242,12 +293,10 @@ static int counter = -16; // availableAddressOffset + 16; } -#ifdef NOTYET - // // Returns true iff instruction is mul or imul // -static bool isMultiplyInstruction32(Instruction_t *p_instruction) +bool IntegerTransform::isMultiplyInstruction32(Instruction_t *p_instruction) { if (!p_instruction) return false; @@ -264,7 +313,7 @@ static bool isMultiplyInstruction32(Instruction_t *p_instruction) // // Returns true iff instruction is mul or imul // -static bool isAddSubNonEspInstruction32(Instruction_t *p_instruction) +bool IntegerTransform::isAddSubNonEspInstruction32(Instruction_t *p_instruction) { if (!p_instruction) return false; @@ -275,8 +324,6 @@ static bool isAddSubNonEspInstruction32(Instruction_t *p_instruction) // look for "addl ..." or "subl ..." p_instruction->Disassemble(disasm); -//fprintf(stderr,"INT DEBUG: inst: 0x%x [%s] [%s]\n", p_instruction->GetAddress(), disasm.Instruction.Mnemonic, p_instruction->GetComment().c_str()); - // beaengine adds space at the end of the mnemonic string if (strcasestr(disasm.Instruction.Mnemonic, "add ")) { @@ -295,4 +342,3 @@ static bool isAddSubNonEspInstruction32(Instruction_t *p_instruction) return false; } -#endif