I was reversing some executable and came across to this code:

enter image description here

As I found out later, it's using function pointer to call function sub_4011C0 and that could be the reason.

My question is why does dissambler show this kind of output? why doesn't it recognize the function pointer and call the function twice? thanks.

  • 1
    I don't understand the question. What's the problem?
    – conio
    Sep 3, 2017 at 10:56
  • 1
    What makes you think the output is wrong? Sep 3, 2017 at 12:18
  • why is it calling two times? when the reference shows only one call?
    – Ojs
    Sep 3, 2017 at 12:22
  • 1
    Sorry I can't follow you. What do you mean by the reference? The application stores the address of the function in [ebp+var_4] and then calls whatever is at [ebp+var_4] 2 times. In this case it's the function it moved there. The original code could have been something like that: pastebin.com/0S83zEhp Sep 3, 2017 at 12:43
  • Thats the point, in original source code there is only one call to the function, even if you look at the picture above sub_4011C0 function has only one reference. In reference I mean IDA only recognizes one call to the function which is from DATA XREF: sub_4011D0+5o
    – Ojs
    Sep 3, 2017 at 15:19

1 Answer 1


In assembly there is only one explicit reference to the target function, and that's where its address is moved to the variable at point 1 (you can see that the reference is marked 'o' (offset) and not 'p' ([procedure] call)). While IDA could in theory track stack var assignments and add xrefs also at the points the variable is used for an indirect call (2 and 3), this:

  1. would increase analysis time for negligible benefit (an experienced user can easily see that var_4 is called twice)
  2. is prone to false positives (e.g. if there's a function call before initialization and use of the variable, you can't be sure that it's not overwritten by the side-effects of the function)
  3. is easily defeatable (e.g. do some simple math on the pointer and IDA will be fooled).

So it's better to add only explicit cross-references and let the human decide if extra ones need to be added manually.

That said, IDA does some limited amount of register tracking to handle the most common situations, e.g.:

mov     esi, ds:__imp__sprintf
push    edi
lea     edx, [esp+0BCh+szOffset]
push    offset Format   ; "%08X"
push    edx             ; Dest
call    esi ; __imp__sprintf

You can see that it added a comment at the call esi instruction with the actual destination loaded earlier into esi. (it also adds a call xref in such case).

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.