我从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记录它们两个!
答案 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