1

I am using the Ghidra P-Code in a Ghidra script and I am looking for an architecture-independent way to decide if a register used in a P-Code Op is the Stack or the Base Pointer (basically making the decision without using the name of the register, since that depends on the architecture).

So for instance if there is this P-Code Op: INT_ADD (register, 0x20, 8) , (const, 0xffffffffffffffc8, 8)

The first parameter is in reality RSP because this operation calculates the offset of a variable on the stack. So my goal is to find an architecture-independent way to ask Ghidra whether this register is the stack or the base pointer.

I looked at the Register class in Ghidra and it seems that Register instances should have an attribute called typeFlags, that could be used to ask what kind of register it is:

public class Register implements java.io.Serializable, Comparable<Register> {

    private static final List<String> EMPTY_COLLECTION = new ArrayList<>();

    private final static long serialVersionUID = 1;
    public final static int TYPE_NONE = 0; // nothing special
    public final static int TYPE_FP = 1; // frame pointer
    public final static int TYPE_SP = 2; // stack pointer
    public final static int TYPE_PC = 4; // program counter
    public final static int TYPE_CONTEXT = 8; // processor state
    public final static int TYPE_ZERO = 16; // Register is always zero
    public final static int TYPE_HIDDEN = 32; // Register should not be exposed to users.
    public final static int TYPE_DOES_NOT_FOLLOW_FLOW = 64; // Register value should NOT follow disassembly flow

    /** Register can be used in SIMD operations **/
    public final static int TYPE_VECTOR = 128;

    private String name;
    private String description; // description of the register
    private Address address; // smallest address containing bits for this register
    private int numBytes;
    private int leastSigBit;
    private int bitLength;
    private int typeFlags; // type of register
    private boolean bigEndian;

So I wrote a function that converts the Varnode to a Register instance using the 'Language' of the analysed binary and checks the typeFlags:

        /*
         *  Checks if the varnode is a stack or a frame pointer, depending on the language in use
         */
        public Boolean isStackRegister(Varnode input) {
            if (input.isRegister()) {
                Register reg = language.getRegister(input.getAddress(), input.getSize());
                printf("XXX %s %s\n", language.toString(), input.toString(language));
                int typeFlags = reg.getTypeFlags();
                // check if the register is either a frame pointer or a stack pointer
                if ((typeFlags & Register.TYPE_SP) != 0 || (typeFlags & Register.TYPE_FP) != 0) {
                    return true;
                }
            }
            return false;           
        }

I was expecting the typeFlags attribute to be correctly populated, however, in the debugger, I see that it is set to 0 even if it is the RSP:

enter image description here

For me, this feels like a Ghidra bug or a not implemented feature.

Anybody know how to get the typeFlags working, or any other way to check whether a register is a Stack or Base pointer, without using its name?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.