Important information: this site is currently scheduled to go offline indefinitely by end of the year.

[req].vfs bms script?

The Original Forum. Game archives, full of resources. How to open them? Get help here.
Chessman
n00b
Posts: 16
Joined: Sat Aug 22, 2009 5:47 pm
Has thanked: 2 times

[req].vfs bms script?

Post by Chessman »

The contents of this post was deleted because of possible forum rules violation.
Mr.Mouse
Site Admin
Posts: 4073
Joined: Wed Jan 15, 2003 6:45 pm
Location: Dungeons of Doom
Has thanked: 450 times
Been thanked: 682 times
Contact:

Re: [req].vfs bms script?

Post by Mr.Mouse »

Code: Select all

IDString 0 "vfs " ;
ComType ZLib1 ;
Get U1 Long 0 ;
Get BankSize Long 0 ;
Get U2 Long 0 ;
Get U3 Long 0 ;
Get U4 Long 0 ;
Get TOffset Long 0 ;
Set J Long 156 ;
GoTo J 0 ;
Do ;
SavePos ResStart 0 ;
Get ID Long 0 ;
If ID = 1751474532 ;
Get NumberOfBanks Long 0 ;
Get U6 Long 0 ;
Get CompressedSize Long 0 ;
SavePos FO 0 ;
Math NumberOfBanks *= BankSize ;
Math ResStart += NumberOfBanks ;
Set UCS Long 16 ;
Math UCS *= CompressedSize ;
CLog "" FO CompressedSize 0 0 UCS 0 ;
GoTo ResStart 0 ;
Else ;
Set ResStart Long TOffset ;
GoTo ResStart 0 ;
EndIf ;
While ResStart < TOffset ;
This is a BMS for MultiEx Commander. You can get the compiled *.bms here:
vfs.zip
Note that there are no filenames with this script, as there are none in the archive. At least, I expect so. There are 9 files (zlib compressed) in the file, followed by a tail. The tail is odd, and has 21 entries. That could be small pieces of text, and hashed at that. I can write another script to extract all those entries.
It would help if we had more *.vfs files to work with.

The files that are extracted are some XML and some GamEmbryo game engine specific files, a long with meshes it seems.
You do not have the required permissions to view the files attached to this post.
User avatar
aluigi
VVIP member
VVIP member
Posts: 1916
Joined: Thu Dec 08, 2005 12:26 pm
Location: www.ZENHAX.com
Has thanked: 4 times
Been thanked: 664 times
Contact:

Re: [req].vfs bms script?

Post by aluigi »

the specified uncompressed size (UCS) is too small.
for example the first file which starts at offset 0xac has a compressed size of 46074 (0xb3fa) and an uncompressed one of 1070608 but your script uses a 16 multiplier which so sets a max size of 737184 and the extraction fails or is incomplete if you have received no warnings/errors (quickbms indeed reports the zlib error -5, Z_BUF_ERROR).
chrrox
Moderator
Posts: 2602
Joined: Sun May 18, 2008 3:01 pm
Has thanked: 57 times
Been thanked: 1422 times

Re: [req].vfs bms script?

Post by chrrox »

if more files are needed here is the installer once I download it Ill upload some more files.
http://down.qq.com/xxz/full/QQXXZ_Full_ ... 4.1735.exe
the installer is 570Mb
Mr.Mouse
Site Admin
Posts: 4073
Joined: Wed Jan 15, 2003 6:45 pm
Location: Dungeons of Doom
Has thanked: 450 times
Been thanked: 682 times
Contact:

Re: [req].vfs bms script?

Post by Mr.Mouse »

OK, aluigi, thanks. It's a bit annoying when there's not a UCS variable somewhere. I just figured an estimated compression 1/16th of original size would suffice. Obviously not. Well, then 32 or even 64 might be enough.
Chessman
n00b
Posts: 16
Joined: Sat Aug 22, 2009 5:47 pm
Has thanked: 2 times

Re: [req].vfs bms script?

Post by Chessman »

Thanks!

after installation of game, we can launch the client and enter game account(acc:869222041,pwd: xentaxforum).then it will give error information,we can dump the xxzshell with hxd. and now we can find the filenames of all file and other information.
Mr.Mouse
Site Admin
Posts: 4073
Joined: Wed Jan 15, 2003 6:45 pm
Location: Dungeons of Doom
Has thanked: 450 times
Been thanked: 682 times
Contact:

Re: [req].vfs bms script?

Post by Mr.Mouse »

Ok, the big xxz.vfs file contains some 17800 files, that I can extract with the adapted script. At the end, there is the tail that has some 18000 entries. I'm pretty sure the tail holds the key to the filenames. Did you see the game has a vfs.dll file? In there, there's text reference to a FDT part in the .vfs. I think that might be File Dxxx Table or something, the tail part ;). Perhaps it's even possible to use the dll to do everything.

Here's a few extracted graphics files, there's TGA, GIF, BMP etc in there.
file10.png
file17379s.jpg
file17588.png
You do not have the required permissions to view the files attached to this post.
chrrox
Moderator
Posts: 2602
Joined: Sun May 18, 2008 3:01 pm
Has thanked: 57 times
Been thanked: 1422 times

Re: [req].vfs bms script?

Post by chrrox »

The contents of this post was deleted because of possible forum rules violation.
Chessman
n00b
Posts: 16
Joined: Sat Aug 22, 2009 5:47 pm
Has thanked: 2 times

Re: [req].vfs bms script?

Post by Chessman »

Great work!

OPEN vfs.dll with ida pro, and we find:

Code: Select all

push  offset aVfsStartReadFd ; "[VFS]Start Read fdt"
call    sub_100033B8
pop     ecx
mov     ecx, [ebp+var_2C]
mov     eax, [ecx]
push    esi
push    offset a_?fdt   ; ".?fdt"
call    dword ptr [eax+8Ch]
cmp     eax, edi
mov     [ebp+var_34], eax
mov     ecx, esi
jz      loc_1000F715

call dword ptr[eax+8ch]:

Code: Select all

push    edi             ; lpOverlapped
lea     ecx, [ebp+NumberOfBytesRead]
push    ecx             ; lpNumberOfBytesRead
push    4               ; nNumberOfBytesToRead
lea     eax, [esi+14h]
push    eax             ; lpBuffer
push    [ebp+hFile]     ; hFile
call    ebx ; ReadFile
test    eax, eax
jz      loc_1000F864

now call ebx;readfile: jump again we can find more functions which handle .vfs file.
Mr.Mouse
Site Admin
Posts: 4073
Joined: Wed Jan 15, 2003 6:45 pm
Location: Dungeons of Doom
Has thanked: 450 times
Been thanked: 682 times
Contact:

Re: [req].vfs bms script?

Post by Mr.Mouse »

Wait, upon examining the vfs.dll file in IDAPro, I noticed a reference to a CodeFilter.cpp, along with a 16-byte array :

Code: Select all

QIKJHMNAETOGDCXS
This code is used in a function that is called by another function. The first function calculates a value by ANDing a gotten value with 0F and then presumably that value is used to pick the right letter from the above array (e.g. 0e would pick 'X', while 0 would pick 'Q'). A value of 16 or higher would return 32 (a space character).

Now notice the following in the tailsection of a vfs file, it is one complete tailentry:
Untitled-2.jpg
Take a look at the distribution of all 256 characters, of course only 16 show up:
Untitled-4.jpg
Recognize them? Yes, only those that are in the filter array in the vfs.dll: QIKJHMNAETOGDCXS

As you can see, Q is represented much more than all the others. I guess you figured out by now why that is so. Yes, because a 0 is more abundant in this type of file allocation table. And the function in the dll picks a 'Q' whenever the value input is 0.

This however leaves us with a problem to solve. These 16 characters can thus presumably only represent a byte value from 00-0F each. That is not much to go by,if we want filenames in our language. Unless, it is like "0F 08 0D 0A" etc that later is combined into F8DA or something alike. Or in UTF-16 to get Oriental characters. Just a thought.
You do not have the required permissions to view the files attached to this post.
GameZelda
advanced
Posts: 61
Joined: Wed Nov 14, 2007 5:56 pm
Been thanked: 29 times

Re: [req].vfs bms script?

Post by GameZelda »

You did almost beat me :mrgreen:

Code: Select all

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include <assert.h>

/**
 * Converts an encoded character to a nibble.
 *
 * [in] c: The encoded character.
 * [out] retVal: The nibble, or -1 on error.
 */
int decodeNibble(char c)
{
    static const char key[] = "QIKJHMNAETOGDCXS";

    for (int i = 0; i < strlen(key); i++)
        if (key[i] == c) return i;

    return -1;
}

/**
 * Decode an encoded string to an array of bytes.
 *
 * [in] text: Encoded string.
 * [in] textLen: Encoded string length.
 * [out] bytes: Decoded bytes (will need to free() them).
 * [out] bytesLen: Size of the "bytes" array.
 * [out] retVal: Zero on success, nonzero on error.
 */
int decodeString(const char *text, size_t textLen, uint8_t **bytes, size_t *bytesLen)
{
    if ((textLen % 2) != 0) // 2 characters are a byte, so it has be a multiple of 2
        return !0;

    // Allocate the output array
    *bytesLen = textLen / 2;
    *bytes = (uint8_t *)malloc(*bytesLen);
    if (*bytes == NULL)
        return !0;

    // Decode
    int n1, n2;

    for (size_t i = 0; i < textLen; i += 2)
    {
        // Decode 2 character to 2 nibbles
        n1 = decodeNibble(text[i + 1]);
        n2 = decodeNibble(text[i]);

        if (n1 == -1 || n2 == -1)
            return !0;

        // Combine
        (*bytes)[i / 2] = n1 | (n2 << 4);
    }

    return 0;
}
Basically it's what you said, each character on the "string" is a nibble (that can be converted using that 16 byte string), and to make bytes, the first character of each pair is the high part, and the second one is the low part.

By the way, it seems to contain the names :)

EDIT: Fixed a little bug
Last edited by GameZelda on Mon Nov 09, 2009 1:10 pm, edited 1 time in total.
Mr.Mouse
Site Admin
Posts: 4073
Joined: Wed Jan 15, 2003 6:45 pm
Location: Dungeons of Doom
Has thanked: 450 times
Been thanked: 682 times
Contact:

Re: [req].vfs bms script?

Post by Mr.Mouse »

:clasdance Ah, I love it when I'm right. :clasdance

Also great work, GameZelda! I'm sure that decode routine will come in handy. Got a few examples of decoded filenames ? Because there's still a lot of Q's in there. We still need to figure out the format of the tail entries after they've been decoded.
User avatar
aluigi
VVIP member
VVIP member
Posts: 1916
Joined: Thu Dec 08, 2005 12:26 pm
Location: www.ZENHAX.com
Has thanked: 4 times
Been thanked: 664 times
Contact:

Re: [req].vfs bms script?

Post by aluigi »

I have written a basic script for the extraction, if someone wants to have fun there is still the directory tree to implement so this simple script extracts the files without the folders:

Code: Select all

idstring "vfs "
goto 0x18
get INFO_OFF long
goto INFO_OFF
get FILES long
for i = 0 < FILES
    get DATASZ long
    get DUMMY long
    savepos INFO_OFF

    #encryption charset2 "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0QIKJHMNAET\0\0\0\0\0\0\0OGDCXS" #wait quickbms 0.3.8
    encryption charset "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x37\0\x64\x63\x38\0\x62\x34\x31\x33\x32\0\x35\x36\x61\0\x30\0\x66\x39\0\0\0\x65\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
    comtype hex
    clog MEMORY_FILE INFO_OFF DATASZ DATASZ
    encryption "" ""

    idstring MEMORY_FILE "daeh"
    get NAMESZ long MEMORY_FILE
    getdstring NAME NAMESZ MEMORY_FILE
    get SIZE long MEMORY_FILE
    get ZSIZE long MEMORY_FILE
    get TYPE long MEMORY_FILE
    get OFFSET long MEMORY_FILE
    get DUMMY long MEMORY_FILE
    get DUMMY long MEMORY_FILE
    get NEXT_DATA long MEMORY_FILE  # for folders

    math OFFSET += 16
    if TYPE == 0
        log NAME OFFSET SIZE
    elif TYPE == 1
        comtype zlib
        clog NAME OFFSET ZSIZE SIZE
    elif TYPE == 2
        # folder
    else
        print "unknown type %TYPE%"
        cleanexit
    endif

    math INFO_OFF += DATASZ
    goto INFO_OFF
next i
Chessman
n00b
Posts: 16
Joined: Sat Aug 22, 2009 5:47 pm
Has thanked: 2 times

Re: [req].vfs bms script?

Post by Chessman »

ok.it works.
but quickbms sends error information after extracting 13128 files from zzx.vfs.

Code: Select all

Error:the compressed zlib/deflate input is wrong or incomplete <-3>
Mr.Mouse
Site Admin
Posts: 4073
Joined: Wed Jan 15, 2003 6:45 pm
Location: Dungeons of Doom
Has thanked: 450 times
Been thanked: 682 times
Contact:

Re: [req].vfs bms script?

Post by Mr.Mouse »

While I applaud you thanking aluigi, the important forework was done by others. :)
Post Reply