【发布时间】: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