3

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 dbs. What is the size of offset unk_804C0B8 and it's value? Am I proceeding correctly?

3
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... – Newbie Nov 10 '17 at 2:25

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.