#include "pch.h" #include #include #include #include #include #include #include #include #include #pragma warning(disable:4996) #define __attribute__(A) #if _WIN32 unsigned int s32(unsigned int i) { return ((i >> 24) | (i << 24) | ((i & 0x00FF0000) >> 8) | ((i & 0x0000FF00) << 8)); } unsigned short s16(unsigned short s) { return (s >> 8) | (s << 8); } #else #include unsigned int s32(unsigned int i) { return ntohl(i); } unsigned int s16(unsigned short s) { return ntohs(s); } #endif #ifndef ATTRIBUTE_ALIGN # define ATTRIBUTE_ALIGN(v) __attribute__((aligned(v))) #endif #define CHARBITS12 11 #define CHARBITS9 9 #define CODESIZE12 (1<(src)); printf("dstSize: %i\n", dstSize); void* dstBuf = malloc(dstSize); Rvl_decode_ash(static_cast(dstBuf), static_cast(src)); return dstBuf; } static int Rvl_decode_ash_size(const unsigned char* s) { return (s[5] << 16) | (s[6] << 8) | s[7]; } /* Main ASH expansion*/ int Rvl_decode_ash(unsigned char *d, unsigned char *s) { int i, j, k, q, t, root9, root12; unsigned short *left9, *right9, *left12, *right12, *stack; t = (s[5] << 16) | (s[6] << 8) | s[7]; /* Expanded size */ k = (s[8] << 24) | (s[9] << 16) | (s[10] << 8) | s[11]; /* Flag information offset*/ /* Initialization */ wptr[0] = 12; wptr[1] = k; bitlen[0] = bitlen[1] = 0; ccnt[0] = CODESIZE9; ccnt[1] = CODESIZE12; left9 = (unsigned short *)work; right9 = left9 + (2 * CODESIZE9 - 1) * sizeof(short); left12 = right9 + (2 * CODESIZE9 - 1) * sizeof(short); right12 = left12 + (2 * CODESIZE12 - 1) * sizeof(short); stack = right12 + (2 * CODESIZE12 - 1) * sizeof(short); (void)getbitsc(s, 32, 0); (void)getbitsc(s, 32, 1); root9 = readtree9(s, left9, right9, stack); printf("root9: %i\n", root9); root12 = readtree12(s, left12, right12, stack); printf("root12: %i\n", root12); /* Expansion*/ for (q = 0; q < t;) { j = root9; while (j >= CODESIZE9) { j = (getbit1c(s, 0)) ? right9[j] : left9[j]; } if (j < 256) { d[q++] = (unsigned char)j; } else { i = root12; while (i >= CODESIZE12) { i = (getbit1c(s, 1)) ? right12[i] : left12[i]; } i = q - i - 1; /* Distance */ j -= 253; for (; j > 0; j--, q++, i++)d[q] = d[i]; } } return(q); } int getbitsc(unsigned char *s, int size, int f) { int k, m; unsigned i, j, g; k = wptr[f]; m = bitlen[f]; g = bitcode[f]; if (m + size > 32) { j = (unsigned)((s[k] << 24) | (s[k + 1] << 16) | (s[k + 2] << 8) | s[k + 3]); i = (g >> (32 - size)) | (j >> (64 - size - m)); m += size - 32; bitcode[f] = j << m; bitlen[f] = m; wptr[f] = k + 4; } else if (m + size == 32) { i = g >> (32 - size); bitcode[f] = (unsigned)((s[k] << 24) | (s[k + 1] << 16) | (s[k + 2] << 8) | s[k + 3]); wptr[f] = k + 4; bitlen[f] = 0; } else { i = g >> (32 - size); bitcode[f] = g << size; bitlen[f] = m + size; } return((int)i); } int getbit1c(unsigned char *s, int f) { int k, m; unsigned i, g; k = wptr[f]; m = bitlen[f]; g = bitcode[f]; i = g >> 31; if (m == 31) { bitcode[f] = (unsigned)((s[k] << 24) | (s[k + 1] << 16) | (s[k + 2] << 8) | s[k + 3]); wptr[f] = k + 4; bitlen[f] = 0; } else { bitcode[f] = g << 1; bitlen[f] = m + 1; } return((int)i); } int readtree9(unsigned char *s, unsigned short *left9, unsigned short *right9, unsigned short *stack) { int f, j, m, z, sp; for (j = m = ccnt[0], sp = 0;;) { if (getbit1c(s, 0)) { stack[sp] = (unsigned short)(0x8000 | j); stack[sp + 1] = (unsigned short)(0x4000 | j); j++; m++; sp += 2; if (sp >= TREESTACKSIZE) { // OS_Printf("stack over flow\n"); } } else { z = getbitsc(s, CHARBITS9, 0); while (1) { f = (int)stack[--sp]; if (f & 0x8000) { right9[f & 0x3FFF] = (unsigned short)z; z = f & 0x3FFF; if (sp == 0)return(z); } else { left9[f & 0x3FFF] = (unsigned short)z; j = m; break; } } } } } int readtree12(unsigned char *s, unsigned short *left12, unsigned short *right12, unsigned short *stack) { int f, j, m, z, sp; for (j = m = ccnt[1], sp = 0;;) { if (getbit1c(s, 1)) { //if (sp < 100) printf("sp: %i, j: %i\n", sp, 0x8000 | j); stack[sp] = (unsigned short)(0x8000 | j); stack[sp + 1] = (unsigned short)(0x4000 | j); j++; m++; sp += 2; if (sp >= TREESTACKSIZE) { //printf("stack over flow\n"); } } else { z = getbitsc(s, CHARBITS12, 1); while (1) { f = (int)stack[--sp]; if (f & 0x8000) { right12[f & 0x3FFF] = (unsigned short)z; z = f & 0x3FFF; if (sp == 0)return(z); } else { left12[f & 0x3FFF] = (unsigned short)z; j = m; break; } } } } } std::vector readFile(std::string filename) { std::ifstream file(filename, std::ios::binary); file.unsetf(std::ios::skipws); std::streampos fileSize; file.seekg(0, std::ios::end); fileSize = file.tellg(); file.seekg(0, std::ios::beg); std::vector vec; vec.reserve(fileSize); vec.insert(vec.begin(), std::istream_iterator(file), std::istream_iterator()); return vec; } int main() { std::cout << "Hello World!\n"; std::string filePath = "C:/Users/User/source/repos/ConsoleApplication7/Debug/mii.ash"; std::vector buffer = readFile(filePath); void* out = DecompAsh(buffer.data()); int size = Rvl_decode_ash_size(static_cast(buffer.data())); std::FILE* file = std::fopen("C:/Users/User/source/repos/ConsoleApplication7/Debug/course.arc", "wb"); size_t numWritten = std::fwrite(out, 1, size * sizeof(uint8_t), file); std::fclose(file); std::cout << "Success!" << std::endl; }