// Pin calls this function every time a new instruction is encountered
VOID Instruction(INS ins, VOID *v)
{
    string *disptr = new string(INS_Disassemble(ins));

    // reads
    if (INS_IsMemoryRead(ins)) {
        INS_InsertCall(ins, 
            IPOINT_BEFORE, 
            (AFUNPTR)readMemoryFunc, 
            IARG_FAST_ANALYSIS_CALL,
            IARG_MEMORYREAD_EA,
            IARG_MEMORYREAD_PTR,
            IARG_THREAD_ID,
            IARG_PTR, disptr,
            IARG_INST_PTR,
            IARG_END);
    }

    // writes
    if (INS_IsMemoryWrite(ins)) {
        INS_InsertCall(ins, 
            IPOINT_BEFORE, 
            (AFUNPTR)writeMemoryFunc, 
            IARG_FAST_ANALYSIS_CALL,
            IARG_THREAD_ID,
            IARG_MEMORYWRITE_EA,
            IARG_MEMORYWRITE_PTR ,
            IARG_INST_PTR,
            IARG_PTR, disptr, 
            IARG_END);
    }

    UINT32 memOperands = INS_MemoryOperandCount(ins);
    if (!INS_IsVgather(ins) && memOperands)
    {
        // OPs
        for (UINT32 memOp = 0; memOp < memOperands; memOp++)
        {
            if (INS_MemoryOperandIsRead(ins, memOp) ||  
                INS_MemoryOperandIsWritten(ins, memOp)) {
                INS_InsertCall(ins, 
                    IPOINT_BEFORE, 
                    (AFUNPTR)opMemoryFunc, 
                    IARG_FAST_ANALYSIS_CALL,
                    IARG_MEMORYOP_EA, memOp,
                    IARG_MEMORYOP_PTR, memOp,
                    IARG_INST_PTR ,
                    IARG_PTR, disptr, 
                    IARG_END);
            }
        }
    }

    // READ2
    if (INS_HasMemoryRead2(ins)) {
        INS_InsertCall(ins, 
            IPOINT_BEFORE, 
            (AFUNPTR)read2MemoryFunc, 
            IARG_FAST_ANALYSIS_CALL,
            IARG_MEMORYREAD_EA,
            IARG_MEMORYREAD_PTR,
            IARG_MEMORYREAD2_EA,
            IARG_MEMORYREAD2_PTR,
            IARG_THREAD_ID,
            IARG_PTR, disptr, 
            IARG_CONTEXT,
            IARG_INST_PTR,
            IARG_END);
    }

}
Beispiel #2
0
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);
    }
}
Beispiel #3
0
VOID Emulate2Address(OPCODE opcode,
                     INS ins,
                     ADDRINT (*OpRM)(ADDRINT,ADDRINT*),
                     ADDRINT (*OpRV)(ADDRINT,ADDRINT),
                     VOID (*OpMV)(ADDRINT*,ADDRINT))
{
    if (INS_Opcode(ins) != opcode)
        return;
    if (INS_OperandIsMemory(ins, 0)
        // This will filter out segment overrides
        && INS_IsMemoryWrite(ins))
    {
        if (INS_OperandIsReg(ins, 1)
            && REG_is_gr(INS_OperandReg(ins, 1)))
        {
            // Source register, dst memory
            INS_InsertCall(ins,
                           IPOINT_BEFORE,
                           AFUNPTR(OpMV),
                           IARG_MEMORYWRITE_EA,
                           IARG_REG_VALUE,
                           INS_OperandReg(ins, 1),
                           IARG_END);
            INS_Delete(ins);
        }
        else
        {
            ASSERTX(!INS_OperandIsMemory(ins, 1));
        }
    }
    else if (INS_OperandIsReg(ins, 0))
    {
    	REG dst = INS_OperandReg(ins, 0);
    	if ((dst == REG_SEG_GS) || (dst == REG_SEG_FS))
    		return;
        if (INS_OperandIsReg(ins, 1))
        {
            // Source register, dst register
            INS_InsertCall(ins,
                           IPOINT_BEFORE,
                           AFUNPTR(OpRV),
                           IARG_REG_VALUE,
                           INS_OperandReg(ins, 0),
                           IARG_REG_VALUE,
                           INS_OperandReg(ins, 1),
                           IARG_RETURN_REGS,
                           INS_OperandReg(ins, 0),
                           IARG_END);
            INS_Delete(ins);
        }
        else if (INS_OperandIsMemory(ins, 1)
                 // This will filter out segment overrides
                 && INS_IsMemoryRead(ins))
        {
            // Source register, dst register
            INS_InsertCall(ins,
                           IPOINT_BEFORE,
                           AFUNPTR(OpRM),
                           IARG_REG_VALUE,
                           INS_OperandReg(ins, 0),
                           IARG_MEMORYREAD_EA,
                           IARG_RETURN_REGS,
                           INS_OperandReg(ins, 0),
                           IARG_END);
           INS_Delete(ins);
        }
    }
    
#if 0
    if (KnobCount == icount)
        fprintf(stderr,"Last one %s\n",INS_Disassemble(ins).c_str());
    else if (icount > KnobCount)
        return;
    icount++;
#endif

}
VOID Instruction(INS ins, VOID *v)
{
  PIN_LockClient();
  IMG img = IMG_FindByAddress(INS_Address(ins));
  PIN_UnlockClient();
  
  if (IMG_Valid(img) && IMG_IsMainExecutable(img)){
    if (INS_IsCall(ins)){
      INS_InsertCall(
          ins, IPOINT_BEFORE, (AFUNPTR)PrologueAnalysis,
          IARG_ADDRINT, INS_Address(ins),
          IARG_ADDRINT, INS_NextAddress(ins),
          IARG_PTR, new string(INS_Disassemble(ins)),
          IARG_END);
    }
    else if (INS_IsRet(ins)){
      INS_InsertCall(
          ins, IPOINT_BEFORE, (AFUNPTR)EpilogueAnalysis,
          IARG_ADDRINT, INS_Address(ins),
          IARG_ADDRINT, INS_NextAddress(ins),
          IARG_PTR, new string(INS_Disassemble(ins)),
          IARG_END);
    }
    else if (INS_OperandCount(ins) > 1 && INS_MemoryOperandIsWritten(ins, 0)){
      INS_InsertCall(
          ins, IPOINT_BEFORE, (AFUNPTR)WriteMem,
          IARG_ADDRINT, INS_Address(ins),
          IARG_PTR, new string(INS_Disassemble(ins)),
          IARG_UINT32, INS_OperandCount(ins),
          IARG_UINT32, INS_OperandReg(ins, 1),
          IARG_MEMORYOP_EA, 0,
          IARG_END);
    }

    /* Value Set Analysis */
    if (INS_Opcode(ins) == XED_ICLASS_MOV &&
        INS_RegR(ins, 0) == REG_RBP && 
        INS_RegR(ins, 1) == REG_INVALID() && 
        INS_IsMemoryWrite(ins)){
      INS_InsertCall(
          ins, IPOINT_BEFORE, (AFUNPTR)ValueSetAnalysis,
          IARG_ADDRINT, INS_Address(ins),
          IARG_PTR, new string(INS_Disassemble(ins)),
          IARG_REG_VALUE, REG_RSP,
          IARG_REG_VALUE, REG_RBP,
          IARG_MEMORYOP_EA, 0,
          IARG_END);
    }

    /* Analyzes stack overflow */
    if (INS_MemoryOperandIsWritten(ins, 0)){
        INS_InsertCall(
            ins, IPOINT_BEFORE, (AFUNPTR)WriteMemAnalysis,
            IARG_ADDRINT, INS_Address(ins),
            IARG_PTR, new string(INS_Disassemble(ins)),
            IARG_MEMORYOP_EA, 0,
            IARG_END);
      }

    /* Timer Handler - And instruction counter */
    INS_InsertCall(ins, IPOINT_BEFORE, (AFUNPTR)timerHandler, 
      IARG_ADDRINT, INS_Address(INS_Prev(ins)),
      IARG_ADDRINT, INS_Address(ins),
      IARG_ADDRINT, INS_Address(INS_Next(ins)),
      IARG_PTR, new string(INS_Disassemble(ins)),
      IARG_END);

  }
}