From 090e17b3d923d491c9295614a170f29b038f9925 Mon Sep 17 00:00:00 2001 From: atxr Date: Wed, 21 Feb 2024 17:08:57 +0100 Subject: [PATCH] Track only LFH offsets and init zip struct --- libmineziper/include/libmineziper_zip.h | 13 ++++--- libmineziper/src/libmineziper.c | 16 ++++---- libmineziper/src/libmineziper_zip.c | 52 ++++++++++++++----------- tests/test_decode_fixed_tree.c | 12 +++--- tests/test_get_cdh.c | 36 +++++++++-------- 5 files changed, 70 insertions(+), 59 deletions(-) diff --git a/libmineziper/include/libmineziper_zip.h b/libmineziper/include/libmineziper_zip.h index 86dc934..82da20e 100644 --- a/libmineziper/include/libmineziper_zip.h +++ b/libmineziper/include/libmineziper_zip.h @@ -82,19 +82,20 @@ typedef struct DHCH typedef struct zip { - // compression type + char* start; + unsigned int size; + char* cd; - CDH** cdh; - LFH** lfh; unsigned int* lfh_off; unsigned int entries; EOCD* eocd; } zip; -void get_eocd(char* data, int size, zip* out); -void get_cdh(char* data, zip* out); +zip init_zip(char* data, int size); +void get_eocd(zip* out); +void get_cdh(zip* out); + char* get_encoded_block(zip* in, int n); -void parse_zip(char* filename, zip* out); void deflate(zip* in); diff --git a/libmineziper/src/libmineziper.c b/libmineziper/src/libmineziper.c index 5595881..7e41c5d 100644 --- a/libmineziper/src/libmineziper.c +++ b/libmineziper/src/libmineziper.c @@ -1,5 +1,7 @@ #include #include +#include +#include #include "libmineziper.h" @@ -12,9 +14,10 @@ int get_uncompressed_size(zip* in) { 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; @@ -22,13 +25,11 @@ int get_uncompressed_size(zip* in) bool scan_zip(char* zip_data, int zip_size) { - zip zip; - get_eocd(zip_data, zip_size, &zip); - get_cdh(zip_data, &zip); + zip zip = init_zip(zip_data, zip_size); 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) { @@ -72,8 +73,7 @@ bool scan_zip(char* zip_data, int zip_size) fprintf(stderr, "[FILE %d] Error in compressed data\n", i); } -#include - if (strcmp("VIRUS", decoded_data) == NULL) + if (strcmp("VIRUS", decoded_data) == 0) { printf("-> VIRUS FOUND\n"); return true; diff --git a/libmineziper/src/libmineziper_zip.c b/libmineziper/src/libmineziper_zip.c index 60893dc..2057c0a 100644 --- a/libmineziper/src/libmineziper_zip.c +++ b/libmineziper/src/libmineziper_zip.c @@ -5,28 +5,36 @@ #include "libmineziper_huffman_tree.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; - char* se = &data[size - START_EOCD_SEARCH]; - while (se > data) + char* se = &z->start[z->size - START_EOCD_SEARCH]; + while (se > z->start) { if (strcmp(se, EOCD_SIG) == 0) { - out->eocd = (EOCD*) se; - out->entries = out->eocd->number_of_entries; + z->eocd = (EOCD*) se; + z->entries = z->eocd->number_of_entries; - out->cdh = (CDH**) malloc(out->entries * sizeof(CDH*)); - out->lfh = (LFH**) malloc(out->entries * sizeof(LFH*)); - out->lfh_off = malloc(out->entries * sizeof(int)); + z->lfh_off = malloc(z->entries * sizeof(int)); - if (!out->cdh || !out->lfh || !out->lfh_off) + if (!z->lfh_off) { printf( "[ERROR] Failed to allocate CDH/LFH buffer for %d entries\n", - out->entries); + z->entries); 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(" error: No EOCD found.\n"); + fprintf(stderr, "[ERROR]: No EOCD found when fetching CDH.\n"); exit(-1); } - out->cd = data + out->eocd->off_cdh; + z->cd = z->start + z->eocd->off_cdh; - CDH* cdh = (CDH*) out->cd; - for (int i = 0; i < out->eocd->number_of_entries; i++) + CDH* cdh = (CDH*) z->cd; + for (int i = 0; i < z->eocd->number_of_entries; i++) { - out->cdh[i] = cdh; - out->lfh[i] = (LFH*) (data + cdh->off_lfh); - - out->lfh_off[i] = cdh->off_lfh; + z->lfh_off[i] = cdh->off_lfh; cdh = (CDH*) (((char*) cdh) + sizeof(CDH) + cdh->filename_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) { - return (char*) (in->lfh[n]) + sizeof(LFH) + in->lfh[n]->filename_length + - in->lfh[n]->extraf_length; + LFH* lfh = &in->start[in->lfh_off[n]]; + 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) diff --git a/tests/test_decode_fixed_tree.c b/tests/test_decode_fixed_tree.c index 0c12583..d52242d 100644 --- a/tests/test_decode_fixed_tree.c +++ b/tests/test_decode_fixed_tree.c @@ -27,24 +27,24 @@ void main(int argc, char** argv) int read_size = fread(buf, 1, BUF_SIZE, stream); buf[BUF_SIZE] = '\0'; - zip zip; - get_eocd(buf, read_size, &zip); - get_cdh(buf, &zip); + zip zip = init_zip(buf, read_size); for (int k = 0; k < zip.eocd->number_of_entries; 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); - if (zip.lfh[k]->compressed_size == 0) + if (lfh->compressed_size == 0) { printf("Empty bloc\n"); } else { - if (zip.cdh[k]->compression_method == DEFLATE) + if (lfh->compression_method == DEFLATE) { char* data = get_encoded_block(&zip, k); diff --git a/tests/test_get_cdh.c b/tests/test_get_cdh.c index cb475c3..2be0d4e 100644 --- a/tests/test_get_cdh.c +++ b/tests/test_get_cdh.c @@ -17,50 +17,54 @@ int main(int argc, char** argv) int read_size = fread(buf, 1, BUF_SIZE, stream); buf[BUF_SIZE] = '\0'; - zip zip; - get_eocd(buf, read_size, &zip); - get_cdh(buf, &zip); + zip zip = init_zip(buf, read_size); printf( "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->size_cdh); + CDH* cdh = (CDH*) zip.cd; for (int i = 0; i < zip.eocd->number_of_entries; i++) { printf( "cdh %d = {\n sig: 0x%x\n off lfh: 0x%x\n " "comp size: 0x%x\n uncomp size: 0x%x\n filename: ", i, - zip.cdh[i]->sig, - zip.cdh[i]->off_lfh, - zip.cdh[i]->compressed_size, - zip.cdh[i]->uncompressed_size); + cdh->sig, + cdh->off_lfh, + cdh->compressed_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"); + + cdh = (CDH*) (((char*) cdh) + sizeof(CDH) + cdh->filename_length + + cdh->extraf_length + cdh->file_comment_length); } 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( "lfh %d = {\n sig: 0x%x\n comp size: 0x%x\n uncomp size: 0x%x\n " "filename: ", i, - zip.lfh[i]->sig, - zip.lfh[i]->compressed_size, - zip.lfh[i]->uncompressed_size); + lfh->sig, + lfh->compressed_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");