void BlowFish::Encode(byte* key,ByteBuf & buf)
{
	CBlowFish blow;
	blow.Initialize((byte*)key,16);
	int iLength = buf.first;
	int iDifference = iLength % 8;
	int iNewLength = iLength;
	if( iDifference	!= 0 )
		iNewLength = (iLength - iDifference) + 8;
	buf.first=blow.Encode(buf.second,buf.second,iNewLength);
}
Beispiel #2
0
DWORD WINAPI Encrypt(PBYTE pbBuffer, TMyPAZEntry *pEntry)
{
    CHAR   szName[MAX_PATH];
    BYTE   bySeed[400];
    DWORD  dwSeed, dwSize;
    LPCSTR lpCrud;
    LPSTR  lpExt, lpFileName;

    lpFileName = pEntry->szName;
    lstrcpy(szName, lpFileName);
    lpExt = findext(szName);
    if (lpExt && bIsVoice)
    {
        *lpExt = 0;
    }

    dwSize = pEntry->dwCompSize;
    lpCrud = GetCrud(findext(lpFileName), &GameInfo[dwInfoIndex]);
    if (lpCrud)
        dwSeed = sprintf((char *)bySeed, "%s %08X %s", strlwr(lpFileName), pEntry->dwCompSize, lpCrud ? lpCrud : "");

    if (g_bIsMovie == False)
    {
        CBlowFish bf;
        bf.Initialize(GameInfo[dwInfoIndex].key[dwKeyIndex].DataKey, sizeof(GameInfo[dwInfoIndex].key[dwKeyIndex].DataKey));
        if (lpCrud)
        {
            Decrypt(bySeed, dwSeed, pbBuffer, dwSize);
        }
        dwSize = bf.Encode(pbBuffer, pbBuffer, pEntry->dwDecryptSize);
    }
    else
    {
        if (dwInfoIndex != EF_FIRST)
        {
            memset(&bySeed[dwSeed + 10], 0, 0x100);
            DecryptMovie(&bySeed[dwSeed + 10], bySeed, dwSeed, pbBuffer, pEntry->dwCompSize);
        }
        else
        {
        }
    }

    if (bNeedXor)
        Xor(pbBuffer, dwSize);

    return dwSize;
}
Beispiel #3
0
int Compact(TCHAR* szFolder,TCHAR* szFileName)
{
	DWORD temp;
	if(!::SetCurrentDirectory(szFolder))
		return -1;

	char* p=szFolder;
	p+=strlen(szFolder);
	if(*(p-1)=='\\')
		p--;
	while(*--p!='\\');
	string prefix=++p;

	p=szFolder+strlen(szFolder);
	if(*(p-1)=='\\')
		--p;
	strcpy(p,".dat");

	key_info_t  keys;
	for (unsigned long i = 0; !GAME_INFO.keys[i].prefix.empty(); i++)
	{
		if (prefix == GAME_INFO.keys[i].prefix)
		{
			keys = GAME_INFO.keys[i];
		}
	}
	if (keys.prefix.empty())
		return -1;

	bool is_audio = prefix == "bgm" || prefix == "se" || prefix == "voice" || prefix == "PMvoice";
	bool is_mov   = prefix == "mov";
	if(is_mov)
		return -1;

	PAZHDR hdr;
//	strcpy((char*)&hdr,"mashiroiro");

	HANDLE hOldFile=CreateFile(szFileName,GENERIC_READ,FILE_SHARE_READ,0,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,0);
	if(hOldFile==INVALID_HANDLE_VALUE)
		return -1;
	ReadFile(hOldFile,&hdr,sizeof(hdr),&temp,0);
	char simple_key = hdr.toc_len >> 24;
	if(simple_key)
		return -1;
	char* toc_buff2=new char[hdr.toc_len];
	ReadFile(hOldFile,toc_buff2,hdr.toc_len,&temp,0);
	CloseHandle(hOldFile);

	CBlowFish bf;
	bf.Initialize(keys.toc_key,sizeof(keys.toc_key));
	bf.Decode((unsigned char*)toc_buff2,(unsigned char*)toc_buff2,hdr.toc_len);
	list<PAZENTRY2> entries;
	list<PAZENTRY2>::iterator ent_itr,ent_itr_end;
	char*p2=toc_buff2;
	int nEntryCount=*(long*)p2;
	p2+=4;
	for(int i=0;i<nEntryCount;i++)
	{
		PAZENTRY2 entry;
		entry.fn=p2;
		p2+=entry.fn.length()+1;
		memcpy(&entry.ent,p2,sizeof(entry.ent));
		p2+=sizeof(entry.ent);
		entries.push_back(entry);
	}
	delete[] toc_buff2;

	//int nSizeEntries=sizeof(PAZHDR2);
	//WIN32_FIND_DATA stFindData;

	//HANDLE hFind=FindFirstFile(TEXT("*"),&stFindData);
	//if(hFind!=INVALID_HANDLE_VALUE)
	//	do
	//	{
	//		PAZENTRY2 entry;
	//		HANDLE hNowFile=CreateFile(stFindData.cFileName,GENERIC_READ,0,0,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,0);
	//		if(hNowFile==INVALID_HANDLE_VALUE)
	//			continue;
	//		entry.fn=stFindData.cFileName;
	//		entry.ent.length =GetFileSize(hNowFile,NULL);
	//		entry.ent.original_length=entry.ent.length ;
	//		entry.ent.padded_length   = (entry.ent.length + 7) & ~7;

	//		entries.push_back(entry);

	//		nSizeEntries+=entry.fn.length ()+1+sizeof(PAZENTRY);
	//		CloseHandle(hNowFile);
	//	}while(FindNextFile(hFind,&stFindData));
	//else
	//	return -1;
	//FindClose(hFind);

//	nSizeEntries=(nSizeEntries + 7) & ~7;
	int nNowOffset=sizeof(PAZHDR)+hdr.toc_len;
	ent_itr=entries.begin();
	ent_itr_end=entries.end();
	char* toc_buff=new char[hdr.toc_len];
	memset(toc_buff,0,hdr.toc_len);
	*(long*)toc_buff=entries.size();
	for(char* p=toc_buff+sizeof(PAZHDR2);ent_itr!=ent_itr_end;ent_itr++)
	{
		ent_itr->ent.offset=nNowOffset;
		nNowOffset+=ent_itr->ent.padded_length;
		strcpy(p,ent_itr->fn.c_str());
		p+=ent_itr->fn.length()+1;
		memcpy(p,&ent_itr->ent,sizeof(ent_itr->ent));
		p+=sizeof(ent_itr->ent);
	}

	HANDLE hNewFile=CreateFile(szFolder,GENERIC_WRITE,FILE_SHARE_READ,0,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,0);
	if(hNewFile==INVALID_HANDLE_VALUE)
		return -1;

//	hdr.toc_len=nSizeEntries;
	WriteFile(hNewFile,&hdr,sizeof(hdr),&temp,0);

	bf.Initialize(keys.toc_key,sizeof(keys.toc_key));
	bf.Encode((unsigned char*)toc_buff,(unsigned char*)toc_buff,hdr.toc_len);
	WriteFile(hNewFile,toc_buff,hdr.toc_len,&temp,0);

	delete[] toc_buff;

	ent_itr=entries.begin();
	ent_itr_end=entries.end();
	for(;ent_itr!=ent_itr_end;ent_itr++)
	{
		string filename=ent_itr->fn;
		HANDLE hNowFile=CreateFile(filename.c_str(),GENERIC_READ,0,0,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,0);
		if(hNowFile==INVALID_HANDLE_VALUE)
			return -1;

		char* buff=new char[ent_itr->ent.padded_length];
		memset(buff,0,ent_itr->ent.padded_length);
		ReadFile(hNowFile,buff,ent_itr->ent.length,&temp,0);
		CloseHandle(hNowFile);

		string crud;

		if (filename.find(".png") != string::npos)
		{
			crud = GAME_INFO.crud.png;
		}
		else if (filename.find(".ogg") != string::npos || is_audio)
		{
			crud = GAME_INFO.crud.ogg;
		}
		else if (filename.find(".sc") != string::npos)
		{
			crud = GAME_INFO.crud.sc;
		}
		else if (filename.find(".avi") != string::npos || filename.find(".mpg") != string::npos)
		{
			crud = GAME_INFO.crud.avi;
		}

		char entrylen[12];
		wsprintf(entrylen," %08X ",ent_itr->ent.length);
		transform(filename.begin (),filename.end (),filename.begin (),tolower);
		string seed=filename+(string)entrylen+crud;

		if(is_mov)
			return -1;
		else
		{
			bf.Initialize(keys.dat_key,sizeof(keys.dat_key));
			if(!crud.empty())
				unobfuscate3(seed,(unsigned char*)buff,ent_itr->ent.padded_length);
			bf.Encode((unsigned char*)buff,(unsigned char*)buff,ent_itr->ent.padded_length);
		}
		WriteFile(hNewFile,buff,ent_itr->ent.padded_length,&temp,0);
		delete[] buff;
	}
	SetEndOfFile(hNewFile);
	CloseHandle(hNewFile);
	return 0;
}
Beispiel #4
0
Void WINAPI WriteEntry(HANDLE hFile, TMyPAZEntry *pEntry, DWORD dwCount, Bool bEncrypt)
{
    DWORD  dwLength, dwEntryPos, dwRemainder;
    PBYTE  pbEntry;
    BYTE   byMovieSeed[256], byMod8[8];

    *(LPDWORD)&byMod8[0] = 0;
    *(LPDWORD)&byMod8[3] = 0;
    dwEntryPos = 0x24 + (g_bIsMovie ? 0x100 : 0);
    SetFilePointer(hFile, 0x20, 0, FILE_BEGIN);
    WriteFile(hFile, &dwCount, 4, &dwLength, NULL); // entry size
    WriteFile(hFile, &dwCount, 4, &dwLength, NULL); // entry count

    if (g_bIsMovie)
    {
        if (bEncrypt == False)
        {
            if (dwInfoIndex != EF_FIRST)
            {
                memset(byMovieSeed, 0, sizeof(byMovieSeed));
                WriteFile(hFile, byMovieSeed, sizeof(byMovieSeed), &dwLength, NULL);
            }
            else
            {
                for (int i = 0; i != 256; ++i)
                {
                    byMovieSeed[i] = i;
                }

                for (int i = 0; i != 256; ++i)
                    WriteFile(hFile, byMovieSeed, sizeof(byMovieSeed), &dwLength, NULL);
            }
        }
        else
        {
            SetFilePointer(hFile, dwInfoIndex != EF_FIRST ? 0x100 : 0x10000, 0, FILE_CURRENT);
        }
    }

    for (DWORD i = dwCount; i; )
    {
        LPSTR lpExt;

        --i;
        lpExt = findext(pEntry[i].szName);
        if (lpExt)
        {
            if (lstrcmpiA(lpExt, ".uca") && bIsVoice)
                *lpExt = 0;
            else if (lstrcmpiA(lpExt, ".ogg") && lstrcmpiA(lpExt, ".m4a"))
                lpExt = NULL;
        }

        dwLength = lstrlenA(pEntry[i].szName) + 1;
        WriteFile(hFile, pEntry[i].szName, dwLength, &dwLength, NULL);
        if (lpExt && *lpExt == 0)
        {
            *lpExt = '.';
        }

        WriteFile(hFile, &pEntry[i].l64Offset, sizeof(*pEntry) - sizeof(pEntry->szName), &dwLength, NULL);
    }
    dwCount = SetFilePointer(hFile, 0, 0, FILE_CURRENT) - sizeof(TPAZHeader);

    dwRemainder = dwCount % 8;
    if (dwRemainder)
    {
        dwRemainder = 8 - dwRemainder;
        WriteFile(hFile, byMod8, dwRemainder, &dwLength, NULL);
        dwCount += dwRemainder;
    }

    if (bEncrypt)
    {
        HANDLE hHeap;
        CBlowFish bf;

        hHeap = ghHeap;
        pbEntry = (PBYTE)HeapAlloc(hHeap, 0, dwCount);
        SetFilePointer(hFile, 0x24, 0, FILE_BEGIN);
        ReadFile(hFile, pbEntry, dwCount, &dwLength, NULL);

        bf.Initialize(GameInfo[dwInfoIndex].key[dwKeyIndex].IndexKey, sizeof(GameInfo[dwInfoIndex].key[dwKeyIndex].IndexKey));
        dwLength = bf.Encode(pbEntry, pbEntry, dwLength);
        if (bNeedXor)
        {
            Xor(pbEntry, dwLength);
        }

        SetFilePointer(hFile, 0x24, 0, FILE_BEGIN);
        WriteFile(hFile, pbEntry, dwLength, &dwLength, NULL);
        dwCount = SetFilePointer(hFile, 0, 0, FILE_CURRENT) - sizeof(TPAZHeader) + 4;
    }
    dwCount += 4;

    SetFilePointer(hFile, 0x20, NULL, FILE_BEGIN);
    WriteFile(hFile, &dwCount, 4, &dwLength, NULL); // entry size
    if (bEncrypt && bNeedXor)
    {
        CHAR h[0x24];
        SetFilePointer(hFile, 0, NULL, FILE_BEGIN);
        ReadFile(hFile, h, sizeof(h), &dwLength, NULL);
        Xor((PBYTE)h, sizeof(h));
        SetFilePointer(hFile, 0, NULL, FILE_BEGIN);
        WriteFile(hFile, h, sizeof(h), &dwLength, NULL);
    }
    SetFilePointer(hFile, 0, 0, FILE_END);
}
Beispiel #5
0
int Compact(TCHAR* szFolder,TCHAR* szFileName)
{
	DWORD temp;
	int len=lstrlen(szFolder);
	if(szFolder[len-1]=='\\')
		szFolder[len-1]='\0';

	if(!(GetFileAttributes(szFolder)&FILE_ATTRIBUTE_DIRECTORY))
	{
		Mbe(TEXT("目录错误"));
		return -1;
	}

	vector<LPTSTR> vFiles;
	GetDirectoryFiles(szFolder,&vFiles,lstrlen(szFolder)+1);

	string* prefix=GetPrefix((char*)szFolder);

	key_info_t  keys;
	for (unsigned long i = 0; !GAME_INFO.keys[i].prefix.empty(); i++)
	{
		if (*prefix == GAME_INFO.keys[i].prefix)
		{
			keys = GAME_INFO.keys[i];
		}
	}
	if (keys.prefix.empty())
	{
		Mbe(TEXT("请使用scr,mov等游戏目录中已存在的目录名"));
		delete prefix;
		FreeDirectoryFiles(&vFiles);
		return -1;
	}

	bool is_audio = *prefix == "bgm" || *prefix == "se" || *prefix == "voice" || *prefix == "PMvoice";
	bool is_mov   = *prefix == "mov";

	delete prefix;

	int idxlen=4;
	for(int i=0;i<vFiles.size();i++)
	{
		idxlen+=lstrlen(vFiles[i])+1+0x18;
	}
	if(is_mov)
		idxlen+=256;

	HANDLE hNewFile=CreateFile(szFileName,GENERIC_WRITE,FILE_SHARE_READ,0,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,0);
	if(hNewFile==INVALID_HANDLE_VALUE)
	{
		Mbe(TEXT("无法访问封包文件!"));
		FreeDirectoryFiles(&vFiles);
		return -1;
	}

	BYTE mov_block[256];
	memset(mov_block,0,256);

	MyPazEnt* ents=new MyPazEnt[vFiles.size()];
	MyPazEnt* pe=ents;
	DWORD offset=((idxlen+7)&~7)+sizeof(PAZHDR);
	CBlowFish bf;
	string rootpath=szFolder;
	rootpath+="\\";
	for(int i=0;i<vFiles.size();i++)
	{
		pe->fn=vFiles[i];
		HANDLE hf=CreateFile((rootpath+vFiles[i]).c_str(),GENERIC_READ,FILE_SHARE_READ,0,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,0);
		if(hf==INVALID_HANDLE_VALUE)
		{
			delete[] ents;
			FreeDirectoryFiles(&vFiles);
			sprintf(errmes,"无法访问%s!",vFiles[i]);
			Mbe(errmes);
			return -1;
		}

		DWORD fsize=GetFileSize(hf,0);
		pe->comprlen=fsize;
		pe->uncomprlen=fsize;
		pe->decryptlen=(fsize+7)&~7;
		pe->unk=0;
		pe->iscompr=0;
		pe->offset=offset;
		offset+=pe->decryptlen;

		BYTE* buf=new BYTE[pe->decryptlen];
		memset(buf+pe->decryptlen-8,0,8);
		ReadFile(hf,buf,fsize,&temp,0);

		string* seed=MakeSeed(pe);

		if(is_mov)
		{
			if(seed==NULL)
			{
				delete[] buf;
				delete[] ents;
				FreeDirectoryFiles(&vFiles);
				Mbe(TEXT("视频格式错误!"));
				return -1;
			}
			decrypt_mov(mov_block,*seed,buf,pe->decryptlen);
			delete seed;
		}
		else
		{
			if(seed!=NULL)
			{
				unobfuscate3(*seed,buf,pe->decryptlen);
				delete seed;
			}

			bf.Initialize(keys.dat_key,sizeof(keys.dat_key));
			bf.Encode(buf,buf,pe->decryptlen);
		}

		SetFilePointer(hNewFile,pe->offset,0,FILE_BEGIN);
		WriteFile(hNewFile,buf,pe->decryptlen,&temp,0);
		
		delete[] buf;
		CloseHandle(hf);
		pe++;
	}

	PAZHDR hdr;
	strcpy((char*)&hdr,"mashiroiro");
	hdr.toc_len=(idxlen+7)&~7;
	SetFilePointer(hNewFile,0,0,FILE_BEGIN);
	WriteFile(hNewFile,&hdr,sizeof(hdr),&temp,0);

	BYTE* idxbuff=new BYTE[idxlen];
	BYTE* p=idxbuff;
	*(DWORD*)p=vFiles.size();
	p+=4;
	if(is_mov)
	{
		memset(p,0,256);
		p+=256;
	}
	pe=ents;
	for(int i=0;i<vFiles.size();i++)
	{
		strcpy((char*)p,pe->fn);
		p+=strlen(pe->fn)+1;
		memcpy(p,&(pe->offset),0x18);
		p+=0x18;
		pe++;
	}
	//bf.Initialize(keys.toc_key,sizeof(keys.toc_key));
	//bf.Encode(idxbuff,idxbuff,hdr.toc_len);

	WriteFile(hNewFile,idxbuff,idxlen,&temp,0);

	CloseHandle(hNewFile);
	delete[] idxbuff;
	delete[] ents;
	FreeDirectoryFiles(&vFiles);
	return 0;
}