1

I am trying to learn the hexrays ctree api. I am using the python bindings.

The task I am trying to automate is tracing the arguments to wrmsr instructions.

I notice that hexrays represents them like this:

__writemsr(*(_DWORD *)SYSTEM_BUFFER, *((_QWORD *)SYSTEM_BUFFER + 1));

Using Hexrayscodexplorer I figured out that this is a "helper" expression:

helper __writemsr
ea->FFFFFFFFFFFFFFFF
void (__fastcall *)(unsigned int, unsigned __int64)

By the looks of the decompilation output, I expect I should be able to access the arguments to the "helper" (*(_DWORD *)SYSTEM_BUFFER, *((_QWORD *)SYSTEM_BUFFER + 1) in this case) - however the spots where I would look for operands or function arguments for a function call (cot_call) aren't populated.

Is this possible to do?

I have so far tried to look for arguments in:

cexpr_t.x

cexpr_t.y

cexpr_t.a

I'm sure I just don't understand how these helper expressions work in IDA. Unfortunately the function I'm trying to analyze is nested very deeply in a huge function, so it's kind of hard to see how all of the trees work together in the ctrees graph view provided by Hexrayscodexplorer.

Are the arguments held in some other cexpr object? How do I get to them?

1
  • FYI, the excellent HRDevHelper plugin shows a visual representation of the ctree, which makes it easy to answer questions like these, and more generally to understand Hex-Rays' internal representations of its decompilation listings. I highly recommend installing it and using it often: github.com/patois/HRDevHelper Mar 25, 2022 at 21:46

1 Answer 1

1

The helpers do have arguments just like other function calls, and you get to them the same way.

You are looking one level too low in the tree. If you look one level up, you'll see the cot_call that ties everything together. At a high level:

cot_call
   .x: cot_helper
         .helper: "__writemsr"
         .type: type of the helper (args and their types, return type)
   .a: carglist_t
    .a[0]: cexpr_t of arg0
    .a[1]: cexpr_t of arg1

and in code:

if expr.op == cot_call and expr.x.op == cot_helper and expr.x.helper == "__writemsr":
    # We have a helper "__writemsr" call!
    print("helper type: {}".format(expr.x.type))
    print("arg count: {}".format(len(expr.a)))
    print("args: {}".format(", ".join(arg.opname for arg in expr.a)))
    

Your Answer

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

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