Jump to content
Sign in to follow this  
Aceguy

Reading .dat files, is this possible

Recommended Posts

Bowmore

 Some application is probably is using it and has locked it. 

.dat files are usually plain text files or contain fixed length or delimited binary data depending on the application that created them

Some things you could try

  • Try opening it in read only mode
  • Try making a copy of the file and read that, if you don't need to work with a live version.
  • Close the application that is using the file.
Edited by Bowmore

"Programming today is a race between software engineers striving to build bigger and better idiot-proof programs, and the universe trying to build bigger and better idiots. So far, the universe is winning."- Rick Cook

Share this post


Link to post
Share on other sites
Aceguy

thanks for your replay...... i have tried lots of things, and did lots of internet seraches and game up with this.....

im not a programmer, so if anyone could shed some light on this i would be very greatfull.....

BTW.... the coder does give FULL permission to use the code...

Several of the FFXI DATs are "encrypted" using a simple per-byte bit rotation.

For some DATs (like item data) it's a fixed-size rotation, for others (like the ability and spell info), it's based on the data.

Note: all rotations are to the right.

The formula (shamelessly stolen from ffxitool, and I assume its author reverse-engineered it from FFXI itself) seems to depend on whether or not the data is text-only.

for text-only data (at least 2 bytes of data required) it's:

Code:

if (data[0] == 0 && data[1] == 0)
    return 0;
int seed = countbits(data[1]) - countbits(data[0]);
  switch (abs(seed) % 5) {
    case 0: return 1;
    case 1: return 7;
    case 2: return 2;
    case 3: return 6;
    case 4: return 3;
  }

and for all other data (at least 13 bytes of data required) it's:

Code:

int seed = countbits(data[2]) - countbits(data[11]) + countbits(data[12]);
  switch (abs(seed) % 5) {
    case 0: return 7;
    case 1: return 1;
    case 2: return 6;
    case 3: return 2;
    case 4: return 5;
  }

In both cases, countbit() is a function that returns the number of bits set in that byte.

As an example, say you have an ability data block that you want to decode. You'll need bytes 3, 12 and 13 from it - let's say they're 0x04, 0xCA and 0xD8. That means they are 00000100, 11001010 and 11011000 in binary, so they have 1, 4, and 4 bits set, respectively.

This means the 'seed' is 1 - 4 + 4 = 1, which leads to a rotation size of 1 - so to decrypt the ability block, you need to rotate each byte 1 bit to the right.

If someone can suggest a simpler calculation that returns the same result as these for both cases, please let me know ^^

I hereby also grant the permission to use my handler for this encryption from the PlayOnline.FFXI assembly. This includes permission to distribute that assembly with your own application, provided it is unmodified, and credit is clearly given.

To use, add a reference to that DLL to your own application. Once that's done, all that's needed is (for C#)

Code:

Code:

using PlayOnline.FFXI;

...
// For the fixed rotations:
FFXIEncryption.Rotate(foo, bits);
// For the variable rotations:
FFXIEncryption.DecodeDataBlock(foo);
FFXIEncryption.DecodeTextBlock(foo);
...

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this  

×