Igor’s Tip of the Week #164: Where’s my code? The case of missing function arguments

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

Article Link: Igor’s Tip of the Week #164: Where’s my code? The case of missing function arguments – Hex Rays