VOID Trace (TRACE trace, VOID *v) { for (BBL bbl = TRACE_BblHead(trace); BBL_Valid(bbl); bbl = BBL_Next(bbl)) { for (INS ins = BBL_InsHead(bbl); INS_Valid(ins); ins = INS_Next(ins)) { xed_iclass_enum_t iclass1 = static_cast<xed_iclass_enum_t>(INS_Opcode(ins)); if (iclass1 == XED_ICLASS_FLD1 && INS_Valid(INS_Next(ins))) { xed_iclass_enum_t iclass2 = static_cast<xed_iclass_enum_t>(INS_Opcode(INS_Next(ins))); if (iclass2 == XED_ICLASS_FLD1 && INS_Valid(INS_Next(INS_Next(ins)))) { xed_iclass_enum_t iclass3 = static_cast<xed_iclass_enum_t>(INS_Opcode(INS_Next(INS_Next(ins)))); if (iclass3 == XED_ICLASS_FLD1) { printf ("found fld1 sequence at %x\n", INS_Address(INS_Next(INS_Next(ins)))); { INS_InsertCall(INS_Next(INS_Next(ins)), IPOINT_AFTER, AFUNPTR(CallToFldzToTop3), IARG_END); printf ("Inserted call1 to FldzToTop3 after instruction at %x\n", INS_Address(INS_Next(INS_Next(ins)))); } } } } } } }
// Pin calls this function every time a new instruction is encountered VOID Instruction(INS ins, VOID *v) { BOOL doInstrument =FALSE; xed_iclass_enum_t iclass = (xed_iclass_enum_t) INS_Opcode(ins); if (INS_Opcode(ins)==XED_ICLASS_FXSAVE || INS_Opcode(ins)==XED_ICLASS_FXSAVE64 || INS_Opcode(ins)==XED_ICLASS_XSAVE || INS_Opcode(ins)==XED_ICLASS_XSAVE64) { doInstrument = TRUE; } else { for (REG reg=REG_XMM_BASE; reg <= REG_YMM_LAST; reg=static_cast<REG>((static_cast<INT32>(reg)+1))) { if (INS_RegRContain(ins, reg)) { doInstrument = TRUE; break; } else if (INS_RegWContain(ins, reg)) { doInstrument = TRUE; break; } } } if (doInstrument) { INS_InsertCall(ins, IPOINT_BEFORE, (AFUNPTR)SetYmmScratchesFun, IARG_ADDRINT, ymmInitVals, IARG_ADDRINT, xmmSaveVal, IARG_END); } }
VOID Trace (TRACE trace, VOID *v) { for (BBL bbl = TRACE_BblHead(trace); BBL_Valid(bbl); bbl = BBL_Next(bbl)) { for (INS ins = BBL_InsHead(bbl); INS_Valid(ins); ins = INS_Next(ins)) { xed_iclass_enum_t iclass1 = static_cast<xed_iclass_enum_t>(INS_Opcode(ins)); if (iclass1 == XED_ICLASS_FLD1 && INS_Valid(INS_Next(ins))) { xed_iclass_enum_t iclass2 = static_cast<xed_iclass_enum_t>(INS_Opcode(INS_Next(ins))); if (iclass2 == XED_ICLASS_FLD1 && INS_Valid(INS_Next(INS_Next(ins)))) { xed_iclass_enum_t iclass3 = static_cast<xed_iclass_enum_t>(INS_Opcode(INS_Next(INS_Next(ins)))); if (iclass3 == XED_ICLASS_FLD1) { printf ("tool: found fld1 sequence at %p\n", (void *)INS_Address(INS_Next(INS_Next(ins)))); fflush (stdout); // Insert an analysis call that will cause the xmm scratch registers to be spilled INS_InsertCall(INS_Next(INS_Next(ins)), IPOINT_AFTER, (AFUNPTR)SetXmmScratchesFun, IARG_END); return; } } } } } }
VOID Trace (TRACE trace, VOID *v) { for (BBL bbl = TRACE_BblHead(trace); BBL_Valid(bbl); bbl = BBL_Next(bbl)) { for (INS ins = BBL_InsHead(bbl); INS_Valid(ins); ins = INS_Next(ins)) { xed_iclass_enum_t iclass1 = static_cast<xed_iclass_enum_t>(INS_Opcode(ins)); if (iclass1 == XED_ICLASS_FLD1 && INS_Valid(INS_Next(ins))) { xed_iclass_enum_t iclass2 = static_cast<xed_iclass_enum_t>(INS_Opcode(INS_Next(ins))); if (iclass2 == XED_ICLASS_FLD1 && INS_Valid(INS_Next(INS_Next(ins)))) { xed_iclass_enum_t iclass3 = static_cast<xed_iclass_enum_t>(INS_Opcode(INS_Next(INS_Next(ins)))); if (iclass3 == XED_ICLASS_FLD1) { printf ("found fld1 sequence at %lx\n", (unsigned long)(INS_Address(INS_Next(INS_Next(ins))))); if (testNum == 0) { INS_InsertCall(INS_Next(INS_Next(ins)), IPOINT_AFTER, AFUNPTR(CallToUnMaskZeroDivideInMxcsr), IARG_END); printf ("Inserted call1 to UnMaskZeroDivideInMxcsr after instruction at %lx\n", (unsigned long)(INS_Address(INS_Next(INS_Next(ins))))); testNum++; } return; } } } } } }
VOID Image(IMG img, VOID * v) { if (strstr (IMG_Name(img).c_str(), "flags_at_analysis_app")==NULL) { return; } for (SEC sec = IMG_SecHead(img); SEC_Valid(sec); sec = SEC_Next(sec)) { for (RTN rtn = SEC_RtnHead(sec); RTN_Valid(rtn); rtn = RTN_Next(rtn)) { // Prepare for processing of RTN, an RTN is not broken up into BBLs, // it is merely a sequence of INSs RTN_Open(rtn); for (INS ins = RTN_InsHead(rtn); INS_Valid(ins); ins = INS_Next(ins)) { if (INS_Opcode(ins)==XED_ICLASS_POPF || INS_Opcode(ins)==XED_ICLASS_POPFD || INS_Opcode(ins)==XED_ICLASS_POPFQ) { // popf is the marker printf ("found popf in rtn %s\n", RTN_Name(rtn).c_str()); if (!INS_Valid(INS_Next(ins)) || !INS_Valid(INS_Next(INS_Next(ins)))) { printf ("wrong popf marker found\n"); exit (-1); } printf ("next ins should be cmp al, 0x81 it is %s\n", INS_Disassemble(INS_Next(ins)).c_str()); printf ("next ins should be xor ecx, ecx it is %s\n", INS_Disassemble(INS_Next(INS_Next(ins))).c_str()); // Insert analysis calls to read the value of the flags register just after the cmp al, 0x81 - the OF flag should be set INS_InsertIfCall(INS_Next(INS_Next(ins)), IPOINT_BEFORE, (AFUNPTR)IfReturnTrue, IARG_INST_PTR, IARG_END); INS_InsertThenCall(INS_Next(INS_Next(ins)), IPOINT_BEFORE, (AFUNPTR)ThenFunc, IARG_REG_VALUE, REG_GFLAGS, IARG_END); INS_InsertCall(INS_Next(INS_Next(ins)), IPOINT_BEFORE, (AFUNPTR)AnalysisFunc, IARG_REG_VALUE, REG_GFLAGS, IARG_END); } } // to preserve space, release data associated with RTN after we have processed it RTN_Close(rtn); } } }
static VOID InstrumentInstruction(INS ins, VOID *) { if (INS_IsPredicated(ins)) { INS_InsertIfCall(ins, IPOINT_BEFORE, (AFUNPTR)returnArg, IARG_EXECUTING, IARG_END); INS_InsertThenCall(ins, IPOINT_BEFORE, (AFUNPTR)increment, IARG_ADDRINT, ADDRINT(&predicatedTrueCount), IARG_END); INS_InsertCall(ins, IPOINT_BEFORE, (AFUNPTR)add, IARG_ADDRINT, ADDRINT(&predicatedTrueCountArg), IARG_EXECUTING, IARG_END); // CountOp = TRUE; } if (INS_HasRealRep(ins)) { INS_InsertIfCall(ins, IPOINT_BEFORE, (AFUNPTR)returnArg, IARG_FIRST_REP_ITERATION, IARG_END); INS_InsertThenCall(ins, IPOINT_BEFORE, (AFUNPTR)increment, IARG_ADDRINT, ADDRINT(&firstRepCount), IARG_END); INS_InsertCall(ins, IPOINT_BEFORE, (AFUNPTR)add, IARG_ADDRINT, ADDRINT(&firstRepCountArg), IARG_FIRST_REP_ITERATION, IARG_END); } if (INS_IsBranch(ins)) { UINT32 op = INS_Opcode(ins); INS_InsertIfCall(ins, IPOINT_BEFORE, (AFUNPTR)returnArg, IARG_BRANCH_TAKEN, IARG_END); INS_InsertThenCall(ins, IPOINT_BEFORE, (AFUNPTR)increment, IARG_ADDRINT, ADDRINT(&(branchCounts[op].taken)), IARG_END); INS_InsertCall(ins, IPOINT_BEFORE, (AFUNPTR)add, IARG_ADDRINT, ADDRINT(&(branchCounts[op].takenArg)), IARG_BRANCH_TAKEN, IARG_END); } }
VOID Instruction(INS ins, VOID *v) { INT32 xedEtension = INS_Extension(ins); if (xedEtension==XED_EXTENSION_AVX || xedEtension==XED_EXTENSION_SSE || xedEtension==XED_EXTENSION_SSE2 || xedEtension==XED_EXTENSION_SSE3 || xedEtension==XED_EXTENSION_SSE4 || xedEtension==XED_EXTENSION_SSE4A || xedEtension==XED_EXTENSION_SSSE3 || xedEtension==XED_EXTENSION_X87 ) { numInstruction++; xed_iclass_enum_t iclass = (xed_iclass_enum_t) INS_Opcode(ins); //if (numInstruction<=1) { //printf ("InstrumentingX# %d: IP: %x instruction: %s\n", numInstruction, INS_Address(ins), INS_Disassemble(ins).c_str()); INS_InsertCall(ins, IPOINT_BEFORE, (AFUNPTR)VerifyFpContext, IARG_INST_PTR, IARG_CONTEXT, IARG_END); INS_InsertCall(ins, IPOINT_AFTER, (AFUNPTR)VerifyFpContext, IARG_INST_PTR, IARG_CONTEXT, IARG_END); } } }
VOID CheckXlat(INS ins) { if (INS_Opcode(ins) != XED_ICLASS_XLAT) return; INS_InsertCall(ins, IPOINT_BEFORE, AFUNPTR(SaveEa), IARG_THREAD_ID, IARG_MEMORYREAD_EA, IARG_END); INS_InsertCall(ins, IPOINT_AFTER, AFUNPTR(CheckXlatAfter), IARG_THREAD_ID, IARG_REG_VALUE, REG_EAX, IARG_END); }
static void DoInstrumentation7 (INS ins) { if (XED_ICLASS_MOVSB != INS_Opcode(ins)) { printf ("Unexpected seventh rep instruction\n"); exit (1); } if (!INS_RepPrefix(ins)) { printf ("Unexpected seventh rep type\n"); exit (1); } INS_InsertCall(ins, IPOINT_AFTER, (AFUNPTR)After7WithContext, IARG_REG_VALUE, REG_INST_PTR , IARG_INST_PTR, IARG_CONTEXT, IARG_CONST_CONTEXT, IARG_REG_CONST_REFERENCE, REG_INST_PTR , IARG_END); INS_InsertCall(ins, IPOINT_AFTER, (AFUNPTR)After7WithoutContext, IARG_REG_VALUE, REG_INST_PTR , IARG_INST_PTR, IARG_CONST_CONTEXT, // has CONST_CONTEXT but not CONTEXT IARG_REG_CONST_REFERENCE, REG_INST_PTR , IARG_END); }
VOID delete_int3(INS ins, VOID* v) { if (INS_Opcode(ins) == XED_ICLASS_INT3) { INS_Delete(ins); } }
// Offset the addressing of the first "or" instruction back by 4 bytes. static VOID modifyAddressing (RTN rtn) { for (INS ins = RTN_InsHead(rtn); INS_Valid(ins); ins = INS_Next(ins)) { if (INS_Opcode(ins) == XED_ICLASS_OR) { printf ("Rewriting address of ins\n%x: %s\n", INS_Address(ins), INS_Disassemble(ins).c_str()); // pass the original memory address accessed by the app instruction (i.e. before the rewrite) to AddrValueA INS_InsertCall(ins, IPOINT_BEFORE, AFUNPTR(AddrValueA), IARG_MEMORYOP_EA, 0, IARG_END); INS_InsertCall(ins, IPOINT_BEFORE, AFUNPTR(returnValueMinus4), IARG_MEMORYOP_EA, 0, IARG_RETURN_REGS, scratchReg, IARG_END); INS_RewriteMemoryOperand(ins, 0, scratchReg); // pass the original memory address accessed by the app instruction (i.e. before the rewrite) to AddrValueB INS_InsertCall(ins, IPOINT_BEFORE, AFUNPTR(AddrValueB), IARG_MEMORYOP_EA, 0, IARG_END); instrumentationCount++; return; } } }
/****************************************************************** Title:instruction Function:Pin calls this function every time a new instruction is executed Input: RTN rtn:The current instruction. VOID *v:The second argument. Output: VOID ******************************************************************/ VOID instruction(INS ins, VOID *v) { /*fprintf(trace,insName.c_str()); fprintf(trace,"\n"); decode(ins);*/ if(flag==0&&hasFound==0) return; else hasFound=1; if(flag==1&&hasFound==1){ fprintf(output,"****************************************************\n"); fprintf(output,"Before the application\n"); ADDRINT baseAdd = getAddr(); ADDRINT length = getSizeL(); memManager->markTaintedBlock(baseAdd,length); memManager->printState(output); flag=0; } OPCODE opcode = INS_Opcode(ins); UINT32 operandCount = INS_OperandCount(ins); UINT insExt = INS_Extension(ins); unsigned int realOpcode = opcode&0xffff; OperandKind kind = getOperandKind(ins); unsigned int insKind = INSNUM(realOpcode,kind); handleIns(insKind,ins); }
static VOID Instrument(INS ins) { UINT32 op = INS_Opcode(ins); switch (op) { case XED_ICLASS_BT: case XED_ICLASS_BTC: case XED_ICLASS_BTR: case XED_ICLASS_BTS: // Filter out the BTs we want to look at, we don't expect any in system libraries, // but we have seen a bt reg,reg on FC12 if (INS_IsMemoryRead(ins) && !INS_OperandIsImmediate(ins,1)) break; // Fall through and ignore non mem,reg operations. default: return; } INS_InsertCall(ins, IPOINT_BEFORE, AFUNPTR(ProcessAddress), IARG_ADDRINT, ADDRINT (formatInstruction(ins)), IARG_MEMORYREAD_SIZE, IARG_MEMORYOP_EA, 0, IARG_REG_VALUE, INS_OperandReg(ins, 1), IARG_END); }
int should_instrument_ins(INS ins) { if(is_accepted_address(ins)) { return is_accepted_mnemonic(INS_Opcode(ins)); } return 0; }
VOID Instruction(INS ins, VOID *v) { //if (RTN_Valid(INS_Rtn(ins)) && RTN_Name(INS_Rtn(ins)) == "__SEH_epilog4") { // cerr << "image " << IMG_Name(SEC_Img(RTN_Sec(INS_Rtn(ins)))) << endl; //} if ( leaflag && INS_IsLea(ins) ) { INS_InsertCall(ins, IPOINT_BEFORE, AFUNPTR(LeaAdd), IARG_THREAD_ID, IARG_REG_VALUE, REG_STACK_PTR, IARG_INST_PTR, IARG_REG_VALUE, REG_GBP, IARG_END); } if ( INS_IsBranch(ins) && !(INS_IsCall(ins)) && !(INS_IsRet(ins)) ) { INS_InsertCall(ins, IPOINT_TAKEN_BRANCH, AFUNPTR(Branch), IARG_THREAD_ID, IARG_REG_VALUE, REG_STACK_PTR, IARG_BRANCH_TARGET_ADDR, IARG_INST_PTR, IARG_END); } else if (INS_IsRet(ins)) { INS prev = INS_Prev(ins); //cout<< "CALL TO RET" << endl; INS_InsertCall(ins, IPOINT_BEFORE, AFUNPTR(Ret), IARG_THREAD_ID, IARG_REG_VALUE, REG_STACK_PTR, IARG_BRANCH_TARGET_ADDR, IARG_INST_PTR, IARG_UINT32, (INS_Valid(prev) && INS_Opcode(prev) == XED_CATEGORY_PUSH), IARG_END); } else if (INS_IsCall(ins)) { //cout << "CALL TO CALL" << endl; INS_InsertCall(ins, IPOINT_TAKEN_BRANCH, AFUNPTR(Call), IARG_THREAD_ID, IARG_REG_VALUE, REG_STACK_PTR, IARG_BRANCH_TARGET_ADDR, IARG_INST_PTR, IARG_END); } else if (INS_IsMemoryWrite(ins)) { //cout<< "CALL TO MEWRITE" << endl; INS_InsertCall(ins, IPOINT_BEFORE, AFUNPTR(MemWrite), IARG_THREAD_ID, IARG_MEMORYWRITE_EA, IARG_END); } }
VOID Instruction(INS ins, VOID *v) { xed_iclass_enum_t iclass = static_cast<xed_iclass_enum_t>(INS_Opcode(ins)); if (iclass == XED_ICLASS_FLD1 || iclass == XED_ICLASS_FADDP || iclass == XED_ICLASS_FSTP) { INS_InsertCall(ins, IPOINT_BEFORE, (AFUNPTR)AnalysisFunc, IARG_CONST_CONTEXT, IARG_END); numFpsInstrumented++; } }
/*! * Instruction instrumentation routine. */ VOID Instruction(INS ins, VOID* v) { if (INS_Opcode(ins)==XED_ICLASS_JRCXZ) { INS_InsertCall(ins, IPOINT_BEFORE, AFUNPTR(VerifyNotTaken), IARG_BRANCH_TAKEN, IARG_END); } }
VOID RecordMemRead(INS ins, VOID * ip, VOID * addr) { cout<<"opcode:"<<INS_Opcode(ins)<<", mnemonic: "<<INS_Mnemonic(ins)<<endl; printf("%p: addr: %p, R %d\n", ip,addr, *(((int *)addr)+1)); /*if(*(int *)addr == 666) { cout<<"replacing"<<endl; *(int *)addr = 777; }*/ }
/* * trace inspection (instrumentation function) * * traverse the basic blocks (BBLs) on the trace and * inspect every instruction for instrumenting it * accordingly * * @trace: instructions trace; given by PIN * @v: callback value */ static void trace_inspect(TRACE trace, VOID *v) { /* iterators */ BBL bbl; INS ins; xed_iclass_enum_t ins_indx; /* versioning support */ ADDRINT version, version_mask = (ADDRINT)v; if (version_mask) { /* * ignore code cache versions that we * are not supposed to instrument */ version = TRACE_Version(trace); if ((version & version_mask) == 0) return; } /* traverse all the BBLs in the trace */ for (bbl = TRACE_BblHead(trace); BBL_Valid(bbl); bbl = BBL_Next(bbl)) { /* traverse all the instructions in the BBL */ for (ins = BBL_InsHead(bbl); INS_Valid(ins); ins = INS_Next(ins)) { /* * use XED to decode the instruction and * extract its opcode */ ins_indx = (xed_iclass_enum_t)INS_Opcode(ins); /* * invoke the pre-ins instrumentation callback */ if (ins_desc[ins_indx].pre != NULL) ins_desc[ins_indx].pre(ins); /* * analyze the instruction (default handler) */ if (ins_desc[ins_indx].dflact == INSDFL_ENABLE) ins_inspect(ins); /* * invoke the post-ins instrumentation callback */ if (ins_desc[ins_indx].post != NULL) ins_desc[ins_indx].post(ins); } } }
void convert_load_addr(INS ins, void* v) { if (INS_Opcode(ins) == XED_ICLASS_MOV && INS_IsMemoryRead(ins) && INS_OperandIsReg(ins, 0) && INS_OperandIsMemory(ins, 1)) { // op0 <- *op1 INS_InsertCall(ins, IPOINT_BEFORE, AFUNPTR(convert), IARG_MEMORYREAD_EA, IARG_END); } }
VOID Instruction(INS ins, VOID *v) { //printf ("Instruction at %x\n", INS_address(ins)); if (INS_Opcode(ins)==XED_ICLASS_POPF || INS_Opcode(ins)==XED_ICLASS_POPFD || INS_Opcode(ins)==XED_ICLASS_POPFQ || instrumentNext) { if (instrumentNext) { // IPOINT_BEFORE instrumentation on instruction after popf* INS_InsertCall(ins, IPOINT_BEFORE, (AFUNPTR)UnalignedReadAndWrite, IARG_END); instrumentNext = FALSE; } else { // IPOINT_AFTER instrumentation on popf* INS_InsertCall(ins, IPOINT_AFTER, (AFUNPTR)UnalignedReadAndWrite, IARG_END); instrumentNext = TRUE; } return; } }
void instruction (INS ins, void *v) { if (INS_IsMemoryRead(ins)) { INS_InsertPredicatedCall(ins, IPOINT_BEFORE, AFUNPTR(on_load), IARG_THREAD_ID, IARG_INST_PTR, IARG_MEMORYREAD_EA, IARG_MEMORYREAD_SIZE, IARG_ADDRINT, INS_Opcode(ins), IARG_END); } if (INS_HasMemoryRead2(ins)) { INS_InsertPredicatedCall(ins, IPOINT_BEFORE, AFUNPTR(on_load), IARG_THREAD_ID, IARG_INST_PTR, IARG_MEMORYREAD2_EA, IARG_MEMORYREAD_SIZE, IARG_ADDRINT, INS_Opcode(ins), IARG_END); } if (INS_IsMemoryWrite(ins)) { //TODO get value. see SimpleExamples/pinatrace.cpp INS_InsertPredicatedCall(ins, IPOINT_BEFORE, AFUNPTR(on_store), IARG_THREAD_ID, IARG_INST_PTR, IARG_MEMORYWRITE_EA, IARG_MEMORYWRITE_SIZE, IARG_ADDRINT, INS_Opcode(ins), IARG_END); } }
// Insert a call to an analysis routine that sets the scratch xmm registers, the call is inserted just after the // movdqa instruction of DoXmm (see xmm-asm-*.s) static VOID InstrumentRoutine(RTN rtn, VOID *) { if (RTN_Name(rtn) == "DoXmm") { RTN_Open(rtn); for (INS ins = RTN_InsHead(rtn); INS_Valid(ins); ins = INS_Next(ins)) { if (INS_Opcode(ins)==XED_ICLASS_MOVDQA) { fprintf (fp, "instrumenting ins %p %s\n", (void *)INS_Address(ins), INS_Disassemble(ins).c_str()); instrumented = TRUE; INS_InsertCall(ins, IPOINT_AFTER, (AFUNPTR)SetXmmScratchesFun, IARG_PTR, xmmInitVals, IARG_END); } } RTN_Close(rtn); } }
/* * trace inspection (instrumentation function) * * traverse the basic blocks (BBLs) on the trace and * inspect every instruction for instrumenting it * accordingly * * @trace: instructions trace; given by PIN * @v: callback value */ static void trace_inspect(TRACE trace, VOID *v) { /* iterators */ BBL bbl; INS ins; xed_iclass_enum_t ins_indx; //printf("dealing trace!\n"); /* traverse all the BBLs in the trace */ for (bbl = TRACE_BblHead(trace); BBL_Valid(bbl); bbl = BBL_Next(bbl)) { /* traverse all the instructions in the BBL */ ins = BBL_InsHead(bbl); for (ins = BBL_InsHead(bbl); INS_Valid(ins); ins = INS_Next(ins)) { /* * use XED to decode the instruction and * extract its opcode */ ins_indx = (xed_iclass_enum_t)INS_Opcode(ins); /* * invoke the pre-ins instrumentation callback */ if (ins_desc[ins_indx].pre != NULL) ins_desc[ins_indx].pre(ins); /* * analyze the instruction (default handler) */ if (ins_desc[ins_indx].dflact == INSDFL_ENABLE){ ins_inspect(ins); //printf("dealing ins_inspect!\n"); } /* * invoke the post-ins instrumentation callback */ if (ins_desc[ins_indx].post != NULL) ins_desc[ins_indx].post(ins); } } }
VOID EmulateLoad(INS ins, VOID* v) { if (INS_Opcode(ins) == XEDICLASS_MOV && INS_IsMemoryRead(ins) && INS_OperandIsReg(ins, 0) && INS_OperandIsMemory(ins, 1)) { // op0 <- *op1 INS_InsertCall(ins, IPOINT_BEFORE, AFUNPTR(DoLoad), IARG_UINT32, REG(INS_OperandReg(ins, 0)), IARG_MEMORYREAD_EA, IARG_RETURN_REGS, INS_OperandReg(ins, 0), IARG_END); INS_Delete(ins); } }
// Pin calls this function every time a new instruction is encountered VOID Instruction(INS ins, VOID *v) { // ADITYAV EDIT // check if opcode is rdtscp if (INS_Opcode(ins) == XED_ICLASS_RDTSCP) { insert_call = ~insert_call; // flip instrumentation if (insert_call) fprintf(trace, "\nJS Event Start\n"); else fprintf(trace, "\nJS Event End\n"); } if (insert_call) { // Insert a call to printip before every instruction, and pass it the IP INS_InsertCall(ins, IPOINT_BEFORE, (AFUNPTR)printip, IARG_INST_PTR, IARG_END); } }
void taint_ins(INS ins, void *v) { uint32_t opcode = INS_Opcode(ins); uint32_t opcount = INS_OperandCount(ins); // the generic stuff only supports up to 5 operands if(opcount < 6 && taint_handler_count[opcode] != 0) { // first we have to build up the flags, which is kind of expensive. uint32_t flags = 0; for (uint32_t i = 0; i < opcount; i++) { uint32_t op_flag = 0; if(INS_OperandIsMemory(ins, i) != 0) { op_flag |= T_MEM; } if(INS_OperandIsAddressGenerator(ins, i) != 0) { op_flag |= T_ADR; } if(INS_OperandIsReg(ins, i) != 0) { op_flag |= T_REG; } if(INS_OperandIsImmediate(ins, i) != 0) { op_flag |= T_IMM; } if(INS_OperandRead(ins, i) != 0) { op_flag |= T_RD; } if(INS_OperandWritten(ins, i) != 0) { op_flag |= T_WR; } flags |= op_flag << (6 * i); } for (uint32_t i = 0; i < taint_handler_count[opcode]; i++) { if(taint_handler_flag[opcode][i] == flags) { taint_prop_handle(ins, taint_handler_fn[opcode][i], taint_handler_args[opcode][i]); return; } } } }
static void Instruction(INS ins, VOID *) { UINT32 op = INS_Opcode(ins); for (UINT32 j=0; j<NumTestDescriptions; j++) { instructionTest * t = &tests[j]; if (t->opcode != op) continue; /* Aha, a test which applies to this opcode */ UINT32 result = 0; INT32 operand = t->operand; if (operand < 0) operand = INS_OperandCount(ins) - operand; // Run all the property enquiries and accumulate the results. for (UINT32 i=0;i<NumTestFunctions;i++) { if (t->testProps & (1<<i)) { if (testFunctions[i](ins, operand)) result |= (1<<i); } } testCounts[op].tested++; // Check the result against the expected value. if (result != t->result) { testCounts[op].failed++; out << std::setw(50) << std::left << INS_Disassemble(ins) << std::right << "Operand " << operand << " Expected '" << formatMask(t->result) << "' Got '" << formatMask(result) << "'" << endl; } } }
// Instrument individual instructions. // Specific instrumentation for REP prefixed instructions. static VOID InstrumentInstruction(INS ins, VOID *) { if (INS_IsBranchOrCall(ins)) { INS_InsertCall(ins, IPOINT_BEFORE, (AFUNPTR)ClearPrevRep, IARG_END); } // We're only interested in REP prefixed instructions. if (!INS_HasRealRep(ins)) return; UINT32 opIdx = opcodeIndex(INS_Opcode(ins)); insertRepExecutionCountInstrumentation(ins, opIdx); // If requested also add the instrumentation to count memory references. if (KnobCountMemory) insertRepMemoryCountInstrumentation (ins, opIdx); if (KnobAddresses) insertRepMemoryTraceInstrumentation (ins, opIdx); }
static VOID RewriteIns(INS ins, VOID *) { if (INS_Opcode(ins) != XED_ICLASS_POP) return; if (!INS_IsMemoryWrite(ins)) return; if (INS_MemoryBaseReg(ins) != REG_STACK_PTR) return; // If we get here we have a pop into a stack pointer relative address. ADDRDELTA offset = INS_MemoryDisplacement(ins); INS_InsertCall(ins, IPOINT_BEFORE, AFUNPTR(validateWriteAddress), IARG_INST_PTR, IARG_MEMORYWRITE_EA, IARG_REG_VALUE, REG_STACK_PTR, IARG_ADDRINT, offset, IARG_UINT32, INS_MemoryReadSize(ins), IARG_END); }