Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <Windows.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <conio.h>
- #include <string.h>
- #include "../Shared/StdLib.h"
- #include "../Shared/StringBuffer.h"
- #include "../Shared/String.h"
- #include "../Shared/Memory.h"
- #include "../Shared/Buffer.h"
- #define LTC_SOURCE
- #define LTC_NO_PROTOTYPES
- #include <tomcrypt.h>
- //#define NO_CRYPT
- #ifndef NO_CRYPT
- //#define TEST_FILE L"C:\\Shaders.pak"
- #define TEST_FILE L"C:\\UI.pak"
- //#define TEST_FILEO L"C:\\UI.zip"
- #define TEST_FILEO L"D:\\C3\\UI.zip"
- #else //!NO_CRYPT
- #define TEST_FILE L"C:\\Engine.pak"
- #endif //NO_CRYPT
- void SwapDWORDBuffer(DWORD* pBuffer, int SizeInDwords){
- DWORD* pEnd;
- DWORD temp;
- for (pEnd = pBuffer+SizeInDwords; pBuffer < pEnd; pBuffer++){
- temp = *pBuffer;
- *pBuffer = (temp >> 24) | (temp << 24) | ((temp & 0xFF00) << 8) | ((temp >> 8) & 0xFF00);
- }
- }
- void XXTEA(DWORD* v, int n, DWORD k[4]){
- #define MX (((z>>5^y<<2) + (y>>3^z<<4)) ^ ((sum^y) + (k[(p&3)^e] ^ z)))
- #define DefaultXXTEA_Delta (0x9E3779B9)
- #define CrytekXXTEA_Delta (0x9E3779B9) //(0x61C88647)
- DWORD y, z, sum;
- unsigned p, rounds, e;
- if (n > 1) { /* Coding Part */
- rounds = 6 + 52/n;
- sum = 0;
- z = v[n-1];
- do {
- sum += CrytekXXTEA_Delta;
- e = (sum >> 2) & 3;
- for (p=0; p<(unsigned)n-1; p++) {
- y = v[p+1];
- z = v[p] += MX;
- }
- y = v[0];
- z = v[n-1] += MX;
- } while (--rounds);
- } else if (n < -1) { /* Decoding Part */
- n = -n;
- rounds = 6 + 52/n;
- sum = rounds*DefaultXXTEA_Delta;
- y = v[0];
- do {
- e = (sum >> 2) & 3;
- for (p=n-1; p>0; p--) {
- z = v[p-1];
- y = v[p] -= MX;
- }
- z = v[n-1];
- y = v[0] -= MX;
- } while ((sum -= CrytekXXTEA_Delta) != 0);
- }
- }
- void XXTEADecrypt(void* pData, int size){
- DWORD key[4] = { 0xC968FB67, 0x8F9B4267, 0x85399E84, 0xF9B99DC4, };
- size /= 4; //Size in DWORDs
- SwapDWORDBuffer((DWORD*)pData, size);
- XXTEA((DWORD*)pData, -size, key);
- SwapDWORDBuffer((DWORD*)pData, size);
- }
- void XXTEAEncrypt(void* pData, int size){
- DWORD key[4] = { 0xC968FB67, 0x8F9B4267, 0x85399E84, 0xF9B99DC4, };
- size /= 4; //Size in DWORDs
- SwapDWORDBuffer((DWORD*)pData, size);
- XXTEA((DWORD*)pData, size, key);
- SwapDWORDBuffer((DWORD*)pData, size);
- }
- char *strndup(const char* _Src, int _MaxCount){
- char* pBuf;
- int slen;
- slen = strlen(_Src);
- if (slen < _MaxCount)
- return _strdup(_Src);
- if (!_Src || _MaxCount < 0 || !(pBuf = (char*)malloc(_MaxCount+1)))
- return NULL;
- memcpy(pBuf, _Src, _MaxCount);
- pBuf[_MaxCount] = 0;
- return pBuf;
- }
- int GetPathTokenCount(const char *pPath){
- int result;
- bool had_char;
- result = 0;
- had_char = false;
- for (;;){
- switch (*pPath){
- case 0:
- case '/':
- case '\\':
- if (!had_char) break;
- result++;
- had_char = FALSE;
- break;
- default:
- had_char = TRUE;
- }
- if (*pPath == 0) break;
- pPath++;
- }
- return result;
- }
- char *GetPathToken(const char *pPath, int *pLength, int token, bool copy){
- int len = 0;
- int count = 0;
- bool had_char, had_slash;
- had_char = had_slash = false;
- const char* pPtr;
- pPtr = pPath;
- for (;;){
- switch (*pPath){
- case 0:
- case '/':
- case '\\':
- had_slash = TRUE;
- if (!had_char) break;
- if (count++ == token){
- while (len && (pPtr[len-1] == ' '))
- len--;
- if (pLength) *pLength = len;
- if (!copy) return (char*)pPtr;
- return strndup(pPtr, len);
- }
- had_char = false;
- break;
- default:
- had_char = TRUE;
- len++;
- if (!had_slash) break;
- had_slash = FALSE;
- pPtr = pPath;
- len = 1;
- }
- if (*pPath == 0) break;
- pPath++;
- }
- return NULL;
- }
- bool MakeDirFromFilename(char* pBuf, int buffsize, const char *pBaseDir, const char *pFilename, char** ppFilename){
- int count, i;
- char *pTemp;
- int l;
- //Assume full path in pBuf if this is NULL
- if (pBaseDir){
- strcpy_s(pBuf, buffsize, pBaseDir);
- strcat_s(pBuf, buffsize, "\\");
- strcat_s(pBuf, buffsize, pFilename);
- }
- count = GetPathTokenCount(pBuf);
- if (count < 1 || count > 128) return false;
- if (ppFilename)
- *ppFilename = GetPathToken(pBuf, &l, count-1, false);
- if (count == 1) return true;
- for (i = 0; i < count-1; i++){
- pTemp = GetPathToken(pBuf, &l, i, FALSE);
- *(pTemp+l) = 0;
- if (*(pBuf) && *(pBuf+1) == ':' && !*(pBuf+2)){
- *(pTemp+l) = '\\';
- continue;
- }
- if ((!CreateDirectoryA(pBuf, NULL) && GetLastError() != ERROR_ALREADY_EXISTS)) return false;
- *(pTemp+l) = '\\';
- }
- return true;
- }
- CDynMemoryBuffer g_Src(8192);
- CDynMemoryBuffer g_Dest(8192);
- #define ZIP_NUMKEYS 16
- #define ZIP_IV_SIZE 128
- #define ZIP_KEY_SIZE 128
- #define ZIP_SIG_SIZE 128
- struct SEncryptionHeader{
- enum { SIZE = sizeof(UINT32)+sizeof(UINT8[ZIP_IV_SIZE]) + sizeof(UINT8[ZIP_KEY_SIZE][ZIP_NUMKEYS]) };
- UINT32 Size;
- UINT8 IV[ZIP_IV_SIZE];
- UINT8 Keys[ZIP_NUMKEYS][ZIP_KEY_SIZE];
- };
- struct SExtensionHeader {
- enum { SIZE = sizeof(UINT32) + sizeof(UINT16) + sizeof(UINT16) };
- UINT32 Size;
- UINT16 EncryptionType;
- UINT16 SignatureType;
- };
- struct SSignatureHeader {
- enum { SIZE = sizeof(UINT32)+sizeof(UINT8[ZIP_SIG_SIZE]) };
- UINT32 Size;
- UINT8 SignatureData[ZIP_SIG_SIZE];
- };
- class ZipFile {
- public:
- #pragma pack(push, 1)
- struct CDREnd {
- DWORD lSignature; //04
- USHORT nDisk; //06
- USHORT nCDRStartDisk; //08
- USHORT numEntriesOnDisk; //0A
- USHORT numEntriesTotal; //0C
- DWORD lCDRSize; //10
- DWORD lCDROffset; //14
- USHORT nCommentLength; //16
- };
- struct DataDescriptor {
- UINT32 lCRC32;
- UINT32 lSizeCompressed;
- UINT32 lSizeUncompressed;
- };
- /*
- uint32 lSignature; // local file header signature 4 bytes (0x04034b50)
- uint16 nVersionNeeded; // version needed to extract 2 bytes
- uint16 nFlags; // general purpose bit flag 2 bytes
- uint16 nMethod; // compression method 2 bytes
- uint16 nLastModTime; // last mod file time 2 bytes
- uint16 nLastModDate; // last mod file date 2 bytes
- DataDescriptor desc;
- uint16 nFileNameLength; // file name length 2 bytes
- uint16 nExtraFieldLength; // extra field length 2 bytes
- */
- struct LocalFileHeader {
- UINT32 lSignature;
- UINT16 nVersionNeeded;
- UINT16 nFlags;
- UINT16 nMethod;
- UINT16 nLastModTime;
- UINT16 nLastModDate;
- DataDescriptor desc;
- UINT16 nFileNameLength;
- UINT16 nExtraFieldLength;
- };
- struct CDRFileHeader {
- long lSignature;
- USHORT nVersionMadeBy;
- USHORT nVersionNeeded;
- USHORT nFlags;
- USHORT nMethod;
- USHORT nLastModTime;
- USHORT nLastModDate;
- DataDescriptor desc;
- USHORT nFileNameLength;
- USHORT nExtraFieldLength;
- USHORT nFileCommentLength;
- USHORT nDiskNumberStart;
- USHORT nAttrInternal;
- long lAttrExternal;
- long lLocalHeaderOffset;
- };
- #pragma pack(pop)
- };
- struct FileEntry {
- ZipFile::DataDescriptor desc;
- UINT nFileDataOffset;
- UINT nFileHeaderOffset;
- UINT nNameOffset;
- USHORT nMethod;
- USHORT nReserved0;
- USHORT nLastModTime;
- USHORT nLastModDate;
- UINT64 nNTFS_LastModifyTime;
- UINT nEOFOffset;
- };
- struct SExtraZipFileData{
- UINT64 nLastModifyTime;
- };
- enum
- {
- HeaderEncryption_None=0,
- HeaderEncryption_StreamCipher=1,
- HeaderEncryption_XXTEA=2,
- HeaderEncryption_Twofish=3,
- };
- enum {
- HeaderSignature_None = 0,
- HeaderSignature_Signed = 1,
- };
- rsa_key g_RSAKey;
- prng_state g_Yarrow;
- //Crysis 3 Encryption key
- unsigned char g_RSAKeyData[162] = {
- 0x30, 0x81, 0x9F, 0x30, 0x0D, 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x01,
- 0x05, 0x00, 0x03, 0x81, 0x8D, 0x00, 0x30, 0x81, 0x89, 0x02, 0x81, 0x81, 0x00, 0xA9, 0xD5, 0x90,
- 0xA4, 0xBC, 0x92, 0xDB, 0x8C, 0xF1, 0xFC, 0x5A, 0xD5, 0x8F, 0x46, 0x05, 0x52, 0x16, 0xEE, 0xF3,
- 0xC3, 0xBE, 0x86, 0xDE, 0x70, 0x1F, 0x4E, 0x2D, 0x18, 0xD3, 0x01, 0x92, 0x46, 0xBE, 0xFA, 0xAD,
- 0x66, 0x04, 0x7B, 0x8C, 0xDD, 0x0D, 0x24, 0x8D, 0xA7, 0x23, 0xCA, 0x52, 0xC8, 0xE5, 0x01, 0xE0,
- 0xB7, 0x2B, 0xEB, 0x55, 0xCF, 0x0D, 0xF7, 0x97, 0x77, 0xDC, 0x11, 0xE8, 0x7B, 0x18, 0xCC, 0xDB,
- 0x90, 0x07, 0x2D, 0x9D, 0xC4, 0xAD, 0x80, 0x7C, 0x50, 0x23, 0x85, 0x46, 0xF3, 0xE9, 0x2C, 0x54,
- 0x81, 0x11, 0x7B, 0x6D, 0xE2, 0x57, 0x87, 0x8E, 0x65, 0xE1, 0xD3, 0x16, 0xC4, 0x54, 0xED, 0x29,
- 0xED, 0x51, 0xFD, 0xB1, 0xEF, 0xE4, 0x95, 0x01, 0x24, 0xAE, 0xC0, 0x6A, 0xFA, 0xE0, 0x5B, 0x19,
- 0xD2, 0xE6, 0xF0, 0x22, 0x3B, 0xC3, 0xE7, 0xDD, 0x17, 0x1A, 0x8C, 0xF8, 0xE1, 0x02, 0x03, 0x01,
- 0x00, 0x01
- };
- void InitCrypto(){
- ltc_mp = ltm_desc;
- register_hash(&sha1_desc);
- register_hash(&sha256_desc);
- register_cipher(&twofish_desc);
- register_prng(&yarrow_desc);
- rng_make_prng(128, find_prng("yarrow"), &g_Yarrow, NULL);
- rsa_import(g_RSAKeyData, sizeof(g_RSAKeyData), &g_RSAKey);
- }
- int my_rsa_decrypt_key_ex(const unsigned char *in, unsigned long inlen,
- unsigned char *out, unsigned long *outlen,
- const unsigned char *lparam, unsigned long lparamlen,
- int hash_idx, int padding,
- int *stat, rsa_key *key)
- {
- unsigned long modulus_bitlen, modulus_bytelen, x;
- int err;
- unsigned char *tmp;
- LTC_ARGCHK(out != NULL);
- LTC_ARGCHK(outlen != NULL);
- LTC_ARGCHK(key != NULL);
- LTC_ARGCHK(stat != NULL);
- /* default to invalid */
- *stat = 0;
- /* valid padding? */
- if ((padding != LTC_LTC_PKCS_1_V1_5) &&
- (padding != LTC_LTC_PKCS_1_OAEP)) {
- return CRYPT_PK_INVALID_PADDING;
- }
- if (padding == LTC_LTC_PKCS_1_OAEP) {
- /* valid hash ? */
- if ((err = hash_is_valid(hash_idx)) != CRYPT_OK) {
- return err;
- }
- }
- /* get modulus len in bits */
- modulus_bitlen = mp_count_bits( (key->N));
- /* outlen must be at least the size of the modulus */
- modulus_bytelen = mp_unsigned_bin_size( (key->N));
- if (modulus_bytelen != inlen) {
- return CRYPT_INVALID_PACKET;
- }
- /* allocate ram */
- tmp = (unsigned char*)XMALLOC(inlen);
- if (tmp == NULL) {
- return CRYPT_MEM;
- }
- /* rsa decode the packet */
- x = inlen;
- if ((err = ltc_mp.rsa_me(in, inlen, tmp, &x, PK_PUBLIC, key)) != CRYPT_OK) {
- XFREE(tmp);
- return err;
- }
- if (padding == LTC_LTC_PKCS_1_OAEP) {
- /* now OAEP decode the packet */
- err = pkcs_1_oaep_decode(tmp, x, lparam, lparamlen, modulus_bitlen, hash_idx,
- out, outlen, stat);
- } else {
- /* now LTC_PKCS #1 v1.5 depad the packet */
- err = pkcs_1_v1_5_decode(tmp, x, LTC_LTC_PKCS_1_EME, modulus_bitlen, out, outlen, stat);
- }
- XFREE(tmp);
- return err;
- }
- void MakeIV(ZipFile::DataDescriptor *desc, unsigned char* iv){
- DWORD* liv;
- liv = (DWORD*)iv;
- liv[0] = (desc->lSizeCompressed << 12) ^ desc->lSizeUncompressed;
- liv[1] = !desc->lSizeCompressed;
- liv[2] = (desc->lSizeCompressed << 12) ^ desc->lCRC32;
- liv[3] = desc->lSizeCompressed ^ (!desc->lSizeUncompressed);
- }
- int GetKeyIndex(ZipFile::DataDescriptor* desc){
- return (~(desc->lCRC32 >> 2)) & 0xF;
- }
- class CPakCryptography{
- private:
- bool InitTwofish(const void* key, const void* iv, symmetric_CTR* ctr, int padlen){
- int cipher;
- int d;
- unsigned char buf[1024];
- cipher = find_cipher("twofish");
- if (cipher < 0)
- return false;
- if (ctr_start(cipher, (unsigned char*)iv, (unsigned char*)key, 16, 0, CTR_COUNTER_LITTLE_ENDIAN, ctr) != CRYPT_OK)
- return false;
- for (;padlen > 0;){
- d = min(padlen, 1024);
- ctr_decrypt(buf, buf, d, ctr);
- padlen -= d;
- }
- return true;
- }
- bool DecryptTwofish(void* data, int len, const void* key, const void* iv){
- symmetric_CTR ctr;
- if (!InitTwofish(key, iv, &ctr, 0))
- return false;
- if (ctr_decrypt((unsigned char*)data, (unsigned char*)data, len, &ctr) != CRYPT_OK)
- return false;
- ctr_done(&ctr);
- return true;
- }
- public:
- UINT32 m_Mode;
- UINT8 IV[16];
- UINT8 Keys[ZIP_NUMKEYS][16];
- bool InitKeys(SEncryptionHeader &hdr){
- int hash, stat;
- int i;
- unsigned long outlen;
- unsigned char buf[1024];
- hash = find_hash("sha256");
- outlen = sizeof(buf);
- 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)
- return false;
- memcpy(IV, buf, 16);
- for (i = 0; i < ZIP_NUMKEYS; i++){
- outlen = sizeof(buf);
- 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)
- return false;
- memcpy(Keys[i], buf, 16);
- }
- return true;
- }
- bool DecryptTFInternal(void* pData, int len, int key, unsigned char* iv){
- return DecryptTwofish(pData, len, Keys[key], iv);
- }
- bool Decrypt(void* pData, int len, int key){
- if (m_Mode == HeaderEncryption_Twofish)
- return DecryptTFInternal(pData, len, key, IV);
- else if (m_Mode == HeaderEncryption_XXTEA)
- return XXTEADecrypt(pData, len), true;
- else if (m_Mode == HeaderEncryption_StreamCipher)
- return false;
- else
- return true;
- }
- bool DecryptTF(void* pData, int len, ZipFile::DataDescriptor &desc){
- unsigned char iv[16];
- int key;
- key = GetKeyIndex(&desc);
- MakeIV(&desc, iv);
- return DecryptTFInternal(pData, len, key, iv);
- }
- };
- void fcopy(FILE* src, FILE*dst, int count){
- char lBuf[1024];
- int r;
- for (;count > 0;){
- r = min(count, sizeof(lBuf));
- fread(lBuf, 1, r, src);
- fwrite(lBuf, 1, r, dst);
- count -= r;
- }
- }
- CDynMemoryBuffer g_LocalHeaderBuffer(8192);
- CDynMemoryBuffer g_FileBuffer(8192*1024);
- int SwitchMethod(int method){
- switch (method){
- default:
- return method;
- case 13:
- return 0;
- case 14:
- return 8;
- }
- }
- bool ProcessCDR(file f, ZipFile::CDREnd* pCDRInfo, file fo, long cdrendoffset){
- char* pCDR;
- char* pEndOfData;
- char* pEndOfHeader;
- char* pEndOfRecord;
- int nlen, i, chr;
- int len;
- FileEntry entry;
- unsigned char iv[16];
- char buf[512];
- ZipFile::CDRFileHeader* pHdr;
- int encmode = pCDRInfo->nDisk >> 14;
- int sigmode;
- pCDRInfo->nDisk &= 0x3FFF;
- char fname[512];
- SExtraZipFileData extra;
- char* pCache;
- ZipFile::LocalFileHeader *lHdr;
- CPakCryptography cg;
- SExtensionHeader ehdr;
- SEncryptionHeader chdr;
- SSignatureHeader shdr;
- UINT32 esize;
- sigmode = HeaderSignature_None;
- //fseek_(f, cdrendoffset+sizeof(ZipFile::CDREnd), SEEK_SET);
- //filecopy_(f, fo, buf, 512, pCDRInfo->nCommentLength);
- if (pCDRInfo->nCommentLength >= SExtensionHeader::SIZE){
- esize = SExtensionHeader::SIZE;
- fseek_(f, pCDRInfo->lCDROffset+pCDRInfo->lCDRSize+sizeof(ZipFile::CDREnd), SEEK_SET);
- if (!fread_b(&ehdr, SExtensionHeader::SIZE, f))
- return false;
- if (ehdr.Size != SExtensionHeader::SIZE)
- return false; //Bad extended header
- if (ehdr.EncryptionType != HeaderEncryption_None && encmode != 0)
- return false; //Unexpected encryption technique in header
- encmode = ehdr.EncryptionType;
- if (encmode == 0){
- } else if (encmode == HeaderEncryption_Twofish){
- esize += SEncryptionHeader::SIZE;
- } else
- return false; //Bad encryption technique in header
- sigmode = ehdr.SignatureType;
- if (sigmode == HeaderSignature_None){
- } else if (sigmode == HeaderSignature_Signed){
- esize += SSignatureHeader::SIZE;
- } else
- return false; //Bad signing technique in header
- if (pCDRInfo->nCommentLength != esize)
- return false; //Comment field is the wrong length
- if (sigmode == HeaderSignature_Signed){
- if (!fread_b(&shdr, SSignatureHeader::SIZE, f))
- return false;
- if (shdr.Size != SSignatureHeader::SIZE)
- return false; //Bad signature header
- }
- if (encmode == HeaderEncryption_Twofish){
- if (!fread_b(&chdr, SEncryptionHeader::SIZE, f))
- return false;
- if (chdr.Size != SEncryptionHeader::SIZE)
- return false; //Bad signature header
- //Initialize keys
- cg.InitKeys(chdr);
- }
- }
- cg.m_Mode = encmode;
- pCDRInfo->nCommentLength = 0;
- fseek_(fo, cdrendoffset, SEEK_SET);
- if (!fwrite_b(pCDRInfo, sizeof(ZipFile::CDREnd), fo))
- return false;
- pCDR = NULL;
- pCache = NULL;
- pCDR = (char*)g_pAllocator(pCDRInfo->lCDRSize+16);
- if (!pCDR)
- return false;
- pCache = (char*)g_pAllocator(4096);
- if (!pCache)
- goto __failexit;
- fseek_(f, pCDRInfo->lCDROffset, SEEK_SET);
- if (!fread_b(pCDR, pCDRInfo->lCDRSize, f))
- return false;
- if (!cg.Decrypt(pCDR, pCDRInfo->lCDRSize, 0))
- goto __failexit;
- fseek_(fo, pCDRInfo->lCDROffset, SEEK_SET);
- if (!fwrite_b(pCDR, pCDRInfo->lCDRSize, fo))
- return false;
- pEndOfHeader = pCDR+sizeof(ZipFile::CDRFileHeader);
- pEndOfData = pCDR+pCDRInfo->lCDRSize;
- pHdr = (ZipFile::CDRFileHeader*)pCDR;
- for (;pEndOfHeader <= pEndOfData; pHdr = (ZipFile::CDRFileHeader*)pEndOfRecord, pEndOfHeader = pEndOfRecord+sizeof(ZipFile::CDRFileHeader)){
- if (pHdr->nVersionNeeded > 20){
- //Bad version
- goto __failexit;
- }
- pEndOfRecord = pEndOfHeader+pHdr->nExtraFieldLength+pHdr->nFileNameLength+pHdr->nFileCommentLength;
- if (pEndOfRecord > pEndOfData)
- goto __failexit;
- nlen = pHdr->nFileNameLength;
- //if (nlen < 1 || (*(nlen+pEndOfHeader-1) != '\\' && *(nlen+pEndOfHeader-1) != '/')){
- fseek_(f, pHdr->lLocalHeaderOffset, SEEK_SET);
- //long pos = ftell(f);
- len = sizeof(ZipFile::LocalFileHeader)+pHdr->nFileNameLength+pHdr->nExtraFieldLength;//+pHdr->desc.lSizeCompressed;
- g_LocalHeaderBuffer.Alloc(len);
- if (!fread_b(g_LocalHeaderBuffer.GetPtr(), len+pHdr->nExtraFieldLength+pHdr->nFileCommentLength, f))
- goto __failexit;
- lHdr = (ZipFile::LocalFileHeader*)g_LocalHeaderBuffer.GetPtr();
- if (encmode != HeaderEncryption_None){
- lHdr->desc = pHdr->desc;
- lHdr->nFileNameLength = pHdr->nFileNameLength;
- lHdr->nFlags = 0;
- lHdr->lSignature = 0x04034b50;
- lHdr->nExtraFieldLength = 0;
- lHdr->nVersionNeeded = 20;
- lHdr->nLastModDate = pHdr->nLastModDate;
- lHdr->nLastModTime = pHdr->nLastModTime;
- lHdr->nMethod = SwitchMethod(pHdr->nMethod);
- memcpy(lHdr+1, pEndOfHeader, pHdr->nFileNameLength);
- }
- fseek_(fo, pHdr->lLocalHeaderOffset, SEEK_SET);
- if (!fwrite_b(g_LocalHeaderBuffer.GetPtr(), len+pHdr->nExtraFieldLength+pHdr->nFileCommentLength, fo))
- goto __failexit;
- g_Src.Alloc(pHdr->desc.lSizeCompressed);
- fseek_(f, len+pHdr->lLocalHeaderOffset, 0);
- if (!fread_b(g_Src.GetPtr(), pHdr->desc.lSizeCompressed, f))
- goto __failexit;
- 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);
- if ((pHdr->nMethod == 13 || pHdr->nMethod == 14) && pHdr->desc.lSizeCompressed != 0)
- cg.DecryptTF(g_Src.GetPtr(), pHdr->desc.lSizeCompressed, pHdr->desc);
- pHdr->nMethod = SwitchMethod(pHdr->nMethod);
- fseek_(fo, len+pHdr->lLocalHeaderOffset, SEEK_SET);
- if (!fwrite_b(g_Src.GetPtr(), pHdr->desc.lSizeCompressed, fo))
- goto __failexit;
- //}
- }
- fseek_(fo, pCDRInfo->lCDROffset, SEEK_SET);
- if (!fwrite_b(pCDR, pCDRInfo->lCDRSize, fo))
- goto __failexit;
- if (pCDR)
- g_pFreeer(pCDR);
- if (pCache)
- g_pFreeer(pCache);
- return true;
- __failexit:
- if (pCDR)
- g_pFreeer(pCDR);
- if (pCache)
- g_pFreeer(pCache);
- return false;
- }
- #define PrintError(_fmt, ...) printf(_fmt, __VA_ARGS__)
- #define PrintInfo(_fmt, ...) printf(_fmt, __VA_ARGS__)
- int main(int argc, char** argv){
- file f, fo;
- long size, oldoffset, end, offset;
- ZipFile::CDREnd CDREnd, TempCDR;
- TStringBufferA<MAX_PATH> buf;
- char* pBuffer;
- char* pWindow;
- int ni;
- char* pSignatures;
- InitCrypto();
- pBuffer = (char*)g_pAllocator(277);
- f = fo = NULL;
- long cdrendoffset;
- CStringA fin, fout;
- if (argc < 2){
- printf("Usage: PakDecrypt.exe <input pak> [output zip]\nOutput zip defaults to inputpak.zip\n");
- return 0;
- }
- fin = argv[1];
- if (argc > 2)
- fout = argv[2];
- else {
- buf.Print("%s.zip", fin());
- fout = buf;
- }
- f = fopen_(fin, "r");
- fo = fopen_(fout, "w");
- if (f != INVALID_FILE && fo != INVALID_FILE){
- size = fsize_(f);
- CDREnd.lSignature = 0;
- if (size >= sizeof(ZipFile::CDREnd)){
- end = size-sizeof(ZipFile::CDREnd);
- oldoffset = size;
- for (ni = 0;;ni++){
- pWindow = pBuffer;
- if (oldoffset > 256){
- offset = oldoffset-256;
- } else {
- pWindow = pBuffer-oldoffset+256;
- offset = 0;
- }
- if (size >= 0x10016){
- if (offset < (size-0x10015))
- offset = size-0x10015;
- }
- if (offset >= oldoffset)
- break;
- fseek_(f, offset, SEEK_SET);
- //left -= offset;
- fread_(pWindow, oldoffset-offset, f);
- if (end >= offset){
- pSignatures = pWindow-offset;
- do {
- if (*(DWORD*)(pSignatures+end) == 0x6054B50){
- //Do stuff here;
- memcpy(&TempCDR, pSignatures+end, sizeof(ZipFile::CDREnd));
- if (TempCDR.nCommentLength != (size-end-sizeof(ZipFile::CDREnd)))
- goto __fclose;
- memcpy(&CDREnd, pSignatures+end, sizeof(ZipFile::CDREnd));
- break;
- }
- end--;
- } while (end >= offset);
- }
- if (CDREnd.lSignature == 0x6054B50){
- cdrendoffset = end;
- goto __got_CDREnd;
- }
- oldoffset = offset;
- memmove(pBuffer+0x100, pWindow, 0x15);
- }
- }
- goto __fclose;
- __got_CDREnd:
- ProcessCDR(f, &CDREnd, fo, cdrendoffset);
- }
- __fclose:
- if (fo)
- fclose_(fo);
- if (f)
- fclose_(f);
- g_pFreeer(pBuffer);
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment