|
Expert Witness Compression Format Specification Revised: April 7, 2002 |
Introduction
| Overview |
The Expert Witness Compression format can store a single image in one or more segment files. Each file consists of a standard 13-byte header, followed by a series of sections. The sections are typically arranged back-to-back. A section cannot span two files.
| File Header |
Each file begins with the following 13-byte header. (This is not to be confused with the header section, below.)
Signature Part (8 bytes)...
|
Fields Part (5 bytes)...
|
| The Section |
Every section begins with the same standard data, with the following layout.
| Offset: | Bytes: | Data: | Meaning: |
| 0 (0x0) | 16 | "volume", "header", etc. | Section type string |
| 16 (0x10) | 8 | 64-bit offset in current file to the next section | |
| 24 (0x18) | 8 | 64-bit byte-size of the section | |
| 32 (0x20) | 40 | 0x00... | Padding |
| 72 (0x48) | 4 | CRC of all previous setion data |
| Section Types |
Expert Witness Compression uses the following section types: header, volume, table, next, and done. Some of these section types have unique data that begins directly after the standard section structure above.
| Offset: | Bytes: | Data: | Meaning: |
| 76 (0x4c) | to end of section | zlib compress()'ed data | Comments structure (see below) |
| 1 | ||||||||
| main | ||||||||
| c | n | a | e | t | m | u | p | r |
| Case Number | Evidence Number | Unique Description | Examiner Name | Notes | Acquired Date | System Date | pwhash | char |
The header section should appear in the first segment file only.
| Offset: | Bytes: | Data: | Meaning: |
| 76 (0x4c) | 4 | 1 | Reserved |
| 80 (0x50) | 4 | Chunk Count | |
| 84 (0x54) | 4 | 64 | Sectors per Chunk |
| 88 (0x58) | 4 | 512 | Bytes per Sector |
| 92 (0x5c) | 4 | Sector Count | |
| 96 (0x60) | 20 | 0x00... | Reserved |
| 116 (0x74) | 45 | 0x00... | Padding |
| 161 (0xa1) | 5 | Reserved (Signature) | |
| 166 (0xa6) | 4 | CRC of all previous 'volume' data, starting with offset 76 |
The volume section should appear in the first segment file only.
| Offset: | Bytes: | Data: | Meaning: |
| 76 (0x4c) | 4 | 1 | Chunk Count (for this table) |
| 80 (0x50) | 16 | 0x00... | Padding |
| 96 (0x60) | 4 | CRC of all previous 'table' data, starting with offset 76 | |
| 100 (0x64) | as long as necessary | Offset array (see below) | |
| from end of offset array | to end of section | zlib compress()'ed data Chunks |
The offset array is a series of back-to-back 4-byte unsigned integer values. Each entry is an offset to the start of a compressed 'Chunk'. The high bit of each value must be set! There must be one entry per Chunk.
Each table section can hold 16375 entries. If more entries are needed, you must create multiple table
sections per file.
'next' and 'done' sections...
Each file ends with a 'next' or 'done' section. If the file is the last segment in an Expert Witness compressed image, the
section will be named 'done'. Otherwise, the section will be named 'next' to indicate that another segment
file must be read. The "next section" pointer for these section types points to the beginning of the section itself, since
it is the last section in a file. These section types have no unique data.
| CRC Algorithm |
The following function returns the 4-byte CRC value used in the Expert Witness Compression format. When calling the function to start a new CRC, the third argument (prevkey) should be '1'.
uint Expert_Witness_Compression_crc(void *buffer, int buffersize, uint prevkey)
{
unsigned char *cbuffer = (unsigned char *)buffer;
unsigned int b = prevkey & 0xffff;
unsigned int d = (prevkey >> 16) & 0xffff;
for(int i=0; i < buffersize; i++)
{
b += cbuffer[i];
d += b;
if ( i != 0 && ( (i % 0x15b0 == 0) || (i == buffersize - 1) ) )
{
b = b % 0xfff1;
d = d % 0xfff1;
}
}
return (d << 16) | b;
}