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 '17 at 10:56
  • 1
    What makes you think the output is wrong? Sep 3 '17 at 12:18
  • why is it calling two times? when the reference shows only one call?
    – Ojs
    Sep 3 '17 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 '17 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 '17 at 15:19

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, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.