|
|
出于我并不是th135pak的作者,我没法直接发所有源文件
以下提及的函数需要在Riatre大神的th135pak中对应修改才能使用。
本来以为黄昏在正式版当中封入了文件名,,,,结果并没有。。。
我跑了个彩虹表,,,能有3、4千文件名,,,,实在跑不动了。。。。。
以下代码请在有限范围内任意使用。。。
话说我要不要挂一份去github。。。
- const unsigned char PUBLIC_KEY_N[KEY_BYTESIZE] = {
- 0xC6, 0x43, 0xE0, 0x9D, 0x35, 0x5E, 0x98, 0x1D, 0xBE, 0x63, 0x6D, 0x3A, 0x5F, 0x84, 0x0F, 0x49,
- 0xB8, 0xE8, 0x53, 0xF5, 0x42, 0x06, 0x37, 0x3B, 0x36, 0x25, 0xCB, 0x65, 0xCE, 0xDD, 0x68, 0x8C,
- 0xF7, 0x5D, 0x72, 0x0A, 0xC0, 0x47, 0xBD, 0xFA, 0x3B, 0x10, 0x4C, 0xD2, 0x2C, 0xFE, 0x72, 0x03,
- 0x10, 0x4D, 0xD8, 0x85, 0x15, 0x35, 0x55, 0xA3, 0x5A, 0xAF, 0xC3, 0x4A, 0x3B, 0xF3, 0xE2, 0x37
- };
- int Decrypt6432(const unsigned char* src,unsigned char* dst,size_t dstLen)
- {
- if(keyInitialized == -1) InitRSAKeyPair(0);
- if(dstLen > 0x20) return -1;
- unsigned char tmp[64] = {0};
- DecryptBlock(src,tmp);
- unsigned char*lp = tmp + 2;
- while (*lp++ == 0xff);
- memcpy(dst, lp, dstLen);
- return 0;
- }
- int DecodeFile(unsigned char* src, unsigned char* dst, size_t Len, byte* __key)
- {
- memcpy(dst, src, Len);
- unsigned char* currentlp = dst;
- DWORD uk1 = *(DWORD*)__key, uk2 = *(DWORD*)__key;
- byte key[20] = { 0 };
- memcpy(key, __key, 16);
- memcpy(key+16, __key, 4);
-
- if (!strncmp((char*)(currentlp), "TFWA", 4) || !strncmp((char*)(currentlp), "TFBM", 4) || !strncmp((char*)(currentlp), "OggS", 4) || !strncmp((char*)(currentlp+2), "RI", 2))
- {
- uk2 = *(DWORD*)currentlp;
- currentlp += 4;
- uk2 >>= 8;
- uk2 += (*currentlp)*0x1000000;
- *currentlp^= *(key + 4);
- *currentlp ^= *(currentlp-4);
- currentlp++;
- }
- if (Len & 1)
- {
- DWORD tmpKey = uk2 >> 8;
- tmpKey += (*currentlp) * 0x1000000;
- unsigned long current = (currentlp - dst) & 0xf;
- (*(byte*)currentlp) ^= *(byte*)(key + current);
- (*(byte*)currentlp) ^= LOBYTE( uk2);
- uk2 = tmpKey;
- currentlp ++;
- }else
- if (Len & 2)
- {
- DWORD tmpKey = HIWORD(uk2) + LOWORD((*(DWORD*)currentlp)) * 0x10000;
- unsigned long current = (currentlp - dst) & 0xf;
- (*(WORD*)currentlp) ^= *(WORD*)(key + current);
- (*(WORD*)currentlp) ^= LOWORD(uk2);
- currentlp += 2;
- uk2 = tmpKey;
- }
- if (currentlp < dst + Len)
- {
- do
- {
- DWORD tmp = *(DWORD*)currentlp;
- unsigned long current = (currentlp - dst) & 0xf;
- (*(DWORD*)currentlp) ^= *(DWORD*)(key + current);
- (*(DWORD*)currentlp) ^= uk2;
- uk2 = tmp;
- currentlp += 4;
- } while (currentlp < dst + Len);
- }
- return 0;
- }
- DWORD SpecialFNVHash(char *begin, char *end, DWORD initHash = 0x811C9DC5u)
- {
- DWORD hash;
- byte ch;
-
- int inMBCS = 0;
- for (hash = initHash; begin != end; hash = (hash^ch) * 0x1000193 )
- {
- ch = *begin++;
- if (ch == '/') ch = '\\';
- if (!inMBCS && ch>=128)
- inMBCS = 2;
- if(!inMBCS)
- {
- ch = tolower(ch); // bad ass style but WORKS PERFECTLY!
- }
- else inMBCS--;
- }
- return hash;
- }
- int ExtractAll(const wchar_t* ArchiveFileName,const wchar_t* OutputFolder)
- {
- HANDLE hFile = CreateFile(ArchiveFileName,GENERIC_READ,FILE_SHARE_READ,NULL,OPEN_EXISTING,FILE_FLAG_RANDOM_ACCESS,NULL);
- HANDLE hInMapping = CreateFileMapping(hFile,NULL,PAGE_READONLY,0,GetFileSize(hFile,NULL),NULL);
- BYTE* pPackage = (BYTE*)MapViewOfFile(hInMapping,FILE_MAP_READ,0,0,0);
- if(hFile == INVALID_HANDLE_VALUE || hInMapping == INVALID_HANDLE_VALUE || !pPackage)
- return 0;
- DWORD Magic = *(DWORD*)pPackage;
- if(Magic != 'KPFT')
- return 0;
- DWORD cur = 0x5;
- DWORD DirCount = 0;
- Decrypt6432(pPackage + cur, (BYTE*)&DirCount, sizeof(DWORD));
- cur += KEY_BYTESIZE;
- std::unordered_map<DWORD, std::pair<char*, char*> > hashToName;
- if (DirCount)
- {
- DIRLIST* DirList = new DIRLIST[DirCount];
- ZeroMemory(DirList, DirCount*sizeof(DIRLIST));
- for (int i = 0; i < DirCount; i++)
- {
- Decrypt6432(pPackage + cur, (BYTE*)&DirList[i], sizeof(DWORD) * 2);
- cur += KEY_BYTESIZE;
- }
- FNHEADER fnh;
- ZeroMemory(&fnh, sizeof(FNHEADER));
- Decrypt6432(pPackage + cur, (BYTE*)&fnh, sizeof(FNHEADER));
- cur += KEY_BYTESIZE;
- BYTE* CompFN = new BYTE[fnh.CompSize + KEY_BYTESIZE];
- for (int i = 0; i < fnh.BlockCnt; i++)
- {
- Decrypt6432(pPackage + cur, CompFN + i*KEY_BYTESIZE / 2);
- cur += KEY_BYTESIZE;
- }
- char* FNList = new char[fnh.OrigSize];
- DWORD realOrigSize = fnh.OrigSize;
- ZeroMemory(FNList, fnh.OrigSize);
- uncompress((BYTE*)FNList, &realOrigSize, CompFN, fnh.CompSize);
- delete[] CompFN;
- HANDLE hTemp = CreateFile(L"fnlist.txt",GENERIC_READ|GENERIC_WRITE,0,NULL,CREATE_ALWAYS,FILE_FLAG_RANDOM_ACCESS,NULL);
- WriteFile(hTemp,FNList,fnh.OrigSize,&realOrigSize,NULL);
- CloseHandle(hTemp);
- assert(fnh.OrigSize == realOrigSize);
- DWORD fnPos = 0;
- for (int i = 0; i < DirCount; i++)
- {
- for (int j = 0; j < DirList[i].FileCount; j++)
- {
- int tlen = strlen(FNList + fnPos);
- DWORD NameHash = -SpecialFNVHash(FNList + fnPos, FNList + fnPos + tlen, DirList[i].PathHash);
- hashToName[NameHash] = std::make_pair(DirList[i].Path, FNList + fnPos);
- fnPos += tlen + 1;
- }
- }
- }
- DWORD FileCount = 0;
- Decrypt6432(pPackage + cur, (BYTE*)&FileCount, sizeof(DWORD));
- cur += KEY_BYTESIZE;
-
- unordered_map<DWORD, FileLST> fileList;
- vector<DWORD> hashList;
- for (int i = 0; i < FileCount; i++)
- {
- QWORD fileDes = {0};
- Decrypt6432(pPackage + cur, (BYTE*)&fileDes, sizeof(QWORD));
- cur += KEY_BYTESIZE;
- QWORD hashDes = { 0 };
- Decrypt6432(pPackage + cur, (BYTE*)&hashDes, sizeof(QWORD));
- cur += KEY_BYTESIZE;
- DQWORD XorKeys = { 0 };
- Decrypt6432(pPackage + cur, (BYTE*)&XorKeys, sizeof(DQWORD));
- cur += KEY_BYTESIZE;
- fileDes.HIDWORD ^= XorKeys.HIQWORD.HIDWORD;//FileSize
- fileDes.LODWORD ^= XorKeys.HIQWORD.LODWORD;//FileOffset;
- //fileDes.LODWORD += FileBegin;
- hashDes.HIDWORD ^= XorKeys.LOQWORD.HIDWORD;
- hashDes.LODWORD ^= XorKeys.LOQWORD.LODWORD;
- DWORD hash = hashDes.HIDWORD;
- hashList.push_back(hash);
- fileList[hash].size = fileDes.HIDWORD;
- fileList[hash].offset = fileDes.LODWORD;
- fileList[hash].unKey = hashDes.LODWORD;
- memcpy(fileList[hash].xorKey, &XorKeys, 16);
- for (unsigned int i = 0; i<4; i++)
- {
- ((DWORD*)fileList[hash].xorKey)[i] = -((DWORD*)fileList[hash].xorKey)[i];
- }
- }
-
- DWORD FileBegin = cur;
- for (unsigned int i = 0; i < hashList.size(); i++)
- {
- DWORD cHash = hashList[i];
- byte* loadDst = (byte*)calloc(1, fileList[cHash].size + 4);
- DecodeFile(pPackage + fileList[cHash].offset + FileBegin, loadDst, fileList[cHash].size, fileList[cHash].xorKey);
- WCHAR path[MAX_PATH] = { 0 };
- if (dirHashToName.find(cHash)==dirHashToName.end())
- {
- char* extend = NULL;
- if (!strncmp((char*)loadDst, "TFCS", 4))//人家说函数返回值不要是布尔,果然很难理解= =
- {
- extend = ".csv";
- }
- else if (!strncmp((char*)loadDst, "OggS", 4))
- {
- extend = ".ogg";
- }
- else if (!strncmp((char*)(loadDst + 2), "RIQS", 4))
- {
- extend = ".nut";
- }
- else if (!strncmp((char*)(loadDst + 2), "xml", 3))
- {
- extend = ".xml";
- }
- else if (!strncmp((char*)(loadDst), "ACT", 3))
- {
- extend = ".act";
- }
- else if (!strncmp((char*)(loadDst), "#===", 4))
- {
- extend = ".pl";
- }
- else if (!strncmp((char*)(loadDst), "DDS", 3))
- {
- extend = ".dds";
- }
- else if (!strncmp((char*)(loadDst), "OTTO", 4))
- {
- extend = ".otf";
- }
- else if (!strncmp((char*)(loadDst), "TFBM", 4))
- {
- extend = ".bmp";
- }
- else if (!strncmp((char*)(loadDst), "TFWA", 4))
- {
- extend = ".wav";
- }
- else if (!strncmp((char*)(loadDst), "IBMB", 4))
- {
- extend = ".bmb";
- }
- else if (!strncmp((char*)(loadDst), "TFPA", 4))
- {
- extend = ".bmp";
- }
- else
- {
- extend = ".null";
- }
-
- swprintf(path, L"%s%x%s", OutputFolder, cHash, extend);
- }
- else
- {
- swprintf(path, L"%s%s", OutputFolder, dirHashToName[cHash].data());
-
- }
- CreateDirectoryForPath(path);
- DWORD rb = 0;
- HANDLE Hload = CreateFile(path, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ, 0, OPEN_ALWAYS, 0, 0);
- WriteFile(Hload, loadDst, fileList[cHash].size, &rb, NULL);
- CloseHandle(Hload);
- free(loadDst);
- cout << ".";
- }
- UnmapViewOfFile(pPackage);
- CloseHandle(hInMapping);
- CloseHandle(hFile);
- return 1;
- }
复制代码 |
评分
-
查看全部评分
|