[英]How can i get memory effective address of array in pintool?
我尝试打印数组的内存位置(有效地址),发现以下内容:
1-第一种方式:使用(以读取操作为例)
IARG_MEMORYREAD_EA
作为分析函数的参数并在此函数内打印此值,(内存读取的有效地址,仅在INS_IsMemoryRead为true且在IPOINT_BEFORE时有效)。
2-第二种方式:通过插入回调:
INS_OperandMemoryDisplacement(INS ins,UINT32 n)
INS_OperandMemoryBaseReg(INS ins,UINT32 n)
INS_OperandMemoryIndexReg(INS ins,UINT32 n)
INS_OperandMemoryScale(INS ins,UINT32 n)
它返回用于在内存操作数中寻址的位移,基址寄存器,索引寄存器和比例值,并通过以下公式计算有效地址:
有效地址=位移+ BaseReg + IndexReg *比例
它们之间有什么区别,最好的方法是什么?
这个问题有些复杂。
很难知道是否要索引到数组中,因为任何内存位置都可以被视为只有1个条目的数组(并且该指令仅使用基数reg)。
除了检查是否存在基数,索引,小数位数和位移(我认为我们所有人都可以想到在一个指令中不使用SIB [scale,index,base]和位移的各种人为设计的索引方式),在这种情况下,我们几乎可以肯定它是一个数组。
为了使问题有合理的依据,我们假设所有使用SIB(或SIB + disp)的指令都索引到一个数组中,而另一个则没有。
此外,您需要检查它是读(IARG_MEMORYREAD_EA)还是写(IARG_MEMORYWRITE_EA),而且您将无法获得详细的信息(例如数组的基地址是什么,索引和小数位值是什么,位移是多少)。
这就是我要做的(未经测试的代码,只是一个基本概念;适用于读取和写入访问):
// we need at least one op
UINT32 op_count = INS_OperandCount(ins);
if(op_count == 0) {
return;
}
// search for the operand which could be a memory operand
UINT32 current_op;
BOOL found_mem_op = FALSE;
for(current_op = 0; current_op < op_count; ++current_op) {
// operand generates an address (LEA) or operand is directly a mem op
if(INS_OperandIsAddressGenerator(ins, current_op) || INS_OperandIsMemory(ins, current_op)) {
found_mem_op = TRUE;
break;
}
}
// check if we could find a memory operand
if(!found_mem_op) {
return;
}
// get base, index, scale and displacement
REG reg_base = INS_OperandMemoryBaseReg(ins, current_op);
REG reg_index = INS_OperandMemoryIndexReg(ins, current_op);
UINT32 scale = INS_OperandMemoryScale(ins, current_op);
ADDRDELTA disp = INS_OperandMemoryDisplacement(ins, current_op);
// both base and index must be valid to proceed
if(REG_valid(reg_base) && REG_valid(reg_index)) {
// get base register value
INS_InsertCall(ins, IPOINT_AFTER, (AFUNPTR)GetRegVal,
IARG_REG_VALUE,
reg_base,
IARG_END);
ADDRINT reg_base_value = value_reg; //value_reg is obtained by GetRegVal()
// get index register value
INS_InsertCall(ins, IPOINT_AFTER, (AFUNPTR)GetRegVal,
IARG_REG_VALUE,
reg_index,
IARG_END);
ADDRINT reg_index_value = value_reg;
ADDRINT final_address = reg_base_value + (reg_index_value * scale) + disp;
}
PIN测试套件中的source / tools / Tests / ea_verifier.cpp中还有一个有趣的示例(请参阅IntrumentAccess函数)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.