С Новым годом! Форум программистов, компьютерный форум, киберфорум
Visual Basic
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 5.00/1: Рейтинг темы: голосов - 1, средняя оценка - 5.00
Испарился
 Аватар для HackerVlad
1741 / 637 / 45
Регистрация: 10.09.2021
Сообщений: 2,769

Как распаковать файл ZIP функциями из Cabinet.dll или чем отличается ZIP от MSZIP

05.03.2025, 23:14. Показов 3397. Ответов 38

Студворк — интернет-сервис помощи студентам
Всем привет!

Я тут решил поэкспериментировать и узнать чем же отличается ZIP от MSZIP. Моя идея заключалась в том, чтобы распаковывать простые ZIP-файлы кодом функций из Cabinet.dll, распаковывая буфер MSZIP. Идея была до ужаса проста: взять буфер ZIP и перенести в CAB и приклеить его в буфер MSZIP для того чтобы попробовать распаковать файл таким образом. Как вы думаете, получилось у меня это или нет? Получилось! Но только наполовину. Не всегда буфер MSZIP совпадает с буфером обычного ZIP.

Я решил для этого освоить новые функции Windows 8 из Cabinet.dll и попробовать ими распаковывать буфер обычного ZIP. Мои эксперименты длились несколько дней и всё чего я смог достичь это то что половина файлов у меня всё-таки распаковывается таким образом.

Я поэтому даже немного переделал версию своего класса для распаковки ZIP файлов, пытаясь достичь распаковки буфера ZIP, но правильным образом мне всё-таки этого достичь не удалось... Итак, представляю вам версию своего творчества, но только для ознакомления, а не для постоянного использования, так как мне не удалось на 100% разобраться с Cabinet.dll и сделать так чтобы распаковывались все файлы. Сейчас половину файлов не распаковывается у меня этим кодом...

Буду признателен и благодарен если кто-нибудь мне когда-нибудь подскажет, что же можно изменить в этом коде, для того чтобы распаковывались все файлы, и возможно ли это вообще (это тоже вопрос!).
1
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
05.03.2025, 23:14
Ответы с готовыми решениями:

Zip в zip. Как распаковать одним махом?
Я изучаю Zip бомбы. И я решил создать прямо атомную. Но вопрос в том, что мне надо распаковать зип сразу. Пример 1.zip>2.zip>3.zip......

Как распаковать ZIP-файл в 7z?
'При помощи VBA WinRAR распаковывает архив в папку … q = Адрес_сохранения_файла 'путь к каталогу, то есть к папке, в конце пути для...

Как программно распаковать Zip файл
Возможно ли штатными средствами .net или на край виндовыми библиотеками стандаратными распаковать архив?

38
Испарился
 Аватар для HackerVlad
1741 / 637 / 45
Регистрация: 10.09.2021
Сообщений: 2,769
05.03.2025, 23:19  [ТС]
Вот я создал примерчик, для того чтобы Вы увидели как всё это работает у меня. Скорость распаковки при этом, кстати сказать, просто фантастическая! 0 миллисекунд!

Класс только для ознакомления:
Visual Basic
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
Option Explicit
'////////////////////////////////////////////
'// Класс для чтения ZIP-файлов            //
'// Copyright (c) 05.03.2025 by HackerVlad //
'// e-mail: vladislavpeshkov@ya.ru         //
'// Версия: тестовая, полу-рабочая         //
'////////////////////////////////////////////
 
' Декларации API ...
Private Declare Function CreateFileW Lib "kernel32" (ByVal lpFileName As Long, ByVal dwDesiredAccess As Long, ByVal dwShareMode As Long, lpSecurityAttributes As Any, ByVal dwCreationDisposition As Long, ByVal dwFlagsAndAttributes As Long, ByVal hTemplateFile As Long) As Long
Private Declare Function CreateFileA Lib "kernel32" (ByVal lpFileName As String, ByVal dwDesiredAccess As Long, ByVal dwShareMode As Long, lpSecurityAttributes As Any, ByVal dwCreationDisposition As Long, ByVal dwFlagsAndAttributes As Long, ByVal hTemplateFile As Long) As Long
Private Declare Function GetFileSize Lib "kernel32" (ByVal hFile As Long, lpFileSizeHigh As Long) As Long
Private Declare Function SetFilePointer Lib "kernel32" (ByVal hFile As Long, ByVal lDistanceToMove As Long, lpDistanceToMoveHigh As Long, ByVal dwMoveMethod As Long) As Long
Private Declare Function ReadFile Lib "kernel32" (ByVal hFile As Long, ByVal lpBuffer As Long, ByVal nNumberOfBytesToRead As Long, lpNumberOfBytesRead As Long, ByVal lpOverlapped As Any) As Long
Private Declare Function CloseHandle Lib "kernel32" (ByVal hObject As Long) As Long
Private Declare Function MultiByteToWideChar Lib "kernel32" (ByVal CodePage As Long, ByVal dwFlags As Long, ByVal lpMultiByteStr As Long, ByVal cbMultiByte As Long, ByVal lpWideCharStr As Long, ByVal cchWideChar As Long) As Long
Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (Destination As Any, Source As Any, ByVal Length As Long)
Private Declare Function GetMem2 Lib "msvbvm60" (src As Any, dst As Any) As Long
Private Declare Function GetMem4 Lib "msvbvm60" (src As Any, dst As Any) As Long
Private Declare Function CreateDecompressor Lib "cabinet" (ByVal Algorithm As COMPRESS_ALGORITHMS, ByVal AllocationRoutines As Long, hDecompressor As Long) As Long
Private Declare Function Decompress Lib "cabinet" (ByVal hCompressor As Long, CompressedData As Any, ByVal CompressedDataSize As Long, UncompressedBuffer As Any, ByVal UncompressedBufferSize As Long, bytesOut As Long) As Long
Private Declare Function CloseDecompressor Lib "cabinet" (ByVal hDecompressor As Long) As Long
 
' Константы ...
Private Const OPEN_EXISTING As Long = 3
Private Const FILE_SHARE_READ = &H1
Private Const GENERIC_READ As Long = &H80000000
Private Const CREATE_ALWAYS = 2
Private Const EndOFCentralDirSignature As Long = &H6054B50
Private Const CentralFileHeaderSigniature As Long = &H2014B50
Private Const LocalFileHeaderSignature As Long = &H4034B50
Private Const HackMSZIPSignature As Integer = &H4B43
Private Const CP_UTF8 As Long = 65001
Private Const CP_OEMCP = 1 ' default to OEM code page
Private Const MB64 As Long = 67108864
 
' Структуры ...
Private Type zipLocalFileHeader
    LocalFileHeaderSignature As Long
    VersionNeededToExtract As Integer
    GeneralPurposeBitFlag As Integer
    CompressionMethod As Integer
    LastModFileTime As Integer
    LastModFileDate As Integer
    ' hidden padding 2 bytes As Integer
    CRC32 As Long
    CompressedSize As Long
    UnCompressedSize As Long
    FileNameLength As Integer
    ExtraFieldLength As Integer
End Type
 
Private Type HackedMSZIPBufferStructure
    BeginningHeader1 As Long           ' 4
    BeginningHeader2 As Integer        ' 6
    HackByte As Byte                   ' 7
    ContinuationHeader As Byte         ' 8
    UnCompressedSize As Long           ' 12
    NotSolved1 As Long                 ' 16
    UnCompressedLength As Long         ' 20
    NotSolved2 As Long                 ' 24
    CompressedSize As Long             ' 28
    MSZIPSignature As Integer          ' 30
    ' hidden padding 2 bytes As Integer  32
End Type
 
Private Enum COMPRESS_ALGORITHMS
    COMPRESS_ALGORITHM_MSZIP = 2
    COMPRESS_ALGORITHM_XPRESS = 3
    COMPRESS_ALGORITHM_XPRESS_HUFF = 4
    COMPRESS_ALGORITHM_LZMS = 5
End Enum
 
Public Enum AttributesInZip
    zipFileAttr
    zipFileDate
    zipFileTime
    zipFileDateAndTime
End Enum
 
Public Enum FileNameCodePageInZip
    zipCodePageAutoDetect
    zipCodePageCP866
    zipCodePageUTF8
End Enum
 
' Переменные для хранения внутри экземпляра класса
Dim EntriesInTheCentralDir As Integer
Dim zipCountFiles As Integer
Dim zipCountDirs As Integer
Dim zipListFiles As New Collection
Dim zipListFilesCP866 As New Collection
Dim zipListFilesUTF8 As New Collection
Dim zipFileAttributes As New Collection
Dim zipFileDosDate As New Collection
Dim zipFileDosTime As New Collection
Dim zipFileSize As New Collection
Dim zipFileSizeCompressed As New Collection
Dim zipFileOffSet As New Collection
Dim OpenedZIPFileName As String
 
' Открыть файл ZIP на чтение
Public Function OpenZip(ByVal ZipFileName As String) As Boolean
    Dim hFile As Long
    Dim dwBytesReaded As Long
    Dim nFileSize As Long
    Dim bArray() As Byte
    Dim i As Long
    Dim Signature As Long
    Dim FileName As String
    Dim FileNameCP866 As String
    Dim FileNameUTF8 As String
    Dim OffSet As Long
    Dim FileNameLength As Integer
    Dim LastModFileTime As Integer
    Dim LastModFileDate As Integer
    Dim CompressedSize As Long
    Dim UnCompressedSize As Long
    Dim ExtraFieldLength As Integer
    Dim FileCommentLength As Integer
    Dim ExternalFileAttributes As Long
    Dim nOutputCharLen As Long
    Dim numread As Long
    Dim SetNewPosition As Long
    Dim MajorWindowsVersion As Long
    Dim RelativeOffsetOfLocalHeader As Long
    
    hFile = CreateFileW(StrPtr(ZipFileName), GENERIC_READ, FILE_SHARE_READ, ByVal 0&, OPEN_EXISTING, 0, 0)
    If hFile = 0 Then hFile = CreateFileA(ZipFileName, GENERIC_READ, FILE_SHARE_READ, ByVal 0&, OPEN_EXISTING, 0, 0)
    
    If hFile <> -1 And hFile <> 0 Then
        nFileSize = GetFileSize(hFile, ByVal 0&)
        
        If nFileSize <> -1 Then
            If nFileSize <= MB64 Then ' Если размер файла меньше 64 МБ то читать весь файл
                ReDim bArray(nFileSize - 1)
                ReadFile hFile, VarPtr(bArray(0)), nFileSize, dwBytesReaded, ByVal 0&
            Else ' Размер файла больше 64 МБ
                ReDim bArray(MB64 - 1)
                
                ' Прочитать только последние 64 МБ
                SetNewPosition = nFileSize - MB64
                SetFilePointer hFile, SetNewPosition, ByVal 0&, 1
                ReadFile hFile, VarPtr(bArray(0)), MB64, dwBytesReaded, ByVal 0&
            End If
            
            If dwBytesReaded > 0 Then
                For i = UBound(bArray) - 3 To LBound(bArray) Step -1
                    GetMem4 bArray(i), Signature
                    
                    If Signature = EndOFCentralDirSignature Then
                        Exit For
                    End If
                Next
                
                If i > 0 Then
                    ' Загрузить в переменные данные из файла (я решил не использовать структуры)
                    GetMem2 bArray(i + 10), EntriesInTheCentralDir
                    GetMem4 bArray(i + 16), OffSet
                    
                    If SetNewPosition > 0 Then
                        OffSet = OffSet - SetNewPosition
                    End If
                    
                    GetMem4 ByVal &H7FFE026C, MajorWindowsVersion
                    
                    If zipListFiles.Count > 0 Then Set zipListFiles = Nothing
                    If zipListFilesCP866.Count > 0 Then Set zipListFilesCP866 = Nothing
                    If zipListFilesUTF8.Count > 0 Then Set zipListFilesUTF8 = Nothing
                    If zipFileAttributes.Count > 0 Then Set zipFileAttributes = Nothing
                    If zipFileDosDate.Count > 0 Then Set zipFileDosDate = Nothing
                    If zipFileDosTime.Count > 0 Then Set zipFileDosTime = Nothing
                    If zipFileSize.Count > 0 Then Set zipFileSize = Nothing
                    If zipFileSizeCompressed.Count > 0 Then Set zipFileSizeCompressed = Nothing
                    If zipFileOffSet.Count > 0 Then Set zipFileOffSet = Nothing
                    
                    zipCountFiles = 0
                    zipCountDirs = 0
                    
                    For i = 1 To EntriesInTheCentralDir
                        GetMem4 bArray(OffSet), Signature
                        
                        If Signature = CentralFileHeaderSigniature Then
                            ' Получить всю необходимую информацию о файле
                            GetMem2 bArray(OffSet + 12), LastModFileTime
                            GetMem2 bArray(OffSet + 14), LastModFileDate
                            GetMem4 bArray(OffSet + 20), CompressedSize
                            GetMem4 bArray(OffSet + 24), UnCompressedSize
                            GetMem2 bArray(OffSet + 28), FileNameLength
                            GetMem2 bArray(OffSet + 30), ExtraFieldLength
                            GetMem2 bArray(OffSet + 32), FileCommentLength
                            GetMem4 bArray(OffSet + 38), ExternalFileAttributes
                            GetMem4 bArray(OffSet + 42), RelativeOffsetOfLocalHeader
                            
                            OffSet = OffSet + 46
                            
                            FileName = String$(FileNameLength, vbNullChar)
                            CopyMemory ByVal StrPtr(FileName), bArray(OffSet), FileNameLength
                            
                            OffSet = OffSet + FileNameLength + ExtraFieldLength + FileCommentLength
                            
                            FileNameCP866 = Space$(FileNameLength)
                            FileNameUTF8 = Space$(FileNameLength)
                            
                            nOutputCharLen = MultiByteToWideChar(CP_OEMCP, 0&, StrPtr(FileName), -1, 0&, 0&) ' Получить размер буфера в символах для кодировки DOS
                            MultiByteToWideChar CP_OEMCP, 0&, StrPtr(FileName), -1, StrPtr(FileNameCP866), nOutputCharLen ' Преобразовать кодировки
                            nOutputCharLen = 0
                            nOutputCharLen = MultiByteToWideChar(CP_UTF8, 0&, StrPtr(FileName), -1, 0&, 0&) ' Получить размер буфера в символах для кодировки UTF8
                            MultiByteToWideChar CP_UTF8, 0&, StrPtr(FileName), -1, StrPtr(FileNameUTF8), nOutputCharLen ' Преобразовать кодировки
                            
                            FileNameUTF8 = Left$(FileNameUTF8, nOutputCharLen - 1)
                            FileNameCP866 = Replace$(FileNameCP866, "/", "\")
                            FileNameUTF8 = Replace$(FileNameUTF8, "/", "\")
                            
                            If (ExternalFileAttributes And vbDirectory) <> 0 Then
                                zipCountDirs = zipCountDirs + 1
                            Else
                                zipCountFiles = zipCountFiles + 1
                            End If
                            
                            If MajorWindowsVersion >= 6 And MajorWindowsVersion < 600 Then
                                If FileNameUTF8 Like "*[" & ChrW(-3) & "]*" Then ' Авто-определение кодировок
                                    zipListFiles.Add FileNameCP866 ' Кодировка DOS
                                Else
                                    zipListFiles.Add FileNameUTF8 ' Кодировка UTF8
                                End If
                            Else ' Windows версии меньше чем Vista
                                zipListFiles.Add FileNameCP866 ' Кодировка DOS
                            End If
                            
                            zipListFilesCP866.Add FileNameCP866
                            zipListFilesUTF8.Add FileNameUTF8
                            zipFileAttributes.Add ExternalFileAttributes
                            zipFileDosDate.Add LastModFileDate
                            zipFileDosTime.Add LastModFileTime
                            zipFileSize.Add UnCompressedSize
                            zipFileSizeCompressed.Add CompressedSize
                            zipFileOffSet.Add RelativeOffsetOfLocalHeader
                            
                            If OpenZip = False Then
                                OpenedZIPFileName = ZipFileName
                                OpenZip = True
                            End If
                        End If
                    Next
                End If
            End If
        End If
        
        CloseHandle hFile
    End If
End Function
 
' Возвращает количество файлов и каталогов внутри ZIP
Public Property Get CountFilesAndDirs() As Long
    CountFilesAndDirs = EntriesInTheCentralDir
End Property
 
' Возвращает количество файлов внутри ZIP
Public Property Get CountFiles() As Long
    CountFiles = zipCountFiles
End Property
 
' Возвращает количество каталогов внутри ZIP
Public Property Get CountDirs() As Long
    CountDirs = zipCountDirs
End Property
 
' Возвращает список файлов внутри ZIP, по индексу
Public Property Get List(ByVal Index As Integer, Optional ByVal CodePage As FileNameCodePageInZip) As String
    If zipListFiles.Count > 0 And Index > 0 Then
        If CodePage = zipCodePageAutoDetect Then
            List = zipListFiles(Index)
        ElseIf CodePage = zipCodePageCP866 Then
            List = zipListFilesCP866(Index)
        ElseIf CodePage = zipCodePageUTF8 Then
            List = zipListFilesUTF8(Index)
        End If
    End If
End Property
 
' Возвращает атрибуты файла внутри ZIP, по индексу
Public Property Get FileAttributes(ByVal Index As Integer) As Long
    If zipFileAttributes.Count > 0 And Index > 0 Then
        FileAttributes = zipFileAttributes(Index)
    End If
End Property
 
' Возвращает дату файла внутри ZIP, по индексу
Public Property Get FileDosDate(ByVal Index As Integer) As Integer
    If zipFileDosDate.Count > 0 And Index > 0 Then
        FileDosDate = zipFileDosDate(Index)
    End If
End Property
 
' Возвращает время создания файла внутри ZIP, по индексу
Public Property Get FileDosTime(ByVal Index As Integer) As Integer
    If zipFileDosTime.Count > 0 And Index > 0 Then
        FileDosTime = zipFileDosTime(Index)
    End If
End Property
 
' Возвращает размер файла внутри ZIP, по индексу
Public Property Get FileSize(ByVal Index As Integer) As Long
    If zipFileSize.Count > 0 And Index > 0 Then
        FileSize = zipFileSize(Index)
    End If
End Property
 
' Возвращает размер сжатого блока файла внутри ZIP, по индексу
Public Property Get FileSizeCompressed(ByVal Index As Integer) As Long
    If zipFileSizeCompressed.Count > 0 And Index > 0 Then
        FileSizeCompressed = zipFileSizeCompressed(Index)
    End If
End Property
 
' Возвращает имя открытого файла ZIP
Public Property Get GetOpenedZIPFileName() As String
    GetOpenedZIPFileName = OpenedZIPFileName
End Property
 
' Записывает в массив список файлов из ZIP
Public Function ListFiles(arrFileNames() As String, Optional ByVal CodePage As FileNameCodePageInZip) As Boolean
    Dim i As Integer
    
    If zipListFiles.Count > 0 Then
        ReDim arrFileNames(zipListFiles.Count - 1)
        
        For i = 1 To zipListFiles.Count
            If CodePage = zipCodePageAutoDetect Then
                arrFileNames(i - 1) = zipListFiles(i)
            ElseIf CodePage = zipCodePageCP866 Then
                arrFileNames(i - 1) = zipListFilesCP866(i)
            ElseIf CodePage = zipCodePageUTF8 Then
                arrFileNames(i - 1) = zipListFilesUTF8(i)
            End If
        Next
        
        ListFiles = True
    End If
End Function
 
' Возвращает атрибуты файла внутри ZIP, а так же дату и время создания файлов
Public Property Get GetFileAttributesInZip(ByVal FileNameInZip As String, Optional ByVal AttrInZip As AttributesInZip) As Long
    Dim i As Integer
    
    If zipListFilesCP866.Count > 0 Then
        For i = 1 To zipListFilesCP866.Count
            If zipListFilesCP866(i) = FileNameInZip Then
                GoTo Subroutine
                Exit For
            End If
        Next
    End If
    If zipListFilesUTF8.Count > 0 Then
        For i = 1 To zipListFilesUTF8.Count
            If zipListFilesUTF8(i) = FileNameInZip Then
                GoTo Subroutine
                Exit For
            End If
        Next
    End If
    Exit Property
Subroutine:
    If AttrInZip = zipFileAttr Then
        GetFileAttributesInZip = zipFileAttributes(i)
    ElseIf AttrInZip = zipFileDate Then
        GetFileAttributesInZip = zipFileDosDate(i)
    ElseIf AttrInZip = zipFileTime Then
        GetFileAttributesInZip = zipFileDosTime(i)
    ElseIf AttrInZip = zipFileDateAndTime Then
        GetFileAttributesInZip = ((zipFileDosTime(i) And &H7FFF&) * &H10000) Or (zipFileDosDate(i) And &HFFFF&) Or (&H80000000 And zipFileDosTime(i) < 0)
    End If
End Property
 
' Извлекает выбранный по индексу файл из архива ZIP в буфер байтового массива
Public Function ExtractToMemory(ByVal Index As Integer, bData() As Byte) As Boolean
    If zipFileOffSet.Count > 0 And Index > 0 Then
        If zipFileSizeCompressed(Index) > 32 Then
            If (zipFileAttributes(Index) And vbDirectory) = 0 Then
                Dim hFile As Long
                Dim dwBytesReaded As Long
                Dim ZipFileHeader As zipLocalFileHeader
                Dim hack As HackedMSZIPBufferStructure
                Dim bArray() As Byte
                Dim bArrayNew() As Byte
                Dim bytesOut As Long
                Dim h As Long
                Dim i As Byte
                
                hFile = CreateFileW(StrPtr(OpenedZIPFileName), GENERIC_READ, FILE_SHARE_READ, ByVal 0&, OPEN_EXISTING, 0, 0)
                
                If hFile <> -1 And hFile <> 0 Then
                    ReDim bArray(zipFileSizeCompressed(Index) + 1024)
                    
                    SetFilePointer hFile, zipFileOffSet(Index), ByVal 0&, 1
                    ReadFile hFile, VarPtr(bArray(0)), zipFileSizeCompressed(Index) + 1024, dwBytesReaded, ByVal 0&
                    CloseHandle hFile
                    
                    If dwBytesReaded > 0 Then
                        CopyMemory ZipFileHeader, bArray(0), 14
                        CopyMemory ByVal VarPtr(ZipFileHeader) + 16, bArray(14), 14
                        
                        If ZipFileHeader.LocalFileHeaderSignature = LocalFileHeaderSignature Then
                            If ZipFileHeader.CompressedSize = zipFileSizeCompressed(Index) Then
                                If ZipFileHeader.UnCompressedSize = zipFileSize(Index) Then
                                    ' ZipFileHeader.GeneralPurposeBitFlag = 2050 это кодировка UTF8
                                    
                                    ' Заполнить хакерскую структуру
                                    hack.BeginningHeader1 = &HC0E5510A
                                    hack.BeginningHeader2 = &H18
                                    hack.ContinuationHeader = &H2
                                    hack.UnCompressedSize = ZipFileHeader.UnCompressedSize
                                    hack.UnCompressedLength = ZipFileHeader.UnCompressedSize
                                    hack.CompressedSize = ZipFileHeader.CompressedSize + 2
                                    hack.MSZIPSignature = HackMSZIPSignature
                                    
                                    ReDim bArrayNew(ZipFileHeader.CompressedSize + 29)
                                    
                                    CopyMemory bArrayNew(0), hack, 30
                                    CopyMemory bArrayNew(30), bArray(30 + ZipFileHeader.FileNameLength + ZipFileHeader.ExtraFieldLength), ZipFileHeader.CompressedSize
                                    
                                    If CreateDecompressor(COMPRESS_ALGORITHM_MSZIP, 0, h) Then
                                        ReDim bData(hack.UnCompressedSize - 1)
                                        
                                        ' Взламываем неизвестный байт с помощью BruteForce атаки
                                        For i = 0 To 254
                                            bArrayNew(6) = i
                                            Decompress h, bArrayNew(0), UBound(bArrayNew) + 1, bData(0), hack.UnCompressedSize, bytesOut
                                            If bytesOut > 0 Then Exit For
                                        Next
                                        
                                        If bytesOut Then ExtractToMemory = True
                                        CloseDecompressor h
                                    End If
                                End If
                            End If
                        End If
                    End If
                End If
            End If
        End If
    End If
End Function
Форма:

Visual Basic
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
Option Explicit
Private Declare Function GetTickCount Lib "kernel32" () As Long
 
Dim zip As New clsZipReader
 
Private Sub Form_Load()
    Dim i As Long
    
    zip.OpenZip App.Path & "\test.zip"
    
    For i = 1 To zip.CountFilesAndDirs
        List1.AddItem zip.List(i)
    Next
    
    List1.Selected(0) = True
    Label1.Caption = "Count files: " & zip.CountFiles
    If Me.Visible = True Then List1.SetFocus
End Sub
 
Private Sub List1_Click()
    Dim bytesData() As Byte
    Dim tick As Long
    
    tick = GetTickCount
    
    If zip.ExtractToMemory(List1.ListIndex + 1, bytesData) = True Then
        Label2.Caption = "ms: " & GetTickCount - tick
        Picture1.Picture = PictureFromBits(bytesData)
    Else
        Label2.Caption = "Ошибка загрузки"
        Picture1.Picture = LoadPicture("")
    End If
End Sub
Миниатюры
Как распаковать файл ZIP функциями из Cabinet.dll или чем отличается ZIP от MSZIP  
Вложения
Тип файла: zip Чтение картинок из ZIP кодом Cabinet.dll.zip (458.8 Кб, 4 просмотров)
1
Испарился
 Аватар для HackerVlad
1741 / 637 / 45
Регистрация: 10.09.2021
Сообщений: 2,769
05.03.2025, 23:26  [ТС]
Досадно здесь то, что мне пришлось взламывать заголовочную структуру буфера MSZIP не зная при этом, самой этой структуры, где что находится, и куда что должно записываться, документации нет никакой на эту тему вообще, не нашёл у Microsoft, поэтому, то что я сделал, это я всё сделал лишь методом тыка. Даже один байт я так и не смог разгадать какой он должен быть поэтому пришлось его делать с помощью перебора всех возможных комбинаций...
0
1384 / 838 / 91
Регистрация: 08.02.2017
Сообщений: 3,512
Записей в блоге: 1
06.03.2025, 02:30
Цитата Сообщение от HackerVlad Посмотреть сообщение
Private Type zipLocalFileHeader
LocalFileHeaderSignature As Long
VersionNeededToExtract As Integer
GeneralPurposeBitFlag As Integer
CompressionMethod As Integer
LastModFileTime As Integer
LastModFileDate As Integer
' hidden padding 2 bytes As Integer
CRC32 As Long
CompressedSize As Long
UnCompressedSize As Long
FileNameLength As Integer
ExtraFieldLength As Integer
End Type
Вместо этого надо использовать это
Цитата Сообщение от HackerVlad Посмотреть сообщение
Private Type ZipCentralHeaderType
Signature As Long ' Signature
VerMade As Integer ' version made by
VerExt As Integer ' version needed to extract
Flags As Integer ' encrypt and compression flags
Method As Integer ' compression method
FTime As Integer ' time last modifies, dos format
FDate As Integer ' date last modifies, dos format
Crc32 As Long ' CRC32 for uncompressed file
CSize As Long ' compressed size
USize As Long ' uncompressed size
LenFname As Integer ' Length filename
LenExt As Integer ' Length for extra field
LenCom As Integer ' Length for comment field
DiskStart As Integer ' start disk number
AttribI As Integer ' internal file attributes
'--- padding
AttribX As Long ' external file attributes
Offset As Long ' relative offset of local header
Ext As Zip64ExtraDataType
End Type
Может быть как раз в этой структуре где-то кроется "магическое число"..

Добавлено через 13 минут
Цитата Сообщение от HackerVlad Посмотреть сообщение
Decompress h, bArrayNew(0), UBound(bArrayNew) + 1, bData(0), hack.UnCompressedSize, bytesOut
Я вот еще этой фигни не пойму, если там в заголовке буфера должен быть UnCompressedSize, нахрена указывать UnCompressedSize, т.е. нафига у функции этот параметр, просто дрочка?
0
Испарился
 Аватар для HackerVlad
1741 / 637 / 45
Регистрация: 10.09.2021
Сообщений: 2,769
06.03.2025, 04:08  [ТС]
Цитата Сообщение от testuser2 Посмотреть сообщение
Вместо этого надо использовать это
Нет, ты не прав. Это две совершенно разные структуры для разных целей при чтении ZIP.
CentralFileHeader и LocalFileHeader это две разные структуры. Я думал ты вникал в структуру ZIP-файлов. Заголовки определяющие список файлов есть как в начале так и в конце файлов ZIP. Правильный способ чтения ZIP - это чтение ZIP с конца файла именно, точно так как это делал PKUNZIP.EXE во времена MS-DOS. Есть другие сейчас скрипты которые читают ZIP файлы только сначала, и не лезут вообще в конец файла - это откровенно ленивая и неправильная политика, так как при таком чтении ZIP например невозможно будет прочесть SFX-EXE.

Добавлено через 2 минуты
testuser2, прочитай на досуге подробнее техническую документацию по формату файла ZIP, вот например очень информативная статья по этому поводу: https://habr.com/ru/companies/... es/569464/

Добавлено через 2 минуты
Цитата Сообщение от testuser2 Посмотреть сообщение
Может быть как раз в этой структуре где-то кроется "магическое число"..
Там совсем другие структуры, скрытые от людских глаз есть... Кроется всё это в майкрософтовском буфере, который создаётся функциями из Cabinet.dll. К сожалению всё это счастье не документировано вообще...

Добавлено через 52 секунды
Цитата Сообщение от testuser2 Посмотреть сообщение
нахрена указывать UnCompressedSize
у майкрософта спроси, сам не пойму этого...

Добавлено через 1 минуту
Цитата Сообщение от testuser2 Посмотреть сообщение
т.е. нафига у функции этот параметр
я тоже об этому думал кстати, а ещё читал документацию по этим API так там вообще враки написаны в официальной документации что якобы не хранится размер буфера и что его нужно самому запоминать/знать...

Добавлено через 6 минут
Тему вообще я эту поднял для того чтобы понять чем же отличается ZIP от MSZIP ведь что такое MSZIP в формате файла CAB? Это тот же самый буфер для файла, который есть в простом ZIP. Тут вот и самое интересное. Я думал о том, чтобы взять, вырезать из обычного файла ZIP буфер упакованного файла, и вставить, например, в CAB файл, заменить буфер внутри CAB упакованного в MSZIP. И на основе этого уже эксперементировать. Я точно до сих пор не знаю есть ли вообще различия в ZIP и MSZIP, в интернете нет таких сведений нигде. Однако, в официальной документации Microsoft я нашёл утверждение того что MSZIP использует в точности ту же оригинальную технологию ZIP: https://learn.microsoft.com/en... 91da21ca97
[RFC1951]
Я думаю, что RFC1951 это и есть стандарт ZIP который относится как к простому ZIP так и к MSZIP.

Добавлено через 4 минуты
И на основе всех этих своих догадок, я сейчас думаю о том, что в Cabinet.dll есть код, способный распаковывать файлы ZIP и при чём этот код, внутри Cabinet.dll, есть начиная с Windows 95! Главное это правильным образом заставить работать, а это не так просто!
0
1384 / 838 / 91
Регистрация: 08.02.2017
Сообщений: 3,512
Записей в блоге: 1
06.03.2025, 07:41
Цитата Сообщение от HackerVlad Посмотреть сообщение
Может быть как раз в этой структуре где-то кроется "магическое число"..
Там совсем другие структуры, скрытые от людских глаз есть... Кроется всё это в майкрософтовском буфере, который создаётся функциями из Cabinet.dll. К сожалению всё это счастье не документировано вообще...
Я о чем говорю, что может быть, этот байт, который ты угадываешь, может быть не байт, а word, и может быть совпадает со значением GeneralPurposeBitFlag, CompressionMethod или VersionNeededToExtract, допустим.
Цитата Сообщение от HackerVlad Посмотреть сообщение
Я думал о том, чтобы взять, вырезать из обычного файла ZIP буфер упакованного файла, и вставить, например, в CAB файл, заменить буфер внутри CAB упакованного в MSZIP
Так я понимаю, что главное, взять дефляционный буфер и дополнить его нужными структурами..

Добавлено через 49 минут
Цитата Сообщение от HackerVlad Посмотреть сообщение
testuser2, прочитай на досуге подробнее техническую документацию по формату файла ZIP, вот например очень информативная статья по этому поводу: https://habr.com/ru/companies/... es/569464/
Вот я смотрю по той инфе, все сходится с твоим кодом, где ты получаешь аттрибуты файлов в зипе. У тебя там первоначально идет сверка сигнатуры со значением CentralFileHeaderSigniature, дальше получаются данные от этой точки. А эта сигнатура соответсвтует структуре (Хабр)
File header:
central file header signature 4 bytes (0x02014b50)
version made by 2 bytes
version needed to extract 2 bytes
general purpose bit flag 2 bytes
compression method 2 bytes
last mod file time 2 bytes
last mod file date 2 bytes
crc-32 4 bytes
compressed size 4 bytes
uncompressed size 4 bytes
file name length 2 bytes
extra field length 2 bytes
file comment length 2 bytes
disk number start 2 bytes
internal file attributes 2 bytes
external file attributes 4 bytes
relative offset of local header 4 bytes

file name (variable size)
extra field (variable size)
file comment (variable size)
0
Испарился
 Аватар для HackerVlad
1741 / 637 / 45
Регистрация: 10.09.2021
Сообщений: 2,769
06.03.2025, 12:34  [ТС]
Цитата Сообщение от testuser2 Посмотреть сообщение
этот байт, который ты угадываешь,
он вообще какой-то рандомный и непонятный

Добавлено через 1 минуту
не смог проследить никакой закономерности вообще, всегда разный почему-то. Единственную закономерность которую я смог проследить это если файл одинаковое количество байт то и байт этот одинаковый. Но вот дальше, хоть и понимая, что это зависит от размера файла, всё равно не смог проследить никакой закономерности, оно как буд-то по рандому этот байт выставляет...
0
1384 / 838 / 91
Регистрация: 08.02.2017
Сообщений: 3,512
Записей в блоге: 1
06.03.2025, 16:21
Такая мысль, может этот заголовок не обязателен. Согласно вот здесь говорится, что блоки MSZIP должны содержать впереди лишь 2-байтную сигнатуру MSZIP (0x43 and 0x4B) и все, дальше идут компрессионные блоки RFC1951

Добавлено через 2 часа 36 минут
Мне этот магический байт напомнил получение контрольной суммы в коде-примере алгоритма Хоффмана, взятого отсюда. Когда изучал этот код, мне это показалось слегка бредом, поскольку контрольная сумма получалась именно в переменную типа Byte.
Visual Basic
1
2
3
4
5
6
7
8
    'Add a simple checksum value to the result header for corruption identification
'    Добавление простого значения контрольной суммы в заголовок результата для контроля повреждений.
    Char = 0
    For i = 0 To (ByteLen - 1)
        Char = Char Xor ByteArray(i)
    Next
    Result(ResultLen) = Char             
    ResultLen = ResultLen + 1
1
Испарился
 Аватар для HackerVlad
1741 / 637 / 45
Регистрация: 10.09.2021
Сообщений: 2,769
06.03.2025, 23:07  [ТС]
Цитата Сообщение от testuser2 Посмотреть сообщение
Такая мысль
Мысль может и хорошая, я тоже думал о том, что это может быть CRC но не одна из всех мне известных контрольных сумм не совпадала, тем более не вмещалась в ОДИН байт. Ты проверял свои догадки кстати?
0
1384 / 838 / 91
Регистрация: 08.02.2017
Сообщений: 3,512
Записей в блоге: 1
07.03.2025, 01:48
Цитата Сообщение от HackerVlad Посмотреть сообщение
Ты проверял свои догадки кстати?
Не стал бы проверять в виду не приятия самой мысли о возможности макого решения. В любом случае это какая-то пакость, и это плохое решение внедрить непонятный мэджик-байт и для меня неприятно даже попытки угадывания причин его появления, это просто плохо и еще раз плохо. Но если ты отгадаешь эту тайну, это будет конечно хорошо.
0
1384 / 838 / 91
Регистрация: 08.02.2017
Сообщений: 3,512
Записей в блоге: 1
07.03.2025, 09:37
Мысль такая, это может быть колличество блоков, на которые разбивается буфер при компрессии. У каждого формата сжатия там свой размер блока по умолчанию..
0
Испарился
 Аватар для HackerVlad
1741 / 637 / 45
Регистрация: 10.09.2021
Сообщений: 2,769
07.03.2025, 13:45  [ТС]
testuser2, да вряд ли это количество блоков, ZIP разбивается на N количество 32-килобайтных чанок...
А учитывая, что я много раз пробовал на маленьких разных файлах до 32 КБ то я не думаю, что это количество блоков вообще...

Добавлено через 3 минуты
ZIP поэтому и плохо сжимает, я думаю, потому что размер блока всего 32 КБ со времён MS_DOS

Добавлено через 40 минут
Цитата Сообщение от testuser2 Посмотреть сообщение
Мне этот магический байт напомнил получение контрольной суммы в коде-примере алгоритма Хоффмана, взятого отсюда.
Ну я в общем проверил твою теорию, может конечно это и контрольная сумма, но явно не по такому алгоритму, там совсем разные байты получаются, я проверил, данный код не подойдёт для вскрытия магического байта...

Добавлено через 11 минут
Цитата Сообщение от testuser2 Посмотреть сообщение
Такая мысль, может этот заголовок не обязателен.
Тоже проверил эту твою мысль, тоже мысль оказалось неудачной. Без заголовка никак, к сожалению...

Добавлено через 3 минуты
К сожалению без исходного кода функции Decompress мы никак не сможем это разгадать... Вот почему мне не нравится их политика закрытого кода, в отличии от ReactOS...

Добавлено через 2 минуты
И вообще почему MS не создало простой API-функции для распаковки ZIP вообще этого не понимаю...
0
1384 / 838 / 91
Регистрация: 08.02.2017
Сообщений: 3,512
Записей в блоге: 1
07.03.2025, 14:09

Не по теме:

Цитата Сообщение от HackerVlad Посмотреть сообщение
И вообще почему MS не создало простой API-функции для распаковки ZIP вообще этого не понимаю...
У них с Винзипом наверное договорнячек был



Добавлено через 14 минут
Это действительно странный момент, да, учитывая, что зип используется прям везде-везде
0
Испарился
 Аватар для HackerVlad
1741 / 637 / 45
Регистрация: 10.09.2021
Сообщений: 2,769
07.03.2025, 15:39  [ТС]
testuser2, я вообще даже не буду больше пытаться разгадать этот магический байт. Всё равно эта технология только от Win 8. Я теперь буду работать над переклейкой буфера из ZIP в CAB для того чтобы проверить возможно ли это. Взять буфер из файла ZIP вырезать его от туда и вклеить в файл CAB (который MSZIP) вот моя основная идея сейчас. И проверю я сейчас это вручную, через гексоды.

Добавлено через 1 час 27 минут
Но для этого нужно уметь создавать CAB-файл с нуля. Вот здесь прочитал про основной заголовок: https://www.file-recovery.com/... format.htm
Но там есть ещё и дополнительный заголовок, который я не знаю как прочесть и вот эта структура тоже будет загадкой очень большой, без описания, которого я пока не смог нигде найти вообще...

Добавлено через 2 минуты
Просто переклеить буфер из ZIP в CAB пока не получилось, нужно ещё знать какие байты где менять. Это сложнее чем я думал...
0
1384 / 838 / 91
Регистрация: 08.02.2017
Сообщений: 3,512
Записей в блоге: 1
07.03.2025, 15:44
HackerVlad, а что там нет чего-то вроде Compress/Decompress?
0
Испарился
 Аватар для HackerVlad
1741 / 637 / 45
Регистрация: 10.09.2021
Сообщений: 2,769
07.03.2025, 15:54  [ТС]
Цитата Сообщение от testuser2 Посмотреть сообщение
Это действительно странный момент, да, учитывая, что зип используется прям везде-везде
Я думаю просто, что MS решила продвигать свой формат CAB, поэтому не добавляла поддержки ZIP, но пользователям почему-то больше понравился старый добрый ZIP, а CAB людям почему-то вообще не зашёл... Кстати это странно, почему не зашёл людям CAB? Что в нём плохого?

Добавлено через 2 минуты
Цитата Сообщение от testuser2 Посмотреть сообщение
а что там нет чего-то вроде Compress/Decompress?
где?
0
1384 / 838 / 91
Регистрация: 08.02.2017
Сообщений: 3,512
Записей в блоге: 1
07.03.2025, 16:17
Цитата Сообщение от HackerVlad Посмотреть сообщение
где?
среди коллбечных функций
0
Испарился
 Аватар для HackerVlad
1741 / 637 / 45
Регистрация: 10.09.2021
Сообщений: 2,769
07.03.2025, 18:01  [ТС]
testuser2, ой не понимаю я тебя
0
1384 / 838 / 91
Регистрация: 08.02.2017
Сообщений: 3,512
Записей в блоге: 1
08.03.2025, 04:40
HackerVlad, ты же переписывал модуль с Делфи где все на коллбеках, там нету разве функций распаковки буфера? 7zip, кстати, с открытым исходным кодом, там есть распаковка cab, но это надо понимать cpp https://github.com/ip7z/7zip/b... Stream.cpp
1
Испарился
 Аватар для HackerVlad
1741 / 637 / 45
Регистрация: 10.09.2021
Сообщений: 2,769
08.03.2025, 12:24  [ТС]
Цитата Сообщение от testuser2 Посмотреть сообщение
там нету разве функций распаковки буфера?
я думал ты смотрел тот код, там распаковка файла целиком только есть, а не буфера, поэтому чтобы распаковать буфера надо сначала собрать файл

Добавлено через 57 секунд
ааа... хотя я распаковку ещё не выкладывал, точно...

Добавлено через 1 минуту
ну всё равно как ты буфер туда засунешь, там оно должно сразу целым файлом заглатывать с заголовочными структурами

Добавлено через 33 минуты
testuser2, мне надо найти описание структуры дополнительного заголовка для CAB
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
08.03.2025, 12:24
Помогаю со студенческими работами здесь

Программно распаковать zip файл
Необходимо распаковать MACHINEDATA.TT.ZIP файл. Использовав пример из https://www.cyberforum.ru/vb-net/thread343195-page3.html получился...

Открыть zip архив и распаковать pdf файл с паролем
из zip архива распаковать pdf файл с паролем

Как распаковать файл из архива внутри архива? Ionic.Zip
Всем привет! Пишу программу для распаковки файла &quot;Main.xml&quot; в ZIP архиве &quot;Test2&quot; в ZIP архиве &quot;Test&quot;. Для лучшего понимание...

Как в Access97 распаковать ZIP
Как в Access97 распаковать ZIP? Где взять библиотеку по распаковке Zip-архивов, с примерами на VBA?

Как распаковать Zip архив?
Привет, как можно легко распаковать Zip архив? У меня программа качает архив, но как то должна распаковать его.


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Новые блоги и статьи
Owen Logic: О недопустимости использования связки «аналоговый ПИД» + RegKZR
ФедосеевПавел 06.01.2026
Owen Logic: О недопустимости использования связки «аналоговый ПИД» + RegKZR ВВЕДЕНИЕ Введу сокращения: аналоговый ПИД — ПИД регулятор с управляющим выходом в виде числа в диапазоне от 0% до. . .
Модель микоризы: классовый агентный подход 2
anaschu 06.01.2026
репозиторий https:/ / github. com/ shumilovas/ fungi ветка по-частям. коммит Create переделка под биомассу. txt вход sc, но sm считается внутри мицелия. кстати, обьем тоже должен там считаться. . . .
Расчёт токов в цепи постоянного тока
igorrr37 05.01.2026
/ * Дана цепь постоянного тока с сопротивлениями и напряжениями. Надо найти токи в ветвях. Программа составляет систему уравнений по 1 и 2 законам Кирхгофа и решает её. Последовательность действий:. . .
Новый CodeBlocs. Версия 25.03
palva 04.01.2026
Оказывается, недавно вышла новая версия CodeBlocks за номером 25. 03. Когда-то давно я возился с только что вышедшей тогда версией 20. 03. С тех пор я давно снёс всё с компьютера и забыл. Теперь. . .
Модель микоризы: классовый агентный подход
anaschu 02.01.2026
Раньше это было два гриба и бактерия. Теперь три гриба, растение. И на уровне агентов добавится между грибами или бактериями взаимодействий. До того я пробовал подход через многомерные массивы,. . .
Советы по крайней бережливости. Внимание, это ОЧЕНЬ длинный пост.
Programma_Boinc 28.12.2025
Советы по крайней бережливости. Внимание, это ОЧЕНЬ длинный пост. Налог на собак: https:/ / **********/ gallery/ V06K53e Финансовый отчет в Excel: https:/ / **********/ gallery/ bKBkQFf Пост отсюда. . .
Кто-нибудь знает, где можно бесплатно получить настольный компьютер или ноутбук? США.
Programma_Boinc 26.12.2025
Нашел на реддите интересную статью под названием Anyone know where to get a free Desktop or Laptop? Ниже её машинный перевод. После долгих разбирательств я наконец-то вернула себе. . .
Thinkpad X220 Tablet — это лучший бюджетный ноутбук для учёбы, точка.
Programma_Boinc 23.12.2025
Рецензия / Мнение/ Перевод Нашел на реддите интересную статью под названием The Thinkpad X220 Tablet is the best budget school laptop period . Ниже её машинный перевод. Thinkpad X220 Tablet —. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru