在英特尔 PIN 中跟踪本机指令 [重复]

Posted

技术标签:

【中文标题】在英特尔 PIN 中跟踪本机指令 [重复]【英文标题】:Tracking native instructions in Intel PIN [duplicate] 【发布时间】:2018-03-17 17:15:15 【问题描述】:

我正在使用英特尔 PIN 工具对 C 程序的汇编指令进行一些分析。我有一个简单的 C 程序,它打印“Hello World”,我已经编译并生成了一个可执行文件。我有像这样从 gdb 生成的汇编指令跟踪-

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.

我运行了一个 pintool,将可执行文件作为输入,我正在执行指令跟踪并打印指令数。我希望跟踪来自我的 C 程序的指令,并可能获取机器操作码并进行某种分析。我正在使用 C++ PIN 工具来计算指令的数量-

#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;

当我使用这个工具运行我的 hello world 程序时,我得到 icount = 81563。我知道 PIN 会添加自己的分析指令,但我不明白它是如何添加这么多指令的,而我没有我的 C 程序中有 10 多条指令。还有一种方法可以识别来自我的代码和由 PIN 生成的汇编指令。我似乎无法区分 PIN 生成的指令和我的程序生成的指令。请帮忙!

【问题讨论】:

我对 PIN 不熟悉,但想必它也在计算 C 库中的指令。 尝试制作一个静态可执行文件,直接进行exit 系统调用。 (例如,从我的mov elimination microbenchmark 中取出循环)。 @PeterCordes 无论我的 C 程序的内容是什么,icount 总是高于 80k。不知道有没有办法区分机器指令和PIN生成的指令。 printf 的代码不是由 PIN 生成的,它是您的程序自行运行的指令。 CRT 启动和退出代码也是如此。因此,在没有 CRT 且不调用任何库函数的情况下立即退出的程序上尝试 PIN。 @PeterCordes,我仍然得到与以前相似的数字。我怀疑这是由于一些 Pin 库 【参考方案1】:

你没有衡量你认为你正在衡量的东西。有关详细信息,请参阅我的答案: What instructions 'instCount' Pin tool counts?

Pin计算自己的指令。大计数是main()前后的准备和对printf()的调用的结果。

【讨论】:

我suggested OP 应该尝试制作一个静态可执行文件,该可执行文件只从_start 进行sys_exit 系统调用。 OP 说他们得到了“类似数量的指令”,但您的回答表明他们可能做错了。 我当然怀疑是这种情况。我已经有一段时间没有这样做了,但我记得制作这样的可执行文件有点棘手。 如果你一直都在做微基准测试,那就不行了:P 见***.com/questions/44169342/…(去掉循环,只留下_start: xor edi,edi / mov eax, 231 / syscall。)见@987654324 @ 了解如何将 NASM 源代码组装 + 链接到静态可执行文件(无 libc)。

以上是关于在英特尔 PIN 中跟踪本机指令 [重复]的主要内容,如果未能解决你的问题,请参考以下文章

目标代码重定位和 Intel Pin 交互

修改 PIN 中的应用指令

使用英特尔 pintool 记录所有指令

英特尔 PIN 例程地址检索:Linux 与 Windows

如何使用 Intel Pin 工具生成分支列表?

使用英特尔 pin 工具的堆栈分配大小