static VOID SyscallEntry(THREADID threadIndex, CONTEXT *ctxt, SYSCALL_STANDARD std, VOID *v) { if (PIN_GetSyscallNumber(ctxt, std) != SYS_sysarch) return; ADDRINT pc = PIN_GetContextReg(ctxt, REG_INST_PTR); ADDRINT op = PIN_GetSyscallArgument(ctxt, std, 0); ADDRINT addr = PIN_GetSyscallArgument(ctxt, std, 1); ADDRINT value = 0; if (op == AMD64_SET_FSBASE || op == AMD64_SET_GSBASE) { if (PIN_SafeCopy(&value, Addrint2VoidStar(addr), sizeof(ADDRINT)) != sizeof(ADDRINT)) { Out << Header(threadIndex, pc) << "Failed to read actual TLS pointer" << endl; } } else { // Remember the location where to write the segment register in REG_INST_G0 PIN_SetContextReg(ctxt, REG_INST_G0, addr); value = addr; } Out << Header(threadIndex, pc) << "sysarch(" << SysArchFunc(op) << ", 0x" << std::hex << value << ")" << std::endl; }
// This function is called before every instruction is executed // and prints the pre-formatted dis-assembled instruction static VOID printInstruction(THREADID thread, ADDRINT disas) { threadState * s = &threadStates[thread]; UINT32 seqNo = ++s->iCount; out << dec << seqNo << ":" << ((const char *)Addrint2VoidStar(disas)) << endl; }
// Called every time a new image is loaded // Look for routines that we want to probe VOID ImageLoad(IMG img, VOID *v) { const ANNOTATION *ann = 0; USIZE num = 0; printf("Processing %s\n", IMG_Name(img).c_str()); for (SEC sec = IMG_SecHead(img); SEC_Valid(sec); sec = SEC_Next(sec)) { if (SEC_Name(sec) == "MyAnnot") { ann = reinterpret_cast<const ANNOTATION*>(SEC_Data(sec)); num = SEC_Size(sec) / sizeof(ANNOTATION); } } if (ann) { printf("Found annotations: \n"); for (UINT32 i = 0; i < num; i++) { ADDRINT addr = ann[i].addr; ADDRINT val = ann[i].value; printf("\t%p %p\t", Addrint2VoidStar(addr), Addrint2VoidStar(val)); if (PIN_IsSafeForProbedInsertion(addr)) { PIN_InsertCallProbed(addr, AFUNPTR(Notification), IARG_ADDRINT, val, IARG_END); printf(" - OK\n"); } else { printf(" - Failed\n"); } } // Set the write line function, from the image of the annotations (i.e. the main executable). RTN writeRtn = RTN_FindByName(img, "write_line"); if (RTN_Valid(writeRtn)) { writeFun = (void (*)(char *))RTN_Funptr(writeRtn); } } printf("Completed %s\n", IMG_Name(img).c_str()); }
void Notification(ADDRINT val) { char buff[80]; if (!writeFun) { fprintf(stderr, "Write Function was not initialized ...\n"); exit(1); } sprintf(buff, "Notification value: %p", Addrint2VoidStar(val)); writeFun(buff); }
static VOID SyscallExit(THREADID threadIndex, CONTEXT *ctxt, SYSCALL_STANDARD std, VOID *v) { ADDRINT addr = PIN_GetContextReg(ctxt, REG_INST_G0); if (!addr) return; // Reset REG_INST_G0 PIN_SetContextReg(ctxt, REG_INST_G0, 0); ADDRINT pc = PIN_GetContextReg(ctxt, REG_INST_PTR); ADDRINT ret = PIN_GetSyscallReturn(ctxt, std); ADDRINT value = 0; if (ret == (ADDRINT)-1 || PIN_SafeCopy(&value, Addrint2VoidStar(addr), sizeof(ADDRINT)) != sizeof(ADDRINT)) { Out << Header(threadIndex, pc) << "Failed to read actual TLS pointer" << endl; } Out << Header(threadIndex, pc) << "sysarch returned: " << ", 0x" << std::hex << value << "" << std::endl; }
VOID Ins( INS ins, VOID *v ) { if (KnobDetach > 0 && scount > KnobDetach) return; if (KnobLog) { void *addr = Addrint2VoidStar(INS_Address(ins)); string disasm = INS_Disassemble(ins); PrintIns(addr, disasm.c_str()); } scount++; // call and return need also stack manipulation (see emu_stack.cpp) // conditional jumps need handling the condition (not supported yet) if (INS_IsCall(ins) || INS_IsRet(ins) || INS_Category(ins) == XED_CATEGORY_COND_BR) return; if (INS_IsIndirectBranchOrCall(ins)) { INS_InsertCall(ins, IPOINT_BEFORE, AFUNPTR(EmuIndJmp), IARG_BRANCH_TARGET_ADDR, IARG_RETURN_REGS, scratchReg, IARG_END); INS_InsertIndirectJump(ins, IPOINT_AFTER, scratchReg); INS_Delete(ins); } else if (INS_IsDirectBranchOrCall(ins)) { ADDRINT tgt = INS_DirectBranchOrCallTargetAddress(ins); INS_InsertDirectJump(ins, IPOINT_AFTER, tgt); INS_Delete(ins); } }
VOID Ins( INS ins, VOID *v ) { if (KnobDetach > 0 && scount > KnobDetach) return; if (KnobLog) { void *addr = Addrint2VoidStar(INS_Address(ins)); string disasm = INS_Disassemble(ins); PrintIns(addr, disasm.c_str()); } scount++; if (INS_Opcode(ins) == XED_ICLASS_PUSH) { if (INS_OperandIsImmediate(ins, 0)) { ADDRINT value = INS_OperandImmediate(ins, 0); INS_InsertCall(ins, IPOINT_BEFORE, AFUNPTR(EmuPushValue), IARG_REG_VALUE, REG_STACK_PTR, IARG_ADDRINT, value, IARG_RETURN_REGS, REG_STACK_PTR, IARG_END); INS_Delete(ins); } else if(INS_OperandIsReg(ins, 0)) { REG reg = INS_OperandReg(ins, 0); INS_InsertCall(ins, IPOINT_BEFORE, AFUNPTR(EmuPushValue), IARG_REG_VALUE, REG_STACK_PTR, IARG_REG_VALUE, reg, IARG_RETURN_REGS, REG_STACK_PTR, IARG_END); INS_Delete(ins); } else if(INS_OperandIsMemory(ins, 0)) { INS_InsertCall(ins, IPOINT_BEFORE, AFUNPTR(EmuPushMem), IARG_REG_VALUE, REG_STACK_PTR, IARG_MEMORYREAD_EA, IARG_RETURN_REGS, REG_STACK_PTR, IARG_END); INS_Delete(ins); } else { fprintf(stderr, "EmuPush: unsupported operand type (%p:'%s')\n", Addrint2VoidStar(INS_Address(ins)), INS_Disassemble(ins).c_str()); } } else if (INS_Opcode(ins) == XED_ICLASS_POP) { if(INS_OperandIsReg(ins, 0)) { INS_InsertCall(ins, IPOINT_BEFORE, AFUNPTR(EmuPopReg), IARG_REG_VALUE, REG_STACK_PTR, IARG_REG_REFERENCE, INS_OperandReg(ins, 0), IARG_RETURN_REGS, REG_STACK_PTR, IARG_END); INS_Delete(ins); } else if(INS_OperandIsMemory(ins, 0)) { INS_InsertCall(ins, IPOINT_BEFORE, AFUNPTR(EmuPopMem), IARG_REG_VALUE, REG_STACK_PTR, IARG_MEMORYWRITE_EA, IARG_RETURN_REGS, REG_STACK_PTR, IARG_END); INS_Delete(ins); } else { fprintf(stderr, "EmuPop: unsupported operand type (%p:'%s')\n", Addrint2VoidStar(INS_Address(ins)), INS_Disassemble(ins).c_str()); } } else if (INS_Opcode(ins) == XED_ICLASS_LEAVE) { INS_InsertCall(ins, IPOINT_BEFORE, AFUNPTR(EmuLeave), IARG_REG_VALUE, REG_STACK_PTR, IARG_REG_REFERENCE, REG_GBP, IARG_RETURN_REGS, REG_STACK_PTR, IARG_END); INS_Delete(ins); } else if (INS_IsCall(ins)) { INS_InsertCall(ins, IPOINT_BEFORE, AFUNPTR(EmuCall), IARG_ADDRINT, INS_NextAddress(ins), IARG_BRANCH_TARGET_ADDR, IARG_REG_REFERENCE, REG_STACK_PTR, IARG_RETURN_REGS, scratchReg, IARG_END); INS_InsertIndirectJump(ins, IPOINT_AFTER, scratchReg); INS_Delete(ins); } else if (INS_IsRet(ins)) { UINT64 imm = 0; if (INS_OperandCount(ins) > 0 && INS_OperandIsImmediate(ins, 0)) { imm = INS_OperandImmediate(ins, 0); } INS_InsertCall(ins, IPOINT_BEFORE, AFUNPTR(EmuRet), IARG_CALL_ORDER, CALL_ORDER_FIRST, IARG_REG_REFERENCE, REG_STACK_PTR, IARG_ADDRINT, (ADDRINT)imm, IARG_RETURN_REGS, scratchReg, IARG_END); INS_InsertIndirectJump(ins, IPOINT_AFTER, scratchReg); INS_Delete(ins); } else if (INS_IsIndirectBranchOrCall(ins)) { // This is not a call (it was checked before) so this is indirect jump INS_InsertCall(ins, IPOINT_BEFORE, AFUNPTR(EmuIndJmp), IARG_BRANCH_TARGET_ADDR, IARG_RETURN_REGS, scratchReg, IARG_END); INS_InsertIndirectJump(ins, IPOINT_AFTER, scratchReg); INS_Delete(ins); } }