# 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:0804C0B9                 db 0FFh
LOAD:0804C0BA                 db 0FFh
LOAD:0804C0BB                 db  8Bh
LOAD:0804C0BC                 db  85h
LOAD:0804C0BD                 db  68h ; h
LOAD:0804C0BE                 db 0BFh
LOAD:0804C0BF                 db 0FBh
LOAD:0804C0C0                 db 0FFh
LOAD:0804C0C1                 db  89h
LOAD:0804C0C2                 db 0C2h
LOAD:0804C0C3                 db 0B8h
LOAD:0804C0C4                 db    0
LOAD:0804C0C5                 db    0
LOAD:0804C0C6                 db    0
LOAD:0804C0C7                 db    0
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 `db`s. What is the size of `offset unk_804C0B8` and it's value? Am I proceeding correctly?

• did you try changing `804C0B8` to code? Commented Nov 6, 2017 at 8:11

## 1 Answer

``````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
LOAD:0804C0BD                 db  68h ; h
LOAD:0804C0BE                 db 0BFh
LOAD:0804C0BF                 db 0FBh
``````

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
LOAD:0804C0B9                 db 0FFh
LOAD:0804C0BA                 db 0FFh
LOAD:0804C0BB                 db  8Bh
``````

you don't show what is at 8bffffe8

result should be what is at 8bffffe8 - 0xfbbf6885

edit

incase a1 == 1 then it appears you have a NULL pointer so you should reverse some thing else first which moves some data to 0x804c0c4

• Thanks for the clear response @blabb. The thing we didn't notice was that the code segments are all LOAD. It seems the binary is somehow broken. I'm trying to fix it. Playing around with readelf, but don't know how to use it... Commented Nov 10, 2017 at 2:25