; RAR file generator, isn't used in this release ; ######################################################################### .data ArchiveHeader struct HEAD_CRC WORD ? ; CRC of fields HEAD_TYPE to RESERVED2 HEAD_TYPE BYTE ? ; Header type: 0x73 HEAD_FLAGS WORD ? ; Bit flags HEAD_SIZE WORD ? ; Archive header total size including archive comments RESERVED1 WORD ? ; Reserved RESERVED2 DWORD ? ; Reserved ArchiveHeader ends FileHeader struct HEAD_CRC WORD ? ; CRC of fields from HEAD_TYPE to FILEATTR HEAD_TYPE BYTE ? ; Header type: 0x74 HEAD_FLAGS WORD ? ; Bit flags: 0x04 - file encrypted with password HEAD_SIZE WORD ? ; File header full size including file name and comments PACK_SIZE DWORD ? ; Compressed file size UNP_SIZE DWORD ? ; Uncompressed file size HOST_OS BYTE ? ; Operating system used for archiving FILE_CRC DWORD ? ; File CRC FTIME DWORD ? ; Date and time in standard MS DOS format UNP_VER BYTE ? ; RAR version needed to extract file METHOD BYTE ? ; Packing method NAME_SIZE WORD ? ; File name size ATTR DWORD ? ; File attributes FileHeader ends HEAD_MARKER equ 072h ; Marker block HEAD_ARCHIVE equ 073h ; Archive header HEAD_FILE equ 074h ; File header HEAD_COMNT equ 075h ; Comment header HEAD_EXTRA equ 076h ; Extra information HEAD_SUBBLOCK equ 077h ; Subblock HEAD_RECOVERY equ 078h ; Recovery record NROUNDS equ 32 InitSubstTable db 215, 19,149, 35, 73,197,192,205,249, 28, 16,119, 48,221, 2, 42 db 232, 1,177,233, 14, 88,219, 25,223,195,244, 90, 87,239,153,137 db 255,199,147, 70, 92, 66,246, 13,216, 40, 62, 29,217,230, 86, 6 db 71, 24,171,196,101,113,218,123, 93, 91,163,178,202, 67, 44,235 db 107,250, 75,234, 49,167,125,211, 83,114,157,144, 32,193,143, 36 db 158,124,247,187, 89,214,141, 47,121,228, 61,130,213,194,174,251 db 97,110, 54,229,115, 57,152, 94,105,243,212, 55,209,245, 63, 11 db 164,200, 31,156, 81,176,227, 21, 76, 99,139,188,127, 17,248, 51 db 207,120,189,210, 8,226, 41, 72,183,203,135,165,166, 60, 98, 7 db 122, 38,155,170, 69,172,252,238, 39,134, 59,128,236, 27,240, 80 db 131, 3, 85,206,145, 79,154,142,159,220,201,133, 74, 64, 20,129 db 224,185,138,103,173,182, 43, 34,254, 82,198,151,231,180, 58, 10 db 118, 26,102, 12, 50,132, 22,191,136,111,162,179, 45, 4,148,108 db 161, 56, 78,126,242,222, 15,175,146, 23, 33,241,181,190, 77,225 db 0, 46,169,186, 68, 95,237, 65, 53,208,253,168, 9, 18,100, 52 db 116,184,160, 96,109, 37, 30,106,140,104,150, 5,204,117,112, 84 MarkHeader db 052h, 061h, 072h, 021h, 01ah, 007h, 000h ; Original RAR header .data? SubstTable db 256 dup(?) PN1 db ? PN2 db ? PN3 db ? OldKey0 dw ? OldKey1 dw ? OldKey2 dw ? OldKey3 dw ? Key0 dd ? Key1 dd ? Key2 dd ? Key3 dd ? .code substLong proc uses ebx t: DWORD mov ebx, t xor eax, eax mov edx, ebx and edx, 0ffh shr ebx, 8 mov al, byte ptr[SubstTable+edx] mov edx, ebx and edx, 0ffh shr ebx, 8 mov ah, byte ptr[SubstTable+edx] mov edx, ebx and edx, 0ffh shr ebx, 8 movzx edx, byte ptr[SubstTable+edx] shl edx, 16 or eax, edx mov edx, ebx and edx, 0ffh movzx edx, byte ptr[SubstTable+edx] shl edx, 24 or eax, edx ret substLong endp UpdKeys proc Buf: DWORD mov ecx, 4 mov edx, Buf @l: movzx eax, byte ptr[edx] mov eax, dword ptr[CRCTable+eax*4] xor Key0, eax movzx eax, byte ptr[edx+1] mov eax, dword ptr[CRCTable+eax*4] xor Key1, eax movzx eax, byte ptr[edx+2] mov eax, dword ptr[CRCTable+eax*4] xor Key2, eax movzx eax, byte ptr[edx+3] mov eax, dword ptr[CRCTable+eax*4] xor Key3, eax add edx, 4 loop @l ret UpdKeys endp EncryptBlock proc uses esi Buf: DWORD LOCAL A, B, C1, D, T, TA, TB: DWORD mov esi, Buf m2m A, dword ptr[esi] mov eax, Key0 xor A, eax m2m B, dword ptr[esi+4] mov eax, Key1 xor B, eax m2m C1, dword ptr[esi+8] mov eax, Key2 xor C1, eax m2m D, dword ptr[esi+12] mov eax, Key3 xor D, eax xor ecx, ecx @l: ; T=((C+rol(D,11))^Key[I&3]); mov eax, D rol eax, 11 add eax, C1 mov edx, ecx and edx, 3 xor eax, dword ptr[Key0+edx*4] mov T, eax ; TA=A^substLong(T); invoke substLong, T xor eax, A mov TA, eax ; T=((D^rol(C,17))+Key[I&3]); mov eax, C1 rol eax, 17 xor eax, D mov edx, ecx and edx, 3 add eax, dword ptr[Key0+edx*4] mov T, eax ; TB=B^substLong(T); invoke substLong, T xor eax, B mov TB, eax m2m A, C1 m2m B, D m2m C1, TA m2m D, TB inc ecx cmp ecx, NROUNDS jl @l mov eax, C1 xor eax, Key0 mov dword ptr[esi], eax mov eax, D xor eax, Key1 mov dword ptr[esi+4], eax mov eax, A xor eax, Key2 mov dword ptr[esi+8], eax mov eax, B xor eax, Key3 mov dword ptr[esi+12], eax invoke UpdKeys, Buf ret EncryptBlock endp SetOldKeys proc szPassword: DWORD LOCAL Ch1: BYTE invoke lstrlen, szPassword invoke CRC32UpdateRar, 0ffffffffh, szPassword, eax mov OldKey0, ax shr eax, 16 mov OldKey1, ax mov OldKey2, 0 mov OldKey3, 0 mov PN1, 0 mov PN2, 0 mov PN3, 0 mov edx, szPassword @l: movzx eax, byte ptr[edx] add PN1, al xor PN2, al add PN3, al rol PN3, 1 mov ecx, dword ptr[CRCTable+eax*4] xor ecx, eax xor OldKey2, cx mov ecx, dword ptr[CRCTable+eax*4] shr ecx, 16 add ecx, eax add OldKey3, cx inc edx cmp byte ptr[edx], 0 jnz @l ret SetOldKeys endp SetCryptKeys proc uses esi edi ebx szPassword: DWORD LOCAL Psw[256]: BYTE LOCAL N1: BYTE LOCAL N2: BYTE LOCAL I, J, K, PswLength: DWORD invoke SetOldKeys, szPassword mov Key0, 0D3A3B879h mov Key1, 03F6D12F7h mov Key2, 07515A235h mov Key3, 0A4E7F123h invoke ZeroMemory, addr Psw, 256 invoke lstrcpy, addr Psw, szPassword invoke lstrlen, szPassword mov PswLength, eax mov esi, offset InitSubstTable mov edi, offset SubstTable mov ecx, 256 rep movsb mov J, 0 .WHILE J < 256 mov I, 0 @fori: lea eax, Psw mov ecx, I inc ecx movzx eax, byte ptr[eax+ecx] add eax, J and eax, 0ffh mov eax, dword ptr[CRCTable+eax*4] mov N2, al lea eax, Psw mov ecx, I movzx eax, byte ptr[eax+ecx] sub eax, J and eax, 0ffh mov eax, dword ptr[CRCTable+eax*4] mov N1, al mov K, 1 .WHILE TRUE mov cl, N1 .IF cl == N2 .BREAK .ENDIF movzx eax, N1 add eax, offset SubstTable mov bl, byte ptr[eax] movzx edx, N1 add edx, I add edx, K and edx, 0ffh add edx, offset SubstTable mov cl, [edx] mov byte ptr[eax], cl mov byte ptr[edx], bl inc N1 inc K .ENDW add I, 2 mov eax, PswLength cmp I, eax jl @fori inc J .ENDW lea ebx, Psw mov I, 0 @l: invoke EncryptBlock, ebx add ebx, 16 add I, 16 mov eax, I cmp eax, PswLength jl @l ret SetCryptKeys endp RarCloak proc begin_offs, len, zfile: DWORD LOCAL bTemp[16]: BYTE LOCAL bRead: DWORD .IF !len ret .ENDIF invoke SetFilePointer, zfile, begin_offs, NULL, FILE_BEGIN @l: invoke SetFilePointer, zfile, 0, NULL, FILE_CURRENT push eax invoke ReadFile, zfile, addr bTemp, 16, addr bRead, NULL invoke EncryptBlock, addr bTemp pop eax invoke SetFilePointer, zfile, eax, NULL, FILE_BEGIN invoke WriteFile, zfile, addr bTemp, 16, addr bRead, NULL sub len, 16 jnz @l ret RarCloak endp ; Archive type: store only; szPassword can be NULL CreateRarFile proc uses ebx InFile, OutFile, StoreAs, szPassword: DWORD LOCAL hFileIn, hFileOut, buf, dwWritten, bRead: DWORD LOCAL a_hdr: ArchiveHeader LOCAL f_hdr: FileHeader LOCAL storeas_len: DWORD LOCAL f_date: WORD LOCAL f_time: WORD LOCAL crypt_offset: DWORD LOCAL crypt_allign: DWORD xor ebx, ebx invoke GlobalAlloc, GMEM_FIXED, 8192 mov buf, eax invoke CreateFile, InFile, GENERIC_READ, FILE_SHARE_READ or FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL mov hFileIn, eax inc eax jz @cra_ret invoke CreateFile, OutFile, GENERIC_WRITE or GENERIC_READ, FILE_SHARE_READ or FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, 0, NULL mov hFileOut, eax inc eax jz @cra_ret invoke lstrlen, StoreAs mov storeas_len, eax invoke WriteFile, hFileOut, offset MarkHeader, 7, addr dwWritten, NULL invoke ZeroMemory, addr a_hdr, sizeof ArchiveHeader invoke ZeroMemory, addr f_hdr, sizeof FileHeader mov a_hdr.HEAD_TYPE, HEAD_ARCHIVE mov a_hdr.HEAD_SIZE, sizeof ArchiveHeader invoke CRC32Update, 0, addr a_hdr.HEAD_TYPE, sizeof ArchiveHeader - 2 mov a_hdr.HEAD_CRC, ax invoke WriteFile, hFileOut, addr a_hdr, sizeof ArchiveHeader, addr dwWritten, NULL mov f_hdr.HEAD_TYPE, HEAD_FILE mov f_hdr.HEAD_SIZE, sizeof FileHeader mov eax, storeas_len add f_hdr.HEAD_SIZE, ax mov f_hdr.NAME_SIZE, ax invoke GetFileSize, hFileIn, NULL mov f_hdr.PACK_SIZE, eax mov f_hdr.UNP_SIZE, eax mov f_hdr.HEAD_FLAGS, 8040h .IF szPassword or f_hdr.HEAD_FLAGS, 04h ; 16 byte aligned (TODO: div->and) mov ecx, 16 xor edx, edx div ecx sub ecx, edx add f_hdr.PACK_SIZE, ecx mov crypt_allign, ecx .ENDIF mov f_hdr.HOST_OS, 2 ; Win32 invoke CRC32File, hFileIn mov f_hdr.FILE_CRC, eax mov f_hdr.UNP_VER, 14h mov f_hdr.METHOD, 30h ; Store only mov f_hdr.ATTR, 20h invoke ZipFilePutTime, addr f_time, addr f_date movzx eax, f_date shl eax, 16 or ax, f_time mov f_hdr.FTIME, eax invoke CRC32Update, 0, addr f_hdr.HEAD_TYPE, sizeof FileHeader - 2 invoke CRC32Update, eax, StoreAs, storeas_len mov f_hdr.HEAD_CRC, ax invoke WriteFile, hFileOut, addr f_hdr, sizeof FileHeader, addr dwWritten, NULL invoke WriteFile, hFileOut, StoreAs, storeas_len, addr dwWritten, NULL invoke SetFilePointer, hFileOut, 0, NULL, FILE_CURRENT mov crypt_offset, eax @l: invoke ReadFile, hFileIn, buf, 8192, addr bRead, NULL .IF bRead invoke WriteFile, hFileOut, buf, bRead, addr dwWritten, NULL jmp @l .ENDIF .IF szPassword invoke SetCryptKeys, szPassword invoke WriteFile, hFileOut, buf, crypt_allign, addr dwWritten, NULL invoke RarCloak, crypt_offset, f_hdr.PACK_SIZE, hFileOut .ENDIF invoke CloseHandle, hFileIn invoke CloseHandle, hFileOut inc ebx @cra_ret: invoke GlobalFree, buf mov eax, ebx ret CreateRarFile endp