/* * Copyright 2002-2019 Intel Corporation. * * This software is provided to you as Sample Source Code as defined in the accompanying * End User License Agreement for the Intel(R) Software Development Products ("Agreement") * section 1.L. * * This software and the related documents are provided as is, with no express or implied * warranties, other than those that are expressly stated in the License. */ /* * Check that we get the correct effective addresses for pop ops where the stack pointer * is part of the address. * It is *not* sufficient to use lea on the address, because the stack pointer is adjusted * *before* the address is calculated. * * That's a special case, hence a special test... * * This is intended to be used with the "far" test, or smallpush since they already have suitable * instructions in them. */ #include #include #include "pin.H" using std::string; KNOB KnobTrace(KNOB_MODE_WRITEONCE, "pintool", "t", "0", "trace memory addresses of interest"); KNOB KnobOutput(KNOB_MODE_WRITEONCE,"pintool", "o", "popea_verifier.out", "Name for log file"); static FILE *trace = NULL; static UINT32 fails = 0; static UINT32 tests = 0; /* Check the address we are given matches that we calculate from the ctx * * We're only looking at pop offset(%esp) instructions. */ static VOID validateWriteAddress (ADDRINT ip, ADDRINT writeAddr, ADDRINT esp, ADDRDELTA offset, UINT32 operandSize) { ADDRINT expectedAddress = esp+operandSize+offset; /* ESP is incremented *BEFORE* it is used in addressing */ if (writeAddr != expectedAddress) { fprintf (trace, "%p: EA %p should be %p\n", (void*)ip, (void*)writeAddr, (void*)expectedAddress); fails++; } else if (KnobTrace) { fprintf (trace, "%p: EA %p OK\n", (void*)ip, (void*)writeAddr); } tests++; } 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); } void AtEnd(INT32 code, VOID *arg) { fprintf (trace, "Tested: %d, failed: %d\n", tests, fails); fclose(trace); exit (fails); } int main(int argc, char * argv[]) { PIN_InitSymbols(); PIN_Init(argc, argv); trace = fopen(KnobOutput.Value().c_str(), "w"); if (!trace) { perror("fopen"); return 1; } INS_AddInstrumentFunction(RewriteIns, 0); PIN_AddFiniFunction(AtEnd, 0); // Never returns PIN_StartProgram(); return 0; }