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-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-not enough space of buffer to convert", // ERR_ICONV_NOT_ENOUGH_SPACE_OF_BUFFER_TO_CONVERT,
"iconv-etc", // ERR_ICONV_ETC, "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_nVirtualFilePos = 0;
m_nCurFilePos = 0; m_nCurFilePos = 0;
m_bIsEOF = FALSE; m_bIsEOF = FALSE;
m_bIsEncrypted = FALSE;
m_bIsDataDescr = FALSE;
#ifdef _UNALZ_ICONV #ifdef _UNALZ_ICONV
@ -159,7 +165,7 @@ void CUnAlz::SetCallback(_UnAlzCallback* pFunc, void* param)
} }
#ifdef _WIN32 #ifdef _WIN32
#ifndef __GNUWIN32__ #if !defined(__GNUWIN32__) && !defined(__GNUC__)
//////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////
/// 파일 열기 /// 파일 열기
/// @param szPathName /// @param szPathName
@ -319,6 +325,13 @@ BOOL CUnAlz::ReadLocalFileheader()
} }
// ALZ 확장.. // 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; int byteLen = zipHeader.head.fileSizeByte/0x10;
if(byteLen) if(byteLen)
@ -335,6 +348,7 @@ BOOL CUnAlz::ReadLocalFileheader()
zipHeader.head.fileNameLength = unalz_le16toh(zipHeader.head.fileNameLength); zipHeader.head.fileNameLength = unalz_le16toh(zipHeader.head.fileNameLength);
zipHeader.compressedSize = unalz_le64toh(zipHeader.compressedSize); zipHeader.compressedSize = unalz_le64toh(zipHeader.compressedSize);
zipHeader.uncompressedSize = unalz_le64toh(zipHeader.uncompressedSize); zipHeader.uncompressedSize = unalz_le64toh(zipHeader.uncompressedSize);
zipHeader.maybeCRC = unalz_le32toh(zipHeader.maybeCRC);
// FILE NAME // FILE NAME
zipHeader.fileName = (char*)malloc(zipHeader.head.fileNameLength+1); 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 // SKIP FILE DATA
zipHeader.dwFileDataPos = FTell(); // data 의 위치 저장하기.. zipHeader.dwFileDataPos = FTell(); // data 의 위치 저장하기..
FSeek(FTell()+zipHeader.compressedSize); FSeek(FTell()+zipHeader.compressedSize);
@ -594,6 +610,11 @@ BOOL CUnAlz::ExtractCurrentFile(const char* szDestPathName, const char* szDestFi
SExtractDest dest; SExtractDest dest;
char szDestPathFileName[MAX_PATH]; char szDestPathFileName[MAX_PATH];
if(chkValidPassword() == FALSE)
{
return FALSE;
}
// 경로명 // 경로명
strcpy(szDestPathFileName, szDestPathName); strcpy(szDestPathFileName, szDestPathName);
if(szDestPathFileName[strlen(szDestPathFileName)]!=PATHSEPC) 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++) for(i=m_fileList.begin(); i<m_fileList.end(); i++)
{ {
m_posCur = i; m_posCur = i;
ExtractCurrentFile(szDestPathName); if(ExtractCurrentFile(szDestPathName)==FALSE) return FALSE;
if(m_bHalt) if(m_bHalt)
break; // 멈추기.. break; // 멈추기..
} }
@ -1001,6 +1022,9 @@ BOOL CUnAlz::ExtractRawfile(SExtractDest* dest, SLocalFileHeader& file)
{ {
break; break;
} }
CryptDecodeBuffer((int)read, (CHAR *)buf); // xf86
WriteToDest(dest, buf, (int)read); WriteToDest(dest, buf, (int)read);
//fwrite(buf, read, 1, fp); //fwrite(buf, read, 1, fp);
sizeToRead -= read; sizeToRead -= read;
@ -1172,6 +1196,8 @@ BOOL CUnAlz::ExtractDeflate2(SExtractDest* dest, SLocalFileHeader& file)
goto END; goto END;
} }
CryptDecodeBuffer(uReadThis, (CHAR *)pInBuf); // xf86
nRestReadCompressed -= uReadThis; nRestReadCompressed -= uReadThis;
stream.next_in = pInBuf; stream.next_in = pInBuf;
stream.avail_in = uReadThis; 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; } if(nERR>= sizeof(errorstrtable)/sizeof(errorstrtable[0])) {ASSERT(0); return NULL; }
return errorstrtable[nERR]; 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 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/25 - by yongari : __LP64__ , (le64toh/le132oh/le16toh)
2004/10/26 - BSD/LINUX : byte-order, libiconv 2004/10/26 - BSD/LINUX : byte-order, libiconv
2004/10/30 - & .. 2004/10/30 - & ..
2004/11/14 - by xxfre86 :
: ( * ) : ( * )
- bzip2 * - bzip2 *
- UI ( PROGRESS, , ) * - UI ( PROGRESS, , ) *
- * - *
- - *
- -
- CRC - CRC
@ -107,6 +108,9 @@ using namespace std;
#ifndef LONG #ifndef LONG
typedef long LONG; typedef long LONG;
#endif #endif
#ifndef ULONG
typedef unsigned long ULONG; // same as DWORD? i don't know.
#endif
#ifndef BOOL #ifndef BOOL
typedef int BOOL; typedef int BOOL;
#endif #endif
@ -144,10 +148,10 @@ namespace UNALZ
# pragma pack(1) # pragma pack(1)
#endif #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"; static const char UNALZ_COPYRIGHT[] = "Copyright(C) 2004 hardkoder@gmail.com";
enum {ENCR_HEADER_LEN=12}; // xf86
// 맨 파일 앞.. // 맨 파일 앞..
struct SAlzHeader struct SAlzHeader
{ {
@ -180,7 +184,9 @@ enum COMPRESSION_METHOD ///<
struct _SLocalFileHeaderHead ///< 고정 헤더. struct _SLocalFileHeaderHead ///< 고정 헤더.
{ {
SHORT fileNameLength; 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 fileSizeByte; ///< 파일 크기 필드의 크기 : 0x10, 0x20, 0x40, 0x80 각각 1byte, 2byte, 4byte, 8byte
BYTE unknown2[1]; ///< ??? BYTE unknown2[1]; ///< ???
@ -212,7 +218,7 @@ struct SLocalFileHeader
void Clear() { if(fileName) free(fileName); fileName=NULL; if(extraField) free(extraField);extraField=NULL; } void Clear() { if(fileName) free(fileName); fileName=NULL; if(extraField) free(extraField);extraField=NULL; }
_SLocalFileHeaderHead head; _SLocalFileHeaderHead head;
BYTE compressionMethod; ///< 압축 방법 : 2 - deflate, 1 - bzip2(?), 0 - 압축 안함. BYTE compressionMethod; ///< 압축 방법 : 2 - deflate, 1 - 변형 bzip2, 0 - 압축 안함.
BYTE unknown3[1]; ///< ??? BYTE unknown3[1]; ///< ???
UINT32 maybeCRC; ///< 아마도 crc UINT32 maybeCRC; ///< 아마도 crc
@ -223,6 +229,8 @@ struct SLocalFileHeader
BYTE* extraField; BYTE* extraField;
_SDataDescriptor dataDescriptor; _SDataDescriptor dataDescriptor;
INT64 dwFileDataPos; ///< file data 가 저장된 위치.. INT64 dwFileDataPos; ///< file data 가 저장된 위치..
CHAR encChk[ENCR_HEADER_LEN]; // xf86
}; };
struct _SCentralDirectoryStructureHead struct _SCentralDirectoryStructureHead
@ -314,6 +322,9 @@ public:
BOOL ExtractAll(const char* szDestPathName); BOOL ExtractAll(const char* szDestPathName);
void SetCallback(_UnAlzCallback* pFunc, void* param=NULL); 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 #ifdef _UNALZ_ICONV
void SetDestCodepage(const char* szToCodepage) { strcpy(m_szToCodepage, szToCodepage); } void SetDestCodepage(const char* szToCodepage) { strcpy(m_szToCodepage, szToCodepage); }
#endif #endif
@ -363,6 +374,10 @@ public :
ERR_ICONV_NOT_ENOUGH_SPACE_OF_BUFFER_TO_CONVERT, ERR_ICONV_NOT_ENOUGH_SPACE_OF_BUFFER_TO_CONVERT,
ERR_ICONV_ETC, ERR_ICONV_ETC,
ERR_PASSWD_NOT_SET,
ERR_INVALID_PASSWD,
ERR_USER_ABORTED,
}; };
ERR GetLastErr(){return m_nErr;} ERR GetLastErr(){return m_nErr;}
const char* GetLastErrStr(){return LastErrToStr(m_nErr);} const char* GetLastErrStr(){return LastErrToStr(m_nErr);}
@ -383,6 +398,7 @@ public :
static BOOL IsFolder(LPCSTR szPathName); static BOOL IsFolder(LPCSTR szPathName);
static const char* GetVersion() { return UNALZ_VERSION; } static const char* GetVersion() { return UNALZ_VERSION; }
static const char* GetCopyright() { return UNALZ_COPYRIGHT; } static const char* GetCopyright() { return UNALZ_COPYRIGHT; }
BOOL IsHalted() { return m_bHalt; } // by xf86
private : private :
SIGNATURE ReadSignature(); SIGNATURE ReadSignature();
@ -432,6 +448,17 @@ private : //
BOOL FSeek(INT64 offset); BOOL FSeek(INT64 offset);
BOOL FRead(void* buffer, UINT32 nBytesToRead, int* pTotRead=NULL); 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 {MAX_FILES=1000}; ///< 처리 가능한 분할 압축 파일 수.
enum {MULTIVOL_TAIL_SIZE=16,MULTIVOL_HEAD_SIZE=8}; ///< 분할 압축시 꼴랑지, 헤더 크기 enum {MULTIVOL_TAIL_SIZE=16,MULTIVOL_HEAD_SIZE=8}; ///< 분할 압축시 꼴랑지, 헤더 크기
struct SFile ///< 분할 파일 정보 struct SFile ///< 분할 파일 정보
@ -449,6 +476,11 @@ private : //
INT64 m_nCurFilePos; ///< 현재 파일의 물리적 위치. INT64 m_nCurFilePos; ///< 현재 파일의 물리적 위치.
BOOL m_bIsEOF; ///< 파일의 끝까지 (분할 파일 포함해서) 왔나? BOOL m_bIsEOF; ///< 파일의 끝까지 (분할 파일 포함해서) 왔나?
BOOL m_bIsEncrypted; // xf86
BOOL m_bIsDataDescr;
char m_szPasswd[256];
UINT32 m_keys[3];
private : private :
FileList m_fileList; ///< 압축파일 내의 파일 목록 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()) { if (bzf->strm.avail_in == 0 && !bzf->handle->FEof()) {
bzf->handle->FRead(bzf->buf, sizeof(UChar)*BZ_MAX_UNUSED, &n); 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) if(n==0)
{ BZ_SETERR(BZ_IO_ERROR); return 0; }; { BZ_SETERR(BZ_IO_ERROR); return 0; };
bzf->bufN = n; bzf->bufN = n;

0
clear.bat Normal file → Executable file
View file

View file

@ -1,4 +1,5 @@
#include <stdio.h> #include <stdio.h>
#include <iostream>
#include "UnAlz.h" #include "UnAlz.h"
@ -69,7 +70,8 @@ int main(int argc, char* argv[])
{ {
// printf("unalz v0.20 (2004/10/22) \n"); // printf("unalz v0.20 (2004/10/22) \n");
// printf("unalz v0.22 (2004/10/27) \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"); printf("copyright(C) 2004 http://www.kipple.pe.kr\n");
if(argc<2) if(argc<2)
@ -126,8 +128,15 @@ int main(int argc, char* argv[])
return 0; 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 窃荐 技泼 // callback 窃荐 技泼
unalz.SetCallback(UnAlzCallback, (void*)NULL); unalz.SetCallback(UnAlzCallback, (void*)NULL);

View file

@ -18,7 +18,7 @@ all:
@echo "" @echo ""
@echo " posix : POSIX system (FreeBSD/linux/OSX/sparc)" @echo " posix : POSIX system (FreeBSD/linux/OSX/sparc)"
@echo " posix-utf8 : POSIX with utf8 filesystem(OSX)" @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 ""
@echo " and 'clean' for clean" @echo " and 'clean' for clean"

View file

@ -2,7 +2,8 @@
PROG= unalz PROG= unalz
NOMAN= 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++ LDADD+= -lz -lbz2 -liconv -lstdc++
.include <bsd.prog.mk> .include <bsd.prog.mk>