繁体   English   中英

如何在pintool中获取数组的内存有效地址?

[英]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)的指令都索引到一个数组中,而另一个则没有。

  1. 您的第一种方法不会告诉您是否有SIB指令,它只是告诉您您具有内存访问权限(除非您随后检查该指令是否具有SIB)。

此外,您需要检查它是读(IARG_MEMORYREAD_EA)还是写(IARG_MEMORYWRITE_EA),而且您将无法获得详细的信息(例如数组的基地址是什么,索引和小数位值是什么,位移是多少)。

  1. 我认为第二种方法是正确的。 从我的POV(不一定要更简单,但更详尽)(请注意,您可以混合使用两种方法)。

这就是我要做的(未经测试的代码,只是一个基本概念;适用于读取和写入访问):

// 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM