Here is some code to decompress compressed DS ARM9 binaries. I've had this bit of code sitting around for a while. Use it to make me some hook finders
sourceData should point to the start of the ARM9 binary and headerBottom should be the size of it. The compressed data "header" is actually a trailer, as the data is decompressed from the tail to the head, in place in memory.
Code:
unsigned int get_decompressed_data_size (const unsigned char* sourceData, unsigned int headerBottom) {
unsigned int decompressedLength;
decompressedLength = (((unsigned int*)sourceData)[headerBottom / 4 - 1]) + headerBottom;
return decompressedLength;
}
void decompress_ARM9_binary (const unsigned char* sourceData, unsigned int headerBottom, unsigned char* destData) {
int srcPos, destPos;
int controlByte;
int runsLeft;
unsigned int srcLength, destLength;
int srcStart;
srcLength = ((unsigned int*)sourceData)[headerBottom / 4 - 2];
destLength = (((unsigned int*)sourceData)[headerBottom / 4 - 1]) + headerBottom;
srcPos = headerBottom - (srcLength >> 24);
destPos = destLength;
srcStart = headerBottom - (srcLength & 0x00FFFFFF);
while (srcPos > srcStart) {
controlByte = sourceData[--srcPos];
for (runsLeft = 0x08; (runsLeft > 0) && (srcPos >= 0) && (destPos >=0); --runsLeft) {
if (controlByte & 0x80) {
// copy data run from decompressed buffer
int runRepeats, runLength;
unsigned char temp;
runRepeats = sourceData[--srcPos];
runLength = ((sourceData[--srcPos] | (runRepeats << 8)) & 0x0fff) + 0x02;
runRepeats = (runRepeats >> 4) + 0x2;
for ( ; runRepeats >= 0; runRepeats-= 0x1) {
temp = destData[destPos + runLength];
destData[--destPos] = temp;
}
} else {
// copy byte from source compressed data
destData[--destPos] = sourceData[--srcPos];
}
controlByte = controlByte << 1;
}
}
while ((srcPos >= 0) && (destPos >= 0)) {
destData[--destPos] = sourceData[--srcPos];
}
}