I am using idapython to get function return type and arguments @ an indirect call instruction.

I was able to sync ida disassembler with hexrays decompiler as asked here and I can now get decompiled output for specific instruction. For e.g.

for instruction:

call    rdx

I can get:

v4 = ((__int64 (__fastcall *)(_QWORD))fn2)(b) + v3;

My final goal is to get function return type for e.g. in above case it could be the type of variable v4 and argument types, for e.g. type of variable b. So, say the function can possibly be:

return type: int
arg1 type: int

I want to get these for indirect callsites.

I checked the hexrays api but I believe there isn't any function which can give me return type and argument types/ count at a certain callsite.

One way to achieve this may be to extract arguments using regex for e.g. in above case b and then hunt their type by searching through lvars method from decompiled object. But, it seems like a lot of work (and maybe error prone) for seemingly easier problem using some internal ida functions.

Could you please give many any directions on how to solve this? really appreciated.

1 Answer 1


Don't use regular expressions. Generally speaking, never use regular expressions to solve problems in IDA. All of the text you'd be operating upon is available as data via the API, which provides a normalized form and can resolve ambiguities. Anyway, your rough plan of attack here is as follows:

  1. Although it's not strictly necessary, I'm going to strongly recommend installing HRDevHelper and using it often. Any time you wonder "how is X represented in the Hex-Rays ctree data structures?", the fastest way to find out is to invoke HRDevHelper via its keyboard shortcut (default ctrl+.), see the answer visually, and then go to hexrays.hpp in the SDK for more specifics. (Note, you may want to change the default colors in the configuration file for HRDevHelper).
  2. After having done so, locate an indirect call in the decompilation, and use HRDevHelper to view its representation. Here's what we see for the following decompilation (*(void (__fastcall **)(struct BINDING_HANDLE *, __int64))(*(_QWORD *)v5 + 8i64))(v5, 1i64);:

HRDevHelper output

  1. Looking at the figure, we see that calls are represented by cot_call expressions, whose .x member describes the destination of the call. For indirect calls (like the one in the figure), we can see that the node for .x (off to the left) has the text ptr.8 at the top. This indicates that .x is another expression of type cot_ptr. We can also see that the left ptr.8 node has the function type printed inside of it. In fact, the type is stored in a tinfo_t object held within the .x.type member, and HRDevHelper is simply printing it for us.

  2. To summarize: find cot_call expressions whose .x member does not have type cot_obj (as this is how direct calls are represented). Look at the .x.type member to determine the type of the indirect call. You're going to want to take a look at the func_type_data_t data type and the tinfo_t::get_func_details member function from typeinf.hpp. The former is derived from a vector of funcarg_t objects, which contain tinfo_t objects for each argument. The rettype field also describes the function's return type.

  3. Now that we know how Hex-Rays represents indirect calls, the easiest (but not the only) way to get ahold of them is to use a ctree_visitor_t. There are several examples in %IDADIR%\python\examples\hexrays (grep it for ctree_visitor_t); the simplest one is vds7.py. Give it a try; add a visit_expr(self,expr) method to its cblock_visitor_t class, try to implement the logic described in the previous bulletpoint, run the plugin, and see what happens.

  • this is perfect! thank you!
    – R4444
    Apr 29, 2022 at 1:22

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.