Advertisement
Xeeynamo

HCGE decrypter

Sep 17th, 2016
118
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 4.88 KB | None | 0 0
  1. #include <stdint.h>
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. #include <stdbool.h>
  5. #include <string.h>
  6. #include <direct.h>
  7.  
  8. FILE *fHcgData;
  9. unsigned int hcgKey;
  10. unsigned char hcgAkey[0x10];
  11. int hcgPosition2;
  12. int hcgPosition;
  13. uint8_t hcgRootFilesCount;
  14. int hcgEntryRootOff;
  15. int hcgEntryDirOff;
  16. int hcgEntryFilesOff;
  17.  
  18. unsigned short hcgeFillAkey() {
  19.   hcgKey = 0x41C64E6D * hcgKey + 12345;
  20.   return (hcgKey >> 16) & 0x7FFF;
  21. }
  22. uint8_t hcgeDecryptByte()
  23. {
  24.     uint8_t kpos = (hcgPosition ^ hcgAkey[((uint8_t)hcgPosition ^ (uint8_t)(hcgPosition >> 4)) & 0xF]) & 0xF;
  25.     char v1 = fgetc(fHcgData);
  26.     char v2 = hcgPosition++;
  27.     return hcgAkey[kpos] ^ v2 ^ v1;
  28. }
  29. uint8_t hcgeDecryptByte2() {
  30.     uint8_t kpos = (hcgPosition2 ^ hcgAkey[((uint8_t)hcgPosition2 ^ (uint8_t)((uint32_t)hcgPosition2 >> 4)) & 0xF]) & 0xF;
  31.     char v1 = fgetc(fHcgData);
  32.     char v2 = hcgPosition2++;
  33.     return hcgAkey[kpos] ^ v2 ^ v1;
  34. }
  35. bool hcgeOpenHcg(char *path) {
  36.     int i;
  37.  
  38.     FILE *f = fopen(path, "rb");
  39.     if (!f) return false;
  40.     fHcgData = f;
  41.  
  42.     fseek(f, -0x100C, SEEK_END);
  43.     hcgKey = fgetc(f) << 24;
  44.     fseek(f, 2, SEEK_CUR);
  45.     hcgKey += fgetc(f) << 16;
  46.     fseek(f, 2, SEEK_CUR);
  47.     hcgKey += fgetc(f) << 8;
  48.     fseek(f, 2, SEEK_CUR);
  49.     hcgKey += fgetc(f) << 0;
  50.  
  51.     for (i = 0; i < 0x10; i++) {
  52.         hcgAkey[i] = hcgeFillAkey();
  53.     }
  54.  
  55.     fseek(f, -0x100B, SEEK_END);
  56.     hcgPosition2 = ftell(f);
  57.     hcgEntryDirOff = hcgeDecryptByte2() << 24;
  58.     hcgEntryFilesOff = hcgeDecryptByte2() << 24;
  59.     fgetc(fHcgData);
  60.     hcgPosition2++;
  61.     hcgEntryDirOff += hcgeDecryptByte2() << 16;
  62.     hcgEntryFilesOff += hcgeDecryptByte2() << 16;
  63.     fgetc(fHcgData);
  64.     hcgPosition2++;
  65.     hcgEntryDirOff += hcgeDecryptByte2() << 8;
  66.     hcgEntryFilesOff += hcgeDecryptByte2() << 8;
  67.     fgetc(fHcgData);
  68.     hcgPosition2++;
  69.     hcgEntryDirOff += hcgeDecryptByte2();
  70.     hcgEntryFilesOff += hcgeDecryptByte2();
  71.     rewind(fHcgData);
  72.  
  73.     fseek(fHcgData, hcgEntryDirOff, SEEK_SET);
  74.     hcgPosition2 = hcgEntryDirOff;
  75.     hcgEntryRootOff = hcgeDecryptByte2() << 16;
  76.     hcgEntryRootOff += hcgeDecryptByte2() << 8;
  77.     hcgEntryRootOff += hcgeDecryptByte2();
  78.     hcgEntryRootOff += hcgEntryFilesOff;
  79.     hcgRootFilesCount = hcgeDecryptByte2();
  80.     return true;
  81. }
  82.  
  83. int Read2(uint8_t *data, int offset) {
  84.     return (data[offset + 0] << 8) | (data[offset + 1] << 8);
  85. }
  86. int Read3(uint8_t *data, int offset) {
  87.     return (data[offset + 0] << 16) | (data[offset + 1] << 8) | (data[offset + 2] << 0);
  88. }
  89. int Read4(uint8_t *data, int offset) {
  90.     return (data[offset + 0] << 24) | (data[offset + 1] << 16) | (data[offset + 2] << 8) | (data[offset + 3] << 0);
  91. }
  92. int main() {
  93.     char buf[0x100];
  94.     if (hcgeOpenHcg("game.hcg")) {
  95.         int i, j, len;
  96.         char buf[0x100];
  97.  
  98.         fseek(fHcgData, 0, SEEK_END);
  99.         len = ftell(fHcgData);
  100.         rewind(fHcgData);
  101.         hcgPosition = 0;
  102.  
  103.         uint8_t *dec = (uint8_t*)malloc(len);
  104.         for (i = 0; i < len; i++)
  105.             dec[i] = hcgeDecryptByte();
  106.         fclose(fHcgData);
  107.  
  108.         int dirsCount = dec[hcgEntryDirOff + 8];
  109.         int dirsOff = hcgEntryDirOff + 11;
  110.         for (i = 0; i < dirsCount; i++) {
  111.             int entryLen = dec[dirsOff];
  112.             char *strDirname = (char*)&dec[dirsOff + 1];
  113.             int strLen = strlen(strDirname);
  114.             int off = Read3(dec, dirsOff + strLen + 2);
  115.             int count = dec[dirsOff + strLen + 5];
  116.  
  117.             int filesOff = hcgEntryFilesOff + off;
  118.             _mkdir(strDirname);
  119.             for (j = 0; j < count; j++) {
  120.                 int fileEntryLen = dec[filesOff];
  121.                 char *strFilename = (char*)&dec[filesOff + 1];
  122.                 int strLen = strlen(strFilename);
  123.                 int off = Read4(dec, filesOff + strLen + 2);
  124.                 int len = Read3(dec, filesOff + strLen + 6);
  125.                 filesOff += fileEntryLen;
  126.  
  127.  
  128.                 sprintf(buf, "%s\\%s", strDirname, strFilename);
  129.                 printf("%s\n", buf);
  130.                 FILE *fOut = fopen(buf, "wb");
  131.                 if (fOut) {
  132.                     fwrite(dec + off, 1, len, fOut);
  133.                     fclose(fOut);
  134.                 }
  135.             }
  136.             dirsOff += entryLen;
  137.         }
  138.  
  139.         int rootOff = hcgEntryRootOff;
  140.         for (i = 0; i < hcgRootFilesCount; i++) {
  141.             int fileEntryLen = dec[rootOff];
  142.             char *strFilename = (char*)&dec[rootOff + 1];
  143.             int strLen = strlen(strFilename);
  144.             int off = Read4(dec, rootOff + strLen + 2);
  145.             int len = Read3(dec, rootOff + strLen + 6);
  146.             rootOff += fileEntryLen;
  147.  
  148.             printf("%s\n", strFilename);
  149.             FILE *fOut = fopen(strFilename, "wb");
  150.             if (fOut) {
  151.                 fwrite(dec + off, 1, len, fOut);
  152.                 fclose(fOut);
  153.             }
  154.         }
  155.         free(dec);
  156.     }
  157. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement