| 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] |