IDA Python - Identify Pushes for a Function Call

1.7k views Asked by At

Given a sample assembly code snippet as follows:

[1] push eax
[2] push ebx
[3] call function_with_1_arg
[4] push ecx
[5] call function_with_2_args

Is there any IDA Python API, or simple script, to identify that lines 1 and 4 are the "relevant pushes" for the function_with_2_args call (line 5)?

Thanks!

EDIT:

Thanks @ped7g for the insights. I didn't realise that it can be so complicated. (I see that IDA helps to identify and annotate the pushes for some of the system API calls, so I thought that IDA could already identify argument pushes for function calls in general.)

I suppose then, for a start, I'll work with some (many?) simplifying assumptions which should hold for majority of cases that I encounter. E.g. I'm not even considering like fastcall. Probably, stdcall and cdecl should suffice for now.

So I'll assume for now that arguments for the function calls will be pushed to the stack prior to the call. The only complication that I would have to deal with, for now, are "interleaved" function calls (as in the e.g. above).

I've given it a bit of thought on how to implement this:

Get func_argsize = GetFunctionAttr(..., FUNCATTR_ARGSIZE)
Set other_funcs_argsize = 0
Set i = 0
while func_argsize > 0:
    Get prev instruction using PrevHead(...)
    if GetMnem(...) == 'call':
        Follow call operand addr
        Set other_funcs_argsize += FUNCATTR_ARGSIZE of the other function
    elif GetMnem(...) == 'push':
        Get operand size of the PUSH (***)
        if other_funcs_argsize > 0:
            other_funcs_argsize -= operand size
        else:
            func_argsize -= operand size
            output that this is the i-th arg for the function call
            i += 1

The only gap I still have, is how to implement the pseudocode in (***), i.e. how to determine the operand size of a PUSH instruction.

ADDON:

Oh, I need the operand size of PUSH instructions, because FUNCATTR_ARGSIZE gives the number of bytes for function arguments. If, instead, there's an API to find out how many arguments a function expects, then I won't need operand size. I'll just have to count the pushes. But so far, I couldn't find such an API.

0

There are 0 answers