【问题标题】:Intel Pin: How to generate objectdump-ish code?英特尔 Pin:如何生成 objectdump-ish 代码?
【发布时间】:2019-06-28 20:51:06
【问题描述】:

我正在尝试使用 intel-pin 工具。我有一个简单的Hello-world.c(它只打印“Hello world”)程序(比如a.out)。如果我想从二进制文件生成程序集,我会做objdump -D a.out

我想在其中插入一些说明。

是否可以使用 pin 工具获取 objdump,在检测之前(这可以通过 objdump 轻松完成)和检测之后?

我创建了一个打印所有说明的工具。

#include <stdio.h>
#include "pin.H"
#include <cstdint>

FILE * trace;

KNOB<string> KnobOutputFile(KNOB_MODE_WRITEONCE, "pintool", "o", "pinatrace.out","A pin tool");

VOID Count(INS ins, void *v) {


        fprintf(trace,"\n%s",(INS_Disassemble(ins)).c_str());

}

VOID Fini(INT32 code, VOID *v)
{
        printf("count = %ld\n",(long)icount);
        fprintf(trace, "#eof\n");
        fclose(trace);
}

/* ===================================================================== */
/* Print Help Message                                                    */
/* ===================================================================== */

INT32 Usage()
{
    PIN_ERROR( "This Pintool prints a trace of memory addresses\n"
              + KNOB_BASE::StringKnobSummary() + "\n");
    return -1;
}

/* ===================================================================== */
/* Main                                                                  */
/* ===================================================================== */

int main(int argc, char *argv[])
{
    if (PIN_Init(argc, argv)) return Usage();

    trace = fopen("pinatrace.out", "w");


    INS_AddInstrumentFunction(Count, 0);
    PIN_AddFiniFunction(Fini, 0);
    // Never returns
    PIN_StartProgram();

    return 0;
}

它会打印组装说明,但我不确定它是否包含检测说明。

这是正确的方法吗?你能帮帮我吗?

【问题讨论】:

  • PIN 是透明的;您可以认为检测后的代码与检测前的代码相同(当然,实际代码与检测前完全不同,但这是 PIN 的实现细节,纯属魔法)。

标签: c++ intel-pin


【解决方案1】:

是否可以使用 pin 工具获取 objdump,之前(这可以通过 objdump 轻松完成)和插桩之后?

您需要一种方法来告诉 PIN 引擎您想对来自 objdump 的结果执行什么操作。例如,您可能希望通过脚本链接它们。这完全取决于你想做什么。

这是正确的做法吗?

取决于你想做什么,但我猜不是。

PIN 中的instrumentationanalysis 有明显的区别。一旦你理解了它,剩下的就(相对)容易了。

从概念上讲,PIN 检测由两个组件组成:

  • 一种决定在何处以及插入什么代码的机制:instrumentation
  • 在插入点执行的代码:分析

话虽如此,还有一点很重要:

  • 检测仅运行一次:当第一次发现指令(或 BBL 或 TRACE)时。
  • 每次执行指令(或 BBL、TRACE)时都会运行分析。

所以当你有:

// set up the **instrumentation**
INS_AddInstrumentFunction(Func_Instrumentation, 0);

您正在设置检测(然后只调用一次)。如果您需要在每次执行指令(或 BBL、TRACE)时调用回调,则需要设置分析例程,例如:

// this is the **analysis** routine.
// This function is called before every instruction is executed
VOID docount() { icount++; }

// The is the **instrumentation routine**, called by INS_AddInstrumentFunction().
// Pin calls this function each time a **new** instruction is encountered
// Note that is won't be called for the same instruction after the first time.
VOID Func_Instrumentation(INS ins, VOID *v)
{
    // Insert a call to docount before every instruction, no arguments are passed
    INS_InsertCall(
        ins,              // a representation of the instruction
        IPOINT_BEFORE,    // where to insert, relative to the instruction
        (AFUNPTR)docount, // the analysis routine
        IARG_END);        // no args to pass to the analysis routine
}

仔细检查可用的指令计数示例:

【讨论】:

  • 解释得很好。假设我想向程序集添加一些指令,不管我想做什么。例如。我想在程序集中添加一个 mov r1,r2 (只是一个例子)。有什么方法可以验证我的代码是否可以使用这些添加的指令? (如果我错了,请见谅,我只是一个初学者)
  • @Ruturaj 不确定是否要使用 PIN 添加这些新指令(虽然不是很容易但可以)或者只是将它们添加到您的源代码中,编译然后检查它们是否使用 PIN 执行。它还取决于您对“验证我的代码是否正常工作”的期望,但只是验证执行是否符合预期,属于 PIN 能够执行的操作。
  • 是的,我想用 PIN 添加这些新指令,但不在我的源代码中。
  • 考虑到您的考虑,我最终设计了它。我认为您的回答对我有所帮助,因此将其标记为正确答案。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-01-30
  • 2012-03-22
  • 2017-02-20
  • 2018-07-30
  • 2018-04-20
  • 2018-07-28
  • 2020-09-07
相关资源
最近更新 更多