Date: | Wed, 16 Apr 2014 12:03:56 +0900 |
---|---|
From: | êíí <kimpooh2@xxxxxxxxx> |
Subject: | [DynInst_API:] Question about using Dyninst for static instrumentation |
Hello, I'm Taehwan Kim, a Ph.D student at Hongik University in South Korea. I read PASTE '11 article about Dyninst, that is so impressive for me.
I want to do various tests using Dyninst. Dyninst seems to be a very useful instrumentation tool, but I have several problems while I using this tool. I would like to know the destination address of indirect branch instructions during run-time. So, I'm trying to instrument a short snippet code at the points targeting indirect branch instructions. I used static instrumentation methods, but it didn't normally work. Mutator cannot convert a sample binary to mutatee.
I saw the error message of function assert(), however, it is difficult to know exactly what it mean. So, I would like to know your opinion about my code. Best regards. - Kim #include <stdio.h> void TargetCall(void *addr) { printf("[CALL - Target] : %p\n", (unsigned long *)addr); } void TargetJmp(void *addr) { printf("[JMP - Target] : %p\n", (unsigned long *)addr); } void TargetRet(void *addr) { printf("[RET - Target] : %p\n", (unsigned long *)addr); } #include "BPatch.h" #include "BPatch_addressSpace.h" #include "BPatch_process.h" #include "BPatch_image.h" #include "BPatch_binaryEdit.h" #include "BPatch_function.h" #include "BPatch_point.h" #include "BPatch_flowGraph.h" #include <cstdio> #include <fstream> #include <iostream> #include <set> #include <string> using namespace std; int main(int argc, const char * argv[]) { ofstream outFile; outFile.open("/home/kim/test/dyninst/log/test.out"); BPatch * bpatch = new BPatch; BPatch_addressSpace * addSpace; enum {binary_rewriter, attach, create} runmode; switch(argv[1][1]) { case 'b': runmode = binary_rewriter; break; case 'c': runmode = create; break; case 'a': runmode = attach; break; } const char * mutatee = argv[2]; if(runmode == binary_rewriter) addSpace = bpatch->openBinary(mutatee, false); else if(runmode == attach) addSpace = bpatch->processAttach(mutatee, atoi(argv[3])); else if(runmode == create) addSpace = bpatch->processCreate(mutatee, argv+3); // image loading BPatch_image *appImage = addSpace->getImage(); // library setting addSpace->loadLibrary("libTargetBranchInstruction.so"); set<string> skipLibraries; skipLibraries.insert("libTargetBranchInstruction.so"); // snippet setting vector<BPatch_snippet *> args; args.push_back(new BPatch_dynamicTargetExpr()); vector<BPatch_function *> IBFuncs; appImage->findFunction("TargetCall", IBFuncs); appImage->findFunction("TargetJmp", IBFuncs); appImage->findFunction("TargetRet", IBFuncs); BPatch_function *callFunc = IBFuncs[0]; BPatch_function *jmpFunc = IBFuncs[1]; BPatch_function *retFunc = IBFuncs[2]; BPatch_funcCallExpr TargetCall(*callFunc, args); BPatch_funcCallExpr TargetJmp(*jmpFunc, args); BPatch_funcCallExpr TargetRet(*retFunc, args); // inserting snippet point vector vector<BPatch_point *> call_Points; vector<BPatch_point *> jmp_Points; vector<BPatch_point *> ret_Points; // module loading vector<BPatch_module *> * modules = appImage->getModules(); vector<BPatch_module *>::iterator module_iter; for(module_iter = modules->begin(); module_iter != modules->end(); ++module_iter) { char moduleName[1024]; (*module_iter)->getName(moduleName, 1024); if((*module_iter)->isSharedLib() && skipLibraries.find(moduleName) != skipLibraries.end()) continue; outFile << "-- Module : " << moduleName << " --" << endl; // function loading vector<BPatch_function *> * funcs = (*module_iter)->getProcedures(); vector<BPatch_function *>::iterator func_iter; for(func_iter = funcs->begin(); func_iter != funcs->end(); ++func_iter) { char functionName[1024]; (*func_iter)->getName(functionName, 1024); outFile << "-- Function : " << functionName << " --" << endl; // basic block loading set<BPatch_basicBlock *> blocks; BPatch_flowGraph * fg = (*func_iter)->getCFG(); if(!fg) { cerr << "Failed to find CFG for function " << functionName << endl; exit(1); } if(!fg->getAllBasicBlocks(blocks)) { cerr << "Failed to find basic blocks for function " << functionName << endl; exit(1); } else if(blocks.size() == 0) { cerr << "No basic blocks for function " << functionName << endl; exit(1); } unsigned int bb_count = 0; set<BPatch_basicBlock *>::iterator bb_iter; for(bb_iter = blocks.begin(); bb_iter != blocks.end(); ++bb_iter) { BPatch_basicBlock * block = *bb_iter; vector<pair<Dyninst::InstructionAPI::Instruction::Ptr, Dyninst::Address>> insns; block->getInstructions(insns); outFile << endl << "-- Basic Block : " << dec << bb_count++ << endl; /* vector<BPatch_edge *> outgoingEdge; (*bb_iter)->getOutgoingEdges(outgoingEdge); vector<BPatch_edge *>::iterator edge_iter; for(edge_iter = outgoingEdge.begin(); edge_iter != outgoingEdge.end(); ++edge_iter) { temp_points.push_back((*edge_iter)->getPoint()); } */ // instruction loading vector<pair<Dyninst::InstructionAPI::Instruction::Ptr, Dyninst::Address>>::iterator insn_iter; for(insn_iter = insns.begin(); insn_iter != insns.end(); ++insn_iter) { Dyninst::InstructionAPI::Instruction::Ptr insn = insn_iter->first; Dyninst::Address addr = insn_iter->second; Dyninst::InstructionAPI::Operation op = insn->getOperation(); Dyninst::InstructionAPI::InsnCategory category = insn->getCategory(); Dyninst::InstructionAPI::Expression::Ptr exp = insn->getControlFlowTarget(); bool isAccess = false; if(exp && insn->isRead(exp)) { outFile << "==== Expr: " << exp->format() << endl; outFile << "==== Value: " << exp->eval().format() << endl; isAccess = true; } for(Dyninst::InstructionAPI::Instruction::cftConstIter iter = insn->cft_begin(); iter != insn->cft_end(); ++iter) { if(iter->isIndirect) { outFile << "Instrumenting Point(Opcode : " << op.format() << ") at 0x" << hex << addr << " of " << functionName << endl; if(category == Dyninst::InstructionAPI::c_CallInsn) { vector<BPatch_point *> callPoints; appImage->findPoints(addr, callPoints); vector<BPatch_point *>::iterator callPt_iter; for(callPt_iter = callPoints.begin(); callPt_iter != callPoints.end(); ++callPt_iter) { call_Points.push_back(*callPt_iter); } } else if(category == Dyninst::InstructionAPI::c_BranchInsn) { vector<BPatch_point *> jmpPoints; appImage->findPoints(addr, jmpPoints); vector<BPatch_point *>::iterator jmpPt_iter; for(jmpPt_iter = jmpPoints.begin(); jmpPt_iter != jmpPoints.end(); ++jmpPt_iter) { jmp_Points.push_back(*jmpPt_iter); } } else if(category == Dyninst::InstructionAPI::c_ReturnInsn) { vector<BPatch_point *> retPoints; appImage->findPoints(addr, retPoints); vector<BPatch_point *>::iterator retPt_iter; for(retPt_iter = retPoints.begin(); retPt_iter != retPoints.end(); ++retPt_iter) { ret_Points.push_back(*retPt_iter); } } } } /* if(category == Dyninst::InstructionAPI::c_CallInsn && isAccess) { outFile << "Instrumenting Point(Opcode : " << op.format() << ") at 0x" << hex << addr << " of " << functionName << endl; vector<BPatch_point *> callPoints; appImage->findPoints(addr, callPoints); vector<BPatch_point *>::iterator callPt_iter; for(callPt_iter = callPoints.begin(); callPt_iter != callPoints.end(); ++callPt_iter) { points.push_back(*callPt_iter); } } */ /* if(category == Dyninst::InstructionAPI::c_ReturnInsn) { outFile << "Instrumenting Point(Opcode : " << op.format() << ") at 0x" << hex << addr << " of " << functionName << endl; vector<BPatch_point *> returnPoints; appImage->findPoints(addr, returnPoints); vector<BPatch_point *>::iterator returnPt_iter; for(returnPt_iter = returnPoints.begin(); returnPt_iter != returnPoints.end(); ++returnPt_iter) { points.push_back(*returnPt_iter); } } */ /* if(category == Dyninst::InstructionAPI::c_BranchInsn && isAccess) { outFile << "Instrumenting Point(Opcode : " << op.format() << ") at 0x" << hex << addr << " of " << functionName << endl; vector<BPatch_point *> branchPoints; appImage->findPoints(addr, branchPoints); vector<BPatch_point *>::iterator branchPt_iter; for(branchPt_iter = branchPoints.begin(); branchPt_iter != branchPoints.end(); ++branchPt_iter) { points.push_back(*branchPt_iter); } } */ } outFile << "-- END of Basic Block --" << endl << endl; } } } outFile << "Point Size : " << dec << call_Points.size() + jmp_Points.size() + ret_Points.size() << endl; BPatchSnippetHandle * handle; handle = addSpace->insertSnippet(TargetCall, call_Points); if(call_Points.size() && !handle) { cerr << "Failed to insert instrumentation - call_Points" << endl; exit(1); } handle = addSpace->insertSnippet(TargetJmp, jmp_Points); if(jmp_Points.size() && !handle) { cerr << "Failed to insert instrumentation - jmp_Points" << endl; exit(1); } handle = addSpace->insertSnippet(TargetRet, ret_Points); if(ret_Points.size() && !handle) { cerr << "Failed to insert instrumentation - ret_Points" << endl; exit(1); } if(runmode == binary_rewriter) { if(!dynamic_cast<BPatch_binaryEdit *>(addSpace)->writeFile(argv[3])) { cerr << "Failed to write output file: " << argv[3] << endl; exit(1); } } else { dynamic_cast<BPatch_process *>(addSpace)->continueExecution(); while (!dynamic_cast<BPatch_process *>(addSpace)->isTerminated()) bpatch->waitForStatusChange(); } outFile.close(); return 0; } |
[← Prev in Thread] | Current Thread | [Next in Thread→] |
---|---|---|
|
Previous by Date: | Re: [DynInst_API:] Several Dyninst build issues, Bill Williams |
---|---|
Next by Date: | [DynInst_API:] ParseAPI and PE files, E.Robbins |
Previous by Thread: | [DynInst_API:] Question about using Dyninst for static instrumentation, 김태환 |
Next by Thread: | Re: [DynInst_API:] Question about using Dyninst for static instrumentation, Ray Chen |
Indexes: | [Date] [Thread] |