Guest User

Untitled

a guest
Mar 1st, 2021
310
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 21.54 KB | None | 0 0
  1. #include <Windows.h>
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. #include <conio.h>
  5. #include <string.h>
  6.  
  7. #include "../Shared/StdLib.h"
  8. #include "../Shared/StringBuffer.h"
  9. #include "../Shared/String.h"
  10. #include "../Shared/Memory.h"
  11. #include "../Shared/Buffer.h"
  12.  
  13. #define LTC_SOURCE
  14. #define LTC_NO_PROTOTYPES
  15. #include <tomcrypt.h>
  16.  
  17. //#define NO_CRYPT
  18.  
  19. #ifndef NO_CRYPT
  20. //#define TEST_FILE L"C:\\Shaders.pak"
  21. #define TEST_FILE L"C:\\UI.pak"
  22. //#define TEST_FILEO L"C:\\UI.zip"
  23. #define TEST_FILEO L"D:\\C3\\UI.zip"
  24. #else //!NO_CRYPT
  25. #define TEST_FILE L"C:\\Engine.pak"
  26. #endif //NO_CRYPT
  27.  
  28. void SwapDWORDBuffer(DWORD* pBuffer, int SizeInDwords){
  29. DWORD* pEnd;
  30. DWORD temp;
  31. for (pEnd = pBuffer+SizeInDwords; pBuffer < pEnd; pBuffer++){
  32. temp = *pBuffer;
  33. *pBuffer = (temp >> 24) | (temp << 24) | ((temp & 0xFF00) << 8) | ((temp >> 8) & 0xFF00);
  34. }
  35. }
  36.  
  37. void XXTEA(DWORD* v, int n, DWORD k[4]){
  38. #define MX (((z>>5^y<<2) + (y>>3^z<<4)) ^ ((sum^y) + (k[(p&3)^e] ^ z)))
  39. #define DefaultXXTEA_Delta (0x9E3779B9)
  40. #define CrytekXXTEA_Delta (0x9E3779B9) //(0x61C88647)
  41. DWORD y, z, sum;
  42. unsigned p, rounds, e;
  43. if (n > 1) { /* Coding Part */
  44. rounds = 6 + 52/n;
  45. sum = 0;
  46. z = v[n-1];
  47. do {
  48. sum += CrytekXXTEA_Delta;
  49. e = (sum >> 2) & 3;
  50. for (p=0; p<(unsigned)n-1; p++) {
  51. y = v[p+1];
  52. z = v[p] += MX;
  53. }
  54. y = v[0];
  55. z = v[n-1] += MX;
  56. } while (--rounds);
  57. } else if (n < -1) { /* Decoding Part */
  58. n = -n;
  59. rounds = 6 + 52/n;
  60. sum = rounds*DefaultXXTEA_Delta;
  61. y = v[0];
  62. do {
  63. e = (sum >> 2) & 3;
  64. for (p=n-1; p>0; p--) {
  65. z = v[p-1];
  66. y = v[p] -= MX;
  67. }
  68. z = v[n-1];
  69. y = v[0] -= MX;
  70. } while ((sum -= CrytekXXTEA_Delta) != 0);
  71. }
  72. }
  73.  
  74. void XXTEADecrypt(void* pData, int size){
  75. DWORD key[4] = { 0xC968FB67, 0x8F9B4267, 0x85399E84, 0xF9B99DC4, };
  76. size /= 4; //Size in DWORDs
  77. SwapDWORDBuffer((DWORD*)pData, size);
  78. XXTEA((DWORD*)pData, -size, key);
  79. SwapDWORDBuffer((DWORD*)pData, size);
  80. }
  81.  
  82. void XXTEAEncrypt(void* pData, int size){
  83. DWORD key[4] = { 0xC968FB67, 0x8F9B4267, 0x85399E84, 0xF9B99DC4, };
  84. size /= 4; //Size in DWORDs
  85. SwapDWORDBuffer((DWORD*)pData, size);
  86. XXTEA((DWORD*)pData, size, key);
  87. SwapDWORDBuffer((DWORD*)pData, size);
  88. }
  89.  
  90.  
  91.  
  92. char *strndup(const char* _Src, int _MaxCount){
  93. char* pBuf;
  94. int slen;
  95. slen = strlen(_Src);
  96. if (slen < _MaxCount)
  97. return _strdup(_Src);
  98. if (!_Src || _MaxCount < 0 || !(pBuf = (char*)malloc(_MaxCount+1)))
  99. return NULL;
  100. memcpy(pBuf, _Src, _MaxCount);
  101. pBuf[_MaxCount] = 0;
  102. return pBuf;
  103. }
  104.  
  105. int GetPathTokenCount(const char *pPath){
  106. int result;
  107. bool had_char;
  108. result = 0;
  109. had_char = false;
  110. for (;;){
  111. switch (*pPath){
  112. case 0:
  113. case '/':
  114. case '\\':
  115. if (!had_char) break;
  116. result++;
  117. had_char = FALSE;
  118. break;
  119. default:
  120. had_char = TRUE;
  121. }
  122. if (*pPath == 0) break;
  123. pPath++;
  124. }
  125. return result;
  126. }
  127.  
  128. char *GetPathToken(const char *pPath, int *pLength, int token, bool copy){
  129. int len = 0;
  130. int count = 0;
  131. bool had_char, had_slash;
  132. had_char = had_slash = false;
  133. const char* pPtr;
  134. pPtr = pPath;
  135. for (;;){
  136. switch (*pPath){
  137. case 0:
  138. case '/':
  139. case '\\':
  140. had_slash = TRUE;
  141. if (!had_char) break;
  142. if (count++ == token){
  143. while (len && (pPtr[len-1] == ' '))
  144. len--;
  145.  
  146. if (pLength) *pLength = len;
  147. if (!copy) return (char*)pPtr;
  148.  
  149. return strndup(pPtr, len);
  150. }
  151. had_char = false;
  152. break;
  153. default:
  154. had_char = TRUE;
  155. len++;
  156. if (!had_slash) break;
  157. had_slash = FALSE;
  158. pPtr = pPath;
  159. len = 1;
  160. }
  161. if (*pPath == 0) break;
  162. pPath++;
  163. }
  164. return NULL;
  165. }
  166.  
  167. bool MakeDirFromFilename(char* pBuf, int buffsize, const char *pBaseDir, const char *pFilename, char** ppFilename){
  168. int count, i;
  169. char *pTemp;
  170. int l;
  171.  
  172. //Assume full path in pBuf if this is NULL
  173. if (pBaseDir){
  174. strcpy_s(pBuf, buffsize, pBaseDir);
  175. strcat_s(pBuf, buffsize, "\\");
  176. strcat_s(pBuf, buffsize, pFilename);
  177. }
  178.  
  179. count = GetPathTokenCount(pBuf);
  180.  
  181. if (count < 1 || count > 128) return false;
  182. if (ppFilename)
  183. *ppFilename = GetPathToken(pBuf, &l, count-1, false);
  184. if (count == 1) return true;
  185.  
  186. for (i = 0; i < count-1; i++){
  187. pTemp = GetPathToken(pBuf, &l, i, FALSE);
  188. *(pTemp+l) = 0;
  189. if (*(pBuf) && *(pBuf+1) == ':' && !*(pBuf+2)){
  190. *(pTemp+l) = '\\';
  191. continue;
  192. }
  193.  
  194. if ((!CreateDirectoryA(pBuf, NULL) && GetLastError() != ERROR_ALREADY_EXISTS)) return false;
  195. *(pTemp+l) = '\\';
  196. }
  197. return true;
  198. }
  199.  
  200.  
  201. CDynMemoryBuffer g_Src(8192);
  202. CDynMemoryBuffer g_Dest(8192);
  203.  
  204. #define ZIP_NUMKEYS 16
  205. #define ZIP_IV_SIZE 128
  206. #define ZIP_KEY_SIZE 128
  207. #define ZIP_SIG_SIZE 128
  208.  
  209. struct SEncryptionHeader{
  210. enum { SIZE = sizeof(UINT32)+sizeof(UINT8[ZIP_IV_SIZE]) + sizeof(UINT8[ZIP_KEY_SIZE][ZIP_NUMKEYS]) };
  211. UINT32 Size;
  212. UINT8 IV[ZIP_IV_SIZE];
  213. UINT8 Keys[ZIP_NUMKEYS][ZIP_KEY_SIZE];
  214. };
  215.  
  216. struct SExtensionHeader {
  217. enum { SIZE = sizeof(UINT32) + sizeof(UINT16) + sizeof(UINT16) };
  218. UINT32 Size;
  219. UINT16 EncryptionType;
  220. UINT16 SignatureType;
  221. };
  222.  
  223. struct SSignatureHeader {
  224. enum { SIZE = sizeof(UINT32)+sizeof(UINT8[ZIP_SIG_SIZE]) };
  225. UINT32 Size;
  226. UINT8 SignatureData[ZIP_SIG_SIZE];
  227. };
  228.  
  229. class ZipFile {
  230. public:
  231. #pragma pack(push, 1)
  232. struct CDREnd {
  233. DWORD lSignature; //04
  234. USHORT nDisk; //06
  235. USHORT nCDRStartDisk; //08
  236. USHORT numEntriesOnDisk; //0A
  237. USHORT numEntriesTotal; //0C
  238. DWORD lCDRSize; //10
  239. DWORD lCDROffset; //14
  240. USHORT nCommentLength; //16
  241. };
  242. struct DataDescriptor {
  243. UINT32 lCRC32;
  244. UINT32 lSizeCompressed;
  245. UINT32 lSizeUncompressed;
  246. };
  247. /*
  248. uint32 lSignature; // local file header signature 4 bytes (0x04034b50)
  249. uint16 nVersionNeeded; // version needed to extract 2 bytes
  250. uint16 nFlags; // general purpose bit flag 2 bytes
  251. uint16 nMethod; // compression method 2 bytes
  252. uint16 nLastModTime; // last mod file time 2 bytes
  253. uint16 nLastModDate; // last mod file date 2 bytes
  254. DataDescriptor desc;
  255. uint16 nFileNameLength; // file name length 2 bytes
  256. uint16 nExtraFieldLength; // extra field length 2 bytes
  257. */
  258. struct LocalFileHeader {
  259. UINT32 lSignature;
  260. UINT16 nVersionNeeded;
  261. UINT16 nFlags;
  262. UINT16 nMethod;
  263. UINT16 nLastModTime;
  264. UINT16 nLastModDate;
  265. DataDescriptor desc;
  266. UINT16 nFileNameLength;
  267. UINT16 nExtraFieldLength;
  268. };
  269.  
  270. struct CDRFileHeader {
  271. long lSignature;
  272. USHORT nVersionMadeBy;
  273. USHORT nVersionNeeded;
  274. USHORT nFlags;
  275. USHORT nMethod;
  276. USHORT nLastModTime;
  277. USHORT nLastModDate;
  278. DataDescriptor desc;
  279. USHORT nFileNameLength;
  280. USHORT nExtraFieldLength;
  281. USHORT nFileCommentLength;
  282. USHORT nDiskNumberStart;
  283. USHORT nAttrInternal;
  284. long lAttrExternal;
  285. long lLocalHeaderOffset;
  286. };
  287. #pragma pack(pop)
  288. };
  289.  
  290. struct FileEntry {
  291. ZipFile::DataDescriptor desc;
  292. UINT nFileDataOffset;
  293. UINT nFileHeaderOffset;
  294. UINT nNameOffset;
  295. USHORT nMethod;
  296. USHORT nReserved0;
  297. USHORT nLastModTime;
  298. USHORT nLastModDate;
  299. UINT64 nNTFS_LastModifyTime;
  300. UINT nEOFOffset;
  301. };
  302. struct SExtraZipFileData{
  303. UINT64 nLastModifyTime;
  304. };
  305.  
  306. enum
  307. {
  308. HeaderEncryption_None=0,
  309. HeaderEncryption_StreamCipher=1,
  310. HeaderEncryption_XXTEA=2,
  311. HeaderEncryption_Twofish=3,
  312. };
  313.  
  314. enum {
  315. HeaderSignature_None = 0,
  316. HeaderSignature_Signed = 1,
  317. };
  318.  
  319.  
  320. rsa_key g_RSAKey;
  321. prng_state g_Yarrow;
  322.  
  323. //Crysis 3 Encryption key
  324.  
  325. unsigned char g_RSAKeyData[162] = {
  326. 0x30, 0x81, 0x9F, 0x30, 0x0D, 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x01,
  327. 0x05, 0x00, 0x03, 0x81, 0x8D, 0x00, 0x30, 0x81, 0x89, 0x02, 0x81, 0x81, 0x00, 0xA9, 0xD5, 0x90,
  328. 0xA4, 0xBC, 0x92, 0xDB, 0x8C, 0xF1, 0xFC, 0x5A, 0xD5, 0x8F, 0x46, 0x05, 0x52, 0x16, 0xEE, 0xF3,
  329. 0xC3, 0xBE, 0x86, 0xDE, 0x70, 0x1F, 0x4E, 0x2D, 0x18, 0xD3, 0x01, 0x92, 0x46, 0xBE, 0xFA, 0xAD,
  330. 0x66, 0x04, 0x7B, 0x8C, 0xDD, 0x0D, 0x24, 0x8D, 0xA7, 0x23, 0xCA, 0x52, 0xC8, 0xE5, 0x01, 0xE0,
  331. 0xB7, 0x2B, 0xEB, 0x55, 0xCF, 0x0D, 0xF7, 0x97, 0x77, 0xDC, 0x11, 0xE8, 0x7B, 0x18, 0xCC, 0xDB,
  332. 0x90, 0x07, 0x2D, 0x9D, 0xC4, 0xAD, 0x80, 0x7C, 0x50, 0x23, 0x85, 0x46, 0xF3, 0xE9, 0x2C, 0x54,
  333. 0x81, 0x11, 0x7B, 0x6D, 0xE2, 0x57, 0x87, 0x8E, 0x65, 0xE1, 0xD3, 0x16, 0xC4, 0x54, 0xED, 0x29,
  334. 0xED, 0x51, 0xFD, 0xB1, 0xEF, 0xE4, 0x95, 0x01, 0x24, 0xAE, 0xC0, 0x6A, 0xFA, 0xE0, 0x5B, 0x19,
  335. 0xD2, 0xE6, 0xF0, 0x22, 0x3B, 0xC3, 0xE7, 0xDD, 0x17, 0x1A, 0x8C, 0xF8, 0xE1, 0x02, 0x03, 0x01,
  336. 0x00, 0x01
  337. };
  338.  
  339.  
  340. void InitCrypto(){
  341. ltc_mp = ltm_desc;
  342. register_hash(&sha1_desc);
  343. register_hash(&sha256_desc);
  344. register_cipher(&twofish_desc);
  345. register_prng(&yarrow_desc);
  346. rng_make_prng(128, find_prng("yarrow"), &g_Yarrow, NULL);
  347. rsa_import(g_RSAKeyData, sizeof(g_RSAKeyData), &g_RSAKey);
  348. }
  349.  
  350. int my_rsa_decrypt_key_ex(const unsigned char *in, unsigned long inlen,
  351. unsigned char *out, unsigned long *outlen,
  352. const unsigned char *lparam, unsigned long lparamlen,
  353. int hash_idx, int padding,
  354. int *stat, rsa_key *key)
  355. {
  356. unsigned long modulus_bitlen, modulus_bytelen, x;
  357. int err;
  358. unsigned char *tmp;
  359.  
  360. LTC_ARGCHK(out != NULL);
  361. LTC_ARGCHK(outlen != NULL);
  362. LTC_ARGCHK(key != NULL);
  363. LTC_ARGCHK(stat != NULL);
  364.  
  365. /* default to invalid */
  366. *stat = 0;
  367.  
  368. /* valid padding? */
  369.  
  370. if ((padding != LTC_LTC_PKCS_1_V1_5) &&
  371. (padding != LTC_LTC_PKCS_1_OAEP)) {
  372. return CRYPT_PK_INVALID_PADDING;
  373. }
  374.  
  375. if (padding == LTC_LTC_PKCS_1_OAEP) {
  376. /* valid hash ? */
  377. if ((err = hash_is_valid(hash_idx)) != CRYPT_OK) {
  378. return err;
  379. }
  380. }
  381.  
  382. /* get modulus len in bits */
  383. modulus_bitlen = mp_count_bits( (key->N));
  384.  
  385. /* outlen must be at least the size of the modulus */
  386. modulus_bytelen = mp_unsigned_bin_size( (key->N));
  387. if (modulus_bytelen != inlen) {
  388. return CRYPT_INVALID_PACKET;
  389. }
  390.  
  391. /* allocate ram */
  392. tmp = (unsigned char*)XMALLOC(inlen);
  393. if (tmp == NULL) {
  394. return CRYPT_MEM;
  395. }
  396.  
  397. /* rsa decode the packet */
  398. x = inlen;
  399. if ((err = ltc_mp.rsa_me(in, inlen, tmp, &x, PK_PUBLIC, key)) != CRYPT_OK) {
  400. XFREE(tmp);
  401. return err;
  402. }
  403.  
  404. if (padding == LTC_LTC_PKCS_1_OAEP) {
  405. /* now OAEP decode the packet */
  406. err = pkcs_1_oaep_decode(tmp, x, lparam, lparamlen, modulus_bitlen, hash_idx,
  407. out, outlen, stat);
  408. } else {
  409. /* now LTC_PKCS #1 v1.5 depad the packet */
  410. err = pkcs_1_v1_5_decode(tmp, x, LTC_LTC_PKCS_1_EME, modulus_bitlen, out, outlen, stat);
  411. }
  412.  
  413. XFREE(tmp);
  414. return err;
  415. }
  416.  
  417.  
  418. void MakeIV(ZipFile::DataDescriptor *desc, unsigned char* iv){
  419. DWORD* liv;
  420. liv = (DWORD*)iv;
  421. liv[0] = (desc->lSizeCompressed << 12) ^ desc->lSizeUncompressed;
  422. liv[1] = !desc->lSizeCompressed;
  423. liv[2] = (desc->lSizeCompressed << 12) ^ desc->lCRC32;
  424. liv[3] = desc->lSizeCompressed ^ (!desc->lSizeUncompressed);
  425. }
  426.  
  427. int GetKeyIndex(ZipFile::DataDescriptor* desc){
  428. return (~(desc->lCRC32 >> 2)) & 0xF;
  429. }
  430.  
  431. class CPakCryptography{
  432. private:
  433. bool InitTwofish(const void* key, const void* iv, symmetric_CTR* ctr, int padlen){
  434. int cipher;
  435. int d;
  436. unsigned char buf[1024];
  437. cipher = find_cipher("twofish");
  438. if (cipher < 0)
  439. return false;
  440. if (ctr_start(cipher, (unsigned char*)iv, (unsigned char*)key, 16, 0, CTR_COUNTER_LITTLE_ENDIAN, ctr) != CRYPT_OK)
  441. return false;
  442. for (;padlen > 0;){
  443. d = min(padlen, 1024);
  444. ctr_decrypt(buf, buf, d, ctr);
  445. padlen -= d;
  446. }
  447. return true;
  448. }
  449. bool DecryptTwofish(void* data, int len, const void* key, const void* iv){
  450. symmetric_CTR ctr;
  451. if (!InitTwofish(key, iv, &ctr, 0))
  452. return false;
  453. if (ctr_decrypt((unsigned char*)data, (unsigned char*)data, len, &ctr) != CRYPT_OK)
  454. return false;
  455. ctr_done(&ctr);
  456. return true;
  457. }
  458. public:
  459. UINT32 m_Mode;
  460. UINT8 IV[16];
  461. UINT8 Keys[ZIP_NUMKEYS][16];
  462. bool InitKeys(SEncryptionHeader &hdr){
  463. int hash, stat;
  464. int i;
  465. unsigned long outlen;
  466. unsigned char buf[1024];
  467. hash = find_hash("sha256");
  468. outlen = sizeof(buf);
  469. if (my_rsa_decrypt_key_ex(hdr.IV, 128, buf, &outlen, NULL, 0, hash, LTC_LTC_PKCS_1_OAEP, &stat, &g_RSAKey) != CRYPT_OK || stat != 1 || outlen != 16)
  470. return false;
  471. memcpy(IV, buf, 16);
  472. for (i = 0; i < ZIP_NUMKEYS; i++){
  473. outlen = sizeof(buf);
  474. if (my_rsa_decrypt_key_ex(hdr.Keys[i], 128, buf, &outlen, NULL, 0, hash, LTC_LTC_PKCS_1_OAEP, &stat, &g_RSAKey) != CRYPT_OK || stat != 1 || outlen != 16)
  475. return false;
  476. memcpy(Keys[i], buf, 16);
  477. }
  478. return true;
  479. }
  480. bool DecryptTFInternal(void* pData, int len, int key, unsigned char* iv){
  481. return DecryptTwofish(pData, len, Keys[key], iv);
  482. }
  483. bool Decrypt(void* pData, int len, int key){
  484. if (m_Mode == HeaderEncryption_Twofish)
  485. return DecryptTFInternal(pData, len, key, IV);
  486. else if (m_Mode == HeaderEncryption_XXTEA)
  487. return XXTEADecrypt(pData, len), true;
  488. else if (m_Mode == HeaderEncryption_StreamCipher)
  489. return false;
  490. else
  491. return true;
  492. }
  493. bool DecryptTF(void* pData, int len, ZipFile::DataDescriptor &desc){
  494. unsigned char iv[16];
  495. int key;
  496. key = GetKeyIndex(&desc);
  497. MakeIV(&desc, iv);
  498. return DecryptTFInternal(pData, len, key, iv);
  499. }
  500. };
  501.  
  502. void fcopy(FILE* src, FILE*dst, int count){
  503. char lBuf[1024];
  504. int r;
  505. for (;count > 0;){
  506. r = min(count, sizeof(lBuf));
  507. fread(lBuf, 1, r, src);
  508. fwrite(lBuf, 1, r, dst);
  509. count -= r;
  510. }
  511. }
  512.  
  513. CDynMemoryBuffer g_LocalHeaderBuffer(8192);
  514. CDynMemoryBuffer g_FileBuffer(8192*1024);
  515.  
  516. int SwitchMethod(int method){
  517. switch (method){
  518. default:
  519. return method;
  520. case 13:
  521. return 0;
  522. case 14:
  523. return 8;
  524. }
  525. }
  526.  
  527. bool ProcessCDR(file f, ZipFile::CDREnd* pCDRInfo, file fo, long cdrendoffset){
  528. char* pCDR;
  529. char* pEndOfData;
  530. char* pEndOfHeader;
  531. char* pEndOfRecord;
  532. int nlen, i, chr;
  533. int len;
  534. FileEntry entry;
  535. unsigned char iv[16];
  536. char buf[512];
  537. ZipFile::CDRFileHeader* pHdr;
  538. int encmode = pCDRInfo->nDisk >> 14;
  539. int sigmode;
  540. pCDRInfo->nDisk &= 0x3FFF;
  541. char fname[512];
  542. SExtraZipFileData extra;
  543. char* pCache;
  544. ZipFile::LocalFileHeader *lHdr;
  545. CPakCryptography cg;
  546.  
  547. SExtensionHeader ehdr;
  548. SEncryptionHeader chdr;
  549. SSignatureHeader shdr;
  550.  
  551. UINT32 esize;
  552.  
  553. sigmode = HeaderSignature_None;
  554. //fseek_(f, cdrendoffset+sizeof(ZipFile::CDREnd), SEEK_SET);
  555. //filecopy_(f, fo, buf, 512, pCDRInfo->nCommentLength);
  556.  
  557. if (pCDRInfo->nCommentLength >= SExtensionHeader::SIZE){
  558. esize = SExtensionHeader::SIZE;
  559. fseek_(f, pCDRInfo->lCDROffset+pCDRInfo->lCDRSize+sizeof(ZipFile::CDREnd), SEEK_SET);
  560. if (!fread_b(&ehdr, SExtensionHeader::SIZE, f))
  561. return false;
  562. if (ehdr.Size != SExtensionHeader::SIZE)
  563. return false; //Bad extended header
  564. if (ehdr.EncryptionType != HeaderEncryption_None && encmode != 0)
  565. return false; //Unexpected encryption technique in header
  566. encmode = ehdr.EncryptionType;
  567. if (encmode == 0){
  568. } else if (encmode == HeaderEncryption_Twofish){
  569. esize += SEncryptionHeader::SIZE;
  570. } else
  571. return false; //Bad encryption technique in header
  572. sigmode = ehdr.SignatureType;
  573. if (sigmode == HeaderSignature_None){
  574. } else if (sigmode == HeaderSignature_Signed){
  575. esize += SSignatureHeader::SIZE;
  576. } else
  577. return false; //Bad signing technique in header
  578.  
  579. if (pCDRInfo->nCommentLength != esize)
  580. return false; //Comment field is the wrong length
  581.  
  582. if (sigmode == HeaderSignature_Signed){
  583. if (!fread_b(&shdr, SSignatureHeader::SIZE, f))
  584. return false;
  585. if (shdr.Size != SSignatureHeader::SIZE)
  586. return false; //Bad signature header
  587. }
  588. if (encmode == HeaderEncryption_Twofish){
  589. if (!fread_b(&chdr, SEncryptionHeader::SIZE, f))
  590. return false;
  591. if (chdr.Size != SEncryptionHeader::SIZE)
  592. return false; //Bad signature header
  593. //Initialize keys
  594. cg.InitKeys(chdr);
  595. }
  596. }
  597. cg.m_Mode = encmode;
  598.  
  599. pCDRInfo->nCommentLength = 0;
  600. fseek_(fo, cdrendoffset, SEEK_SET);
  601. if (!fwrite_b(pCDRInfo, sizeof(ZipFile::CDREnd), fo))
  602. return false;
  603.  
  604. pCDR = NULL;
  605. pCache = NULL;
  606. pCDR = (char*)g_pAllocator(pCDRInfo->lCDRSize+16);
  607. if (!pCDR)
  608. return false;
  609. pCache = (char*)g_pAllocator(4096);
  610. if (!pCache)
  611. goto __failexit;
  612.  
  613. fseek_(f, pCDRInfo->lCDROffset, SEEK_SET);
  614. if (!fread_b(pCDR, pCDRInfo->lCDRSize, f))
  615. return false;
  616. if (!cg.Decrypt(pCDR, pCDRInfo->lCDRSize, 0))
  617. goto __failexit;
  618. fseek_(fo, pCDRInfo->lCDROffset, SEEK_SET);
  619. if (!fwrite_b(pCDR, pCDRInfo->lCDRSize, fo))
  620. return false;
  621. pEndOfHeader = pCDR+sizeof(ZipFile::CDRFileHeader);
  622. pEndOfData = pCDR+pCDRInfo->lCDRSize;
  623. pHdr = (ZipFile::CDRFileHeader*)pCDR;
  624.  
  625. for (;pEndOfHeader <= pEndOfData; pHdr = (ZipFile::CDRFileHeader*)pEndOfRecord, pEndOfHeader = pEndOfRecord+sizeof(ZipFile::CDRFileHeader)){
  626. if (pHdr->nVersionNeeded > 20){
  627. //Bad version
  628. goto __failexit;
  629. }
  630. pEndOfRecord = pEndOfHeader+pHdr->nExtraFieldLength+pHdr->nFileNameLength+pHdr->nFileCommentLength;
  631.  
  632. if (pEndOfRecord > pEndOfData)
  633. goto __failexit;
  634.  
  635. nlen = pHdr->nFileNameLength;
  636. //if (nlen < 1 || (*(nlen+pEndOfHeader-1) != '\\' && *(nlen+pEndOfHeader-1) != '/')){
  637. fseek_(f, pHdr->lLocalHeaderOffset, SEEK_SET);
  638. //long pos = ftell(f);
  639.  
  640. len = sizeof(ZipFile::LocalFileHeader)+pHdr->nFileNameLength+pHdr->nExtraFieldLength;//+pHdr->desc.lSizeCompressed;
  641. g_LocalHeaderBuffer.Alloc(len);
  642. if (!fread_b(g_LocalHeaderBuffer.GetPtr(), len+pHdr->nExtraFieldLength+pHdr->nFileCommentLength, f))
  643. goto __failexit;
  644. lHdr = (ZipFile::LocalFileHeader*)g_LocalHeaderBuffer.GetPtr();
  645. if (encmode != HeaderEncryption_None){
  646. lHdr->desc = pHdr->desc;
  647. lHdr->nFileNameLength = pHdr->nFileNameLength;
  648. lHdr->nFlags = 0;
  649. lHdr->lSignature = 0x04034b50;
  650. lHdr->nExtraFieldLength = 0;
  651. lHdr->nVersionNeeded = 20;
  652. lHdr->nLastModDate = pHdr->nLastModDate;
  653. lHdr->nLastModTime = pHdr->nLastModTime;
  654. lHdr->nMethod = SwitchMethod(pHdr->nMethod);
  655. memcpy(lHdr+1, pEndOfHeader, pHdr->nFileNameLength);
  656. }
  657. fseek_(fo, pHdr->lLocalHeaderOffset, SEEK_SET);
  658. if (!fwrite_b(g_LocalHeaderBuffer.GetPtr(), len+pHdr->nExtraFieldLength+pHdr->nFileCommentLength, fo))
  659. goto __failexit;
  660.  
  661. g_Src.Alloc(pHdr->desc.lSizeCompressed);
  662. fseek_(f, len+pHdr->lLocalHeaderOffset, 0);
  663. if (!fread_b(g_Src.GetPtr(), pHdr->desc.lSizeCompressed, f))
  664. goto __failexit;
  665. printf("File %.*s, method %d, local header @ %u, comment = %u, extra = %u, crc = %u, size = %u:%u\n", pHdr->nFileNameLength, pEndOfHeader, pHdr->nMethod, pHdr->lLocalHeaderOffset, pHdr->nFileCommentLength, pHdr->nExtraFieldLength, pHdr->desc.lCRC32, pHdr->desc.lSizeCompressed, pHdr->desc.lSizeUncompressed);
  666. if ((pHdr->nMethod == 13 || pHdr->nMethod == 14) && pHdr->desc.lSizeCompressed != 0)
  667. cg.DecryptTF(g_Src.GetPtr(), pHdr->desc.lSizeCompressed, pHdr->desc);
  668. pHdr->nMethod = SwitchMethod(pHdr->nMethod);
  669. fseek_(fo, len+pHdr->lLocalHeaderOffset, SEEK_SET);
  670. if (!fwrite_b(g_Src.GetPtr(), pHdr->desc.lSizeCompressed, fo))
  671. goto __failexit;
  672. //}
  673. }
  674. fseek_(fo, pCDRInfo->lCDROffset, SEEK_SET);
  675. if (!fwrite_b(pCDR, pCDRInfo->lCDRSize, fo))
  676. goto __failexit;
  677. if (pCDR)
  678. g_pFreeer(pCDR);
  679. if (pCache)
  680. g_pFreeer(pCache);
  681. return true;
  682. __failexit:
  683. if (pCDR)
  684. g_pFreeer(pCDR);
  685. if (pCache)
  686. g_pFreeer(pCache);
  687. return false;
  688.  
  689. }
  690.  
  691. #define PrintError(_fmt, ...) printf(_fmt, __VA_ARGS__)
  692. #define PrintInfo(_fmt, ...) printf(_fmt, __VA_ARGS__)
  693.  
  694. int main(int argc, char** argv){
  695. file f, fo;
  696. long size, oldoffset, end, offset;
  697. ZipFile::CDREnd CDREnd, TempCDR;
  698. TStringBufferA<MAX_PATH> buf;
  699. char* pBuffer;
  700. char* pWindow;
  701. int ni;
  702. char* pSignatures;
  703. InitCrypto();
  704. pBuffer = (char*)g_pAllocator(277);
  705. f = fo = NULL;
  706. long cdrendoffset;
  707.  
  708. CStringA fin, fout;
  709. if (argc < 2){
  710. printf("Usage: PakDecrypt.exe <input pak> [output zip]\nOutput zip defaults to inputpak.zip\n");
  711. return 0;
  712. }
  713. fin = argv[1];
  714. if (argc > 2)
  715. fout = argv[2];
  716. else {
  717. buf.Print("%s.zip", fin());
  718. fout = buf;
  719. }
  720. f = fopen_(fin, "r");
  721. fo = fopen_(fout, "w");
  722.  
  723.  
  724. if (f != INVALID_FILE && fo != INVALID_FILE){
  725. size = fsize_(f);
  726. CDREnd.lSignature = 0;
  727.  
  728. if (size >= sizeof(ZipFile::CDREnd)){
  729. end = size-sizeof(ZipFile::CDREnd);
  730. oldoffset = size;
  731. for (ni = 0;;ni++){
  732. pWindow = pBuffer;
  733. if (oldoffset > 256){
  734. offset = oldoffset-256;
  735. } else {
  736. pWindow = pBuffer-oldoffset+256;
  737. offset = 0;
  738. }
  739. if (size >= 0x10016){
  740. if (offset < (size-0x10015))
  741. offset = size-0x10015;
  742. }
  743. if (offset >= oldoffset)
  744. break;
  745. fseek_(f, offset, SEEK_SET);
  746. //left -= offset;
  747. fread_(pWindow, oldoffset-offset, f);
  748. if (end >= offset){
  749. pSignatures = pWindow-offset;
  750. do {
  751. if (*(DWORD*)(pSignatures+end) == 0x6054B50){
  752. //Do stuff here;
  753. memcpy(&TempCDR, pSignatures+end, sizeof(ZipFile::CDREnd));
  754. if (TempCDR.nCommentLength != (size-end-sizeof(ZipFile::CDREnd)))
  755. goto __fclose;
  756. memcpy(&CDREnd, pSignatures+end, sizeof(ZipFile::CDREnd));
  757. break;
  758. }
  759. end--;
  760. } while (end >= offset);
  761. }
  762. if (CDREnd.lSignature == 0x6054B50){
  763. cdrendoffset = end;
  764. goto __got_CDREnd;
  765. }
  766. oldoffset = offset;
  767. memmove(pBuffer+0x100, pWindow, 0x15);
  768. }
  769. }
  770. goto __fclose;
  771. __got_CDREnd:
  772. ProcessCDR(f, &CDREnd, fo, cdrendoffset);
  773. }
  774. __fclose:
  775. if (fo)
  776. fclose_(fo);
  777. if (f)
  778. fclose_(f);
  779. g_pFreeer(pBuffer);
  780. return 0;
  781. }
Advertisement
Add Comment
Please, Sign In to add comment