Example #1
0
static VOID InsertIfNoBridgeThenInline(RTN rtn)
{
    RTN_Open(rtn);
    INS_InsertIfCall(RTN_InsHead(rtn), IPOINT_BEFORE, AFUNPTR(IfNoBridge), IARG_END);
    INS_InsertThenCall(RTN_InsHead(rtn), IPOINT_BEFORE, AFUNPTR(ThenInline), IARG_END);
    RTN_Close(rtn);
}
Example #2
0
VOID Image(IMG img, void *v)
{
    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))
        {
            RTN_Open(rtn);
            numRtnsFoundInImageCallback++;
            INS ins = RTN_InsHeadOnly(rtn);
            if (INS_Invalid() == ins)
            {   // no instruction found - assert that RTN_InsHead(rtn) also doesn't find any INS 
                ASSERTX (INS_Invalid() == RTN_InsHead(rtn));
                RTN_Close(rtn);
                continue;
            }
                       
            if (INS_HasFallThrough(ins))
            {
                ADDRINT insAddress = INS_Address(ins);
                numRtnsInstrumentedFromImageCallback++;
                RTN_InsertCall( rtn, IPOINT_BEFORE,  AFUNPTR(AtRtn),            IARG_ADDRINT, RTN_Address(rtn), IARG_END);
                
                INS_InsertCall (ins, IPOINT_BEFORE, AFUNPTR(BeforeInsHeadOnly), IARG_ADDRINT, INS_Address(ins), IARG_END);
                INS_InsertCall (ins, IPOINT_AFTER,  AFUNPTR(AfterInsHeadOnly),  IARG_ADDRINT, INS_Address(ins), IARG_END);
                ins = RTN_InsHead(rtn);
                ASSERTX(INS_Invalid() != ins);
                ASSERTX(INS_Address(ins)==insAddress);
                INS_InsertCall (ins, IPOINT_BEFORE, AFUNPTR(BeforeInsHead),      IARG_ADDRINT, insAddress,      IARG_END);
                INS_InsertCall (ins, IPOINT_AFTER,  AFUNPTR(AfterInsHead),       IARG_ADDRINT, insAddress,      IARG_END);
            }
            RTN_Close(rtn);
        }
    }
}
Example #3
0
static VOID InsertIfBridgeThenBridge(RTN rtn)
{
    RTN_Open(rtn);
    INS_InsertIfCall(RTN_InsHead(rtn), IPOINT_BEFORE, AFUNPTR(IfBridge), IARG_BRIDGE_IF, IARG_END);
    INS_InsertThenCall(RTN_InsHead(rtn), IPOINT_BEFORE, AFUNPTR(ThenBridge), IARG_BRIDGE, IARG_END);
    RTN_Close(rtn);
}
static VOID OnRoutine(RTN rtn, VOID *)
{
#if defined(TARGET_MAC)
    if (RTN_Name(rtn) == "_DoThenInstrumentation")
#else
    if (RTN_Name(rtn) == "DoThenInstrumentation")
#endif
    {
        RTN_Open(rtn);
        INS_InsertIfCall(RTN_InsHead(rtn), IPOINT_BEFORE, AFUNPTR(IfTrue), IARG_END);
        INS_InsertThenCall(RTN_InsHead(rtn), IPOINT_BEFORE, AFUNPTR(ThenFunction), IARG_END);
        RTN_Close(rtn);
    }
}
Example #5
0
VOID Image(IMG img, VOID * v)
{
    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))
        {
            RTN_Open(rtn);
            
            for (INS ins = RTN_InsHead(rtn); INS_Valid(ins); ins = INS_Next(ins))
            {
                if( INS_IsPredicated(ins) )
                    GlobalStatsStatic.predicated[ INS_Category(ins) ]++;
                else
                    GlobalStatsStatic.unpredicated[ INS_Category(ins) ]++;
            }

            RTN_Close(rtn);
        }
    }

    if( KnobProfileStaticOnly.Value() )
    {
        Fini(0,0);
        exit(0);
    }
}
// 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;
        }
    }
}
Example #7
0
/*
 * Instrumentation-time routine looking for the routine we'd like to instrument.
 */
static VOID ImageLoad(IMG img, VOID * v)
{
    if (IMG_IsMainExecutable(img))
    {
        *outFile << "In main application image" << endl;
        // Search for the assembly routine in the application
        RTN AsmRtn = RTN_FindByName(img, "operImmCmds");
        if (!RTN_Valid(AsmRtn))
        {
            AsmRtn = RTN_FindByName(img, "_operImmCmds");
        }
        if (RTN_Valid(AsmRtn))
        {
            *outFile << "Function operImmCmds found" << endl;
            RTN_Open(AsmRtn);
            // Go over each of the routine's instructions
            for (INS ins = RTN_InsHead(AsmRtn); INS_Valid(ins); ins = INS_Next(ins))
            {
                Instruction(ins, 0);
            }
            RTN_Close(AsmRtn);
            *outFile << "Done with function operImmCmds" << endl;
        }
        else
        {
            *outFile << "Function operImmCmds not found!" << endl;
        }
    }
}
Example #8
0
// Pin calls this function every time a new rtn is executed
VOID Routine(RTN rtn, VOID *v)
{
    
    // Allocate a counter for this routine
    RTN_COUNT * rc = new RTN_COUNT;

    // The RTN goes away when the image is unloaded, so save it now
    // because we need it in the fini
    rc->_name = RTN_Name(rtn);
    rc->_image = StripPath(IMG_Name(SEC_Img(RTN_Sec(rtn))).c_str());
    rc->_address = RTN_Address(rtn);
    rc->_icount = 0;
    rc->_rtnCount = 0;

    // Add to list of routines
    rc->_next = RtnList;
    RtnList = rc;
            
    RTN_Open(rtn);
            
    // Insert a call at the entry point of a routine to increment the call count
    RTN_InsertCall(rtn, IPOINT_BEFORE, (AFUNPTR)docount, IARG_PTR, &(rc->_rtnCount), IARG_END);
    
    // For each instruction of the routine
    for (INS ins = RTN_InsHead(rtn); INS_Valid(ins); ins = INS_Next(ins))
    {
        // Insert a call to docount to increment the instruction counter for this rtn
        INS_InsertCall(ins, IPOINT_BEFORE, (AFUNPTR)docount, IARG_PTR, &(rc->_icount), IARG_END);
    }

    
    RTN_Close(rtn);
}
Example #9
0
PyObject* Python_RTN_InsHead(PyObject* self, PyObject* args) {
    PyObject* rtn;
    PyArg_ParseTuple(args, "L", &rtn);
    RTN rtn_object = *(RTN*) rtn;
    INS* ins_return = (INS*) malloc(sizeof(INS));
    *ins_return = RTN_InsHead(rtn_object);
    return Py_BuildValue("L", ins_return);
}
Example #10
0
VOID Rtn(RTN rtn, VOID * v)
{
    string name = RTN_Name(rtn);
    if (name == "test1") {
        RTN_Open(rtn);
        for (INS ins = RTN_InsHead(rtn); INS_Valid(ins); ins = INS_Next(ins)) {
            CountsUpdate(ins);
        }
        RTN_Close(rtn);
    }
}
static void InstrumentImage(IMG img, VOID *dummy)
{
    RTN rtn = RTN_FindByName(img, "MakeSegv");
    if (RTN_Valid(rtn))
    {
        RTN_Open(rtn);
        INS first = RTN_InsHead(rtn);
        if (INS_Valid(first))
            INS_InsertCall(first, IPOINT_BEFORE, (AFUNPTR)AtSegv, IARG_END);
        RTN_Close(rtn);
    }
}
// Delete the first mov immediate
static VOID deleteMov (RTN rtn)
{
    for (INS ins = RTN_InsHead(rtn); INS_Valid(ins); ins = INS_Next(ins))
    {
        if (INS_IsMov(ins) && INS_HasImmediateOperand(ins))
        {
            INS_Delete(ins);
            instrumentationCount++;
            return;
        }
    }
}
// Insert a direct branch over the first mov immediate
static VOID insertJump (RTN rtn)
{
    for (INS ins = RTN_InsHead(rtn); INS_Valid(ins); ins = INS_Next(ins))
    {
        if (INS_IsMov(ins) && INS_HasImmediateOperand(ins))
        {
            INS_InsertDirectJump(ins, IPOINT_BEFORE, INS_Address(ins) + INS_Size(ins));
            instrumentationCount++;
            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);
        }
    }
}
// Insert an indirect branch over the first mov immediate
static VOID insertIndirectJump (RTN rtn)
{
    for (INS ins = RTN_InsHead(rtn); INS_Valid(ins); ins = INS_Next(ins))
    {
        if (INS_IsMov(ins) && INS_HasImmediateOperand(ins))
        {
            INS_InsertCall(ins, IPOINT_BEFORE,
                           AFUNPTR(returnValue),
                           IARG_ADDRINT, INS_Address(ins) + INS_Size(ins),
                           IARG_RETURN_REGS, scratchReg, IARG_END);

            INS_InsertIndirectJump(ins, IPOINT_BEFORE, scratchReg);
            instrumentationCount++;
            return;
        }
    }
}
Example #16
0
VOID Image(IMG img, VOID * v)
{
    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))
        {
            RTN_Open(rtn);
            
            for (INS ins = RTN_InsHead(rtn); INS_Valid(ins); ins = INS_Next(ins))
            {
                sandbox.RecordIns(ins);
            }

            RTN_Close(rtn);
        }
    }
}
Example #17
0
// 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);
    }
}
static VOID imageLoad(IMG img, VOID *v)
{
    // Just instrument the main image.
    if (!IMG_IsMainExecutable(img))
        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))
        {
            RTN_Open(rtn);
            for (INS ins=RTN_InsHead(rtn); INS_Valid(ins); ins=INS_Next(ins))
            {
                INS_InsertCall(ins, IPOINT_BEFORE,
                               (AFUNPTR)incCount, IARG_END);
            }
            RTN_Close(rtn);
        }
    }
}
Example #19
0
VOID Routine(RTN rtn, VOID *v) {
  std::string name = PIN_UndecorateSymbolName(RTN_Name(rtn).c_str(),
                       UNDECORATION_NAME_ONLY);

  std::vector<std::string>::iterator it;
  for (it = userFuncs.begin(); it != userFuncs.end(); ++it) {
    std::string userFunc = *it;
    if (name.find(userFunc) == std::string::npos) continue;

    RTN_Open(rtn);

    // For each instruction of the routine
    for (INS ins = RTN_InsHead(rtn); INS_Valid(ins); ins = INS_Next(ins)) {
      UINT32 memOperands = INS_MemoryOperandCount(ins);

      // Iterate over each memory operand of the instruction.
      for (UINT32 memOp = 0; memOp < memOperands; memOp++) {
        if (INS_IsStackRead(ins) || INS_IsStackWrite(ins))
          break;

        if (INS_MemoryOperandIsRead(ins, memOp)) {
          INS_InsertPredicatedCall(
            ins, IPOINT_BEFORE, (AFUNPTR)RecordMemRead,
            IARG_INST_PTR,
            IARG_MEMORYOP_EA, memOp, IARG_THREAD_ID,
            IARG_END);
        }
        if (INS_MemoryOperandIsWritten(ins, memOp)) {
          INS_InsertPredicatedCall(
            ins, IPOINT_BEFORE, (AFUNPTR)RecordMemWrite,
            IARG_INST_PTR,
            IARG_MEMORYOP_EA, memOp, IARG_THREAD_ID,
            IARG_END);
        }
      }
    }

    RTN_Close(rtn);
  }
}
Example #20
0
/* ===================================================================== */
VOID Image(IMG img, VOID *v){

  for (UINT16 i = 0; i < n_excluded_lib_names; i++)
  {
    if (IMG_Name(img).find(excluded_lib_names[i]) != string::npos){
      cout << "Excluded module: " << IMG_Name(img) << endl;
      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)) {
      RTN_Open(rtn);
      for (INS ins = RTN_InsHead(rtn); INS_Valid(ins); ins = INS_Next(ins)) {
        // Avoid instrumenting the instrumentation
        if (!INS_IsOriginal(ins))
          continue;
				
        if(!SeqProgram) {
				  if ((INS_IsMemoryWrite(ins) || INS_IsMemoryRead(ins)) && INS_HasFallThrough(ins)) {		
				  	if (INS_IsMemoryWrite(ins) && INS_IsMemoryRead(ins) &&
                INS_HasMemoryRead2(ins)) {
              INS_InsertCall(ins, IPOINT_BEFORE, (AFUNPTR)ProcessInst, IARG_THREAD_ID,
                            IARG_MEMORYWRITE_EA,
                            IARG_MEMORYREAD_EA,
                            IARG_MEMORYREAD2_EA,
                            IARG_INST_PTR,
                            IARG_END); 
            }					
				  	else if (INS_IsMemoryWrite(ins) && INS_IsMemoryRead(ins) &&
          	          !INS_HasMemoryRead2(ins)) {
				  		INS_InsertCall(ins, IPOINT_BEFORE, (AFUNPTR)ProcessInst, IARG_THREAD_ID,
                            IARG_MEMORYWRITE_EA,
                            IARG_MEMORYREAD_EA,
                            IARG_ADDRINT, 0,
                            IARG_INST_PTR,
                            IARG_END);		
				  		
				  	}
				  	else if (INS_IsMemoryWrite(ins) && !INS_IsMemoryRead(ins)) {
				  		INS_InsertCall(ins, IPOINT_BEFORE, (AFUNPTR)ProcessInst, IARG_THREAD_ID,
                            IARG_MEMORYWRITE_EA,
                            IARG_ADDRINT, 0,
                            IARG_ADDRINT, 0,
                            IARG_INST_PTR,
                            IARG_END);		
				  	}
				  	else if (!INS_IsMemoryWrite(ins) && INS_IsMemoryRead(ins) &&
                    INS_HasMemoryRead2(ins)) {
				  		INS_InsertCall(ins, IPOINT_BEFORE, (AFUNPTR)ProcessInst, IARG_THREAD_ID,
                 						IARG_ADDRINT, 0,
                            IARG_MEMORYREAD_EA,
                            IARG_MEMORYREAD2_EA,
                            IARG_INST_PTR,
                            IARG_END);
				  	}
				  	else if (!INS_IsMemoryWrite(ins) && INS_IsMemoryRead(ins) &&
                    !INS_HasMemoryRead2(ins)) {
				  		INS_InsertCall(ins, IPOINT_BEFORE, (AFUNPTR)ProcessInst, IARG_THREAD_ID,
                 						IARG_ADDRINT, 0,
                            IARG_MEMORYREAD_EA,
                            IARG_ADDRINT,0,
                            IARG_INST_PTR,
                            IARG_END);	
				  	}
				  	else { //not a memory opeartion     
              ASSERTX(0);
				  	}
				  }
        }
        else {
          if(INS_IsBranch(ins)){
            INS_InsertCall(ins, IPOINT_BEFORE, (AFUNPTR)ProcessBranch, 
              IARG_BRANCH_TAKEN, IARG_INST_PTR, IARG_END);
          }
        }
			}
			RTN_Close(rtn);
		}
	}

  
}
Example #21
0
int rtn_ins_head (lua_State *L) {
  RTN* v1 = check_rtn(L,1);
  INS_to_lua(L, RTN_InsHead(*v1));
  return 1;
}
Example #22
0
int main(INT32 argc, CHAR **argv)
{
    PIN_InitSymbols();

    if( PIN_Init(argc,argv) )
    {
        return Usage();
    }
    
    IMG img = IMG_Open(KnobInputFile);

    if (!IMG_Valid(img))
    {
        std::cout << "Could not open " << KnobInputFile.Value() << endl;
        exit(1);
    }
    
    std::cout << hex;
    rtnInternalRangeList.clear();

    for (SEC sec = IMG_SecHead(img); SEC_Valid(sec); sec = SEC_Next(sec))
    {
        std::cout << "Section: " << setw(8) << SEC_Address(sec) << " " << SEC_Name(sec) << endl;
                
        for (RTN rtn = SEC_RtnHead(sec); RTN_Valid(rtn); rtn = RTN_Next(rtn))
        {
            std::cout << "  Rtn: " << setw(8) << hex << RTN_Address(rtn) << " " << RTN_Name(rtn) << endl;
            string path;
            INT32 line;
            PIN_GetSourceLocation(RTN_Address(rtn), NULL, &line, &path);

            if (path != "")
            {
                std::cout << "File " << path << " Line " << line << endl; 
            }

            RTN_Open(rtn);
           
            if (!INS_Valid(RTN_InsHead(rtn)))
            {
                RTN_Close(rtn);
                continue;
            }
 
            RTN_INTERNAL_RANGE rtnInternalRange;
            rtnInternalRange.start = INS_Address(RTN_InsHead(rtn));
            rtnInternalRange.end 
              = INS_Address(RTN_InsHead(rtn)) + INS_Size(RTN_InsHead(rtn));
            INS lastIns = INS_Invalid();
            for (INS ins = RTN_InsHead(rtn); INS_Valid(ins); ins = INS_Next(ins))
            {
                std::cout << "    " << setw(8) << hex << INS_Address(ins) << " " << INS_Disassemble(ins) << endl;
                if (INS_Valid(lastIns))
                {
                    if ((INS_Address(lastIns) + INS_Size(lastIns)) == INS_Address(ins))
                    {
                        rtnInternalRange.end = INS_Address(ins)+INS_Size(ins);
                    }
                    else
                    { 
                        rtnInternalRangeList.push_back(rtnInternalRange);
                        std::cout << "  rtnInternalRangeList.push_back " << setw(8) << hex << rtnInternalRange.start << " " << setw(8) << hex << rtnInternalRange.end << endl;
                        // make sure this ins has not already appeared in this RTN
                        for (vector<RTN_INTERNAL_RANGE>::iterator ri = rtnInternalRangeList.begin(); ri != rtnInternalRangeList.end(); ri++)
                        {
                            if ((INS_Address(ins) >= ri->start) && (INS_Address(ins)<ri->end))
                            {
                                std::cout << "***Error - above instruction already appeared in this RTN\n";
                                std::cout << "  in rtnInternalRangeList " << setw(8) << hex << ri->start << " " << setw(8) << hex << ri->end << endl;
                                exit (1);
                            }
                        }
                        rtnInternalRange.start = INS_Address(ins);
                        rtnInternalRange.end = INS_Address(ins) + INS_Size(ins);
                    }
                }
                lastIns = ins;
            }

            RTN_Close(rtn);
            rtnInternalRangeList.clear();
        }
    }
    IMG_Close(img);
}
Example #23
0
// This function is called before every instruction is executed
VOID instrument_routine(RTN rtn, void *ip)
{
    string name = RTN_Name(rtn);
    if(name == "ivan")
    {
        RTN_Open(rtn);
        for (INS ins = RTN_InsHead(rtn); INS_Valid(ins); ins = INS_Next(ins))
        {
            int opCount = INS_OperandCount(ins);

            int opcode = INS_Opcode(ins);
            if(INS_IsMemoryRead(ins))
            {


                for(int i = 0; i< opCount; i++)
                {
                    if(INS_MemoryOperandIsRead(ins,i))
                    {
                        /*
                           INS_InsertCall(ins, IPOINT_BEFORE, (AFUNPTR)RecordMemRead,IARG_PTR,ins,
                           IARG_INST_PTR,
                           IARG_MEMORYOP_EA, i,
                           IARG_END);
                           */

                        cout<<"opcode:"<<INS_Opcode(ins)<<", mnemonic: "<<INS_Mnemonic(ins)<<endl;
                        if(INS_Opcode(ins)!= XED_ICLASS_RET_NEAR)
                        {
                            REG scratchReg = GetScratchReg(i);
                            INS_InsertCall(ins, IPOINT_BEFORE, AFUNPTR(GetMemAddress),
                                           IARG_MEMORYOP_EA, i, IARG_RETURN_REGS, scratchReg, IARG_END);

                            INS_RewriteMemoryOperand(ins, i, scratchReg);
                        }
                    }
                }
            }

            if(INS_IsMemoryWrite(ins))
            {
                for(int i = 0; i< opCount; i++)
                {
                    /*
                    if(INS_OperandIsImmediate(ins,i))
                    {
                    	cout<<"immediate "<<INS_OperandImmediate(ins,i)<<endl;
                    }
                    */
                    if(INS_MemoryOperandIsWritten(ins,i) && INS_HasFallThrough(ins))
                    {

                        /*
                        INS_InsertCall(
                                ins, IPOINT_BEFORE, (AFUNPTR)RecordMemWrite,
                                IARG_INST_PTR,
                                IARG_MEMORYOP_EA, i,
                                IARG_END);

                        INS_InsertCall(
                                ins, IPOINT_AFTER, (AFUNPTR)RecordMemWrite,
                                IARG_INST_PTR,
                                IARG_MEMORYOP_EA, i,
                                IARG_END);
                                */

                        if(opcode != XED_ICLASS_PUSH)
                        {
                            REG scratchReg = GetScratchReg(i);
                            INS_InsertCall(ins, IPOINT_BEFORE, AFUNPTR(GetMemAddress),
                                           IARG_MEMORYOP_EA, i, IARG_RETURN_REGS, scratchReg, IARG_END);

                            INS_RewriteMemoryOperand(ins, i, scratchReg);
                        }

                    }
                }
            }
        }
        RTN_Close(rtn);
    }
}
VOID Image(IMG img, VOID *v)
{

#ifdef HEAP
    // Instrument the malloc() and free() functions.  Print the input argument
    // of each malloc() or free(), and the return value of malloc().
    //
    // 1. Find the malloc() function.
    RTN mallocRtn = RTN_FindByName(img, MALLOC);
    if (RTN_Valid(mallocRtn))
    {
        RTN_Open(mallocRtn);

        // Instrument malloc() to print the input argument value and the return value.
        RTN_InsertCall(mallocRtn, IPOINT_BEFORE, (AFUNPTR)AllocSize,
                       IARG_FUNCARG_ENTRYPOINT_VALUE, 0,
                       IARG_END);
        RTN_InsertCall(mallocRtn, IPOINT_AFTER, (AFUNPTR)AllocAddress,
                       IARG_FUNCRET_EXITPOINT_VALUE, IARG_END);

        RTN_Close(mallocRtn);
    }

    // 2. Find the free() function.
    RTN freeRtn = RTN_FindByName(img, FREE);
    if (RTN_Valid(freeRtn))
    {
        RTN_Open(freeRtn);
        // Instrument free() to print the input argument value.
        RTN_InsertCall(freeRtn, IPOINT_BEFORE, (AFUNPTR)DeallocAddress,
                       IARG_FUNCARG_ENTRYPOINT_VALUE, 0,
                       IARG_END);
        RTN_Close(freeRtn);
    }
#endif

#ifdef STACK
	// 3. Visit all routines to collect frame size
	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) )
		{
			RTN_Open(rtn);

			// collect user functions as well as their addresses
			ADDRINT fAddr = RTN_Address(rtn);	
			string szFunc = RTN_Name(rtn);
			g_hAddr2Name[fAddr] = szFunc;
			//cerr << fAddr << ":\t" << szFunc << endl;
			//bool bFound = false;
			for(INS ins = RTN_InsHead(rtn); INS_Valid(ins); ins = INS_Next(ins) )
			{
				// collecting stack size according to "SUB 0x20, %esp" or "ADD 0xffffffe0, %esp"
				if( INS_Opcode(ins) == XED_ICLASS_SUB && 
					INS_OperandIsReg(ins, 0 ) && INS_OperandReg(ins, 0) == REG_STACK_PTR  &&
					INS_OperandIsImmediate(ins, 1) )
				{		                         
				   	int nOffset = INS_OperandImmediate(ins, 1);
					if(nOffset < 0 )
					{
						nOffset = -nOffset;
					}           	
					g_hFunc2FrameSize[fAddr] = nOffset;	             
					//bFound = true;
					break;           
				}
				if( INS_Opcode(ins) == XED_ICLASS_ADD && 
					INS_OperandIsReg(ins, 0 ) && INS_OperandReg(ins, 0) == REG_STACK_PTR  &&
					INS_OperandIsImmediate(ins, 1) )
				{
					int nOffset = INS_OperandImmediate(ins, 1);
					if(nOffset < 0 )
					{
						nOffset = -nOffset;
					}           	
					g_hFunc2FrameSize[fAddr] = nOffset;	  
					//bFound = true;
					break;
				}		
			}
			//if( !bFound )
			//	g_hFunc2FrameSize[fAddr] = 0;
			RTN_Close(rtn);
		}
	}
#endif
}