Pin Tool意外的检测结果

时间:2011-11-23 12:16:49

标签: dbi instrumentation

我从Pin Tool得到了意想不到的结果,我的工具查找CALL / RET指令,然后记录正确的消息:

VOID CallBack(VOID * ip, ADDRINT esp)
{
    UINT32 *RetAddrPtr = (UINT32 *)esp;
    fprintf(log_info,"RET inst @%p ==> Retuen Address @%p.\n", ip, *RetAddrPtr);
}

// Pin calls this function every time a new instruction is encountered
VOID Trace(TRACE trace, VOID *v)
{
    ADDRINT insAddress = TRACE_Address(trace);

    // Visit every basic block in the trace
    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))
        {   
            ADDRINT instAddress = INS_Address(ins);

            if( INS_IsCall(ins) )
            {
                ADDRINT nextInstAddress = (ADDRINT)( (USIZE)instAddress + INS_Size(ins) );
                fprintf(log_info,"CALL  inst @%p    ==> CALL Return Address @%p.\n", instAddress, nextInstAddress);
            }  
            if(INS_IsRet(ins))
            {
                INS_InsertCall( ins, 
                                IPOINT_BEFORE, 
                                (AFUNPTR)CallBack, 
                                IARG_INST_PTR, 
                                IARG_REG_VALUE, 
                                REG_STACK_PTR, 
                                IARG_END);
            }
        }
    }
}

但结果很不寻常: - /。看这是程序入口点的日志结果:

CALL    inst @0101247C  ==> CALL Return Address @01012481.
RET inst @01012800 ==> Return Address @01012481.
CALL    inst @0101248A  ==> CALL Return Address @0101248C.
CALL    inst @7C80B73F  ==> CALL Return Address @7C80B744.
RET inst @7C80B751 ==> Return Address @0101248C.
CALL    inst @010124E3  ==> CALL Return Address @010124E9.
RET inst @77C3538A ==> Return Address @010124E9.
CALL    inst @010124F8  ==> CALL Return Address @010124FE.
RET inst @77C1F1E0 ==> Return Address @010124FE.
CALL    inst @01012506  ==> CALL Return Address @0101250C.
RET inst @77C1F1A9 ==> Return Address @0101250C.
CALL    inst @01012520  ==> CALL Return Address @01012525.
RET inst @010127C4 ==> Return Address @01012525.
CALL    inst @01012532  ==> CALL Return Address @01012538.
CALL    inst @01012539  ==> CALL Return Address @0101253E.
CALL    inst @010127BA  ==> CALL Return Address @010127BF.
CALL    inst @77C4EE60  ==> CALL Return Address @77C4EE65.
RET inst @77C4ED04 ==> Return Address @77C4EE28. <=========
RET inst @77C4ED97 ==> Return Address @77C4EE3F. <=========
RET inst @77C4EE49 ==> Return Address @77C4EE65.
RET inst @77C4EE68 ==> Return Address @010127BF.
RET inst @010127C1 ==> Return Address @0101253E.

如您所见,有两条RET指令不会映射到任何CALL。 在此之后,我在调试器中打开了程序并看到了:

77C4EE15 >  8BFF            MOV EDI,EDI                              ; kernel32.GetModuleHandleA
77C4EE17    55              PUSH EBP
77C4EE18    8BEC            MOV EBP,ESP
77C4EE1A    51              PUSH ECX
77C4EE1B    53              PUSH EBX
77C4EE1C    9B              WAIT
77C4EE1D    D97D FC         FSTCW WORD PTR SS:[EBP-4]
77C4EE20    FF75 FC         PUSH DWORD PTR SS:[EBP-4]
77C4EE23    E8 41FEFFFF     CALL msvcrt.77C4EC69 <============
77C4EE28    8BD8            MOV EBX,EAX
77C4EE2A    8B45 0C         MOV EAX,DWORD PTR SS:[EBP+C]
77C4EE2D    F7D0            NOT EAX
77C4EE2F    23D8            AND EBX,EAX
77C4EE31    8B45 08         MOV EAX,DWORD PTR SS:[EBP+8]
77C4EE34    2345 0C         AND EAX,DWORD PTR SS:[EBP+C]
77C4EE37    59              POP ECX                                  ; msvcrt.77C4EE65
77C4EE38    0BD8            OR EBX,EAX
77C4EE3A    E8 CBFEFFFF     CALL msvcrt.77C4ED0A <==============
77C4EE3F    8945 0C         MOV DWORD PTR SS:[EBP+C],EAX
77C4EE42    D96D 0C         FLDCW WORD PTR SS:[EBP+C]
77C4EE45    8BC3            MOV EAX,EBX
77C4EE47    5B              POP EBX                                  ; msvcrt.77C4EE65
77C4EE48    C9              LEAVE

Pin Tool看不到这个电话?我想也许我使用了错误的API调用序列。 并且还有另一个意外的结果:在一个函数中有两个不同的CALL指令,在CALL之间有一个条件jmp,这意味着只有那些CALL指令应该执行但是Pin记录它们两个!

1 个答案:

答案 0 :(得分:0)

Pin不会检测所有进程执行,它会在实际进程启动后稍微启动它,并在实际退出之前稍微结束。 当流程执行没有重定向到Pin时,可能会执行调用,但这就是为什么你看到retn而不是调用。

一小段代码来解释它:

call start_instrumentation  
label ret_call_start_ins:  
[...]

function start_instrumentation:

_do_stuff_  
* now the process is under Pin control *  
_do_stuff_under_pin_control_  

retn ; the return you see without any associated call