Let’s consider this snippet from decompilation of an x86 Windows binary:
The same function is called twice with the same argument and the last one doesn’t seem to use the result of the GetComputerNameExW
call.
By switching to disassembly, we can see that eax
is initialized before each call with a string address:
However the decompiler does not consider it, because on x86 the stack is the usual way of passing arguments and eax
is most commonly just a temporary scratch register.
One option is to edit the prototype of sub_10006FC7
to use the __usercall calling convention and add eax
to the argument manually. But when the function is situated in the same binary, it is usually easier to simply go inside the function and decompile it so that the decompiler can see that it does use eax
before initializing, and so it is added to the argument list:
In addition, esi
is also detected to be an argument.
If we go back to the caller now, we should see the previously missing arguments being passed to the calls:
NB: usage of non-standard, custom calling convention is often a sign of either functions using hand-written assembly, or whole program optimization (aka LTO or LTCG) being enabled.
See also:
Igor’s tip of the week #51: Custom calling conventions