Learn lf2.exe from C
This tutorial teach you how to use C to understand what the assembly means in lf2.exe.
Please download the tool IDA and ollydbg, we use these tools to find what lf2.exe doing in this tutorial.
Stack frame
Lets checkout this function func_417400.
At begining
When this function get called, the stack will pushed a return address.
The return address is where to jump back when this function is doned and ready to return.
When the sub esp,30 is executed, stack pointer (esp) will prepare the space for local variables usage.
When the mov eax,dword ptr ss:[esp+34] is executed, we get the first argument of this function and store it in eax register.
So the definition of this function looks like:
When the push esi is executed, we save the data in esi register to prevent the code below from ruining the data in esi register.
We will use esi register for another purpose in code below.
When the mov esi,ecx is executed, we copy the this pointer to esi register.
Because LF2 is developed by Visual C++, by convension, Visual C++ compiler uses ecx register to transfor the this pointer to the function be called.
You can regard this pointer as a first argument of this function in C.
So the definition of this function looks like:
Code in function
Now we look this code:
The first line mov eax,dword ptr ds:[esi+eax*4+194] is a little bit complicated, this instruction use two registers to locate the address which data is stored in.
We can translate this intruction to mov eax,dword ptr ds:[this+arg_1*4+194].
By using this image, we know arg_1 should be index of objects and this pointer should be struct 'global' pointer, so the definition of this function becomes:
By inspecting this intruction mov eax,dword ptr ds:[this+arg_1*4+194], we know corresponding C code:
By using the data structure, we can understand what the code below means.
The second line mov ecx,dword ptr ds:[eax+7C] means:
The third line mov edx,dword ptr ds:[eax+368] means:
These two lines imul ecx,ecx,178 and lea ecx,dword ptr ds:[ecx+edx+7A4] means:
So the function should looks like:
If you have any question, please reply below.
Thanks you for reading this tutorial :)
This tutorial teach you how to use C to understand what the assembly means in lf2.exe.
Please download the tool IDA and ollydbg, we use these tools to find what lf2.exe doing in this tutorial.
Stack frame
Lets checkout this function func_417400.
At begining
When this function get called, the stack will pushed a return address.
The return address is where to jump back when this function is doned and ready to return.
When the sub esp,30 is executed, stack pointer (esp) will prepare the space for local variables usage.
When the mov eax,dword ptr ss:[esp+34] is executed, we get the first argument of this function and store it in eax register.
So the definition of this function looks like:
C-Code:
int func_417400(arg_1) { } |
When the push esi is executed, we save the data in esi register to prevent the code below from ruining the data in esi register.
We will use esi register for another purpose in code below.
When the mov esi,ecx is executed, we copy the this pointer to esi register.
Because LF2 is developed by Visual C++, by convension, Visual C++ compiler uses ecx register to transfor the this pointer to the function be called.
You can regard this pointer as a first argument of this function in C.
So the definition of this function looks like:
C-Code:
int func_417400(this, arg_1) { } |
Code in function
Now we look this code:
The first line mov eax,dword ptr ds:[esi+eax*4+194] is a little bit complicated, this instruction use two registers to locate the address which data is stored in.
We can translate this intruction to mov eax,dword ptr ds:[this+arg_1*4+194].
By using this image, we know arg_1 should be index of objects and this pointer should be struct 'global' pointer, so the definition of this function becomes:
C-Code:
int func_417400(struct global * global, uint32_t object_index) { } |
By inspecting this intruction mov eax,dword ptr ds:[this+arg_1*4+194], we know corresponding C code:
C-Code:
struct object * a_object = global->objects[object_index]; |
By using the data structure, we can understand what the code below means.
The second line mov ecx,dword ptr ds:[eax+7C] means:
C-Code:
uint32_t frame_id = a_object->frame_id; |
The third line mov edx,dword ptr ds:[eax+368] means:
C-Code:
struct file * a_file = a_object->file; |
These two lines imul ecx,ecx,178 and lea ecx,dword ptr ds:[ecx+edx+7A4] means:
C-Code:
struct frame * a_frame = &a_file->frames[frame_id]; |
So the function should looks like:
C-Code:
int func_417400(struct global * global, uint32_t object_index) { struct object * a_object = global->objects[object_index]; uint32_t frame_id = a_object->frame_id; struct file * a_file = a_object->file; struct frame * a_frame = &a_file->frames[frame_id]; } |
If you have any question, please reply below.
Thanks you for reading this tutorial :)
Decompiled functions: [documented] Functions decompiled
Decompile lf2.exe project for documentation: https://github.com/xsoameix/lf2
Decompile lf2.exe project for implementation: https://github.com/xsoameix/openlf2
Once any function fully engineer reversed in documentation project, then we implement it in implementation project.
lf2 data structure: Updated spreadsheet, many changes made by o_g349/xsoameix, I have two different nick names.
A old project: lf2-MS
Decompile lf2.exe project for documentation: https://github.com/xsoameix/lf2
Decompile lf2.exe project for implementation: https://github.com/xsoameix/openlf2
Once any function fully engineer reversed in documentation project, then we implement it in implementation project.
lf2 data structure: Updated spreadsheet, many changes made by o_g349/xsoameix, I have two different nick names.
A old project: lf2-MS