1

I have recently been debugging a binary and at a point I started to decompile a function. One of the lines of the decompiled file is this:

v14 = (int (__cdecl *)(signed int))sub_8048FB6(1);

I have been told it is a function pointer but I have no clue to what function it is pointing to. I will appreciate if someone breaks this absolutely vague string to me into pieces with elaboration.

  • how is v14 being used? Also show the assembly at both places – Igor Skochinsky Nov 3 '17 at 11:06
  • Maybe you should start a new question with his. – Willem Hengeveld Nov 5 '17 at 12:31
  • @WillemHengeveld Ok. I will right now. – Newbie Nov 5 '17 at 19:26
6

The variable being assigned to:

v14 = 

The type cast needed to convert the result of the subroutine to the type of v14:

(int (__cdecl *)(signed int))

The subroutine call, with one argument: 1:

sub_8048FB6(1);

The typecast is needed because hexrays did not figure out automatically what the return type of sub_8048FB6 is, so it probably defaulted to int, instead of the function pointer.


Now the type:

The outer brackets denote a type cast:

(int (__cdecl *)(signed int))
^                           ^

The calling convention cdecl is cpu specific, commonly, a couple of arguments in registers, the rest on the stack, with the last argument pushed first:

(int (__cdecl *)(signed int))
      ^^^^^^^

It is a function pointer, denoted by the bracketed (...*)

(int (__cdecl *)(signed int))
     ^        ^^

A function taking one argument, a signed integer:

(int (__cdecl *)(signed int))
                ^^^^^^^^^^^^

And the function returning an integer:

(int (__cdecl *)(signed int))
 ^^^

This is the same as you would declare a function pointer in C:

typedef  int (*myfunctype)(signed int);
int afunction(signed int arg);
myfunctype  fp = afunction;

If you want to know what function pointer it is that is returned, you will have to look inside sub_8048FB6, to see where it gets it’s return value from.

For example, sub_8048FB6 may something look like this:

(int (__cdecl *)(signed int)) sub_8048FB6(int a1)
{
     switch(a1) {
        case 1:
            return sub_80123456;
        case 2:
            return sub_80456789;
    }
}

And elsewhere, the returned functions:

int sub_80123456(signed int)
{
   …
}

int sub_80456789(signed int)
{
   …
}
  • Thanks for the clear response. What I understood from it is that the return value of the sub_8048FB6(1) call actually provides the address of the function which the function pointer is supposed to point to. Some of the function's arguments are located on the stack while others may be in registers and finally the input output type for the function is determined. What I still don't know is that where in the binary am I supposed to find the function's actual code? – Newbie Nov 3 '17 at 20:29

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.