⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 rartool.cpp

📁 一个解压程序,只要设定了解压路径和解压文件的种类,就可以随意解压
💻 CPP
📖 第 1 页 / 共 3 页
字号:
	else
		for(DWORD i=0;i!=Size;i++)
			StartVal+=ptr[i],StartVal=(WORD)rol(StartVal,1);
	return StartVal;
}
void CRarTool::EncryptBlock(BYTE *Buf)
{
	int I;
	DWORD A,B,C,D,T,TA,TB;
	DWORD *BufPtr;
	BufPtr=(DWORD *)Buf;
	A=BufPtr[0]^Key[0];
	B=BufPtr[1]^Key[1];
	C=BufPtr[2]^Key[2];
	D=BufPtr[3]^Key[3];
	for(I=0;I<NROUNDS;I++)
	{
		T=((C+rol(D,11))^Key[I&3]);
		TA=A^substLong(T);
		T=((D^rol(C,17))+Key[I&3]);
		TB=B^substLong(T);
		A=C;
		B=D;
		C=TA;
		D=TB;
	}
	BufPtr[0]=C^Key[0];
	BufPtr[1]=D^Key[1];
	BufPtr[2]=A^Key[2];
	BufPtr[3]=B^Key[3];
	UpdKeys(Buf);
}
void CRarTool::DecryptBlock(BYTE *Buf)
{
	int I;
	BYTE InBuf[16];
	DWORD A,B,C,D,T,TA,TB;
	DWORD *BufPtr;
	BufPtr=(DWORD *)Buf;
	A=BufPtr[0]^Key[0];
	B=BufPtr[1]^Key[1];
	C=BufPtr[2]^Key[2];
	D=BufPtr[3]^Key[3];
	memcpy(InBuf,Buf,sizeof(InBuf));
	for(I=NROUNDS-1;I>=0;I--)
	{
		T=((C+rol(D,11))^Key[I&3]);
		TA=A^substLong(T);
		T=((D^rol(C,17))+Key[I&3]);
		TB=B^substLong(T);
		A=C;
		B=D;
		C=TA;
		D=TB;
	}
	BufPtr[0]=C^Key[0];
	BufPtr[1]=D^Key[1];
	BufPtr[2]=A^Key[2];
	BufPtr[3]=B^Key[3];
	UpdKeys(InBuf);
}
void CRarTool::UpdKeys(BYTE *Buf)
{
	for( int i=0;i!=16;i+=4)
	{
		Key[0]^=crcTable[Buf[i]];
		Key[1]^=crcTable[Buf[i+1]];
		Key[2]^=crcTable[Buf[i+2]];
		Key[3]^=crcTable[Buf[i+3]];
	}
}
void CRarTool::Swap(BYTE *Ch1,BYTE *Ch2)
{
	BYTE Ch=*Ch1;
	*Ch1=*Ch2;
	*Ch2=Ch;
}
void CRarTool::SetCryptKeys(char *Password)
{
	unsigned int I,J,K,PswLength;
	BYTE N1,N2;
	unsigned char Psw[256];
	SetOldKeys(Password);
	Key[0]=0xD3A3B879L;
	Key[1]=0x3F6D12F7L;
	Key[2]=0x7515A235L;
	Key[3]=0xA4E7F123L;
	memset(Psw,0,sizeof(Psw));
	strcpy((char*)Psw,Password);
	PswLength=strlen(Password);
	memcpy(SubstTable,InitSubstTable,sizeof(SubstTable));
	for(J=0;J!=256;J++)
		for(I=0;I<PswLength;I+=2)
		{
			N2=(BYTE)crcTable[(Psw[I+1]+J)&0xFF];
			for(K=1,N1=(BYTE)crcTable[(Psw[I]-J)&0xFF];(N1-N2)&0xFF;N1++,K++)
				Swap(&SubstTable[N1&0xFF],&SubstTable[(N1+I+K)&0xFF]);
		}
	for(I=0;I<PswLength;I+=16)
		EncryptBlock(&Psw[I]);
}
void CRarTool::SetOldKeys(char *Password)
{
	DWORD PswCRC;
	BYTE Ch;
	PswCRC=UpdateChecker(0xFFFFFFFFL,(BYTE*)Password,strlen(Password),true);
	OldKey[0]=(WORD)PswCRC;
	OldKey[1]=(WORD)(PswCRC>>16);
	OldKey[2]=OldKey[3]=0;
	PN1=PN2=PN3=0;
	while((Ch=*Password)!=0)
	{
		PN1+=Ch;
		PN2^=Ch;
		PN3+=Ch;
		PN3=(BYTE)rol(PN3,1);
		OldKey[2]^=(WORD)(Ch^crcTable[Ch]);
		OldKey[3]+=(WORD)(Ch+(crcTable[Ch]>>16));
		Password++;
	}
}
void CRarTool::Crypt(BYTE *Data,DWORD Count,int Method)
{
	if( Method==OLD_DECODE )
		Decode13(Data,Count);
	else
		if( Method==OLD_ENCODE )
			Encode13(Data,Count);
		else
			Crypt15(Data,Count);
}
void CRarTool::Encode13(BYTE *Data,DWORD Count)
{
	while(Count--)
	{
		PN2+=PN3;
		PN1+=PN2;
		*Data+=PN1;
		Data++;
	}
}
void CRarTool::Decode13(BYTE *Data,DWORD Count)
{
	while(Count--)
	{
		PN2+=PN3;
		PN1+=PN2;
		*Data-=PN1;
		Data++;
	}
}
void CRarTool::Crypt15(BYTE *Data,DWORD Count)
{
	while(Count--)
	{
		OldKey[0]+=(WORD)0x1234;
		OldKey[1]^=(WORD)crcTable[(OldKey[0] & 0x1fe)>>1];
		OldKey[2]-=(WORD)(crcTable[(OldKey[0] & 0x1fe)>>1]>>16);
		OldKey[0]^=OldKey[2];
		OldKey[3]=(WORD)ror(OldKey[3],1)^OldKey[1];
		OldKey[3]=(WORD)ror(OldKey[3],1);
		OldKey[0]^=OldKey[3];
		*Data^=(BYTE)(OldKey[0]>>8);
		Data++;
	}
}

/******* 偄傠偄傠 ***************************/

DWORD CRarTool::UnpRead(BYTE *Addr,DWORD Count)
{
	unsigned int RetCode=0,ReadSize,TotalRead=0;
	unsigned char *ReadAddr=Addr;

	while( Count>0 )
	{
		ReadSize=(unsigned int)((Count>(unsigned long)UnpPackedSize) ? UnpPackedSize : Count);
		if(arc==NULL)
			return 0;
		RetCode=fread(ReadAddr,1,ReadSize,arc);
		if( NewLhd.Flags&LHD_SPLIT_AFTER )
			PackedCRC=UpdateChecker(PackedCRC,ReadAddr,ReadSize,true);
		CurUnpRead+=RetCode;
		ReadAddr+=RetCode;
		TotalRead+=RetCode;
		Count-=RetCode;
		UnpPackedSize-=RetCode;
		if( UnpPackedSize==0 && bNeedNextVol )
			GetNextVolume();
		else
			break;
	}
	if( RetCode!=0xffffffff )
	{
		RetCode=TotalRead;
		if( Encryption )
			if( Encryption<20 )
				Crypt(Addr,RetCode,(Encryption==15)?NEW_CRYPT:OLD_DECODE);
		else
			for(DWORD I=0;I<RetCode;I+=16)
				DecryptBlock(&Addr[I]);
	}
	return RetCode;
}

DWORD CRarTool::UnpWrite(BYTE *Addr,DWORD Count)
{
	DWORD RetCode=fwrite(Addr,1,Count,out);
	CurUnpWrite+=RetCode;
	UnpFileCRC=UpdateChecker(UnpFileCRC,Addr,RetCode,ArcFormat==NEW);
	return RetCode;
}

void CRarTool::Unstore()
{
	int Code;
	BYTE* TempMemory=new BYTE[0x8000];
	while( true )
	{
		if( (Code=UnpRead(TempMemory,0x8000))<=0 )
			break;
		Code=(int)Min((unsigned long)Code,(unsigned long)DestUnpSize);
		UnpWrite(TempMemory,Code);
		if( DestUnpSize>=0 )
			DestUnpSize-=Code;
	}
	delete [] TempMemory;
}

bool CRarTool::GetNextVolume()
{
	fclose(arc);

//	char *ChPtr;
	TCHAR *ChPtr; //fixed by uema2.
	TCHAR t_ArcName[MAX_PATH];

	//ArcName傪TCHAR偵 by uema2.
	_MultiByteToWideChar(CP_ACP, 0, ArcName, strlen(ArcName)+1,
		t_ArcName, strlen(ArcName)+1);

//	if( (ChPtr=strrchr(ArcName,'.'))==NULL )
//		strcat(ArcName,".rar"),ChPtr=strrchr(ArcName,'.');
//	else if( ChPtr[1]==0 || stricmp(ChPtr+1,"exe")==0 )
//		strcpy(ChPtr+1,"rar");
	// 崌偭偰傞偐傢偐傜傫偑寈崘夞旔偺偨傔丒丒丒 by uema2.
	if( (ChPtr=_tcsrchr(t_ArcName,L'.'))==NULL )
		lstrcat(t_ArcName,L".rar"),ChPtr=_tcsrchr(t_ArcName,L'.');
	else if( ChPtr[1]==0 || lstrcmp(ChPtr+1,L"exe")==0 ) 
		lstrcpy(ChPtr+1,L"rar"); 

	if( !('0'<=ChPtr[2] && ChPtr[2]<='9') || !('0'<=ChPtr[3] && ChPtr[3]<='9') )
//		strcpy(ChPtr+2,"00");
		lstrcpy(ChPtr+2,L"00");	// by uema2.
	else
	{
		ChPtr+=3;
		while( (++(*ChPtr))=='9'+1 )
		{
			if( *(ChPtr-1)=='.' )
			{	*ChPtr='A';	break;	}
			else
			{	*ChPtr='0';	ChPtr--;}
		}
	}

	//(TCHAR)t_ArcName傪(char)ArcName偵栠偡 by uema2.
	DWORD charlength = _WideCharToMultiByte(CP_ACP, 0, t_ArcName,
							-1, NULL, 0, NULL, NULL);
	_WideCharToMultiByte(CP_ACP, 0, t_ArcName,
		-1, ArcName, charlength, NULL, NULL);

	if( (arc=fopen(ArcName,"rb"))==NULL )
		return false;
	if( !IsArchive(false) )
		return false;

	fseek(arc,NewMhd.HeadSize-MainHeadSize,SEEK_CUR);
	ReadBlock(FILE_HEAD);
	fseek(arc,NextBlockPos-NewLhd.PackSize,SEEK_SET);
	bNeedNextVol=(0!=(NewLhd.Flags&LHD_SPLIT_AFTER));

	UnpPackedSize=NewLhd.PackSize;
	PackedCRC=0xFFFFFFFF;
	return true;
}

bool CRarTool::IsArchive(bool bStrict)
{
	bSolid=false;
	ArcFormat=0;

	if( fread(MarkHead.Mark,1,SIZEOF_MARKHEAD,arc)!=SIZEOF_MARKHEAD )
		return false;

	if( MarkHead.Mark[0]==0x52 && MarkHead.Mark[1]==0x45 && MarkHead.Mark[2]==0x7e && MarkHead.Mark[3]==0x5e)
	{
		ArcFormat=OLD;
		fseek(arc,0,SEEK_SET);
		ReadHeader(MAIN_HEAD);
	}
	else if( MarkHead.Mark[0]==0x52 && MarkHead.Mark[1]==0x61 &&
			 MarkHead.Mark[2]==0x72 && MarkHead.Mark[3]==0x21 &&
			 MarkHead.Mark[4]==0x1a && MarkHead.Mark[5]==0x07 &&
			 MarkHead.Mark[6]==0x00)
	{
		ArcFormat=NEW;
		if( ReadHeader(MAIN_HEAD)!=SIZEOF_NEWMHD )
			return false;
    }
    else
    {
		BYTE* TempMemory=new BYTE[0x20000];
		long CurPos=ftell(arc);
		int ReadSize=fread(TempMemory,1,0x1FFF0,arc);
		unsigned char* ChPtr=TempMemory;

		while( ArcFormat==0 && ChPtr!=NULL && ChPtr<TempMemory+ReadSize )
		{
			if( (ChPtr=(BYTE*)memchr(ChPtr,0x52,ReadSize-(int)(ChPtr-TempMemory)))!=NULL )
			{
				ChPtr++;
				if( ChPtr[0]==0x45 && ChPtr[1]==0x7e && ChPtr[2]==0x5e &&
					TempMemory[28-CurPos]==0x52 && TempMemory[29-CurPos]==0x53 &&
					TempMemory[30-CurPos]==0x46 && TempMemory[31-CurPos]==0x58)
				{
					ArcFormat=OLD;
					fseek(arc,(CurPos+ChPtr-TempMemory-1),SEEK_SET);
					ReadHeader(MAIN_HEAD);
				}
				if( ChPtr[0]==0x61 && ChPtr[1]==0x72 && ChPtr[2]==0x21 &&
					ChPtr[3]==0x1a && ChPtr[4]==0x07 && ChPtr[5]==0x00 &&
					ChPtr[8]==MAIN_HEAD)
				{
					ArcFormat=NEW;
					fseek(arc,(CurPos+ChPtr-TempMemory-1),SEEK_SET);
					fread(MarkHead.Mark,1,SIZEOF_MARKHEAD,arc);
					ReadHeader(MAIN_HEAD);
				}
			}
		}
		delete [] TempMemory;
		if( !ArcFormat )
			return false;
    }

	if( ArcFormat==OLD )
	{
		MainHeadSize=SIZEOF_OLDMHD;
		NewMhd.Flags=OldMhd.Flags & 0x3f;
		NewMhd.HeadSize=OldMhd.HeadSize;
	}
	else
	{
		MainHeadSize=SIZEOF_NEWMHD;
		if( bStrict && (WORD)~HeaderCRC!=NewMhd.HeadCRC )
			return false;
	}

	if( NewMhd.Flags & MHD_SOLID )
		bSolid=true;

	return true;
}

int CRarTool::ReadHeader(int BlockType)
{
	int Size;
	BYTE Header[64];

#define GetHeaderByte(N) Header[N]
#define GetHeaderWord(N) (Header[N]+((WORD)Header[N+1]<<8))
#define GetHeaderDword(N) (Header[N]+((WORD)Header[N+1]<<8)+((DWORD)Header[N+2]<<16)+((DWORD)Header[N+3]<<24))
	switch(BlockType)
	{
	case MAIN_HEAD:
		if(ArcFormat==OLD)
		{
			Size=fread(Header,1,SIZEOF_OLDMHD,arc);
			memcpy(OldMhd.Mark,Header,4);
			OldMhd.HeadSize=GetHeaderWord(4);
			OldMhd.Flags=GetHeaderByte(6);
		}
		else
		{
			Size=fread(Header,1,SIZEOF_NEWMHD,arc);
			NewMhd.HeadCRC=GetHeaderWord(0);
			NewMhd.HeadType=GetHeaderByte(2);
			NewMhd.Flags=GetHeaderWord(3);
			NewMhd.HeadSize=GetHeaderWord(5);
			NewMhd.Reserved=GetHeaderWord(7);
			NewMhd.Reserved1=GetHeaderDword(9);
			HeaderCRC=UpdateChecker(0xFFFFFFFFL,&Header[2],SIZEOF_NEWMHD-2,true);
		}
		break;
    case FILE_HEAD:
		if( ArcFormat==OLD )
		{
			Size=fread(Header,1,SIZEOF_OLDLHD,arc);
			OldLhd.PackSize=GetHeaderDword(0);
			OldLhd.UnpSize=GetHeaderDword(4);
			OldLhd.FileCRC=GetHeaderWord(8);
			OldLhd.HeadSize=GetHeaderWord(10);
			OldLhd.FileTime=GetHeaderDword(12);
			OldLhd.FileAttr=GetHeaderByte(16);
			OldLhd.Flags=GetHeaderByte(17);
			OldLhd.UnpVer=GetHeaderByte(18);
			OldLhd.NameSize=GetHeaderByte(19);
			OldLhd.Method=GetHeaderByte(20);
		}
		else
		{
			Size=fread(Header,1,SIZEOF_NEWLHD,arc);
			NewLhd.HeadCRC=GetHeaderWord(0);
			NewLhd.HeadType=GetHeaderByte(2);
			NewLhd.Flags=GetHeaderWord(3);
			NewLhd.HeadSize=GetHeaderWord(5);
			NewLhd.PackSize=GetHeaderDword(7);
			NewLhd.UnpSize=GetHeaderDword(11);
			NewLhd.HostOS=GetHeaderByte(15);
			NewLhd.FileCRC=GetHeaderDword(16);
			NewLhd.FileTime=GetHeaderDword(20);
			NewLhd.UnpVer=GetHeaderByte(24);
			NewLhd.Method=GetHeaderByte(25);
			NewLhd.NameSize=GetHeaderWord(26);
			NewLhd.FileAttr=GetHeaderDword(28);
			HeaderCRC=UpdateChecker(0xFFFFFFFFL,&Header[2],SIZEOF_NEWLHD-2,true);
		}
		break;
    case COMM_HEAD:
		Size=fread(Header,1,SIZEOF_COMMHEAD,arc);
		CommHead.HeadCRC=GetHeaderWord(0);
		CommHead.HeadType=GetHeaderByte(2);
		CommHead.Flags=GetHeaderWord(3);
		CommHead.HeadSize=GetHeaderWord(5);
		CommHead.UnpSize=GetHeaderWord(7);
		CommHead.UnpVer=GetHeaderByte(9);
		CommHead.Method=GetHeaderByte(10);
		CommHead.CommCRC=GetHeaderWord(11);
		HeaderCRC=UpdateChecker(0xFFFFFFFFL,&Header[2],SIZEOF_COMMHEAD-2,true);
		break;
    case PROTECT_HEAD:
		Size=fread(Header,1,SIZEOF_PROTECTHEAD,arc);
		ProtectHead.HeadCRC=GetHeaderWord(0);
		ProtectHead.HeadType=GetHeaderByte(2);
		ProtectHead.Flags=GetHeaderWord(3);
		ProtectHead.HeadSize=GetHeaderWord(5);
		ProtectHead.DataSize=GetHeaderDword(7);
		ProtectHead.Version=GetHeaderByte(11);
		ProtectHead.RecSectors=GetHeaderWord(12);
		ProtectHead.TotalBlocks=GetHeaderDword(14);
		memcpy(ProtectHead.Mark,&Header[18],8);
		HeaderCRC=UpdateChecker(0xFFFFFFFFL,&Header[2],SIZEOF_PROTECTHEAD-2,true);
		break;
    case ALL_HEAD:
		Size=fread(Header,1,SIZEOF_SHORTBLOCKHEAD,arc);
		BlockHead.HeadCRC=GetHeaderWord(0);
		BlockHead.HeadType=GetHeaderByte(2);
		BlockHead.Flags=GetHeaderWord(3);
		BlockHead.HeadSize=GetHeaderWord(5);
		if( BlockHead.Flags&LONG_BLOCK )
		{
			Size+=fread(&Header[7],1,4,arc);
			BlockHead.DataSize=GetHeaderDword(7);
		}
		break;
	}
	return Size;
}

int CRarTool::ReadBlock(int BlockType)
{
	NewFileHeader SaveFileHead;
	int Size,CurBlockPos=0;
	bool ReadSubBlock=(0!=(BlockType&READSUBBLOCK));
	static int LastBlock;
	memcpy(&SaveFileHead,&NewLhd,sizeof(SaveFileHead));
	BlockType &= 0xff;

	if( ArcFormat==OLD )
	{
		memset(&OldLhd,0,sizeof(OldLhd));
		CurBlockPos=ftell(arc);
		Size=ReadHeader(FILE_HEAD);
		if (Size != 0)
			if (OldLhd.Method > SIZEOF_SHORTBLOCKHEAD || OldLhd.NameSize==0 || OldLhd.NameSize > 80 ||
				OldLhd.UnpVer==0 || OldLhd.UnpVer > 20 || OldLhd.HeadSize <= 21 ||
				OldLhd.Flags<8 && OldLhd.HeadSize!=21+OldLhd.NameSize)
				return 0;
		NewLhd.HeadType=FILE_HEAD;
		NewLhd.HeadSize=OldLhd.HeadSize;
		NewLhd.Flags=OldLhd.Flags|LONG_BLOCK;
		NewLhd.PackSize=OldLhd.PackSize;
		NewLhd.UnpSize=OldLhd.UnpSize;
		NewLhd.FileTime=OldLhd.FileTime;
		NewLhd.UnpVer=(OldLhd.UnpVer==2) ? 13 : 10;
		NewLhd.Method=OldLhd.Method+0x30;
		NewLhd.NameSize=OldLhd.NameSize;
		NewLhd.FileAttr=OldLhd.FileAttr;
		NewLhd.FileCRC=OldLhd.FileCRC;
		if (Size!=0)
			NextBlockPos=CurBlockPos+OldLhd.HeadSize+OldLhd.PackSize;
	}
	else
	{
		while(true)
		{
			CurBlockPos=ftell(arc);
			Size=ReadHeader(FILE_HEAD);
			if(Size!=0)
			{
				if(NewLhd.HeadSize<SIZEOF_SHORTBLOCKHEAD)
					return 0;
				NextBlockPos=CurBlockPos+NewLhd.HeadSize;
				if( NewLhd.Flags&LONG_BLOCK )
					NextBlockPos+=NewLhd.PackSize;
				if( NextBlockPos<=CurBlockPos )
					return 0;
			}

			if( Size>0 && BlockType!=SUB_HEAD )
				LastBlock=BlockType;
			if( Size==0 || BlockType==ALL_HEAD || NewLhd.HeadType==BlockType ||
				(NewLhd.HeadType==SUB_HEAD && ReadSubBlock && LastBlock==BlockType) )
				break;
			fseek(arc,NextBlockPos,SEEK_SET);
		}
	}

	BlockHead.HeadCRC=NewLhd.HeadCRC;
	BlockHead.HeadType=NewLhd.HeadType;
	BlockHead.Flags=NewLhd.Flags;
	BlockHead.HeadSize=NewLhd.HeadSize;
	BlockHead.DataSize=NewLhd.PackSize;

	if( BlockType!=NewLhd.HeadType )
		BlockType=ALL_HEAD;

	if( BlockType==FILE_HEAD )
	{
		if( Size>0 )
		{
			NewLhd.NameSize=Min(NewLhd.NameSize,sizeof(ExtrName)-1);
			fread(ExtrName,1,NewLhd.NameSize,arc);
			ExtrName[NewLhd.NameSize]=0;
			if( ArcFormat==NEW && NewLhd.HeadCRC!=(WORD)~UpdateChecker(HeaderCRC,(BYTE*)ExtrName,NewLhd.NameSize,true) )
				return 0;
			Size+=NewLhd.NameSize;
		}
	}
	else
	{
		memcpy(&NewLhd,&SaveFileHead,sizeof(NewLhd));
		fseek(arc,CurBlockPos,SEEK_SET);
	}

	return Size;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -