I need some help with extracting DATA.BIN from monster hunter freedom unite (PSP), I've tried other ways but just wasn't successful.
Something that could help would be appreciated.
(PSP) Monster Hunter Freedom Unite DATA.BIN extract
-
- Posts: 7
- Joined: Sat May 28, 2016 10:19 pm
-
- Site Admin
- Posts: 12984
- Joined: Wed Jul 30, 2014 9:32 pm
Re: (PSP) Monster Hunter Freedom Unite DATA.BIN extract
Please provide DATA.BIN.
If it's very big you can upload the 2 files generated with this script:
http://aluigi.org/bms/filecutter.bms
If it's very big you can upload the 2 files generated with this script:
http://aluigi.org/bms/filecutter.bms
-
- Posts: 7
- Joined: Sat May 28, 2016 10:19 pm
-
- Site Admin
- Posts: 12984
- Joined: Wed Jul 30, 2014 9:32 pm
Re: (PSP) Monster Hunter Freedom Unite DATA.BIN extract
Completely encrypted. Can't help.
-
- Posts: 1383
- Joined: Sat Aug 09, 2014 2:34 pm
Re: (PSP) Monster Hunter Freedom Unite DATA.BIN extract
*Edited*
Seems it's :
https://github.com/codestation/mhtools/ ... ypter.java
https://github.com/codestation/mhtools/ ... aKeys.java
and
https://github.com/svanheulen/mhef/blob ... hef/psp.py
=======================
=======================
Converted
All data's crypted by offset
Seems it's :
https://github.com/codestation/mhtools/ ... ypter.java
https://github.com/codestation/mhtools/ ... aKeys.java
and
https://github.com/svanheulen/mhef/blob ... hef/psp.py
=======================
Code: Select all
void fun_884ea1c(struct s0* Buffer, int32_t Size) {
struct s0* s4_6;
unsigned char* s3_7;
unsigned char* s2_8;
unsigned char* s1_9;
int32_t i;
uint32_t v0_11;
int32_t Secret = 0;
s4_6 = Buffer;
s3_7 = &Buffer->f1;
s2_8 = &Buffer->f2;
s1_9 = &Buffer->f3;
if (Size > 0) {
i = 0;
while (1) {
s4_6->f0 = static_cast<unsigned char>(static_cast<uint32_t>(*reinterpret_cast<unsigned char*>(m_Key + s4_6->f0)));
*s3_7 = static_cast<unsigned char>(static_cast<uint32_t>(*reinterpret_cast<unsigned char*>(m_Key + *s3_7)));
*s2_8 = static_cast<unsigned char>(static_cast<uint32_t>(*reinterpret_cast<unsigned char*>(m_Key + *s2_8)));
*s1_9 = static_cast<unsigned char>(static_cast<uint32_t>(*reinterpret_cast<unsigned char*>(m_Key + *s1_9)));
v0_11 = fun_884ecac(Secret);
i = i + 4;
s3_7 = s3_7 + 4;
s4_6->f0 = reinterpret_cast<unsigned char>(s4_6->f0 ^ v0_11);
s2_8 = s2_8 + 4;
++s4_6;
if (i >= Size)
break;
s1_9 = s1_9 + 4;
}
}
return;
}
=======================
Converted
Code: Select all
unsigned char m_Encrypted_Table[256] =
{
0xCB, 0x96, 0x85, 0xA6, 0x5F, 0x3E, 0xAB, 0x03, 0x50, 0xB7, 0x9C, 0x5C, 0xB2, 0x40, 0xEF, 0xF6,
0xFF, 0x61, 0x15, 0x29, 0xA2, 0xF1, 0xEC, 0x52, 0x35, 0x28, 0xD9, 0x68, 0x24, 0x36, 0xC4, 0x74,
0x26, 0xE2, 0xD5, 0x8C, 0x47, 0x4D, 0x2C, 0xFA, 0x86, 0x66, 0xC1, 0x4F, 0x0B, 0x81, 0x5B, 0x1B,
0xC0, 0x0A, 0xFD, 0x17, 0xA4, 0xA9, 0x6D, 0x63, 0xAD, 0xF3, 0xF4, 0x6E, 0x8D, 0x89, 0x14, 0xDD,
0x59, 0x87, 0x4A, 0x30, 0xCE, 0xFE, 0x3F, 0x7E, 0x06, 0x49, 0xA5, 0x04, 0x5E, 0xD0, 0xDE, 0xE8,
0x0F, 0xD4, 0x13, 0x1F, 0xBA, 0xB9, 0x69, 0x71, 0x3D, 0xE4, 0xDC, 0x58, 0x90, 0x34, 0x3A, 0x3C,
0xCA, 0x10, 0x76, 0xC7, 0xC8, 0x45, 0x33, 0xC3, 0x92, 0x1D, 0x2B, 0x1C, 0x8F, 0x6F, 0x05, 0x07,
0x38, 0x57, 0x51, 0xD6, 0xDA, 0x2D, 0xB3, 0xC6, 0x2E, 0x64, 0x32, 0x1E, 0x43, 0xB1, 0x5D, 0xE1,
0xBB, 0x8E, 0x9D, 0x72, 0x77, 0xF2, 0x27, 0xC9, 0x7F, 0x9E, 0xAA, 0x6A, 0x2F, 0x6C, 0xF9, 0x48,
0xE7, 0xA0, 0x09, 0x56, 0xB8, 0xBD, 0x20, 0x41, 0xCD, 0x95, 0x80, 0xD7, 0x23, 0x0C, 0x42, 0xE5,
0xAE, 0x8B, 0x7D, 0xBC, 0x54, 0x39, 0xBF, 0x65, 0x01, 0x88, 0xE0, 0x7B, 0xB6, 0x16, 0x18, 0x4B,
0xCC, 0x22, 0x5A, 0xB5, 0xEB, 0xFC, 0xF8, 0x9B, 0x4E, 0xE6, 0xA8, 0xBE, 0x67, 0x73, 0x97, 0x94,
0x00, 0x62, 0xB4, 0xD2, 0x21, 0x25, 0x11, 0x82, 0xDB, 0x93, 0x02, 0x84, 0x7C, 0xD3, 0xB0, 0xA3,
0x91, 0xA7, 0xF7, 0x55, 0x70, 0x7A, 0x08, 0x75, 0x8A, 0x53, 0x79, 0xFB, 0x9F, 0x46, 0xF5, 0x83,
0xD8, 0x0E, 0xE9, 0xED, 0x12, 0xD1, 0xDF, 0xF0, 0x37, 0x2A, 0x44, 0x19, 0x9A, 0x31, 0xCF, 0xA1,
0xAF, 0xE3, 0x3B, 0x1A, 0x4C, 0x78, 0xC2, 0x60, 0xEE, 0x98, 0x6B, 0x0D, 0x99, 0xEA, 0xC5, 0xAC,
};
int dwKey1 = 0x00007F8D;
int dwKey2 = 0x00002345;
void set_key(int dwOffset)
{
dwKey1 = dwOffset & 0xFFFF;
if(dwKey1 == 0)
dwKey1 = 0x7F8D;
dwKey2 = dwOffset >> 16;
if(dwKey2 == 0)
dwKey2 = 0x2345;
}
int xor_by_key(void)
{
dwKey1 = (dwKey1 * 0x7F8D) % 0xFFF1;
dwKey2 = (dwKey2 * 0x2345) % 0xFFD9;
return dwKey1 + (dwKey2 << 16);
}
void iDecrypt(unsigned char *pBuffer, int dwSize)
{
for(int i = 0; i < dwSize; i += 4){
pBuffer[0] = m_Encrypted_Table[pBuffer[0]];
pBuffer[1] = m_Encrypted_Table[pBuffer[1]];
pBuffer[2] = m_Encrypted_Table[pBuffer[2]];
pBuffer[3] = m_Encrypted_Table[pBuffer[3]];
*(int*)pBuffer ^= xor_by_key();
pBuffer += 4;
}
}
All data's crypted by offset
-
- Site Admin
- Posts: 12984
- Joined: Wed Jul 30, 2014 9:32 pm
Re: (PSP) Monster Hunter Freedom Unite DATA.BIN extract
I see the header till 0x8170 but then?
Curiosity: MEMORY_FILE3 is a just function containing the code posted by Ekey with m_Encrypted_Table generated at runtime to avoid non-stack buffers and calling "set_key(offset); iDecrypt(data, datasz);"
Code: Select all
set MEMORY_FILE3 compressed "eNo91WegD3QYxfH/NYq6ureSlJTM7GggJOMp2bKyKRIKWckIccolqYRooUTDqhCKLvqSUUZZFRqyicqs++94483vc87L583vtMjY32rl+OGJRMsVu5KJRLPlUSSRGHk0PSWRGBe50N9ZyeQG9I+ZjE4bpS3ZjM44va+t6KxDx7Q4j8453Zt5Nh2dd/ooLXaiC07Z0b+mCfrPLEFZ5k2UNO1QIplMfoJSzH0omzmBspvTKIdJopx+O6PLzHXoclMS5TIzUW5zEl1hjqIrzUMo1dyF8pjb0FVmF0ozj6N0UxRdbe5G15g16FrTH+U1xdF15leUz/yArjcvovzmAXSDaYhuNGVQAePTbzLPo4LmMXSzyUS3mMaokLkS3WpGosKmLSpiCqCi5itUzFyBipv/UAlzPbrNvIdKmg9QKfMkKm0eRWXMXFTW/IXKmb9RedML3W7GowomA1U0edEd5md0p2mN7jIvoLtNPVTJ3I4qm29RFZOF7jE1UFXzLKpmLkPVzYPoXjML1TA50H2mA6ppNqNaZg+qbQ6iOiYNhfke3W+uRQ+YW1Bdsww9aJaieqY7qm+eQg1MddTQ/I4amZ9QY/MwamJeRk3Nneghcw9qZqqh5mY9amHSUUszELUya9HDZh1qbQK1MXegtmY1amdeRe1NQdTBlEYdzU2ok5mAOpve6BGTEz1qLkddTGXU1bRCj5mmqJvZjh43u1F3Uxb1MJ+ingb0hCmHnjRdUC9TEfU2N6M+pjZ6yixEfU171M/8gvqb5WiAeQkNNG+hp01fNMg8jZ4xp9BgUwINMd+goWY4GmbeRs+aD9Fw04MYUZ4Y+QTx3DliVF1i9AFC04nncxMvtCTGfE5kfEmMLUSMq0m8uIkYP4l4aQQxYQfxchHilVTi1VrExP3Ea/OISeOIycOIKV8QrzcnplYhpq0k3uhKvJlCvDWGeHsf8c4QYvpiYkY+YmZ+4t36xHsbiVmFiffbELMXEXOOEB/8S3x4lvjoDeLjRsTcP4h5c4j5K4gF3YiF/YhPphCfvkZ8liAWPUIs/oxYspX4/FZiaTFi2dXE8ueIL34kvpxIrMhGrBxNfDWUyNxGrFpArH6XWPMK8fVsgjPE2hbEuj7EN4OJ9bmIDQOIjWOJTc2Ib58hvrtAbH6H2HI/sfUfYtso4vudxA9XEdsPETuOETuvIXZtIXbvJX78c1zDVOKnSsTPpYg9dYi9NxD7phG/VCB+/Y74bQbx+3xi/2/EH1WJAzcSBxsQhwYRh1cRRzoRR48Tx14njvckTuQh/pxKnDxMnPqa+OvjjHWlI7VqpA/rmLY4ZezonBe/8DEpaYtrXio1L7Zsl1o2t+yXWvbuay/uwcqTnoOpZ5LdV4cXIWPH1DNZGZsztmXuS085WyFlVGaOI1NGrrk4E207dGy/+n/TxBkw"
savepos OFFSET
get SIZE asize
math SIZE - OFFSET
encryption calldll "MEMORY_FILE3 0 cdecl RET OFFSET #INPUT# #INPUT_SIZE#"
log "test.dat" OFFSET SIZE
Curiosity: MEMORY_FILE3 is a just function containing the code posted by Ekey with m_Encrypted_Table generated at runtime to avoid non-stack buffers and calling "set_key(offset); iDecrypt(data, datasz);"
-
- Posts: 1383
- Joined: Sat Aug 09, 2014 2:34 pm
Re: (PSP) Monster Hunter Freedom Unite DATA.BIN extract
aluigi wrote:I see the header till 0x8170 but then?
Yeah, it's index table.
based of python code we need read 4 bytes, decrypt it, result value * 2048 = index table size > 0x8800. I tryed and in index table last 0x690 bytes is invalid, just junk.
Code: Select all
def decrypt_file(self, data_file, out_file):
"""
Save a decrypted copy of the given DATA.BIN file.
Arguments:
data_file -- Path to an encrypted DATA.BIN file
out_file -- Path to save the decrypted DATA.BIN file
"""
with open(data_file, 'rb') as data, open(out_file, 'wb') as out:
# Decrypt the block address of the first file to determine the size
# of the table of contents
toc_size = self.decrypt(data.read(4), 0)
toc_size = array.array('I', toc_size)[0] * 2048
file_size = data.seek(0, os.SEEK_END)
data.seek(0)
# Decrypt the table of contents
toc = self.decrypt(data.read(toc_size), 0)
out.write(toc)
toc = array.array('I', toc)
# Find the number of files by getting the index of the table of
# contents entry pointing to the end of the file
file_count = toc.index(file_size // 2048)
# Decrypt each file in the data file
for i in range(file_count):
data.seek(toc[i] * 2048)
out.seek(toc[i] * 2048)
buff = data.read((toc[i+1] - toc[i]) * 2048)
# Skip decryption of certain files
if i in self._exceptions:
out.write(buff)
else:
out.write(self.decrypt(buff, toc[i]))
* Edited 2 *
From bin loader - decrypting two times:
First - with size 0x6808
Second - with size 0x1968
Code: Select all
li $a2, 0x6808
jal VFS_DECRYPT
Code: Select all
li $a2, 0x1968
jal VFS_DECRYPT
0x6808 + 0x1968 = 0x8170
Looks like there is two tables