Welcome!

Join our community of MMO enthusiasts and game developers! By registering, you'll gain access to discussions on the latest developments in MMO server files and collaborate with like-minded individuals. Join us today and unlock the potential of MMO server development!

Join Today!

Reverse engineering a world map file

Newbie Spellweaver
Joined
Aug 14, 2015
Messages
79
Reaction score
18
I was wondering if anyone is familiar with the map file format ".ma1, .ma2" or at least its structure in general. If not, how would I go about figuring out the structure of a world map file? Thanks in advance.

 
Skilled Illusionist
Joined
May 6, 2012
Messages
309
Reaction score
33
Did You get The source for The Game reading it? If yes You Can look there how its read ans know what is what. Else search by using hex editor for The header. This mostly have The needed informations. The offset for The vertices, polygons, objects, fileversion, etc. I am only a newbie at This. It's More a trying to find The right values. Without having The source or else its pretty hard. I recommend You using 010 editor. And Look at xentax for some tutorials.
 
Elite Diviner
Joined
Apr 28, 2012
Messages
420
Reaction score
439
[STRIKE]what game?[/STRIKE]
Archlord
 
Last edited:
Newbie Spellweaver
Joined
Aug 14, 2015
Messages
79
Reaction score
18
@lastfun
Yep.
Zenshin112
I do not have the source sadly. I've tried using notepad++ with the hex editor plugin but couldn't make much sense of it. I'll keep trying.
 
[emoji848]
Legend
Joined
Dec 3, 2011
Messages
2,232
Reaction score
1,518
Looks to me like a 51 bytes long header followed by several entries.
The entries seem to always start with 0xC0 (maybe a token declaring a new entry) and a string (maybe containing the file name) trailed by a 4 byte large value that could be an integer or something indicating the data length probably:

AcarX - Reverse engineering a world map file - RaGEZONE Forums


Sorry for the crappy illustration, I didn't have much time.

Maybe that already gets you somewhere, I have limited time atm. but I could try some parsing tomorrow. Doesn't look too difficult to find out. By the extension names like .dff it's highly likely those are DirectX resource files.
 
Newbie Spellweaver
Joined
Aug 14, 2015
Messages
79
Reaction score
18
@Future
Thanks for taking the time to check it out. I believe 0x0C is the length of the file name. Dff is I believe the 3D file format for the renderware engine(which is the engine this game was built in). I tried to figure out if the data part was repeating itself or had something to do with the blue marked parts but didn't have much success yet.
 
Elite Diviner
Joined
Apr 28, 2012
Messages
420
Reaction score
439
@AcarX


offset for first file name (byte file name length):
long offset = 0x32;

struct header see in screen
xor body length:
Code:
  byte[] key = { 0x69, 0x69};
  var f_size = reader.ReadBytes(4);  //blue in header screen
              for (int x = 0; x < key.Length; x++)
              {
                 f_size[x] = (byte)(key[x] ^ f_size[x]);
              }
and one small problem))) body file is compressed (so it seems to me, did not look in detail, the time is not... look later)
 
Last edited:
Newbie Spellweaver
Joined
Aug 14, 2015
Messages
79
Reaction score
18
Thanks @lastfun
I couldn't have thought of that ever. [STRIKE]Although I seem to fail to get same results in C[/STRIKE]. Got the same results as well. Is the key same for all files or?

Edit: For .ma2 files 0x1485 seems to be the separator.
 
Last edited:
Elite Diviner
Joined
Apr 28, 2012
Messages
420
Reaction score
439
Yes, for all (100% for *.ma1, for ma2 i'm not looking, but it should be the same )
 
[emoji848]
Legend
Joined
Dec 3, 2011
Messages
2,232
Reaction score
1,518
Thanks for donig the work lastfun :p
I would have taken a look at it now but I see you're already into it.

How did you fiddle out that the length is XORed and the key for it as well?
 
Newbie Spellweaver
Joined
Aug 14, 2015
Messages
79
Reaction score
18
I believe those 'separators' are also being xor'ed and being used to allocate memory for data. From what I could dig up in assembly something like:

Code:
size_t dataSize = separator ^ 0x6969;
if(dataSize > SOME_CONSTANT)
	; // error checking
else
	char* memoryPtr = new char[dataSize]; // memoryPtr seems to be a fixed address instead of a local variable

I guess this is it as far as the file structure goes. I would love some help with parsing the contents of data parts but it might be too much to ask for.
 
[emoji848]
Legend
Joined
Dec 3, 2011
Messages
2,232
Reaction score
1,518
I agree with you AcarX that value looks like an offset or length definition to me. A 4 byte val (uint32 / int32) typically looks like some kind of size definition and it's right behind the file name of each entry.
 
Elite Diviner
Joined
Apr 28, 2012
Messages
420
Reaction score
439
I would love some help with parsing the contents of data parts but it might be too much to ask for.
no, not much)
I (later, ~4-5h) will continue to parse this pack...
I'm not sure exactly, but i think it's just a marker (0x6d79)
I'm more worried about the file body compress method (if there is one), need take any *.amf and compared with that in the pack
 
Newbie Spellweaver
Joined
Aug 14, 2015
Messages
79
Reaction score
18
The word 'DXT1' is pretty common in .ma2 files which as far as I know is a compressed texture format so they could be non-encrypted/uncompressed by a common method. From what I could figure, each file has 256 files(bodies) in them. I could try and write an extractor if it would help.

Edit:
 
Last edited:
Elite Diviner
Joined
Apr 28, 2012
Messages
420
Reaction score
439
I'm not interested in this game, but!
I like it when someone does something
Thank you, AcarX
 
Elite Diviner
Joined
Apr 28, 2012
Messages
420
Reaction score
439
hi bro, AcarX ;)
i was really stupid in C and C ++ (i don't show my code, i am ashamed)) ... i used C++ just to insert assembler unit)
i know you write in C
insert this assembly code in your project
the output will be unpacked file
Code:
...
std::ifstream is ("d.b", std::ifstream::binary);
  if (is) {
    is.seekg (0, is.end);
    int length = is.tellg();
    is.seekg (0, is.beg);

    char * pack = new char [length];
    char * unpack = new char [0x410]; //<-- unpack size
    std::cout << "Reading " << length*2 << " bytes... ";
    is.read (pack,length);
...
Code:
__asm{

		mov esi,pack             //pointer for pack body
		mov edi,unpack       //pointer for unpack body
		cld
		mov dl,0x80                                   
loop99:	mov al,byte ptr ds:[esi] 
		inc esi
		mov byte ptr ds:[edi],al 
		inc edi
loop111:add dl,dl
		jne loop1                                    
		mov dl,byte ptr ds:[esi]                           
		inc esi                                     
		adc dl,dl                               
loop1:  jae loop99                        
		add dl,dl           
		jne loop2                                    
		mov dl,byte ptr ds:[esi]                
		inc esi               
		adc dl,dl              
loop2:  jae loop3                     
		xor eax,eax         
		add dl,dl          
		jne loop4     
		mov dl,byte ptr ds:[esi]                            
		inc esi                                             
		adc dl,dl                                           
loop4:  jae loop5                                   
		add dl,dl                                           
		jne loop6                                    
		mov dl,byte ptr ds:[esi]                            
		inc esi                                             
		adc dl,dl                                           
loop6:  adc eax,eax                                         
		add dl,dl                                           
		jne loop7                                   
		mov dl,byte ptr ds:[esi]                            
		inc esi                                             
		adc dl,dl                                           
loop7: 	adc eax,eax                                         
		add dl,dl                                           
		jne loop8                                   
		mov dl,byte ptr ds:[esi]                            
		inc esi                                             
		adc dl,dl                                           
loop8:  adc eax,eax                                         
		add dl,dl                                           
		jne loop10
		mov dl,byte ptr ds:[esi]                            
		inc esi                                             
		adc dl,dl                                           
loop10: adc eax,eax                                         
		je loop11                                     
		push edi                                            
		sub edi,eax                                         
		mov al,byte ptr ds:[edi]                            
		pop edi                                             
loop11: mov byte ptr ds:[edi],al                            
		inc edi                                             
		jmp loop111                                    
loop3:	mov eax,1                                           
loop23: add dl,dl                                           
		jne loop25                                   
		mov dl,byte ptr ds:[esi]                            
		inc esi                                             
		adc dl,dl                                           
loop25: adc eax,eax                                         
		add dl,dl                                           
		jne loop24
		mov dl,byte ptr ds:[esi]                            
		inc esi                                             
		adc dl,dl                                           
loop24: jb loop23
		sub eax,2                                           
		jne loop22                                    
		mov ecx,1                                           
loop19: add dl,dl                                           
		jne loop21                                    
		mov dl,byte ptr ds:[esi]                            
		inc esi                                             
		adc dl,dl                                           
loop21: adc ecx,ecx                                         
		add dl,dl                                           
		jne loop20                                    
		mov dl,byte ptr ds:[esi]                            
		inc esi                                             
		adc dl,dl                                           
loop20: jb loop19                                     
		push esi                                            
		mov esi,edi                                         
		sub esi,ebp   
		rep movsb     
		pop esi                                             
		jmp loop111                                    
loop22: dec eax                                             
		shl eax,8                                           
		mov al,byte ptr ds:[esi]                            
		inc esi                                             
		mov ebp,eax                                         
		mov ecx,1                                           
loop15: add dl,dl                                           
		jne loop16                                    
		mov dl,byte ptr ds:[esi]                            
		inc esi                                             
		adc dl,dl                                           
loop16: adc ecx,ecx                                         
		add dl,dl                                           
		jne loop17                                    
		mov dl,byte ptr ds:[esi]                            
		inc esi                                             
		adc dl,dl                                           
loop17: jb loop15                                     
		cmp eax,0x7D00                                        
		jae loop18                                    
		cmp eax,0x500                                         
		jb loop12
		inc ecx                                             
		push esi                                            
		mov esi,edi                                         
		sub esi,eax   
		rep movsb   
		pop esi                                             
		jmp loop111                                    
loop12: cmp eax,0x7F                                          
		ja loop13                                     
loop18: add ecx,2                                           
loop13: push esi                                            
		mov esi,edi                                         
		sub esi,eax  
		rep movsb    
		pop esi                                             
		jmp loop111                                    
loop5:  mov al,byte ptr ds:[esi]                            
		inc esi                                             
		xor ecx,ecx                                         
		shr al,1                                            
		je loop14                                    
		adc ecx,2                                           
		mov ebp,eax                                         
		push esi                                            
		mov esi,edi                                         
		sub esi,eax   
		rep movsb  
loop1001: pop esi                                             
		  jmp loop111                                   
loop14: sub edi,dword ptr ss:[esp+28]                       
		mov dword ptr ss:[esp+0x1C],edi                       
                                              
	};
You right)
/body pack file/

p.s. asm insert real work (i check output in XDBG)
p.s.2. i just ripped the unpacking of exe, i no tried to make out the algorithm)
p/s/3 screen pack -> unpack in my tools and client (debug) i show tomorrow (working code on work computer)
 
Last edited:
Newbie Spellweaver
Joined
Aug 14, 2015
Messages
79
Reaction score
18
@lastfun
Great work thanks. I stumbled upon same routine but couldn't make much sense of it. So if I pass the files to that assembly block I'll get the unpacked file data?
 
Back
Top