📄 rartool.cpp
字号:
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 + -