I always write ad-hoc code to get the values passed to function calls, like finding the XRef to a function and then tracking back disassembly to find some specific MOV or PUSH instruction. For example, in the following example:

.text:080488B1                 push    [ebp+gid]
.text:080488B4                 push    [ebp+gid]       ; gid
.text:080488B7                 call    setregid

I would find the XRefs to setregid and then find "push instructions". Or, in the next example:

LOAD:FFFFFFFF824047A4                 mov     rdi, exec_map
LOAD:FFFFFFFF824047AC                 mov     esi, 40400h
LOAD:FFFFFFFF824047B1                 call    kmem_alloc_wait

I would find the XRef to kmem_alloc_wait and then find before that call the values set to the registers RDI, RSI, RDX, RCX... And for each new processor, I would have to re-write again my code to handle the specific calling convention(s) of that CPU or VM. However, I'm sure there must be some proper way of getting the argument values to function calls, from IDAPython, in a CPU agnostic way.

So, do you know any way of getting the values passed to a function call from IDAPython that doesn't rely on parsing disassembly?

  • How about decompiling and then parsing the C generated file? – Train Mar 4 '18 at 14:58
  • I can walk the AST. Actually, this is an approach that I use sometimes. However: what can I do if I don't have a decompiler for that specific processor? What if it's a VM? – joxeankoret Mar 4 '18 at 17:30

Answering my own question: I sent an email to Hex-Rays and got back the answer in like minutes. The answer is using idaapi.get_arg_addrs().

For example, given the following code:

LOAD:FFFFFFFF82491188                 mov     rdi, offset unk_FFFFFFFF832EF148 ; a1
LOAD:FFFFFFFF8249118F                 mov     rsi, rbx        ; a2
LOAD:FFFFFFFF82491192                 xor     edx, edx        ; a3
LOAD:FFFFFFFF82491194                 xor     ecx, ecx
LOAD:FFFFFFFF82491196                 xor     r8d, r8d
LOAD:FFFFFFFF82491199                 call    _sx_xlock_hard

By running idaapi.get_arg_address(0xFFFFFFFF82491199) it would return the address of the 3 arguments in the order they are given when the function is called:

Python>print map(hex, idaapi.get_arg_addrs(here()))
['0xffffffff82491188L', '0xffffffff8249118fL', '0xffffffff82491192L']

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.