I'm developing a frontend to 7za named xarchiver. To automatically prompt the user to enter a password I need to know if an archive is password protected. Could someone tell me at which byte position in the file I have to read to know this ?
Thanks,
gt67
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Thanks for replying, xarchiver is for Linux. When I run 7za from the bash shell it asks me a password, so it recognize the archive is password protected. Can you tell me wich header I shall look for ? I red the 7zip format .txt file but it is not clear.
Thank you,
gt67
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
You have been very kind Igor, thank you, I hope to succeed so to give my GTK frontend the ability to automatically recognize 7z password protected archives.
Happy coding,
gt67
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
after going thorugh the source file you indicated me I came to the conclusion that is better for me to have the technical specs of the 7z format. I have the file p7zip_4.29/DOCS/7zFormat.txt but inside it there is no mention of a flag/byte that indicates the file is pass encrypted. Do you have another version of the 7z format please ? I have been able to detect zip,rar, arj password protected archives, only 7zip is missing, I hope you can kindly help me.
Thanks,
gt67
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Thank you for replying. Igor, the information in the file 7zFormat.txt and Methods.txt are incomplete, I need info like the following (taken from zip format) to proceed:
Overall .ZIP file format:
[local file header 1]
[file data 1]
[data descriptor 1]
.
.
.
[local file header n]
[file data n]
[data descriptor n]
[archive decryption header] (EFS)
[archive extra data record] (EFS)
[central directory]
[zip64 end of central directory record]
[zip64 end of central directory locator]
[end of central directory record]
A. Local file header:
local file header signature 4 bytes (0x04034b50)
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 name (variable size)
extra field (variable size)
B. File data
Immediately following the local header for a file
is the compressed or stored data for the file.
The series of [local file header][file data][data
descriptor] repeats for each file in the .ZIP archive.
Then there is a series of dot and something that looks like code. If possible I would ask you to provide me a better documented 7z format :-) . What else is stored after NextheaderCRC for example ?
Thanks for your kind attention,
gt67
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Ok, I located the k_7zAES header (06 f1 07 01) in the file above containing only one small encrypted text file, but the problem is how to reach that position with fseek ? I don't know which fields ( and their size) are written BEFORE the k_7zAES header.
Thank you,
gt67
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
I noticed if there are two or more files the signature 37 7a bc af 27 1c is not repeated for each of the files contained in the archive as it happens with zip and arj. How can I know where the info for each files in the archive begins and ends ?
Thanks for your time,
gt67
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
MainStreamsInfo
{
(Same as in AdditionalStreams)
}
FilesInfo
{
NumFiles
Properties[]
{
ID
Size
Data
}
}
If so, before it there are many other fields, how can I load in memory the main header to decompress it, if I don't know the sizes of the previous fields before the main header itself ?? I tried to reconstruct the steps 7za performs when writing to a file by looking into 7zOut.cpp but the name of the variables are different from those you used in the 7zFormat.txt. Can you help please ?
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
After immediately following NextheaderCRC you said in the file there is stored the file data in compressed form right. Immediately after this I expect to find the header for the file itself right ? So the compressed data first and the the header containing file info: the name, the size of the name and the compression method (LZMA or LZMA + 7ZAES), am I right ?
gt67
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
> Immediately after this I expect to find the header for the file itself right ?
1) Read NextHeaderOffset/NextHeaderSize
2) Read that header and parse it. If there are more header, this header contains some size/offset/encodingMethod information.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
This is the content of NextHeader 35 bytes (23 in hex):
17 6 82 10 1 9 80 83 0 7 b 1 0 1 23 3 1 1 5 5d 0 0 10 0 c 80 a4 a 1 f 86 5d f1 0 0
> 2) Read that header and parse it.
0x17 means that this header is a kEncodedHeader according to 7zFormat.txt, 0x6 I guess it's kPackInfo but 82 ?? I don't find 82 in 7zFormat.txt. Could you please help me here ?
> If there are more header, this header contains some size/offset/encodingMethod information.
I guess in this case there is another header because of the presence of 0x17 right ? But how to parse it ? Which structure shall I look ?
Thanks Igor,
gt67
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Hi,
I'm developing a frontend to 7za named xarchiver. To automatically prompt the user to enter a password I need to know if an archive is password protected. Could someone tell me at which byte position in the file I have to read to know this ?
Thanks,
gt67
It's difficult. Headers are complex.
And 7za.exe now can't tell you that archive is encrypted .
I'll think how to fix it in future.
Thanks for replying, xarchiver is for Linux. When I run 7za from the bash shell it asks me a password, so it recognize the archive is password protected. Can you tell me wich header I shall look for ? I red the 7zip format .txt file but it is not clear.
Thank you,
gt67
You must decompress header. It's complex task. If header is encrypted you must also decrypt header.
Could at least tell me which source files I shall look into ? I will try to get the solution myself thank you.
gt67
7zip\Archive\7z\7zIn.cpp
You have been very kind Igor, thank you, I hope to succeed so to give my GTK frontend the ability to automatically recognize 7z password protected archives.
Happy coding,
gt67
Igor,
after going thorugh the source file you indicated me I came to the conclusion that is better for me to have the technical specs of the 7z format. I have the file p7zip_4.29/DOCS/7zFormat.txt but inside it there is no mention of a flag/byte that indicates the file is pass encrypted. Do you have another version of the 7z format please ? I have been able to detect zip,rar, arj password protected archives, only 7zip is missing, I hope you can kindly help me.
Thanks,
gt67
For enctyption 7-zip uses 7zAES/AES plugins. Check Methods.txt also.
Thank you for replying. Igor, the information in the file 7zFormat.txt and Methods.txt are incomplete, I need info like the following (taken from zip format) to proceed:
Overall .ZIP file format:
[local file header 1]
[file data 1]
[data descriptor 1]
.
.
.
[local file header n]
[file data n]
[data descriptor n]
[archive decryption header] (EFS)
[archive extra data record] (EFS)
[central directory]
[zip64 end of central directory record]
[zip64 end of central directory locator]
[end of central directory record]
A. Local file header:
local file header signature 4 bytes (0x04034b50)
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 name (variable size)
extra field (variable size)
B. File data
Immediately following the local header for a file
is the compressed or stored data for the file.
The series of [local file header][file data][data
descriptor] repeats for each file in the .ZIP archive.
C. Data descriptor:
crc-32 4 bytes
compressed size 4 bytes
uncompressed size 4 bytes
This way I know which field is stored in the file and its size. In the file format 7zFormat.txt only the signature part is documented such way:
7z format headers
-----------------
SignatureHeader
~~~~~~~~~~~~~~~
BYTE kSignature[6] = {'7', 'z', 0xBC, 0xAF, 0x27, 0x1C};
ArchiveVersion
{
BYTE Major; // now = 0
BYTE Minor; // now = 2
};
UINT32 StartHeaderCRC;
StartHeader
{
REAL_UINT64 NextHeaderOffset
REAL_UINT64 NextHeaderSize
UINT32 NextHeaderCRC
}
Then there is a series of dot and something that looks like code. If possible I would ask you to provide me a better documented 7z format :-) . What else is stored after NextheaderCRC for example ?
Thanks for your kind attention,
gt67
> What else is stored after NextheaderCRC for example ?
File data in compressed form.
Archive structure
~~~~~~~~~~~~~~~~~
SignatureHeader
[PackedStreams]
[PackedStreamsForHeaders]
[
Header
or
{
Packed Header
HeaderInfo
}
]
HeaderInfo
~~~~~~~~~~
[]
BYTE NID::kEncodedHeader; (0x17)
StreamsInfo for Encoded Header
[]
mmm and a flag indicating that the file in the archive is password protected where it is stored ?
Parse all headers. If methodID = id of 7zAES, then header is compressed.
Parse headers. If methodID = id of 7zAES, then header is encrypted.
[gt@Paradise Xarchiver_Test]$ hexdump -C test_con_pass.7z
00000000 37 7a bc af 27 1c 00 02 e9 7a 41 9f 20 00 00 00 |7z..'....zA. ...|
00000010 00 00 00 00 52 00 00 00 00 00 00 00 d6 4c dd 1c |....R........L..|
00000020 56 5a 25 8f d9 f4 89 53 1f e5 2d 94 44 6b 43 d0 |VZ%....S..-.DkC.|
00000030 40 16 f9 57 71 0f 39 2e a3 f8 54 0d 6e 47 46 4d |@..Wq.9...T.nGFM|
00000040 01 04 06 00 01 09 20 00 07 0b 01 00 02 24 06 f1 |...... ......$..|
00000050 07 01 01 12 23 03 01 01 05 5d 00 00 20 00 01 00 |....#....].. ...|
00000060 0c 1d 18 00 08 0a 01 f4 54 0e 89 00 00 05 01 11 |........T.......|
00000070 0b 00 74 00 65 00 73 00 74 00 00 00 14 0a 01 00 |..t.e.s.t.......|
00000080 00 22 33 c5 dc f5 c5 01 15 06 01 00 20 80 a4 81 |."3......... ...|
00000090 00 00 |..|
00000092
Ok, I located the k_7zAES header (06 f1 07 01) in the file above containing only one small encrypted text file, but the problem is how to reach that position with fseek ? I don't know which fields ( and their size) are written BEFORE the k_7zAES header.
Thank you,
gt67
You must read and parse start header and then header at the end of archive.
I noticed if there are two or more files the signature 37 7a bc af 27 1c is not repeated for each of the files contained in the archive as it happens with zip and arj. How can I know where the info for each files in the archive begins and ends ?
Thanks for your time,
gt67
1. Parse start/end headers
2. Decompress main header
3. Check methods.
Is the main header compressed with LZMA algorithm or what else ?
Really many many thanks for your patience, if I succeed I will quote your name in the About dialog of Xarchiver.
gt67
> Is the main header compressed with LZMA algorithm or what else
LZMA or LZMA + 7zAES
Igor, is the main header this one:
MainStreamsInfo
{
(Same as in AdditionalStreams)
}
FilesInfo
{
NumFiles
Properties[]
{
ID
Size
Data
}
}
If so, before it there are many other fields, how can I load in memory the main header to decompress it, if I don't know the sizes of the previous fields before the main header itself ?? I tried to reconstruct the steps 7za performs when writing to a file by looking into 7zOut.cpp but the name of the variables are different from those you used in the 7zFormat.txt. Can you help please ?
Check PackPos:
HeaderInfo
~~~~~~~~~~
BYTE NID::kEncodedHeader; (0x17)
StreamsInfo for Encoded Header
Streams Info
BYTE NID::kPackInfo (0x06)
UINT64 PackPos !!!!!!!!!!!!
UINT64 NumPackStreams
Ok,let's sum up the whole thread:
After immediately following NextheaderCRC you said in the file there is stored the file data in compressed form right. Immediately after this I expect to find the header for the file itself right ? So the compressed data first and the the header containing file info: the name, the size of the name and the compression method (LZMA or LZMA + 7ZAES), am I right ?
gt67
> Immediately after this I expect to find the header for the file itself right ?
1) Read NextHeaderOffset/NextHeaderSize
2) Read that header and parse it. If there are more header, this header contains some size/offset/encodingMethod information.
> 1) Read NextHeaderOffset/NextHeaderSize
Done, the 7za test archive I used contains 2 small pass protected text files ( I used -ms=off):
[gt@Paradise Xarchiver_Test]$ ./7z_detect
First sig: 377abcaf271c
0
2
CRC: fee185c1
NextHeaderOffset: 293
NextHeaderSize: 0x23
This is the content of NextHeader 35 bytes (23 in hex):
17 6 82 10 1 9 80 83 0 7 b 1 0 1 23 3 1 1 5 5d 0 0 10 0 c 80 a4 a 1 f 86 5d f1 0 0
> 2) Read that header and parse it.
0x17 means that this header is a kEncodedHeader according to 7zFormat.txt, 0x6 I guess it's kPackInfo but 82 ?? I don't find 82 in 7zFormat.txt. Could you please help me here ?
> If there are more header, this header contains some size/offset/encodingMethod information.
I guess in this case there is another header because of the presence of 0x17 right ? But how to parse it ? Which structure shall I look ?
Thanks Igor,
gt67