diff --git a/tools/transforms/integerbugtransform.cpp b/tools/transforms/integerbugtransform.cpp index efc305c3dc9a2f2b1115c795e7a1540ebf773dc3..7eff124a5eecf9091d3765c617863c3e6c447023 100644 --- a/tools/transforms/integerbugtransform.cpp +++ b/tools/transforms/integerbugtransform.cpp @@ -10,10 +10,25 @@ using namespace libIRDB; using namespace std; +string getAssembly(Instruction_t *p_instruction) +{ + DISASM disasm; + memset(&disasm, 0, sizeof(DISASM)); + + disasm.Options = NasmSyntax + PrefixedNumeral; + disasm.Archi = 32; + disasm.EIP = (UIntPtr) p_instruction->GetDataBits().c_str(); + disasm.VirtualAddr = p_instruction->GetAddress()->GetVirtualOffset(); + + Disasm(&disasm); // dissassemble the instruction + + return string(disasm.CompleteInstr); +} + // -// returns true iff instruction is MUL or IMUL +// returns true iff instruction is mul or imul // -bool isMultiplyInstruction(Instruction_t *p_instruction) +bool isMultiplyInstruction32(Instruction_t *p_instruction) { if (!p_instruction) return false; @@ -34,12 +49,64 @@ bool isMultiplyInstruction(Instruction_t *p_instruction) return (found_pos == 0 || found_pos == 1); // we expect mul or imul to be the first word in the string } +Instruction_t* addOverflowHandler(VariantIR_t *p_virp) +{ + AddressID_t *newaddr=new AddressID_t; + Instruction_t* hltInstruction = new Instruction_t(); + + string haltDataBits; + + haltDataBits.resize(1); + haltDataBits[0] = 0xF4; + + hltInstruction->SetComment("hlt"); // 0xF4 + hltInstruction->SetDataBits(haltDataBits); + hltInstruction->SetFallthrough(hltInstruction); // yes, set to self + hltInstruction->SetAddress(newaddr); + + p_virp->GetAddresses().insert(newaddr); + p_virp->GetInstructions().insert(hltInstruction); + cout << "Sanity check for hlt: " << getAssembly(hltInstruction) << endl; + return hltInstruction; +} + +void addOverflowCheck(VariantIR_t *p_virp, Instruction_t *p_instruction, Instruction_t *p_overflowHandler) +{ + // insert after the instruction, a check for overflow: + // imul ... + // jo <overflowHandler> + // <instr...> + // <instr...> + + AddressID_t *newaddr=new AddressID_t; + Instruction_t* overflowCheckInstruction = new Instruction_t(); + string overflowCheckDataBits; + + overflowCheckDataBits.resize(2); + overflowCheckDataBits[0] = 0x70; + overflowCheckDataBits[1] = 0x0; // we really don't care here as the SPASM generator will use the target address and fill this in correctly + overflowCheckInstruction->SetDataBits(overflowCheckDataBits); + overflowCheckInstruction->SetComment("jo <addressOverflowHandler>"); // 0x70 + overflowCheckInstruction->SetTarget(p_overflowHandler); // jump overflow target = overflow handler + overflowCheckInstruction->SetFallthrough(p_instruction->GetFallthrough()); // use the original fallthrough + overflowCheckInstruction->SetAddress(newaddr); + + // do I have to do anything with the file ID? + + p_instruction->SetFallthrough(overflowCheckInstruction); + + p_virp->GetAddresses().insert(newaddr); + p_virp->GetInstructions().insert(overflowCheckInstruction); + + cout << "Sanity check for jo: " << getAssembly(overflowCheckInstruction) << endl; +} + main(int argc, char* argv[]) { if(argc!=2) { - cerr<<"Usage: integerbug <variant_id>"<<endl; + cerr<<"Usage: integerbugtransform.exe <variant_id>"<<endl; exit(-1); } @@ -71,13 +138,10 @@ main(int argc, char* argv[]) assert(virp && pidp); - cout<<"Do stuff to variant "<<*pidp<< "." <<endl; - // For now, the overflow handler will consist of a HLT instruction -// Instruction_t* overflowHandler = addOverflowHandler(virp); + Instruction_t* overflowHandler = addOverflowHandler(virp); int numberMul = 0; -// set<AddressID_t*> newaddressset; for( set<Instruction_t*>::const_iterator it=virp->GetInstructions().begin(); it!=virp->GetInstructions().end(); @@ -86,7 +150,8 @@ main(int argc, char* argv[]) { Instruction_t* insn=*it; - if (isMultiplyInstruction(insn) && insn->GetFunction()) + if (isMultiplyInstruction32(insn) && insn->GetFunction() + /* && insn->GetFunction()->GetName().find("test_") != string::npos */) { numberMul++; cout << "found MUL: address: " << insn->GetAddress() @@ -94,53 +159,13 @@ main(int argc, char* argv[]) << " in function: " << insn->GetFunction()->GetName() << endl; // for now, insert overflow check to all IMUL instructions // later, we'll want to be more judicious about where to insert overflow checks -// addOverflowCheck(virp, insn, overflowHandler); + addOverflowCheck(virp, insn, overflowHandler); } - - -/* - size_t found = insn->GetComment().find(string("mul")); - if (found != string::npos) - { - numberMul++; - string dataBits = insn->GetDataBits(); - cout << "found MUL: address: " << insn->GetAddress() - << " comment: " << insn->GetComment() - << " dataBits: " << insn->GetDataBits(); - - if (insn->GetFunction()) - { - cout << " in function: " << insn->GetFunction()->GetName() << endl; - } - else - cout << " in function: unknown" << endl; - - } -*/ - - - // - // look for IMUL or MUL - // then do something (initially just count them) - // define new instruction at some new address id: <addressOfHalt> HLT - // no targets, fallthrough is itself - - // insert jo <addressOfhalt> TARGET = <addressOfHalt> "jump overflow" - // fallthrough is what the old fallthrough would have been - // - -/* - AddressID_t *newaddr=new AddressID_t; - newaddr->SetFileID(insn->GetAddress()->GetFileID()); - insn->SetAddress(newaddr); - newaddressset.insert(newaddr); -*/ } -// virp->GetAddresses()=newaddressset; -// cout<<"Writing variant "<<*pidp<<" back to database." << endl; -// virp->WriteToDB(); + cout<<"Writing variant "<<*pidp<<" back to database." << endl; + virp->WriteToDB(); cout<<"Found " << numberMul << " MUL or IMUL instructions" << endl; pqxx_interface.Commit();