Track only LFH offsets and init zip struct

This commit is contained in:
atxr 2024-02-21 17:08:57 +01:00
parent 812ff2fe3e
commit 090e17b3d9
5 changed files with 70 additions and 59 deletions

View file

@ -82,19 +82,20 @@ typedef struct DHCH
typedef struct zip typedef struct zip
{ {
// compression type char* start;
unsigned int size;
char* cd; char* cd;
CDH** cdh;
LFH** lfh;
unsigned int* lfh_off; unsigned int* lfh_off;
unsigned int entries; unsigned int entries;
EOCD* eocd; EOCD* eocd;
} zip; } zip;
void get_eocd(char* data, int size, zip* out); zip init_zip(char* data, int size);
void get_cdh(char* data, zip* out); void get_eocd(zip* out);
void get_cdh(zip* out);
char* get_encoded_block(zip* in, int n); char* get_encoded_block(zip* in, int n);
void parse_zip(char* filename, zip* out);
void deflate(zip* in); void deflate(zip* in);

View file

@ -1,5 +1,7 @@
#include <assert.h> #include <assert.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "libmineziper.h" #include "libmineziper.h"
@ -12,9 +14,10 @@ int get_uncompressed_size(zip* in)
{ {
int size = 0; int size = 0;
for (int i = 0; i < in->eocd->number_of_entries; i++) for (int i = 0; i < in->entries; i++)
{ {
size += in->cdh[i]->uncompressed_size; // TODO overflow LFH* lfh = &in->start[in->lfh_off[i]];
size += lfh->uncompressed_size;
} }
return size; return size;
@ -22,13 +25,11 @@ int get_uncompressed_size(zip* in)
bool scan_zip(char* zip_data, int zip_size) bool scan_zip(char* zip_data, int zip_size)
{ {
zip zip; zip zip = init_zip(zip_data, zip_size);
get_eocd(zip_data, zip_size, &zip);
get_cdh(zip_data, &zip);
for (int i = 0; i < zip.entries; i++) for (int i = 0; i < zip.entries; i++)
{ {
LFH* lfh = &zip_data[zip.lfh_off[i]]; LFH* lfh = &zip.start[zip.lfh_off[i]];
if (lfh->compression_method == DEFLATE) if (lfh->compression_method == DEFLATE)
{ {
@ -72,8 +73,7 @@ bool scan_zip(char* zip_data, int zip_size)
fprintf(stderr, "[FILE %d] Error in compressed data\n", i); fprintf(stderr, "[FILE %d] Error in compressed data\n", i);
} }
#include <string.h> if (strcmp("VIRUS", decoded_data) == 0)
if (strcmp("VIRUS", decoded_data) == NULL)
{ {
printf("-> VIRUS FOUND\n"); printf("-> VIRUS FOUND\n");
return true; return true;

View file

@ -5,28 +5,36 @@
#include "libmineziper_huffman_tree.h" #include "libmineziper_huffman_tree.h"
#include "libmineziper_zip.h" #include "libmineziper_zip.h"
void get_eocd(char* data, int size, zip* out) zip init_zip(char* data, int size)
{ {
if (size < START_EOCD_SEARCH) zip z = {.start = data, .size = size};
get_eocd(&z);
get_cdh(&z);
return z;
}
void get_eocd(zip* z)
{
if (z->size < START_EOCD_SEARCH)
return; return;
char* se = &data[size - START_EOCD_SEARCH]; char* se = &z->start[z->size - START_EOCD_SEARCH];
while (se > data) while (se > z->start)
{ {
if (strcmp(se, EOCD_SIG) == 0) if (strcmp(se, EOCD_SIG) == 0)
{ {
out->eocd = (EOCD*) se; z->eocd = (EOCD*) se;
out->entries = out->eocd->number_of_entries; z->entries = z->eocd->number_of_entries;
out->cdh = (CDH**) malloc(out->entries * sizeof(CDH*)); z->lfh_off = malloc(z->entries * sizeof(int));
out->lfh = (LFH**) malloc(out->entries * sizeof(LFH*));
out->lfh_off = malloc(out->entries * sizeof(int));
if (!out->cdh || !out->lfh || !out->lfh_off) if (!z->lfh_off)
{ {
printf( printf(
"[ERROR] Failed to allocate CDH/LFH buffer for %d entries\n", "[ERROR] Failed to allocate CDH/LFH buffer for %d entries\n",
out->entries); z->entries);
exit(1); exit(1);
} }
@ -37,23 +45,20 @@ void get_eocd(char* data, int size, zip* out)
} }
} }
void get_cdh(char* data, zip* out) void get_cdh(zip* z)
{ {
if (out->eocd == 0 || out->eocd->off_cdh == 0) if (z->eocd == 0 || z->eocd->off_cdh == 0)
{ {
printf("<get_cdh> error: No EOCD found.\n"); fprintf(stderr, "[ERROR]: No EOCD found when fetching CDH.\n");
exit(-1); exit(-1);
} }
out->cd = data + out->eocd->off_cdh; z->cd = z->start + z->eocd->off_cdh;
CDH* cdh = (CDH*) out->cd; CDH* cdh = (CDH*) z->cd;
for (int i = 0; i < out->eocd->number_of_entries; i++) for (int i = 0; i < z->eocd->number_of_entries; i++)
{ {
out->cdh[i] = cdh; z->lfh_off[i] = cdh->off_lfh;
out->lfh[i] = (LFH*) (data + cdh->off_lfh);
out->lfh_off[i] = cdh->off_lfh;
cdh = (CDH*) (((char*) cdh) + sizeof(CDH) + cdh->filename_length + cdh = (CDH*) (((char*) cdh) + sizeof(CDH) + cdh->filename_length +
cdh->extraf_length + cdh->file_comment_length); cdh->extraf_length + cdh->file_comment_length);
@ -62,8 +67,9 @@ void get_cdh(char* data, zip* out)
char* get_encoded_block(zip* in, int n) char* get_encoded_block(zip* in, int n)
{ {
return (char*) (in->lfh[n]) + sizeof(LFH) + in->lfh[n]->filename_length + LFH* lfh = &in->start[in->lfh_off[n]];
in->lfh[n]->extraf_length; return in->start + in->lfh_off[n] + sizeof(LFH) + lfh->filename_length +
lfh->extraf_length;
} }
char* decode_type1_block_vuln(bitstream* bs, char* decoded_data) char* decode_type1_block_vuln(bitstream* bs, char* decoded_data)

View file

@ -27,24 +27,24 @@ void main(int argc, char** argv)
int read_size = fread(buf, 1, BUF_SIZE, stream); int read_size = fread(buf, 1, BUF_SIZE, stream);
buf[BUF_SIZE] = '\0'; buf[BUF_SIZE] = '\0';
zip zip; zip zip = init_zip(buf, read_size);
get_eocd(buf, read_size, &zip);
get_cdh(buf, &zip);
for (int k = 0; k < zip.eocd->number_of_entries; k++) for (int k = 0; k < zip.eocd->number_of_entries; k++)
{ {
printf("BLOC %d:\n", k); printf("BLOC %d:\n", k);
unsigned int uncompressed_size = zip.lfh[k]->uncompressed_size; LFH* lfh = &zip.start[zip.lfh_off[k]];
unsigned int uncompressed_size = lfh->uncompressed_size;
printf("UNCOMPRESSED SIZE: 0x%x\n", uncompressed_size); printf("UNCOMPRESSED SIZE: 0x%x\n", uncompressed_size);
if (zip.lfh[k]->compressed_size == 0) if (lfh->compressed_size == 0)
{ {
printf("Empty bloc\n"); printf("Empty bloc\n");
} }
else else
{ {
if (zip.cdh[k]->compression_method == DEFLATE) if (lfh->compression_method == DEFLATE)
{ {
char* data = get_encoded_block(&zip, k); char* data = get_encoded_block(&zip, k);

View file

@ -17,50 +17,54 @@ int main(int argc, char** argv)
int read_size = fread(buf, 1, BUF_SIZE, stream); int read_size = fread(buf, 1, BUF_SIZE, stream);
buf[BUF_SIZE] = '\0'; buf[BUF_SIZE] = '\0';
zip zip; zip zip = init_zip(buf, read_size);
get_eocd(buf, read_size, &zip);
get_cdh(buf, &zip);
printf( printf(
"eocd = {\n nb of entry: %x\n off cd: %d\n size cd: 0x%x\n}\n", "eocd = {\n nb of entry: %x\n off cd: %d\n size cd: 0x%x\n}\n",
zip.eocd->number_of_entries, zip.entries,
zip.eocd->off_cdh, zip.eocd->off_cdh,
zip.eocd->size_cdh); zip.eocd->size_cdh);
CDH* cdh = (CDH*) zip.cd;
for (int i = 0; i < zip.eocd->number_of_entries; i++) for (int i = 0; i < zip.eocd->number_of_entries; i++)
{ {
printf( printf(
"cdh %d = {\n sig: 0x%x\n off lfh: 0x%x\n " "cdh %d = {\n sig: 0x%x\n off lfh: 0x%x\n "
"comp size: 0x%x\n uncomp size: 0x%x\n filename: ", "comp size: 0x%x\n uncomp size: 0x%x\n filename: ",
i, i,
zip.cdh[i]->sig, cdh->sig,
zip.cdh[i]->off_lfh, cdh->off_lfh,
zip.cdh[i]->compressed_size, cdh->compressed_size,
zip.cdh[i]->uncompressed_size); cdh->uncompressed_size);
for (int j = 0; j < zip.cdh[i]->filename_length; j++) for (int j = 0; j < cdh->filename_length; j++)
{ {
printf("%c", ((char*) zip.cdh[i])[sizeof(CDH) + j]); printf("%c", ((char*) cdh)[sizeof(CDH) + j]);
} }
printf("\n}\n\n"); printf("\n}\n\n");
cdh = (CDH*) (((char*) cdh) + sizeof(CDH) + cdh->filename_length +
cdh->extraf_length + cdh->file_comment_length);
} }
printf("\n--------------------------------------------\n"); printf("\n--------------------------------------------\n");
for (int i = 0; i < zip.eocd->number_of_entries; i++) for (int i = 0; i < zip.entries; i++)
{ {
LFH* lfh = &zip.start[zip.lfh_off[i]];
printf( printf(
"lfh %d = {\n sig: 0x%x\n comp size: 0x%x\n uncomp size: 0x%x\n " "lfh %d = {\n sig: 0x%x\n comp size: 0x%x\n uncomp size: 0x%x\n "
"filename: ", "filename: ",
i, i,
zip.lfh[i]->sig, lfh->sig,
zip.lfh[i]->compressed_size, lfh->compressed_size,
zip.lfh[i]->uncompressed_size); lfh->uncompressed_size);
for (int j = 0; j < zip.lfh[i]->filename_length; j++) for (int j = 0; j < lfh->filename_length; j++)
{ {
printf("%c", ((char*) zip.lfh[i])[sizeof(LFH) + j]); printf("%c", ((char*) lfh)[sizeof(LFH) + j]);
} }
printf("\n}\n\n"); printf("\n}\n\n");