1

I modified the pinatrace pintool example and managed to log all values of the "regular" registers:

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

I read here that

You can't actually be sure that fs is not zero by looking at the EA, because the value in fs is an index into the table of segment descriptors, not a pointer in its own right... The pointer value is taken from the segment descriptor, but is mirrored in the Pin virtual register REG_SEG_FS_BASE.

I am not sure how to get the value using this virtual register.

Related info from the official manual:

When IARG_CONTEXT is used in probe mode,it is impossible to get certain register values correct. The values in these registers are meaningless when IARG_CONTEXT is used in probe mode: REG_SEG_GS_BASE REG_SEG_FS_BASE REG_INST_G0 - REG_INST_G19 Using IARG_RETURN_REGS and IARG_REG_REFERENCE is not supported in Probe mode.

How do I print the value of the fs and gs regsiters after every instruction execution?

2
  • Are you using probe mode (aka hooking)? If not, doesn't this work for you? auto reg = PIN_GetContextReg(ctx, REG_SEG_FS); Commented Oct 4, 2016 at 15:39
  • Are you on x64 because there you cannot change segment registers.
    – mrexodia
    Commented Mar 31, 2017 at 15:18

1 Answer 1

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

You use use PIN_GetContextRegval API to get register value of fs/gs. As mentioned in a question on the Pinheads Yahoo group [1], REG_SEG_GS will only get the value of fs/gs, in other word, the index to GDT, REG_SEG_GS_BASE will get the base address of the corresponding entry of GDT.

[1] https://beta.groups.yahoo.com/neo/groups/pinheads/conversations/topics/5444, retrieved through Wayback machine

I think you're probably after REG_SEG_FS_BASE, which is the address of the base of the F segment.

I know fs is not zero by obtaining the memop effective address (0x7ffff7fd4728 in my case).

You can't actually be sure that fs is not zero by looking at the EA, because the value in fs is an index into the table of segment descriptors, not a pointer in its own right... The pointer value is taken from the segment descriptor, but is mirrored in the Pin virtual register REG_SEG_FS_BASE.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.