英特尔 PIN:如何从分析函数内部访问 INS 对象?

逆向工程 C++ 小工具
2021-06-19 22:09:15

典型的 PIN 码片段如下所示(取自官方手册):

// This function is called before every instruction is executed
// and prints the IP
VOID printip(VOID *ip) { fprintf(trace, "%p\n", ip); }

// Pin calls this function every time a new instruction is encountered
VOID Instruction(INS ins, VOID *v)
{
    // Insert a call to printip before every instruction, and pass it the IP
    INS_InsertCall(ins, IPOINT_BEFORE, (AFUNPTR)printip, IARG_INST_PTR, IARG_END);
}

我只是不知道如何insprintip(VOID *p). 反过来似乎很容易,即从ins对象获取 IP

INS_Address (INS ins)(见这里

我尝试通过传递一个INS *ins指向printip(VOID *ip, INS *ins)ins指针,IARG_PTR, &ins但这以转换错误或分段错误告终。

如何从分析函数内部访问ins对象(类型INS)?

旁注:我在尝试调用INS_Disassemble (INS ins)每个执行的指令时遇到了这个问题

2个回答

你可能注意到这printip是一个函数指针,它被内部懒惰地调用Pin此外ins是一个自动变量(它Instruction从堆栈传入)。因此,传递&insprintip(通过IARG_PTR),然后使用它会导致段故障。

PinINS通过专门化类模板来声明INDEX,因为您可以在 中观察到以下声明type_core.TLH

/*! @ingroup INS_BASIC_API
Handle for INS */  
typedef class INDEX<6> INS;

其中类模板的构造函数和赋值运算符INDEX都是默认的。所以,原则上^^,我们总是可以声明一个持久变量来INS在检测和分析函数之间共享一个对象,例如:

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

这种方法不起作用,不幸的是,这是C/C++^^中“类型良好的程序仍然可能出错”的示例由于Pin不保证内部变量,通过类型的对象访问INS,在持续的分析时间,调用的结果INS_Disassemble(per_ins)分析功能可以是毫无意义的。

对于您的情况,您可能不想INS_Disassemble(ins)每次ins执行时都调用我们不需要那个,例如,如果ins在一个循环中,那么这个函数将被多次调用(使用相同的ins)以获得相同的结果。

一条指令的所有静态信息(例如ins在这种情况下的反汇编形式)应该在检测时间获得特别是,INS_Disassemble在某些检测函数中应该只调用一次。获得所需效果的一种方法是:

static std::unordered_map<ADDRINT, std::string> str_of_ins_at;

VOID Instruction(INS ins, VOID *v)
{
  str_of_ins_at[INS_Address(ins)] = INS_Disassemble(ins);
  ...
}

VOID printip(VOID *ip, ADDRINT addr) 
{
  std::string ins_str = str_of_ins_at[addr];
  ...
}

typedef 类 INDEX<6> INS; 在 types_core.TLH 中定义(类型不是类型)。以下代码适用于我在分析时解散。

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);
}