Tuesday, January 6, 2015

Practical Reverse Engineering p. 35 #6

Question number 6 on page 35 of Practical Reverse Engineering is as follows:

Sample H. The function sub_13846 references several structures whose types are not entirely clear. Your task is to first recover the function prototype and then try to reconstruct the structure fields. After reading Chapter 3, return to this exercise to see if your understanding has changed. (Note: This sample is targeting Windows XP x86.)

The function disassembles to:

sub_13842:
     mov     eax, [ecx+60h]
     push    esi
     mov     esi, [edx+8]
     dec     byte ptr [ecx+23h]
     sub     eax, 24h
     mov     [ecx+60h], eax
     mov     [eax+14h], edx
     movzx   eax, byte ptr [eax]
     push    ecx
     push    edx
     call    dword ptr [esi+eax*4+38h]
     pop     esi
     retn

It's a fastcall convention which has two struct pointer arguments, and the return type is not readily available. There are 3 locals which are stored in registers, two of them pointers within the struct and a char which is an index to a function call table.

PVOID __fastcall sub_13841(
     struct *arg1, struct *arg2)
{
     ULONG_PTR v1, v2;
     CHAR index;

     v1 = arg1->Unkown0x60;    /* mov eax, [ecx+60h] */
     v2 = arg2->Unknown0x8;    /* mov esi, [edx+8] */

     --arg1->Unknown0x23;      /* dec byte ptr [ecx+23h] */

     v1 -= 0x24;               /* sub eax, 24h */

     arg1->Unknown0x60 = v1;   /* mov [ecx+60h], eax */
     v1->Unknown0x14 = arg2;   /* mov [eax+14h], edx */

     index = v1->index;        /* movzx eax, byte ptr [eax] */

     /* call dword ptr [esi+eax*4+38h] */
     return v2->Unknown0x38[index](arg2, arg1);
}

Here is a basic idea so far on the struct meanings:

struct arg1 {
     BYTE Unknown0x0[0x23];   /* 0x0 */
     CHAR decremented;        /* 0x23 */
     BYTE Unknown0x24[0x18];  /* 0x24 */
     union
     {
         struct *v1[9];           /* 0x3c - 0x60 */
         struct
         {
             struct v1_1[0x3c];   /* 0x3c */
             struct v1_2[0x60];   /* 0x60 */
         };
     };
};

struct arg2 {
     BYTE Unknown0x0[0x8];    /* 0x0 */
     struct *v2;              /* 0x8 */    
};

/* size = 0x24 */
struct v1 {
     CHAR index;              /* 0x0 */
     BYTE Unknown0x1[0x13];   /* 0x1 */
     struct *arg2;            /* 0x14 */
     CHAR Unknown0x18[0xc];   /* 0x18 */
};

struct v2 {
     BYTE Unknown0x0[0x38];   /* 0x0 */
     ULONG_PTR function;      /* 0x38 */   
};

No comments :

Post a Comment