C++ 跟踪英特尔PIN码中的本机指令
我正在使用Intel PIN工具对C程序的汇编指令进行一些分析。我有一个简单的C程序,它打印“Hello World”,我已经编译并生成了一个可执行文件。我有从gdb生成的汇编指令跟踪,如下所示-C++ 跟踪英特尔PIN码中的本机指令,c++,c,assembly,intel-pin,C++,C,Assembly,Intel Pin,我正在使用Intel PIN工具对C程序的汇编指令进行一些分析。我有一个简单的C程序,它打印“Hello World”,我已经编译并生成了一个可执行文件。我有从gdb生成的汇编指令跟踪,如下所示- Dump of assembler code for function main: 0x0000000000400526 <+0>: push %rbp 0x0000000000400527 <+1>: mov %rsp,%rbp =>
Dump of assembler code for function main:
0x0000000000400526 <+0>: push %rbp
0x0000000000400527 <+1>: mov %rsp,%rbp
=> 0x000000000040052a <+4>: mov $0x4005c4,%edi
0x000000000040052f <+9>: mov $0x0,%eax
0x0000000000400534 <+14>: callq 0x400400 <printf@plt>
0x0000000000400539 <+19>: mov $0x0,%eax
0x000000000040053e <+24>: pop %rbp
0x000000000040053f <+25>: retq
End of assembler dump.
主函数的汇编程序代码转储:
0x0000000000400526:推送%rbp
0x0000000000400527:mov%rsp,%rbp
=>0x000000000040052a:mov$0x4005c4,%edi
0x000000000040052f:mov$0x0,%eax
0x0000000000400534:callq 0x400400
0x0000000000400539:mov$0x0,%eax
0x000000000040053e:弹出%rbp
0x000000000040053f:retq
汇编程序转储结束。
我运行了一个pintool,将可执行文件作为输入,我正在进行指令跟踪并打印指令数。我希望跟踪我的C程序中的指令,可能得到机器的操作码并进行某种分析。我使用C++ PIN工具来计算指令的数量-< /P>
#include "pin.H"
#include <iostream>
#include <stdio.h>
UINT64 icount = 0;
using namespace std;
//====================================================================
// Analysis Routines
//====================================================================
void docount(THREADID tid) {
icount++;
}
//====================================================================
// Instrumentation Routines
//====================================================================
VOID Instruction(INS ins, void *v) {
INS_InsertCall(ins, IPOINT_BEFORE, (AFUNPTR)docount, IARG_THREAD_ID, IARG_END);
}
VOID Fini(INT32 code, VOID *v) {
printf("count = %ld\n",(long)icount);
}
INT32 Usage() {
PIN_ERROR("This Pintool failed\n"
+ KNOB_BASE::StringKnobSummary() + "\n");
return -1;
}
int main(int argc, char *argv[]) {
if (PIN_Init(argc, argv)) return Usage();
PIN_InitSymbols();
PIN_AddInternalExceptionHandler(ExceptionHandler,NULL);
INS_AddInstrumentFunction(Instruction, 0);
PIN_AddFiniFunction(Fini, 0);
PIN_StartProgram();
return 0;
}
#包括“pin.H”
#包括
#包括
UINT64 icount=0;
使用名称空间std;
//====================================================================
//分析例程
//====================================================================
无效数据计数(线程ID tid){
icount++;
}
//====================================================================
//仪器例程
//====================================================================
无效指令(INS INS,VOID*v){
INS\U InsertCall(INS、IPOINT\U之前、(AFUNPTR)docount、IARG\U线程ID、IARG\U END);
}
VOID Fini(INT32代码,VOID*v){
printf(“计数=%ld\n”,(长)i计数);
}
INT32用法(){
PIN_错误(“此PIN工具失败\n”
+旋钮基础::StringKnobSummary()+“\n”);
返回-1;
}
int main(int argc,char*argv[]){
if(PIN_Init(argc,argv))返回用法();
PIN_InitSymbols();
PIN_AddInternalExceptionHandler(ExceptionHandler,NULL);
INS_AddInstrumentFunction(指令,0);
PIN_addfini函数(Fini,0);
PIN_StartProgram();
返回0;
}
当我用这个工具运行hello world程序时,我得到icount=81563。我知道PIN添加了自己的分析指令,但我不明白它是如何添加这么多指令的,而我的C程序中的指令不超过10条。还有一种方法可以识别来自我的代码和PIN生成的汇编指令。我似乎无法区分PIN生成的指令和程序生成的指令。请帮忙 你不是在测量你认为你在测量的东西。有关详细信息,请参见我的回答:
Pin不计算自己的指令。大量计数是在
main()
之前和之后准备的结果,以及调用printf()
我不熟悉PIN,但可能它也在计算C库中的指令。尝试制作一个静态可执行文件,直接执行退出
系统调用。(例如,从my中取出循环)。@PeterCordes无论我的C程序的内容是什么,icount始终高于80k。我不知道是否有办法区分机器指令和由PIN生成的指令。printf
的代码不是由PIN生成的,而是程序自己运行的指令。CRT启动和退出代码也是如此。所以,试着锁定一个程序,它不需要CRT,也不需要调用任何库函数就可以立即退出。@PeterCordes,我仍然得到一个和以前类似的数字。我怀疑这是由于PinI的一些库,OP应该尝试创建一个静态可执行文件,只从\u start
进行系统退出
调用。OP说他们得到了“相似数量的指令”,但你的回答表明他们可能做错了。我当然怀疑是这样的。我已经有一段时间没做了,但我记得制作这样一个可执行文件有点棘手。如果你一直都在做微基准标记,就不会这样做了:P看(去掉循环,只留下\u start:xor edi,edi
/mov eax,231
/syscall
)有关如何将+link NASM源组装到静态可执行文件(无libc)的信息,请参阅。