These can be downloaded at the following page:
In this exercise, we are expected to have a look at the following routine sub_13842:
.text:00013842 sub_13842
.text:00013842 mov eax, [ecx+60h]
.text:00013845 push esi
.text:00013846 mov esi, [edx+8]
.text:00013849 dec byte ptr [ecx+23h]
.text:0001384C sub eax, 24h
.text:0001384F mov [ecx+60h], eax
.text:00013852 mov [eax+14h], edx
.text:00013855 movzx eax, byte ptr [eax]
.text:00013858 push ecx
.text:00013859 push edx
.text:0001385A call dword ptr [esi+eax*4+38h]
.text:0001385E pop esi
.text:0001385F retn
Firstly, we see that the function prototype takes two parameters, which are not saved on the stack but in the two registers ecx and edx. This can be deducted from the fact that these two registers are immediately referenced without prior initialization.
On a very high abstraction level, the function prototype looks as follows:
sub_13842(struct1* a, struct2* b);
Moreover, we see that edx+8 points to some kind of base address, as it is used to compute the address of the function called on the following line:
.text:0001385A call dword ptr [esi+eax*4+38h]
Both parameters edx and ecx obviously point to some kind of data structure, whose contents we are about to reveal:
struct1:
offset+60: struct3*: s3
offset+23: char: unknown0x23
struct2:
offset+08: void*: here we have some kind of trampoline / array of function pointers
struct3:
offset+00: char: index
offset+14: struct2*: s2
struct4:
offset+38: int*: unknown
sub_13842(struct1* a, struct2* b)
.text:00013842 sub_13842
.text:00013842 mov eax, dword ptr[ecx+60h] // struct3* v1 = a->s3;
.text:00013845 push esi // just save esi register value
.text:00013846 mov esi, [edx+8] // void* v2 = b->unknown0x8
.text:00013849 dec byte ptr [ecx+23h] // a->unknown0x23 = a->unknown0x23 - 1;
.text:0001384C sub eax, 24h // v1 = v1 - 0x24;
.text:0001384F mov [ecx+60h], eax // a->s3 = v1;
.text:00013852 mov [eax+14h], edx // v1->s2 = b;
.text:00013855 movzx eax, byte ptr [eax] // char index = v1->index;
.text:00013858 push ecx
.text:00013859 push edx // call fct(
.text:0001385A call dword ptr [esi+eax*4+38h] // call b->unknown0x8+0x38h[index](b, a)
.text:0001385E pop esi
.text:0001385F retn
Overall, the decompiled code looks as follows:
sub_13842(struct1* a, struct2* b) {
struct3* v1 = a->s3;
void* v2 = b->unknown0x8;
a->unknown0x23 = a->unknown0x23 -1;
v1 = v1 - 0x24;
a->s3 = v1;
v1->s2 = b;
char index = v1->index;
b->unknown0x8+0x38h[index](b, a);
}
sub_13842(struct1* a, struct2* b) {
struct3* v1 = a->s3;
void* v2 = b->unknown0x8;
a->unknown0x23 = a->unknown0x23 -1;
v1 = v1 - 0x24;
a->s3 = v1;
v1->s2 = b;
char index = v1->index;
b->unknown0x8+0x38h[index](b, a);
}
No comments:
Post a comment