# Function Pointer Assembly Calculations

I am reverse engineering a binary in IDA Pro and I came across the function sub_8048FB6 which I think provides the address to a function pointer. The decompilation of the subroutine is as follows and I'm trying to find result.

int __cdecl sub_8048FB6(int a1)
{
int result; // eax
int v2; // [esp+0h] [ebp-10h]
int v3; // [esp+4h] [ebp-Ch]

v2 = *(_DWORD *)dword_804C0D4;
v3 = *(_DWORD *)(8 * a1 + 4 + *(_DWORD *)dword_804C0D4);
if ( a1 & 1 )
result = *(_DWORD *)(8 * a1 + v2) - v3;
else
result = *(_DWORD *)(*(_DWORD *)(8 * a1 + v2) - v3);
return result;
}


The dword_804C0D4 variable I will guess is pointing to a memory location and is only referenced 2 times in the binary as follows:

Up  r   sub_8048FB6+6   mov     eax, ds:dword_804C0D4
Up  w   sub_804A24E+3   mov     ds:dword_804C0D4, offset unk_804C0B8


So, my guess is the offset to the variable unk_804C0B8 is the value which is in the address pointed by ds:dword_804C0D4. If that's the case, with respect to where is the offset calculated? Once I double-click on unk_804C0B8 I get:

LOAD:0804C0B8 unk_804C0B8     db 0E8h   ; DATA XREF: sub_804A24E+3↑o
LOAD:0804C0C8 dword_804C0C8   dd 0FFEB0EE8h   ; DATA XREF: sub_8049D1E+2B1↑r


But I don't know how to read the value with all those dbs. What is the size of offset unk_804C0B8 and it's value? Am I proceeding correctly?

• did you try changing 804C0B8 to code? Nov 6 '17 at 8:11

mov     ds:dword_804C0D4, offset unk_804C0B8


so if this instruction was executed first before the sub was called then

0x804c0d4 would contain 0x804c0b8

v2 = *(_DWORD *)dword_804C0D4;

so v2 would be 0x804c0b8

assuming int a1 == 0

v3 = *(_DWORD *)(8 * a1 + 4 + *(_DWORD *)dword_804C0D4);


v3 would be ((8 * 0) + 4 + 0x804c0b8) == (0 + 4 +0x804c0b8) == *(0x804c0bc) == 0xfbbf6885

                              db  85h


to define a dword you can press d two times at 0x804c0bc

since a1 was assumed to be 0 the if clause is not satisfied and the execution moves to else clause

result = *(_DWORD *)(*(_DWORD *)(8 * a1 + v2) - v3);


**(8*0 + 0x804c0b8) == **(0x804c0b8) == *0x8bffffe8

LOAD:0804C0B8 unk_804C0B8     db 0E8h   ; DATA XREF: sub_804A24E+3↑o