Skip to content

Instantly share code, notes, and snippets.

@balika011
Created December 12, 2019 09:47
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save balika011/336b348b43fe1d10140513d02dba3442 to your computer and use it in GitHub Desktop.
Save balika011/336b348b43fe1d10140513d02dba3442 to your computer and use it in GitHub Desktop.
PSX xosdmain decrypter and decompressor
#include <stdio.h>
#include <stdint.h>
#include <elf.h>
#include <string.h>
struct xorInfo
{
uint8_t *xor_table;
uint8_t *xor_ptr;
uint8_t *source;
};
uint8_t xorGetNextByte(xorInfo *info)
{
uint8_t ret = *info->xor_ptr;
info->xor_ptr = info->source == info->xor_ptr + 1 ? info->xor_table : info->xor_ptr + 1;
return ret;
}
void lzDecompress(uint8_t *dest, uint8_t *source, uint8_t *xor_table, uint32_t dest_size)
{
uint8_t *ptr = dest;
xorInfo info;
info.xor_table = xor_table;
info.xor_ptr = xor_table;
info.source = source;
uint32_t flag = 0, count = 0, mask = 0, shift = 0;
while(ptr - dest < dest_size)
{
if (count == 0)
{
count = 30;
flag = __builtin_bswap32(*(uint32_t *) source) ^ (xorGetNextByte(&info) << 24 | xorGetNextByte(&info) << 16 | xorGetNextByte(&info) << 8 | xorGetNextByte(&info));
source += 4;
mask = 0x3fff >> (flag & 3);
shift = 14 - (flag & 3);
}
if (flag & 0x80000000)
{
uint16_t off_size = __builtin_bswap16(*(uint16_t *) source) ^ (xorGetNextByte(&info) << 8 | xorGetNextByte(&info));
source += 2;
uint16_t offset = (off_size & mask) + 1;
for (uint16_t i = (off_size >> shift) + 3; i > 0; i--)
*(ptr++) = *(ptr - offset);
}
else
*(ptr++) = *(source++) ^ xorGetNextByte(&info);
count--;
flag <<= 1;
}
}
int main(int argc, char ** argv)
{
if (argc != 3)
{
printf("Usage: %s <OSDSYS> <output>\n", argv[0]);
return -1;
}
FILE *f = fopen(argv[1], "rb");
fseek(f, 0, SEEK_END);
int len = ftell(f);
fseek(f, 0, SEEK_SET);
uint8_t *buf = new uint8_t[len];
fread(buf, 1, len, f);
fclose(f);
uint8_t *data = buf + 0x380;
uint32_t uncompressed_len = *(uint32_t *) data;
uint8_t *xor_table = data + 0x10;
uint32_t xor_table_len = *(uint32_t *) (data + 8);
uint8_t *unpacked = new uint8_t[uncompressed_len];
lzDecompress(unpacked, &data[0x10 + xor_table_len], xor_table, uncompressed_len);
delete [] buf;
FILE *fo = fopen(argv[2], "wb");
fwrite(unpacked, 1, uncompressed_len, fo);
fclose(fo);
delete [] unpacked;
return 0;
}
@balika011
Copy link
Author

Similar to OSDSYS compression with an extra xor obfuscation.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment