一个典型的PIN代码片段如下所示(摘自官方手册):相反,这似乎很容易,即从ins对象获取IP:

我该如何从分析函数内部访问printip(VOID *p)对象(类型ins)?

侧面说明:我知道尝试为每个已执行的指令调用INS_Address (INS ins)时出现问题。

#1 楼

您可能会注意到printip是一个函数指针,由Pin内部调用;此外,ins是一个自动变量(从堆栈传递到Instruction)。因此,将&ins传递给printip(通过IARG_PTR),然后使用它会导致分段错误。 />
/*! @ingroup INS_BASIC_API
Handle for INS */  
typedef class INDEX<6> INS;


其中,类模板Pin的构造函数和赋值运算符均为默认值。因此,原则上,^^,我们总是可以声明一个持久变量以在仪器和分析功能之间共享INS的对象,例如:工作时,不幸的是,这是INDEX ^^中“类型良好的程序仍然可能出错”的示例。由于type_core.TLH不能保证由INDEX类型的对象访问的内部变量在分析时间内是持久的,因此在分析函数中调用INS的结果可能毫无意义。

对于您的情况,不想每次执行C/C++时都调用Pin。我们不需要,例如,如果INS处于循环中,则该函数将被多次调用(具有相同的INS_Disassemble(per_ins))以获得相同的结果。

指令的所有静态信息(例如,在这种情况下为INS_Disassemble(ins)的拆卸形式)应在检测时间内获得。特别是,仅在某些仪器功能中,应将ins一次调用。一种获得所需效果的方法是:

static INS per_ins;
...
VOID Instruction(INS ins, VOID *v)
{
  per_ins = ins;
  ...
}
...
VOID printip(VOID *ip)
{
  INS_Disassemble(per_ins);
}


评论


感谢您的详细回答。我想将INS_Disassemble(ins)放入分析函数中,以检查(手动查看)分析函数是否按预期工作。如果将INS_Disassemble(ins)放入Instrumentation函数中,则INS_Disassemble(ins)的输出与分析函数的输出分开。换句话说:我希望对分析功能的输出进行命名,并附上指令以轻松检查其是否正确。

– gogo_gorilla
16-4-12在11:02



没错,我们总是可以使用PIN_SafeCopy和INS_Size获取指令的操作码,然后使用任何反汇编工具,例如Capstone,甚至是Intel的Xed。

– Ta Thanh Dinh
16年4月12日在11:11

抱歉,我删除了有关此方法的评论,因为您存储字符串的想法对我来说看起来更优雅。

– gogo_gorilla
16-4-12在11:12



但是无论如何,对此ins对象发生了什么的很好的解释。

– gogo_gorilla
16年4月12日在11:14

#2 楼

typedef类INDEX <6> INS;在types_core.TLH中定义(类型不是type)。以下代码在分析时可以帮助我理解。

void disasmIns(ADDRINT tid, ADDRINT insarg)
{
  INS ins;
  ins.q_set(insarg);
  std::cout << "Disassembly: " << INS_Disassemble(ins) << std::endl;
}

VOID Instruction(INS ins, VOID *v) {
  INS_InsertCall(ins, IPOINT_BEFORE, (AFUNPTR)disasmIns, 
  IARG_FAST_ANALYSIS_CALL, IARG_ADDRINT, ins.q(), IARG_END);
}