This commit is contained in:
King_DuckZ 2020-05-05 20:22:35 +02:00
parent 06b37f8d16
commit 725a6ca583
7 changed files with 170 additions and 12 deletions

118
UnAlz.cpp
View file

@ -105,6 +105,10 @@ static const char* errorstrtable[]=
"iconv-incomplete multibyte sequence", // ERR_ICONV_INCOMPLETE_MULTIBYTE_SEQUENCE,
"iconv-not enough space of buffer to convert", // ERR_ICONV_NOT_ENOUGH_SPACE_OF_BUFFER_TO_CONVERT,
"iconv-etc", // ERR_ICONV_ETC,
"password not set", //ERR_PASSWD_NOT_SET,
"invalid password", //ERR_INVALID_PASSWD,
"User Aborted",
};
@ -126,6 +130,8 @@ CUnAlz::CUnAlz()
m_nVirtualFilePos = 0;
m_nCurFilePos = 0;
m_bIsEOF = FALSE;
m_bIsEncrypted = FALSE;
m_bIsDataDescr = FALSE;
#ifdef _UNALZ_ICONV
@ -159,7 +165,7 @@ void CUnAlz::SetCallback(_UnAlzCallback* pFunc, void* param)
}
#ifdef _WIN32
#ifndef __GNUWIN32__
#if !defined(__GNUWIN32__) && !defined(__GNUC__)
////////////////////////////////////////////////////////////////////////////////////////////////////
/// 파일 열기
/// @param szPathName
@ -319,6 +325,13 @@ BOOL CUnAlz::ReadLocalFileheader()
}
// ALZ 확장..
if( (zipHeader.head.fileSizeByte & (SHORT)1) != 0){
m_bIsEncrypted = TRUE;
}
if( (zipHeader.head.fileSizeByte & (SHORT)8) != 0){
m_bIsDataDescr = TRUE;
}
int byteLen = zipHeader.head.fileSizeByte/0x10;
if(byteLen)
@ -335,6 +348,7 @@ BOOL CUnAlz::ReadLocalFileheader()
zipHeader.head.fileNameLength = unalz_le16toh(zipHeader.head.fileNameLength);
zipHeader.compressedSize = unalz_le64toh(zipHeader.compressedSize);
zipHeader.uncompressedSize = unalz_le64toh(zipHeader.uncompressedSize);
zipHeader.maybeCRC = unalz_le32toh(zipHeader.maybeCRC);
// FILE NAME
zipHeader.fileName = (char*)malloc(zipHeader.head.fileNameLength+1);
@ -422,6 +436,8 @@ BOOL CUnAlz::ReadLocalFileheader()
}
*/
if(IsEncrypted()) FRead(zipHeader.encChk, ENCR_HEADER_LEN); // xf86
// SKIP FILE DATA
zipHeader.dwFileDataPos = FTell(); // data 의 위치 저장하기..
FSeek(FTell()+zipHeader.compressedSize);
@ -594,6 +610,11 @@ BOOL CUnAlz::ExtractCurrentFile(const char* szDestPathName, const char* szDestFi
SExtractDest dest;
char szDestPathFileName[MAX_PATH];
if(chkValidPassword() == FALSE)
{
return FALSE;
}
// 경로명
strcpy(szDestPathFileName, szDestPathName);
if(szDestPathFileName[strlen(szDestPathFileName)]!=PATHSEPC)
@ -760,7 +781,7 @@ BOOL CUnAlz::ExtractAll(const char* szDestPathName)
for(i=m_fileList.begin(); i<m_fileList.end(); i++)
{
m_posCur = i;
ExtractCurrentFile(szDestPathName);
if(ExtractCurrentFile(szDestPathName)==FALSE) return FALSE;
if(m_bHalt)
break; // 멈추기..
}
@ -1001,6 +1022,9 @@ BOOL CUnAlz::ExtractRawfile(SExtractDest* dest, SLocalFileHeader& file)
{
break;
}
CryptDecodeBuffer((int)read, (CHAR *)buf); // xf86
WriteToDest(dest, buf, (int)read);
//fwrite(buf, read, 1, fp);
sizeToRead -= read;
@ -1172,6 +1196,8 @@ BOOL CUnAlz::ExtractDeflate2(SExtractDest* dest, SLocalFileHeader& file)
goto END;
}
CryptDecodeBuffer(uReadThis, (CHAR *)pInBuf); // xf86
nRestReadCompressed -= uReadThis;
stream.next_in = pInBuf;
stream.avail_in = uReadThis;
@ -1455,3 +1481,91 @@ const char* CUnAlz::LastErrToStr(ERR nERR)
if(nERR>= sizeof(errorstrtable)/sizeof(errorstrtable[0])) {ASSERT(0); return NULL; }
return errorstrtable[nERR];
}
// by xf86
BOOL CUnAlz::chkValidPassword()
{
if (IsEncrypted()) {
if (getPasswordLen() == 0){
m_nErr = ERR_PASSWD_NOT_SET;
return FALSE;
}
CryptInitKeys();
if(CryptCheck(m_posCur->encChk) == FALSE){
m_nErr = ERR_INVALID_PASSWD;
return FALSE;
}
}
return TRUE;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
// from CZipArchive
// Copyright (C) 2000 - 2004 Tadeusz Dracz
//
// http://www.artpol-software.com
//
// it's under GPL.
////////////////////////////////////////////////////////////////////////////////////////////////////
void CUnAlz::CryptDecodeBuffer(UINT32 uCount, CHAR *buf)
{
if (IsEncrypted())
for (UINT32 i = 0; i < uCount; i++)
CryptDecode(buf[i]);
}
void CUnAlz::CryptInitKeys()
{
m_keys[0] = 305419896L;
m_keys[1] = 591751049L;
m_keys[2] = 878082192L;
for (int i = 0; i < strlen(m_szPasswd); i++)
CryptUpdateKeys(m_szPasswd[i]);
}
void CUnAlz::CryptUpdateKeys(CHAR c)
{
m_keys[0] = CryptCRC32(m_keys[0], c);
m_keys[1] += m_keys[0] & 0xff;
m_keys[1] = m_keys[1] * 134775813L + 1;
c = CHAR(m_keys[1] >> 24);
m_keys[2] = CryptCRC32(m_keys[2], c);
}
BOOL CUnAlz::CryptCheck(CHAR *buf)
{
CHAR b = 0;
for (int i = 0; i < ENCR_HEADER_LEN; i++)
{
b = buf[i];
CryptDecode((CHAR&)b);
}
if (IsDataDescr()) // Data descriptor present
return CHAR(m_posCur->head.fileTimeDate >> 8) == b;
else
return CHAR(m_posCur->maybeCRC >> 24) == b;
}
CHAR CUnAlz::CryptDecryptCHAR()
{
int temp = (m_keys[2] & 0xffff) | 2;
return (CHAR)(((temp * (temp ^ 1)) >> 8) & 0xff);
}
void CUnAlz::CryptDecode(CHAR &c)
{
c ^= CryptDecryptCHAR();
CryptUpdateKeys(c);
}
UINT32 CUnAlz::CryptCRC32(UINT32 l, CHAR c)
{
const ULONG *CRC_TABLE = get_crc_table();
return CRC_TABLE[(l ^ c) & 0xff] ^ (l >> 8);
}

44
UnAlz.h
View file

@ -2,7 +2,7 @@
COPYRIGHT(C) 2004 hardkoder@gmail.com / http://www.kipple.pe.kr
:
: ( BSD License )
- // .
- , .
- , ..
@ -39,13 +39,14 @@
2004/10/25 - by yongari : __LP64__ , (le64toh/le132oh/le16toh)
2004/10/26 - BSD/LINUX : byte-order, libiconv
2004/10/30 - & ..
2004/11/14 - by xxfre86 :
: ( * )
- bzip2 *
- UI ( PROGRESS, , ) *
- *
-
- *
-
- CRC
@ -107,6 +108,9 @@ using namespace std;
#ifndef LONG
typedef long LONG;
#endif
#ifndef ULONG
typedef unsigned long ULONG; // same as DWORD? i don't know.
#endif
#ifndef BOOL
typedef int BOOL;
#endif
@ -144,10 +148,10 @@ namespace UNALZ
# pragma pack(1)
#endif
static const char UNALZ_VERSION[] = "CUnAlz0.23";
static const char UNALZ_VERSION[] = "CUnAlz0.30";
static const char UNALZ_COPYRIGHT[] = "Copyright(C) 2004 hardkoder@gmail.com";
enum {ENCR_HEADER_LEN=12}; // xf86
// 맨 파일 앞..
struct SAlzHeader
{
@ -180,7 +184,9 @@ enum COMPRESSION_METHOD ///<
struct _SLocalFileHeaderHead ///< 고정 헤더.
{
SHORT fileNameLength;
BYTE unknown[5]; ///< ???
BYTE fileAttribute; // from http://www.zap.pe.kr
UINT32 fileTimeDate;
BYTE fileSizeByte; ///< 파일 크기 필드의 크기 : 0x10, 0x20, 0x40, 0x80 각각 1byte, 2byte, 4byte, 8byte
BYTE unknown2[1]; ///< ???
@ -212,7 +218,7 @@ struct SLocalFileHeader
void Clear() { if(fileName) free(fileName); fileName=NULL; if(extraField) free(extraField);extraField=NULL; }
_SLocalFileHeaderHead head;
BYTE compressionMethod; ///< 압축 방법 : 2 - deflate, 1 - bzip2(?), 0 - 압축 안함.
BYTE compressionMethod; ///< 압축 방법 : 2 - deflate, 1 - 변형 bzip2, 0 - 압축 안함.
BYTE unknown3[1]; ///< ???
UINT32 maybeCRC; ///< 아마도 crc
@ -223,6 +229,8 @@ struct SLocalFileHeader
BYTE* extraField;
_SDataDescriptor dataDescriptor;
INT64 dwFileDataPos; ///< file data 가 저장된 위치..
CHAR encChk[ENCR_HEADER_LEN]; // xf86
};
struct _SCentralDirectoryStructureHead
@ -314,6 +322,9 @@ public:
BOOL ExtractAll(const char* szDestPathName);
void SetCallback(_UnAlzCallback* pFunc, void* param=NULL);
void setPassword(char *passwd) { if(strlen(passwd) == 0) return; strcpy(m_szPasswd, passwd); }; // xf86
BOOL IsEncrypted() { return m_bIsEncrypted; };
#ifdef _UNALZ_ICONV
void SetDestCodepage(const char* szToCodepage) { strcpy(m_szToCodepage, szToCodepage); }
#endif
@ -363,6 +374,10 @@ public :
ERR_ICONV_NOT_ENOUGH_SPACE_OF_BUFFER_TO_CONVERT,
ERR_ICONV_ETC,
ERR_PASSWD_NOT_SET,
ERR_INVALID_PASSWD,
ERR_USER_ABORTED,
};
ERR GetLastErr(){return m_nErr;}
const char* GetLastErrStr(){return LastErrToStr(m_nErr);}
@ -383,6 +398,7 @@ public :
static BOOL IsFolder(LPCSTR szPathName);
static const char* GetVersion() { return UNALZ_VERSION; }
static const char* GetCopyright() { return UNALZ_COPYRIGHT; }
BOOL IsHalted() { return m_bHalt; } // by xf86
private :
SIGNATURE ReadSignature();
@ -432,6 +448,17 @@ private : //
BOOL FSeek(INT64 offset);
BOOL FRead(void* buffer, UINT32 nBytesToRead, int* pTotRead=NULL);
BOOL IsDataDescr() { return m_bIsDataDescr; }; // xf86
int getPasswordLen() { return strlen(m_szPasswd); };
void CryptDecodeBuffer(UINT32 uCount, CHAR *buf);
void CryptInitKeys();
void CryptUpdateKeys(CHAR c);
BOOL CryptCheck(CHAR *buf);
CHAR CryptDecryptCHAR();
void CryptDecode(CHAR &c);
UINT32 CryptCRC32(UINT32 l, CHAR c);
BOOL chkValidPassword(); // xf86
enum {MAX_FILES=1000}; ///< 처리 가능한 분할 압축 파일 수.
enum {MULTIVOL_TAIL_SIZE=16,MULTIVOL_HEAD_SIZE=8}; ///< 분할 압축시 꼴랑지, 헤더 크기
struct SFile ///< 분할 파일 정보
@ -449,6 +476,11 @@ private : //
INT64 m_nCurFilePos; ///< 현재 파일의 물리적 위치.
BOOL m_bIsEOF; ///< 파일의 끝까지 (분할 파일 포함해서) 왔나?
BOOL m_bIsEncrypted; // xf86
BOOL m_bIsDataDescr;
char m_szPasswd[256];
UINT32 m_keys[3];
private :
FileList m_fileList; ///< 압축파일 내의 파일 목록

View file

@ -131,6 +131,8 @@ int CUnAlz::BZ2_bzRead(int* bzerror, MYBZFILE* b, void* buf, int len)
if (bzf->strm.avail_in == 0 && !bzf->handle->FEof()) {
bzf->handle->FRead(bzf->buf, sizeof(UChar)*BZ_MAX_UNUSED, &n);
bzf->handle->CryptDecodeBuffer(n, (CHAR *)bzf->buf); // xf86 NOT tested -> tested
if(n==0)
{ BZ_SETERR(BZ_IO_ERROR); return 0; };
bzf->bufN = n;

0
clear.bat Normal file → Executable file
View file

View file

@ -1,4 +1,5 @@
#include <stdio.h>
#include <iostream>
#include "UnAlz.h"
@ -69,7 +70,8 @@ int main(int argc, char* argv[])
{
// printf("unalz v0.20 (2004/10/22) \n");
// printf("unalz v0.22 (2004/10/27) \n");
printf("unalz v0.23 (2004/10/30) \n");
// printf("unalz v0.23 (2004/10/30) \n");
printf("unalz v0.30 (2004/11/14) \n");
printf("copyright(C) 2004 http://www.kipple.pe.kr\n");
if(argc<2)
@ -126,8 +128,15 @@ int main(int argc, char* argv[])
return 0;
}
printf("\nExtract %s to %s\n", source, destpath);
if(unalz.IsEncrypted()){
char pwd[256];
cout << "Enter Password : ";
cin >> pwd;
unalz.setPassword(pwd);
}
printf("\nExtract %s to %s\n", source, destpath);
// callback 窃荐 技泼
unalz.SetCallback(UnAlzCallback, (void*)NULL);

View file

@ -18,7 +18,7 @@ all:
@echo ""
@echo " posix : POSIX system (FreeBSD/linux/OSX/sparc)"
@echo " posix-utf8 : POSIX with utf8 filesystem(OSX)"
@echo " posix-noiconv : POSIX without libiconv (CP949 only)"
@echo " posix-noiconv : POSIX without libiconv (MINGW32,CP949 file system)"
@echo ""
@echo " and 'clean' for clean"

View file

@ -2,7 +2,8 @@
PROG= unalz
NOMAN=
SRCS= main.cpp UnAlz.cpp UnAlzBz2decompress.c UnAlzBzip2.cpp UnAlzbzlib.c
SRCS= main.cpp UnAlz.cpp UnAlzBz2decompress.c UnAlzBzip2.cpp \
UnAlzbzlib.c
LDADD+= -lz -lbz2 -liconv -lstdc++
.include <bsd.prog.mk>