Skip to content
View in the app

A better way to browse. Learn more.

ResHax

A full-screen app on your home screen with push notifications, badges and more.

To install this app on iOS and iPadOS
  1. Tap the Share icon in Safari
  2. Scroll the menu and tap Add to Home Screen.
  3. Tap Add in the top-right corner.
To install this app on Android
  1. Tap the 3-dot menu (⋮) in the top-right corner of the browser.
  2. Tap Add to Home screen or Install app.
  3. Confirm by tapping Install.
Help us keep the site running.

love&war ( .wdf )

Featured Replies

  • Author
  • Localization

yianti, posted Fri Aug 21, 2015 11:45 am (6890)


help me ,plz!
  • Author
  • Localization

yianti, posted Tue Aug 25, 2015 4:24 am (6922)


PLZ,i will pay for it~anybody help me~
  • Author
  • Localization

aluigi, posted Sat Aug 29, 2015 10:53 am (6969)


It seems a chaotic format at a first look: no tables, no known file formats, sparse information.
  • Author
  • Localization

Ekey, posted Sat Aug 29, 2015 6:06 pm (7002)


This game using WindSoul Engine. Archives don't contains file names (only hashes) encrypted tables and data.
  • Author
  • Localization

Ekey, posted Mon Aug 31, 2015 1:59 pm (7055)


Header always 16 bytes and encrypted. Encryption is classical random seed xor. Here terrible code

Code:
static unsigned long pKey[3] = {
       0x00000000, 0xDEADBEEF, 0xBEEFDEAD};


Code:
int Decrypt_Core(int mKey, int pBuffer, int dwSize)
{
  int result;
  int mSize;
  char nResult;
  unsigned int dwSeed;

  result = pBuffer;
  mSize = dwSize - 1;
  if ( dwSize != 1 )
  {
    do
    {
      nResult = *(BYTE *)result;
      dwSeed = 0x343FD * *(DWORD *)(mKey 8) 0x269EC3;
      *(DWORD *)(mKey 8) = dwSeed;
      result;
      *(BYTE *)(result - 1) ^= *(BYTE *)(*(DWORD *)mKey mKey 4) (unsigned __int8)(dwSeed >> 16);
      *(BYTE *)(*(DWORD *)mKey mKey 4) = nResult;
      --mSize;
      *(DWORD *)mKey = ((unsigned __int8)*(DWORD *)mKey 1) & 3;
    }
    while ( mSize );
  }
  return result;
}


Decrypt header

Code:
Decrypt_Core((int)pKey, (int)pBuffer, 16);


Header after:

Code:
struct WDFHeader
{
   uint32_t   dwID; //PFDW
   uint32_t   dwUnknown; //Posible hash or version
   uint32_t   dwTotalFiles;
   uint32_t   dwTableOffset; //Note: Table also encrypted
};


Decrypt entry table

Code:
void DecryptTable(unsigned char *pScrBuffer, int dwSize)
{   DWORD dwBlockSize = 16;
    DWORD dwNext = 0;
    DWORD dwBlocks = dwSize / dwBlockSize;

    for (DWORD i = 0; i     {
        Decrypt_Core((int)pKey, (int)pScrBuffer dwNext, 16);
        dwNext = dwNext 16;
    }
}


Entry after

Code:
struct WDFEntry
{
   uint32_t   dwHash; //Hash of file name
   uint32_t   dwSize;
   uint32_t   dwOffset;
   uint32_t   dwNull;
};


Hash algorithm

Code:
int WindSoul_hash_v2(const char *mString, unsigned int dwLength, int dwFlag) {
    unsigned int dwStrSize = dwLength;
    unsigned int dwConstant0 = 0x9E3779B9;
    unsigned int dwConstant3 = dwConstant0;
    unsigned int dwHash;
    unsigned int dwSeed;
    dwSeed = dwLength;
    if (dwLength >= 12) {
        unsigned int dwConstant1 = 0xAAAA;
        unsigned int dwConstant2 = 0xAAAB;
        dwConstant1 *= dwLength;
        dwConstant2 *= dwLength;
        dwConstant2 >>= 0x10;
        dwConstant1 = dwConstant2;
        dwConstant1 >>= 0x13;
        unsigned int k = dwConstant1;
        p1:;
        dwHash = mString[7];
        dwSeed = mString[6];
        dwHash         dwHash = dwSeed;
        dwSeed = mString[5];
        dwHash         dwHash = dwSeed;
        dwSeed = mString[4];
        dwSeed = dwConstant0;
        dwHash         dwConstant0 = dwHash dwSeed;
        dwHash = mString[11];
        dwSeed = mString[10];
        dwHash         dwHash = dwSeed;
        dwSeed = mString[9];
        dwHash         dwHash = dwSeed;
        dwSeed = mString[8];
        dwSeed = dwFlag;
        dwHash         dwFlag = dwHash dwSeed;
        dwHash = mString[3];
        dwSeed = mString[2];
        dwHash         dwHash = dwSeed;
        dwSeed = mString[1];
        dwHash         dwHash = dwSeed;
        dwSeed = mString[0];
        dwHash         dwHash = dwSeed;
        dwHash -= dwFlag;
        dwHash -= dwConstant0;
        dwConstant0 -= dwFlag;
        dwSeed = dwFlag;
        dwSeed >>= 0x0D;
        dwHash = dwConstant3;
        dwHash ^= dwSeed;
        dwConstant0 -= dwHash;
        dwSeed = dwHash;
        dwSeed         dwConstant0 ^= dwSeed;
        dwFlag -= dwConstant0;
        dwFlag -= dwHash;
        dwSeed = dwConstant0;
        dwSeed >>= 0x0D;
        dwFlag ^= dwSeed;
        dwHash -= dwFlag;
        dwHash -= dwConstant0;
        dwSeed = dwFlag;
        dwSeed >>= 0x0C;
        dwHash ^= dwSeed;
        dwConstant0 -= dwFlag;
        dwConstant0 -= dwHash;
        dwSeed = dwHash;
        dwSeed         dwConstant0 ^= dwSeed;
        dwFlag -= dwConstant0;
        dwFlag -= dwHash;
        dwSeed = dwConstant0;
        dwSeed >>= 0x5;
        dwFlag ^= dwSeed;
        dwHash -= dwFlag;
        dwHash -= dwConstant0;
        dwSeed = dwFlag;
        dwSeed >>= 0x03;
        dwHash ^= dwSeed;
        dwConstant0 -= dwFlag;
        dwConstant3 = dwHash;
        dwConstant0 -= dwConstant3;
        dwHash         dwConstant0 ^= dwHash;
        dwFlag -= dwConstant0;
        dwSeed = dwConstant0;
        dwFlag -= dwConstant3;
        dwSeed >>= 0x0F;
        dwFlag ^= dwSeed;
        mString = 0x0C;
        dwLength -= 0x0C;
        k--;
        if (k != 0)
            goto p1;
        dwSeed = dwStrSize;
    }
    dwLength--;
    dwFlag = dwSeed;
    switch (dwLength) {
        case 10:
         dwHash = mString[10];
         dwHash          dwFlag = dwHash;
        case 9:
         dwSeed = mString[9];
         dwSeed          dwFlag = dwSeed;
        case 8:
         dwHash = mString[8];
         dwHash          dwFlag = dwHash;
        case 7:
         dwSeed = mString[7];
         dwSeed          dwConstant0 = dwSeed;
        case 6:
         dwHash = mString[6];
         dwHash          dwConstant0 = dwHash;
        case 5:
         dwSeed = mString[5];
         dwSeed          dwConstant0 = dwSeed;
        case 4:
         dwHash = mString[4];
         dwConstant0 = dwHash;
        case 3:
         dwSeed = mString[3];
         dwSeed          dwConstant3 = dwSeed;
        case 2:
         dwHash = mString[2];
         dwHash          dwConstant3 = dwHash;
        case 1:
         dwSeed = mString[1];
         dwSeed          dwConstant3 = dwSeed;
        case 0:
         dwHash = mString[0];
         dwConstant3 = dwHash;
        default:
         unsigned int c;
         dwConstant3 -= dwFlag;
         dwConstant3 -= dwConstant0;
         dwConstant0 -= dwFlag;
         c = dwFlag;
         c >>= 0x0D;
         dwConstant3 ^= c;
         dwConstant0 -= dwConstant3;
         dwSeed = dwConstant3;
         dwSeed          dwConstant0 ^= dwSeed;
         dwFlag -= dwConstant0;
         dwFlag -= dwConstant3;
         dwHash = dwConstant0;
         dwHash >>= 0x0D;
         dwFlag ^= dwHash;
         dwConstant3 -= dwFlag;
         dwConstant3 -= dwConstant0;
         dwConstant0 -= dwFlag;
         c = dwFlag;
         c >>= 0x0C;
         dwConstant3 ^= c;
         dwConstant0 -= dwConstant3;
         dwSeed = dwConstant3;
         dwSeed          dwConstant0 ^= dwSeed;
         dwFlag -= dwConstant0;
         dwHash = dwConstant0;
         dwFlag -= dwConstant3;
         dwHash >>= 0x05;
         dwFlag ^= dwHash;
         dwHash = dwFlag;
         dwConstant3 -= dwHash;
         dwConstant3 -= dwConstant0;
         c = dwHash;
         dwConstant0 -= dwHash;
         c >>= 0x03;
         dwConstant3 ^= c;
         dwConstant0 -= dwConstant3;
         dwSeed = dwConstant3;
         dwSeed          dwConstant0 ^= dwSeed;
         dwHash -= dwConstant0;
         dwHash -= dwConstant3;
         dwConstant0 >>= 0x0F;
         dwHash ^= dwConstant0;
    }
    return dwHash;
}


Example:

Code:
unsigned int dwHash = WindSoul_hash_v2("engine/excludewdf.csv", 21, 0);
printf("X\n", dwHash);


Code:
Name: engine/excludewdf.csv
Hash: 0x47333B24


It all what you need to know :). Files data in provided archives not encrypted also not compressed.
  • Author
  • Localization

Ekey, posted Mon Aug 31, 2015 6:59 pm (7058)


Anyway. Here my tool for unpack.

Image

Notes:
1) Hash function can't work with unicode strings (most file names with korean symbols -> ~90% of all)
2) No detecting types for unknown files

Thats all what i can do.

LOWUnpacker_v0.0.1.rar

  • Author
  • Localization

yianti, posted Tue Sep 01, 2015 3:18 am (7073)


thanks Ekey,
I try to rename the Unknown file to *.png *.dds...
I found these files can be look!
Can you help me to add these format?
thanks for you help! Plz give me you paypal ID!
thanks!!!
  • Author
  • Localization

Ekey, posted Tue Sep 01, 2015 9:18 am (7077)


yianti wrote:
thanks Ekey,
I try to rename the Unknown file to *.png *.dds...
I found these files can be look!

Use http://www.xnview.com/en/xnview/ . You can see all graphics files with this tool.
  • Author
  • Localization

yianti, posted Fri Sep 04, 2015 4:45 pm (7170)


Ekey wrote:
yianti wrote:
thanks Ekey,
I try to rename the Unknown file to *.png *.dds...
I found these files can be look!

Use http://www.xnview.com/en/xnview/ . You can see all graphics files with this tool.


thanks Ekey!! plz give me you paypal id! :)
  • Author
  • Localization

Ekey, posted Fri Sep 04, 2015 5:07 pm (7171)


yianti wrote:
thanks Ekey!! plz give me you paypal id! :)

Never mind. Just enjoy.
  • Author
  • Localization

howarduong, posted Sat Sep 10, 2022 5:34 am (73410)


aluigi wrote:
I made a script for supporting various versions of the Netease WDF format:
http://aluigi.org/bms/netease_wdf.bms

- GUI mode activated, remember that the tool works also from command-line
where are available various options like folder scanning, filters and so on

- select BMS script. type ? for using the content of clipboard like a script
- select input archives/files, type * for the whole folder and subfolders
- select output folder where extracting files
- open input file D:\Program Files (x86)\Netease\tx1.0.120\res\gui.wdf
- open script D:\Program Files (x86)\Netease\quickbms\bms\netease_wdf.bms
- set output folder D:\Program Files (x86)\Netease\tx1.0.120\res

offset filesize filename
--------------------------------------

Error: the requested amount of bytes to allocate is negative (0xffffffffc5e98997)

Last script line before the error or that produced the error:
66 log MEMORY_FILE OFFSET SIZE

- OFFSET 0x0000000044443444
- SIZE 0xffffffffc5e98997
coverage file 0 0% 16 170769883 . offset 0000000044443444
coverage file -1 0% 0 16 . offset 0000000000000010
coverage file -10 0% 0 906 . offset 0000000000000000

Press ENTER or close the window to quit



I loaded it to extract one of NetEase's games, which are all wdf packages and can't seem to recognize the offset.
game installation package https://mega.nz/file/lYs1AY6Y#6W7ygC1Ui ... cO194VQI3A
Its files are actually suffixed with these types
.cdata
.chunk
.model
.spt
.py
.pyc
.xml
.def
.bmp
.tga
.dds
.jpg
.visual
.mfm
.fx
.wav
.txt
.fdb
.fsb
.fev
.seq
.animation
.anca
.primitives
.gui
.texformat
.fx
.fxo
.fxh
.mfm
.trackers
.opt
.bwp
.texanim
.settings
.timestamps
.stc
.bsp2
.ctree
.ini
.font
Guest
This topic is now closed to further replies.

Account

Navigation

Search

Search

Configure browser push notifications

Chrome (Android)
  1. Tap the lock icon next to the address bar.
  2. Tap Permissions → Notifications.
  3. Adjust your preference.
Chrome (Desktop)
  1. Click the padlock icon in the address bar.
  2. Select Site settings.
  3. Find Notifications and adjust your preference.