From 725a6ca583b994ff170b4aa812262e4e26274df9 Mon Sep 17 00:00:00 2001 From: King_DuckZ Date: Tue, 5 May 2020 20:22:35 +0200 Subject: [PATCH] v0.30 --- UnAlz.cpp | 118 ++++++++++++++++++++++++++++++++++++++++++++++- UnAlz.h | 44 +++++++++++++++--- UnAlzBzip2.cpp | 2 + clear.bat | 0 main.cpp | 13 +++++- makefile | 2 +- makefile.freebsd | 3 +- 7 files changed, 170 insertions(+), 12 deletions(-) mode change 100644 => 100755 clear.bat diff --git a/UnAlz.cpp b/UnAlz.cpp index dd1722b..e98629a 100644 --- a/UnAlz.cpp +++ b/UnAlz.cpp @@ -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= 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); +} + diff --git a/UnAlz.h b/UnAlz.h index e73303d..07ec055 100644 --- a/UnAlz.h +++ b/UnAlz.h @@ -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; ///< ¾ÐÃàÆÄÀÏ ³»ÀÇ ÆÄÀÏ ¸ñ·Ï diff --git a/UnAlzBzip2.cpp b/UnAlzBzip2.cpp index d519d19..6b35507 100644 --- a/UnAlzBzip2.cpp +++ b/UnAlzBzip2.cpp @@ -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; diff --git a/clear.bat b/clear.bat old mode 100644 new mode 100755 diff --git a/main.cpp b/main.cpp index 962d473..79de53a 100644 --- a/main.cpp +++ b/main.cpp @@ -1,4 +1,5 @@ #include +#include #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); diff --git a/makefile b/makefile index 4ce2ccd..c6ae176 100644 --- a/makefile +++ b/makefile @@ -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" diff --git a/makefile.freebsd b/makefile.freebsd index 51217fd..f44670a 100644 --- a/makefile.freebsd +++ b/makefile.freebsd @@ -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