【问题标题】:Pin Tool unexpected instrumentation resultPin Tool 意外检测结果
【发布时间】:2011-11-23 12:16:49
【问题描述】:

我从 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 记录它们!

【问题讨论】:

    标签: dbi instrumentation


    【解决方案1】:

    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 
    

    【讨论】:

    • 感谢您的回答,但此结果由我的 pin 工具 dll 记录。您会看到 Pin spot "CALL inst @77C4EE60",这将调用 sub_77C4EE15(您可以在我的问题中看到 sub_77C4EE15 代码)和在这个函数里面是另外两个 Pin 无法检测到的 CALL!这就是我意料之外的意思。为什么 Pin 检测不到 sub_77C4EE15 内部的那些 CALL,而它的检测是早期开始的。
    • 发现调用并不意味着它们会被执行。您应该添加一个 INS_InsertCall 以确保它们是。也许 77C4EE60 从来没有被调用过,所以 77C4EE15 也没有
    • 非常感谢狒狒,添加 INS_InsertCall 解决了我的问题 :)
    猜你喜欢
    • 2012-09-14
    • 1970-01-01
    • 2021-11-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-05-30
    • 1970-01-01
    • 2012-10-09
    相关资源
    最近更新 更多