From 3b8fd9c901942a11bac0eafbbe07da2829dbe610 Mon Sep 17 00:00:00 2001 From: Pin Date: Tue, 21 Sep 2021 01:15:03 -0400 Subject: [PATCH] wip Signed-off-by: Pin --- .gitignore | 5 ++ Makefile | 16 ++++ cmd/crc.c | 190 ++++++++++++++++++++++++++++++++++++++++ include/CRCLib.h | 51 +++++++++++ include/compress_util.h | 8 ++ include/crc.h | 6 ++ include/crc_util.h | 11 +++ src/compress_util.c | 126 ++++++++++++++++++++++++++ src/crc_util.c | 64 ++++++++++++++ 9 files changed, 477 insertions(+) create mode 100644 .gitignore create mode 100644 Makefile create mode 100644 cmd/crc.c create mode 100644 include/CRCLib.h create mode 100644 include/compress_util.h create mode 100644 include/crc.h create mode 100644 include/crc_util.h create mode 100644 src/compress_util.c create mode 100644 src/crc_util.c diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..961fffd --- /dev/null +++ b/.gitignore @@ -0,0 +1,5 @@ +*.png +*.out +*.woo +*.wow +bin/ diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..b06726e --- /dev/null +++ b/Makefile @@ -0,0 +1,16 @@ +LIBRARIES = `pkg-config --libs zlib libsodium` -Iinclude +SOURCES = ./src/* ./cmd/crc.c +OUTPUT_DIR = ./bin +OUTPUT = -o ${OUTPUT_DIR}/PROG + +build: output_dir + gcc -Wall ${LIBRARIES} ${SOURCES} ${OUTPUT:PROG=crc} + +debug: output_dir + gcc -Wall -g ${LIBRARIES} ${SOURCES} ${OUTPUT:PROG=crc} + +output_dir: + mkdir -p ${OUTPUT_DIR} + +clean: + rm -rf $(OUTPUT_DIR) **.h.gch diff --git a/cmd/crc.c b/cmd/crc.c new file mode 100644 index 0000000..435a44d --- /dev/null +++ b/cmd/crc.c @@ -0,0 +1,190 @@ +#include +#include +#include +#include +#include +#include "crc_util.h" +#include "CRCLib.h" +#include "crc.h" +#include "compress_util.h" + +const long idat_signature = 1229209940; +const long iend_signature = 1229278788; + +unsigned long first_idat(unsigned char *addr) { + int idat_found = 0; + unsigned long offset = 8; + int jump_offset = 0; + int header_type = 0; + while(idat_found == 0) { + jump_offset = check_header_length(addr, offset); + header_type = check_header_length(addr, offset+4); + if(header_type == idat_signature) { + idat_found = 1; + } else { + offset = offset + jump_offset + 12; + } + } + return offset; +} + +int total_idat(unsigned char *addr) { + int iend_found = 0; + int found_idat = 0; + unsigned long offset = 8; + int jump_offset = 0; + int header_type = 0; + while(iend_found == 0) { + jump_offset = check_header_length(addr, offset); + header_type = check_header_length(addr, offset+4); + if(header_type == iend_signature) { + iend_found = 1; + } else { + if(header_type == idat_signature) { + found_idat++; + } + offset = offset + jump_offset + 12; + } + } + return found_idat; +} + +int update_file_crc(unsigned char *addr, unsigned long offset , unsigned int crc_num) { + int startCRC = 8 + offset + check_header_length(addr, offset); + unsigned char new_crc; + for(int i = 0; i < 4; i++) { + new_crc = crc_num >> (8*(3-i)) & 0xFF; + addr[startCRC+i] = new_crc; + } + return 0; +} + +void random_data_change(unsigned char *color_data, int width, int length) { + int searching = 1; + size_t rounds = 0; + width = 16; + int color_range = 3; + unsigned char temp_color_data[length]; + + memcpy(temp_color_data, color_data, length); + + do { + rounds++; + // Creating temporary data set + memcpy(temp_color_data, color_data, length); + // Generating random byte to change + int random_num = randombytes_uniform(length); + // Checking for index break + if(random_num % ((width * color_range) + 1)) { + if(color_data[random_num] == 255) { + temp_color_data[random_num]--; + } else { + temp_color_data[random_num]++; + } + unsigned char *check_data_buff = NULL; + size_t check_data_length = 0; + zlib_compress_data(temp_color_data, length, &check_data_buff, &check_data_length); + + unsigned char full_data[check_data_length+4]; + full_data[0] = 0x49; + full_data[1] = 0x44; + full_data[2] = 0x41; + full_data[3] = 0x54; + for(int i = 0; i < check_data_length; i++) { + full_data[i+4] = check_data_buff[i]; + } + unsigned int temp_crc = crc(full_data, check_data_length); + if ((temp_crc >> (8*3)) == 10 ) { + printf("Found in %zu rounds!\n", rounds); + searching = 0; + } + free(check_data_buff); + } + + } while(searching == 1); +} + +int change_idat_content(unsigned char *addr, unsigned char *message, int accuracy, unsigned long offset) { + //printf("Starting IDAT Tranform\n"); + if(accuracy > 4) { + printf("Warning, accuracy cannot be larger than 4"); + return EXIT_FAILURE; + } + if(accuracy > 2) { + printf("Notice, this could take a long time..."); + } + if(total_idat(addr) < strlen(message)) { + printf("Warning, message exceeds IDAT amount"); + return EXIT_FAILURE; + } + + int idat_length = check_header_length(addr, offset); + printf("IDAT Length: %d\n", idat_length); + + int prop_found = 0; + long size = 1; + long rounds = 0; + size_t idat_byte_length = 0; + unsigned char* idat_data = calloc(size, sizeof(unsigned char)); + for(size_t i = 0; i <= idat_length; i++) { + if(i == size) { + size *= 2; + idat_data = reallocarray(idat_data, size, sizeof(unsigned char)); + } + idat_data[i] = addr[i+offset+8]; + idat_byte_length = i; + } + unsigned char temp_idat_data[idat_byte_length]; + while(prop_found == 0) { + for(int i = 0; i <= idat_length; i++) { + temp_idat_data[i] = idat_data[i]; + } + // Decompressing Data + unsigned char *uncom_data_buff = NULL; + size_t uncom_data_size = 0; + zlib_decompress_data(temp_idat_data, idat_byte_length, &uncom_data_buff, &uncom_data_size); + + random_data_change(uncom_data_buff, 16, uncom_data_size); + + free(uncom_data_buff); + + //printf("Found %d in %d rounds\n", checked_crc ,rounds); + //printf("Full CRC: %08X\n", crcnum); + //printf("Original: %02X\n", idat_data[j]); + //printf("Change offset: %d to hex: %02X\n", j, temp_idat_data[j]); + //addr[offset+8+j] = temp_idat_data[j]; + //update_file_crc(addr, offset, crcnum); + prop_found = 1; + } + + free(idat_data); + + return 0; +} + +// This is where it all starts +int main() { + FILE *fp; + size_t i = 0; + unsigned long offset = 0; + unsigned char *message = malloc(sizeof(char)); + message[0] = '\0'; + + if(sodium_init() == -1) { + return EXIT_FAILURE; + } + + fp = fopen("./1.png", "rt"); + if (fp == NULL) { + return EXIT_FAILURE; + } + + unsigned char *file_data = file_to_char_array(fp, &i); + fclose(fp); + + offset = first_idat(file_data); + change_idat_content(file_data, message, 1, offset); + free(file_data); + free(message); + //create_cc_file(file_data, i); +} diff --git a/include/CRCLib.h b/include/CRCLib.h new file mode 100644 index 0000000..39530ff --- /dev/null +++ b/include/CRCLib.h @@ -0,0 +1,51 @@ +/* Table of CRCs of all 8-bit messages. */ +unsigned long crc_table[256]; + +/* Flag: has the table been computed? Initially false. */ +int crc_table_computed = 0; + +/* Make the table for a fast CRC. */ +void make_crc_table(void) +{ + unsigned long c; + int n, k; + + for (n = 0; n < 256; n++) { + c = (unsigned long) n; + for (k = 0; k < 8; k++) { + if (c & 1) + c = 0xedb88320L ^ (c >> 1); + else + c = c >> 1; + } + crc_table[n] = c; + } + crc_table_computed = 1; +} + + +/* Update a running CRC with the bytes buf[0..len-1]--the CRC + should be initialized to all 1's, and the transmitted value + is the 1's complement of the final running CRC (see the + crc() routine below). */ + +unsigned long update_crc(unsigned long crc, unsigned char *buf, + int len) +{ + unsigned long c = crc; + int n; + + if (!crc_table_computed) + make_crc_table(); + for (n = 0; n < len; n++) { + c = crc_table[(c ^ buf[n]) & 0xff] ^ (c >> 8); + } + return c; +} + +/* Return the CRC of the bytes buf[0..len-1]. */ +unsigned long crc(unsigned char *buf, int len) +{ + return update_crc(0xffffffffL, buf, len) ^ 0xffffffffL; +} + diff --git a/include/compress_util.h b/include/compress_util.h new file mode 100644 index 0000000..f0c623f --- /dev/null +++ b/include/compress_util.h @@ -0,0 +1,8 @@ +#include +#include +#include +#include +#include + +void zlib_decompress_data(unsigned char *data_chunk, size_t file_length, unsigned char **buff, size_t *sz); +void zlib_compress_data(unsigned char *data_chunk, size_t file_length, unsigned char **buff, size_t *sz); diff --git a/include/crc.h b/include/crc.h new file mode 100644 index 0000000..acaba82 --- /dev/null +++ b/include/crc.h @@ -0,0 +1,6 @@ + +int check_file_header(char *addr); +int check_header_length(unsigned char *addr, long offset); +unsigned long first_idat(unsigned char *addr); +int total_idat(unsigned char *addr); +int change_idat_content(unsigned char *addr, unsigned char *message, int accuracy, unsigned long offset); diff --git a/include/crc_util.h b/include/crc_util.h new file mode 100644 index 0000000..6eae8e2 --- /dev/null +++ b/include/crc_util.h @@ -0,0 +1,11 @@ +#include + +// PNG File Struct +struct PNG + +extern const long png_signature[8]; + +int check_header_length(unsigned char *addr, long offset); +int check_file_header(char *addr); +int create_cc_file(unsigned char *addr, unsigned long file_length); +unsigned char* file_to_char_array(FILE *in_file, size_t* size); diff --git a/src/compress_util.c b/src/compress_util.c new file mode 100644 index 0000000..ebf3663 --- /dev/null +++ b/src/compress_util.c @@ -0,0 +1,126 @@ +#include +#include +#include +#include +#include "compress_util.h" + +#define CHUNK 1024 + +void zlib_decompress_data(unsigned char *data_chunk, size_t file_length, unsigned char **buff, size_t *sz) { + int ret; + unsigned int have; + z_stream strm; + // Adding one to zero here + unsigned char out[CHUNK]; + unsigned char in[CHUNK]; + + errno=0; + FILE *data_stream = fmemopen(data_chunk, file_length, "r"); + FILE *of = open_memstream((char**)buff, sz); + if(data_stream == NULL) { + perror("F MEM OPEN"); + } + + strm.zalloc = Z_NULL; + strm.zfree = Z_NULL; + strm.opaque = Z_NULL; + strm.avail_in = 0; + strm.next_in = Z_NULL; + ret = inflateInit(&strm); + if(ret != Z_OK) { + return; + } + + do { + strm.avail_in = fread(in, 1, CHUNK, data_stream); + if(ferror(data_stream)) { + (void)inflateEnd(&strm); + return; + } + if(strm.avail_in == 0) { + break; + } + strm.next_in = in; + + do { + strm.avail_out = CHUNK; + strm.next_out = out; + ret = inflate(&strm, Z_NO_FLUSH); + assert(ret != Z_STREAM_ERROR); + switch(ret) { + case Z_NEED_DICT: + ret = Z_DATA_ERROR; + case Z_DATA_ERROR: + case Z_MEM_ERROR: + (void)inflateEnd(&strm); + printf("Error: %d\n", ret); + printf("MSG: %s\n", (char*)strm.msg); + return; + } + have = CHUNK - strm.avail_out; + fwrite(out, 1, have, of); + } while(strm.avail_out == 0); + } while(ret != Z_STREAM_END); + + (void)inflateEnd(&strm); + + fclose(data_stream); + fclose(of); +} + +void zlib_compress_data(unsigned char *data_chunk, size_t file_length, unsigned char **buff, size_t *sz) { + int ret, flush; + unsigned int have; + z_stream strm; + unsigned char in[CHUNK]; + unsigned char out[CHUNK]; + int level = 9; + int method = Z_DEFLATED; + int windowBits = 10; + int memLevel = 9; + //int strategy = Z_DEFAULT_STRATEGY; + int strategy = Z_FILTERED; + + FILE *data_stream = fmemopen(data_chunk, file_length, "r"); + FILE *out_data_stream = NULL; + out_data_stream = open_memstream((char**)buff, sz); + + strm.zalloc = Z_NULL; + strm.zfree = Z_NULL; + strm.opaque = Z_NULL; + ret = deflateInit2(&strm, level, method, windowBits, memLevel, strategy); + if (ret != Z_OK) { + return; + } + + do { + strm.avail_in = fread(in, 1, CHUNK, data_stream); + if (ferror(data_stream)) { + (void)deflateEnd(&strm); + return; + } + flush = feof(data_stream) ? Z_FINISH : Z_NO_FLUSH; + strm.next_in = in; + + do { + strm.avail_out = CHUNK; + strm.next_out = out; + + ret = deflate(&strm, flush); + assert(ret != Z_STREAM_ERROR); + have = CHUNK - strm.avail_out; + if(fwrite(out, 1, have, out_data_stream) != have || ferror(out_data_stream)) { + (void)deflateEnd(&strm); + return; + } + } while(strm.avail_out == 0); + assert(strm.avail_in == 0); + + } while(flush != Z_FINISH); + assert(ret == Z_STREAM_END); + + fclose(data_stream); + fclose(out_data_stream); + + (void)deflateEnd(&strm); +} diff --git a/src/crc_util.c b/src/crc_util.c new file mode 100644 index 0000000..5df74ca --- /dev/null +++ b/src/crc_util.c @@ -0,0 +1,64 @@ +#include +#include +#include "crc_util.h" + +const long png_signature[8] = { 0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a }; + +int check_header_length(unsigned char *addr, long offset) { + unsigned int res = 0; + for( int i = 0; i < 4; i++ ) { + res |= addr[offset+i]; + if (i < 3) { + res <<= 8; + } + } + return res; +} + +int check_file_header(char *addr) { + int signature_match = 0; + for( int i = 0; i < 8; i++ ) { + if (addr[i] != png_signature[i]) { + signature_match = 1; + } + } + printf("Sig Match: %d\n", signature_match); + return signature_match; + +} + +int create_cc_file(unsigned char *addr, unsigned long file_length) { + FILE *fp; + fp = fopen("png2.png", "w"); + + if(fp == NULL) { + return EXIT_FAILURE; + } + + for(int i = 0; i < file_length; i++){ + fputc(addr[i], fp); + } + fclose(fp); + return 0; +} + +unsigned char* file_to_char_array(FILE *in_file, size_t* size) { + unsigned int c; + unsigned long file_data_cap = 8; + unsigned char* file_data = calloc(file_data_cap, sizeof(unsigned char)); + + for(size_t i = 0;(c = fgetc(in_file)) != EOF; i++) { + if(i == file_data_cap) { + file_data_cap *= 2; + file_data = reallocarray(file_data, file_data_cap, sizeof(unsigned char)); + if(file_data == NULL) { + perror("FAILED ARRAY RESIZE"); + return NULL; + } + } + file_data[i] = c; + *size += 1; + } + return file_data; +} +