Assemble source code

  • Thread starter Thread starter Marco
  • Start date Start date
Status
Not open for further replies.
M

Marco

Guest
I managed to dissasemble the FF7 executable ("only" 105 MB or so) and now I'd like to re-assemble it. Would anyone be able to walk me through it?

So far I've just tried masm32 version 8 but it don't want to do it.
ff7n.asm(60) : error A2085: instruction or register not accepted in current CPU mode
ff7n.asm(66) : error A2066: incompatible CPU mode and segment size
ff7n.asm(69) : error A2085: instruction or register not accepted in current CPU mode
....
ff7n.asm(217) : fatal error A1012: error count exceeds 100; stopping assembly
 
Probably the CPU mode hadn't been set, but...

Aren't those errors kind of... self-explanatory to you? If not: What are you going to do with the code you've "obtained"? Change it? Not knowing the assembly language?

dziugo
 
I'm guessing that he probably "reversed" the program by doing some kind of object dump. I'm pretty sure that he didn't follow any functions or bother to figure out  what exactly is going on in the program.

Here a tip: Object dumps most often can't be reassembled again, don't bother trying.

The code has been very optimized, also one can easily add code to loop up an object dumper so it spits out bad machine code.

Here's a test, pick a function, any function in your "reversed code" and tell me how  the inherited data from the parent class is handed off.

If you reversed the code, and the fact FF7 is written is C++, finding classes should be a piece of cake. Right?

We need more people to identify functions in the code so we can see how it works. Trying to recompile fowled object dumps does nothing.
 
I was pretty sure Final Fantasy® VII was written in C.

Also, I have identified all the functions related to loading battle animations, but lost most of that information because I stored it as comment information inside Memory Hacking Software (so it would be easily portable) but, being the author of the software and having to run debug sessions and find problems with it on my own, I eventually made some errors that forced me to delete those files.

I have a few left on paper but I will have to look for them tomorrow.
I am at work now.


L. Spiro
 
No clue if I've done it correctly. Probably not.

Anyway I've "traced" some damage calculating function down to 005C79C0. As usual there.

push    ebp
mov     ebp, esp
sub     esp, 14h
mov     eax, [ebp+arg_0]
xor     ecx, ecx
mov     cl, [eax+5]
push    ecx
mov     edx, [ebp+arg_0]
push    edx
call    Calc_Dam1
add     esp, 8
mov     [ebp+var_C], eax
mov     eax, [ebp+arg_0]
xor     ecx, ecx
mov     cl, [eax+5]
add     ecx, 1
push    ecx
mov     edx, [ebp+arg_0]
push    edx
call    Calc_Dam1
add     esp, 8
mov     [ebp+var_8], eax
mov     eax, [ebp+var_C]
imul    eax, 64h
mov     ecx, [ebp+arg_0]
xor     edx, edx
mov     dx, [ecx+24h]
mov     ecx, edx
cdq
idiv    ecx
sub     eax, 64h
mov     [ebp+var_14], eax
mov     edx, [ebp+var_14]
push    edx
call    Calc_Dam2
add     esp, 4
mov     [ebp+var_10], eax
mov     eax, [ebp+arg_0]
xor     ecx, ecx
mov     cx, [eax+24h]
mov     [ebp+var_4], ecx
mov     eax, [ebp+var_8]
sub     eax, [ebp+var_C]
mov     edx, [ebp+var_10]
xor     ecx, ecx
mov     cl, byte_98E6C4[edx]
imul    eax, ecx
cdq
mov     ecx, 64h // Defense calculation?
idiv    ecx
mov     edx, [ebp+var_4]
add     edx, eax
mov     [ebp+var_4], edx
cmp     [ebp+var_4], 270Fh // damage cap check
jle     short loc_5C7A62 // if less then 9999 skip next step
mov     [ebp+var_4], 270Fh // otherwise set damage to 9999
loc_5C7A62:
mov     eax, [ebp+arg_0]
mov     cx, word ptr [ebp+var_4]
mov     [eax+24h], cx
mov     esp, ebp
pop     ebp
retn

I thought I'd get the thing to compile back before I started investigating what goes on to verify that I do have the correct set of data.
 
if you have disassemble it, most likely it will be decompiled into assembly.
Since a compiler converts all the high level code (c/c++ etc) into assembly/machine code (older systems).
So there is no notable way to go back to high level code with out first understanding assembly ?
 
No clue if I've done it correctly. Probably not.

Anyway I've "traced" some damage calculating function down to 005C79C0. As usual there.
Code: [Select]
Code:
push    ebpmov     ebp, espsub     esp, 14hmov     eax, [ebp+arg_0]xor     ecx, ecxmov     cl, [eax+5]push    ecxmov     edx, [ebp+arg_0]push    edxcall    Calc_Dam1add     esp, 8mov     [ebp+var_C], eaxmov     eax, [ebp+arg_0]xor     ecx, ecxmov     cl, [eax+5]add     ecx, 1push    ecxmov     edx, [ebp+arg_0]push    edxcall    Calc_Dam1add     esp, 8mov     [ebp+var_8], eaxmov     eax, [ebp+var_C]imul    eax, 64hmov     ecx, [ebp+arg_0]xor     edx, edxmov     dx, [ecx+24h]mov     ecx, edxcdqidiv    ecxsub     eax, 64hmov     [ebp+var_14], eaxmov     edx, [ebp+var_14]push    edxcall    Calc_Dam2add     esp, 4mov     [ebp+var_10], eaxmov     eax, [ebp+arg_0]xor     ecx, ecxmov     cx, [eax+24h]mov     [ebp+var_4], ecxmov     eax, [ebp+var_8]sub     eax, [ebp+var_C]mov     edx, [ebp+var_10]xor     ecx, ecxmov     cl, byte_98E6C4[edx]imul    eax, ecxcdqmov     ecx, 64h // Defense calculation?idiv    ecxmov     edx, [ebp+var_4]add     edx, eaxmov     [ebp+var_4], edxcmp     [ebp+var_4], 270Fh // damage cap checkjle     short loc_5C7A62 // if less then 9999 skip next stepmov     [ebp+var_4], 270Fh // otherwise set damage to 9999loc_5C7A62:mov     eax, [ebp+arg_0]mov     cx, word ptr [ebp+var_4]mov     [eax+24h], cxmov     esp, ebppop     ebpretn
I thought I'd get the thing to compile back before I started investigating what goes on to verify that I do have the correct set of data.
Hmmmm let me take a stab at making some C based code from this...
Code: [Select]
Code:
typedef struct{   UINT8 ZZ0[5];   UINT8 ZZ5;   UINT8 ZZ6[30];   UINT16 ZZ24;} Record;fnc_n(Record *arg_0, {   int var_C;   var_C = Calc_dam1(arg_0, arg_0->ZZ5);   var_8 = Calc_dam1(arg_0, arg_0->ZZ5 + 1);   var_14 = ((var_C * 100) / arg_0->ZZ24) - 100;   var_10 = Calc_dam2(var_14);   var_4 = arg_0->ZZ24;   var_4 += AZZ0[var_8 - var_C]/100;   if(var_4 > 9999)      var_4 = 9999;   arg_0->ZZ24 =  var_4;}

That's my current guess :)

Cyb
 
Well, it was something like that I imagined it. So if this is correct we can be rather sure that var_4 is used to hold a temporary damage value, and the value gets copied into a struct that the calling function supplies, thus I believe this function does something else besides just calculating damage, as the straight way would be to just return it in EAL or AX.
 
I was pretty sure Final Fantasy® VII was written in C.

Also, I have identified all the functions related to loading battle animations, but lost most of that information because I stored it as comment information inside Memory Hacking Software (so it would be easily portable) but, being the author of the software and having to run debug sessions and find problems with it on my own, I eventually made some errors that forced me to delete those files.

I have a few left on paper but I will have to look for them tomorrow.
I am at work now.


L. Spiro

Nope it's C++. Look at Gears, I have a partial source listing in the back
 
Definitely C++, yes. The code itself is something like 95% C (the legacy of the PSX version) and 5% C++ (DirectX interface etc.). It's all compiled with a C++ compiler though (MS Visual C++ 6.0 I think).
 
Yeah, you can see traces of code generated from OO design models, so I believe it should have been written in C++
 
Wouldn't it be easier to disassemble the PSX version since there would be no DirectX C++ and could easily be run through an emulator?
 
That would entirely depend on how familiar you are with PSX disassembly (I forgot the name of the CPU), and the quality of the tools available.
 
That would entirely depend on how familiar you are with PSX disassembly (I forgot the name of the CPU), and the quality of the tools available.
The PS1 uses a MIPSR3000 CPU there are plenty of excelent disassemblers for this.
In fact there are a lot of good tools for the R3K in general.
I won't mention any specific tools because that is kind of gray.

Cyb
 
Doesn't look like it it.

What about extracting/decompressing the executable? Is there any program that can handle that?
 
What about extracting/decompressing the executable? Is there any program that can handle that?
What about you tell us: Why (...) would you do that?

dziugo
 
I belive that if I do get it uncompressed and fully working, then I could see the disassembled source code.

While it may or may not be possible to reassemble, the data available should be accurate enought to start checking out how the game works.
 
You can already do exactly what you are trying to do with any debugger available.

And if you don’t know how to use one, there is no reason to think you would know what to do with recompiled assembly using the method you are trying already.

A debugger (with disassembler) already shows you the disassembled “source code” with the same detail you would get from recompiling assembly output.
Especially considering function and symbol names have been stripped and you don’t get them back using your method.


Run the game in a debugger if you want to see how it works.
The code for the game comes shipped with every copy of the game.


L. Spiro
 
You do have a point :/

Anyway I think I did manage to get a program to extract the file.
Just in case someone didn't know this, the executable seems to assume that it's named ff7.exe. It only works properly under that name.

I don't yet know if it's correct, but at least the decompiler picks it up as a Visual C project.
 
Status
Not open for further replies.
Back
Top