Intel PIN:如何在每条指令中记录 fs 和 gs 寄存器的值?

逆向工程 x86 小工具 登记 分割 amd64
2021-07-01 23:53:47

我修改了 pinatrace pintool 示例并设法记录了“常规”寄存器的所有值:

VOID Instruction(INS ins, VOID *v)
{
 ...
 // Instrument REGISTER writes using a predicated call, i.e.
 // the call happens iff the register store will be actually executed
 UINT32 maxNumWRegs;
 maxNumWRegs = INS_MaxNumWRegs(ins);
 for (UINT32 i=0; i<maxNumWRegs; i++)
 {
     // --> BEFORE
     INS_InsertPredicatedCall(
        ins, IPOINT_BEFORE, (AFUNPTR)SaveRegWrite,
        IARG_INST_PTR,
        IARG_UINT32,
        INS_RegW(ins, i),
        IARG_END);
    
    if (INS_HasFallThrough(ins))
    {
        // --> AFTER
        INS_InsertCall(
            ins, IPOINT_AFTER, (AFUNPTR)LogRegWrite,
            IARG_INST_PTR,
            IARG_UINT32,
            INS_RegW(ins, i),
            IARG_CONTEXT, // to access the register value
            IARG_END);
    }
    if (INS_IsBranchOrCall(ins))
    {
        INS_InsertCall(
            ins, IPOINT_TAKEN_BRANCH, (AFUNPTR)LogRegWrite,
            IARG_INST_PTR,
            IARG_UINT32,
            INS_RegW(ins, i),
            IARG_CONTEXT, // to access the register value
            IARG_END);
    }        
}

我读到这里

您实际上无法通过查看 EA 来确定 fs 不为零,因为 fs 中的值是段描述符表的索引,而不是其本身的指针......指针值取自段描述符,但在 Pin 虚拟寄存器 REG_SEG_FS_BASE 中被镜像。

我不确定如何使用此虚拟寄存器获取值。

官方手册中的相关信息:

在探测模式下使用 IARG_CONTEXT 时,无法正确获取某些寄存器值。当 IARG_CONTEXT 在探测模式下使用时,这些寄存器中的值没有意义: REG_SEG_GS_BASE REG_SEG_FS_BASE REG_INST_G0 - REG_INST_G19 在探测模式下不支持使用 IARG_RETURN_REGS 和 IARG_REG_REFERENCE。

如何在每条指令执行后打印 fs 和 gs 寄存器的值?

1个回答
const CONTEXT *ctx; (from the arguments of LogRegWrite...)
PIN_REGISTER regval;
PIN_GetContextRegval(ctx, REG_SEG_GS, reinterpret_cast<UINT8*>(&regval));
PIN_GetContextRegval(ctx, REG_SEG_FS, reinterpret_cast<UINT8*>(&regval));
PIN_GetContextRegval(ctx, REG_SEG_GS_BASE, reinterpret_cast<UINT8*>(&regval));
PIN_GetContextRegval(ctx, REG_SEG_FS_BASE, reinterpret_cast<UINT8*>(&regval));

您使用PIN_GetContextRegvalAPI 来获取fs/ 的寄存器值gs正如在 Pinheads Yahoo group [1] 上的一个问题中提到的,REG_SEG_GS只会获得fs/的值,gs换句话说,GDT 的索引,REG_SEG_GS_BASE将获得 GDT 对应条目的基址。

[1] https://beta.groups.yahoo.com/neo/groups/pinheads/conversations/topics/5444,通过Wayback机器检索

我想你可能是在 REG_SEG_FS_BASE 之后,它是 F 段基址的地址。

通过获取 memop 有效地址(在我的情况下为 0x7ffff7fd4728),我知道 fs 不为零。

您实际上无法通过查看 EA 来确定 fs 不为零,因为 fs 中的值是段描述符表的索引,而不是其本身的指针......指针值取自段描述符,但在 Pin 虚拟寄存器 REG_SEG_FS_BASE 中被镜像。