rgssad bms script
Posted: Thu Jun 07, 2012 3:30 am
Here's an extraction algorithm written in C++
http://pastebin.com/g9utQpC9
Is there a nice way to write a bms script for this?
The problem I'm having is working with the xor key and the performance implications of using a loop to perform the xor, math, and putting the data somewhere.
It is like incremental XOR where you XOR each byte with a new byte, except instead of just increasing by 1, it's increasing like
For example, reading a filename is done like
And reading the file data is done like
If I went ahead and started using a for loop, it would get really slow.
It looks like the key used to grab the file table is different from the key for each individual file (hence the reason why the key is saved for each file data entry)
Here is a simple archive that I put together myself for testing purposes:
http://db.tt/BBfrxkXI
Here is my shot at it. I've gotten the filenames out (really ugly code to try to reproduce what is being done), but the data looks even messier...
Also, how do I initialize a string to be the empty string? You can see that I set the name as "_" but that's only cause I don't know how to make it an empty string lol
Upon extracting my archive, you should get the following files...without the leading underscore
http://pastebin.com/g9utQpC9
Is there a nice way to write a bms script for this?
The problem I'm having is working with the xor key and the performance implications of using a loop to perform the xor, math, and putting the data somewhere.
It is like incremental XOR where you XOR each byte with a new byte, except instead of just increasing by 1, it's increasing like
Code: Select all
magickey = magickey * 7 + 3;
Code: Select all
for(unsigned long i = 0; i < tmpInfo.filenamesize; i++)
{
tmpInfo.filename[i] ^= magickey & 0xFF;
magickey = magickey * 7 + 3;
}
Code: Select all
while(leftsize > 1023)
{
rgssad_file.Read(buf, 1024);
for(j = 0; j < 1024; j+=4)
{
*(unsigned long *)(&buf[j]) ^= magickey;
magickey = magickey * 7 + 3;
}
sp_file.Write(buf, 1024);
leftsize -= 1024;
}
for(j = 0; j < leftsize; j+=4)
{
*(unsigned long *)(&buf[j]) ^= magickey;
magickey = magickey * 7 + 3;
}
It looks like the key used to grab the file table is different from the key for each individual file (hence the reason why the key is saved for each file data entry)
Here is a simple archive that I put together myself for testing purposes:
http://db.tt/BBfrxkXI
Here is my shot at it. I've gotten the filenames out (really ugly code to try to reproduce what is being done), but the data looks even messier...
Code: Select all
#RGSSAD extractor
idstring "RGSSAD\x00"
get VERSION byte
print "Version %VERSION%"
#set the key
set key = 0xDEADCAFE
#set eof
get EOF asize
# start looping
savepos OFFSET
do
string name = ''
get len long
math len ^= key
math key *= 7
math key += 3
for j = 0 < len
get char byte
math charkey = key
math charkey &= 0xFF
math char ^= charkey
math key *= 7
math key += 3
string new = char
string name += new
next j
print "%name%"
get SIZE long
math SIZE ^= key
math key *= 7
math key += 3
#read data
getdstring DATA SIZE
savepos OFFSET
while OFFSET < EOF
Upon extracting my archive, you should get the following files...without the leading underscore
Code: Select all
_Data\Actors.rxdata
_Data\Animations.rxdata
_Data\Armors.rxdata
_Data\Classes.rxdata
_Data\CommonEvents.rxdata
_Data\Enemies.rxdata
_Data\Items.rxdata
_Data\Map001.rxdata
_Data\MapInfos.rxdata
_Data\Scripts.rxdata
_Data\Skills.rxdata
_Data\States.rxdata
_Data\System.rxdata
_Data\Tilesets.rxdata
_Data\Troops.rxdata
_Data\Weapons.rxdata
_Graphics\Pictures\levels1.jpg