Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <stdio.h>
- // сигнатура начала файла jpg
- #define JPG_START_SIGN 0xFFD8
- // сигнатура завершения файла jpg
- #define JPG_END_SIGN 0xFFD9
- /* сигнатура завершения zip-файла, всегда присутствует в zip-файле,
- даже если он пустой. Единственный верный признак,
- так как иные сигнатуры могут различаться
- */
- #define ZIP_END_SIGN 0x504B0506
- //*************************************************************************************************
- // тестовый прототип
- void filedivingtools_init()
- {
- printf("init success...");
- }
- //*************************************************************************************************
- /* определяет является ли файл jpg
- */
- int isJPG(FILE * file, int view_info)
- {
- char signature[2] = {0, 0};
- short welded = 0;
- int result = 0;
- signature[1] = (char)fgetc(file);
- signature[0] = (char)fgetc(file);
- welded = *(short *)(signature);
- result = welded == (short)JPG_START_SIGN ? 1 : 0;
- if(view_info)
- {
- if(result)
- printf
- ("Start signature of file matches *.jpg: %hx\n", welded);
- else
- printf
- ("Start signature of file doesn't matches *.jpeg: %hx\n", welded);
- }
- // перед выходом из файла обязательно сбросить положение считываемого байта
- // что даёт возможность в дальнейшем совершать обход по файлу сначала
- fseek(file, 0, 0);
- return result;
- }
- //*************************************************************************************************
- /* возвращает позицию последнего байта завершающей сигнатуры jpg (до EOF)
- 0 если сигнатура не была найдена
- */
- long long unsigned jpgEndPosition(FILE * file)
- {
- // поле для записи текущего байта файла
- int current_byte = 0;
- // счётчик байтов от начала файла при поиске сигнатуры
- long long unsigned byte_counter = 0;
- // последний байт найденной сигнатуры
- long long unsigned end_sign_byte = 0;
- // массив для записи байтов
- unsigned char sign_array[2] = {0x00, 0x00};
- // поле для "склейки" байтов в двухбайтное значение
- // для сравнения с JPG_END_SIGN
- short result_sign = 0x0000;
- while(1)
- {
- current_byte = fgetc(file);
- byte_counter++;
- if(current_byte == EOF)
- {
- end_sign_byte = 0;
- break;
- }
- // на самом деле здесь можно было бы просто проверить следующий байт
- // хотя по количеству действий будет одинково
- if(current_byte == 0xFF)
- {
- sign_array[1] = (unsigned char)current_byte;
- current_byte = fgetc(file);
- byte_counter++;
- if(current_byte == EOF)
- {
- end_sign_byte = 0;
- break;
- }
- sign_array[0] = (unsigned char)current_byte;
- result_sign = *(short *)(sign_array);
- if(result_sign == (short)JPG_END_SIGN) // приведение так как переменная int
- {
- end_sign_byte = byte_counter - 1;
- break;
- }
- }
- }
- fseek(file, 0, 0);
- return end_sign_byte;
- }
- //*************************************************************************************************
- /* подсчитывает количество байт в файле
- */
- long long unsigned int get_file_bytes_value(FILE * file, int view_info)
- {
- long long unsigned int byte_counter = 0;
- int current_byte = 0;
- while(1)
- {
- current_byte = fgetc(file);
- if(current_byte == EOF)
- break;
- byte_counter++;
- }
- // перед выходом из файла обязательно сбросить положение считываемого байта
- // что даёт возможность в дальнейшем совершать обход по файлу сначала
- fseek(file,0,0);
- if(view_info)
- {
- }
- return byte_counter;
- }
- //*************************************************************************************************
- /* Определяет содержит ли файл сигнатуру завершения zip-файла
- */
- int hasZIPinside(FILE * file, int view_info)
- {
- // поле для записи текущего байта файла
- int current_byte = 0;
- // счётчик байтов от начала файла при поиске сигнатуры
- long long unsigned byte_counter = 0;
- // первый байт найденной сигнатуры
- long long unsigned start_sign_byte = 0;
- // последний байт найденной сигнатуры
- long long unsigned end_sign_byte = 0;
- // массив для записи байтов
- unsigned char sign_array[4] = {0x00, 0x00, 0x00, 0x00};
- // индекс для обращения к элементам sign_array
- // *важно чтобы это было знаковое значение, иначе бесконечный цикл
- // *см. ниже
- char index = 0;
- // поле для "склейки" байтов в четырёхбайтное значение
- // для сравнения с ZIP_END_SIGN
- int result_sign = 0x00000000;
- // флаг для оповещения внешнего цикла о достижении конца файла
- // во внутреннем цикле
- int eof_reached = 0;
- // значение 1 если в файле найдена сигнатура конца zip, 0 если иначе
- int file_has_zip_end = 0;
- printf("------------------------------------------------------------\n");
- printf("Search zip-end signature...\n");
- while(1)
- {
- current_byte = fgetc(file);
- byte_counter++;
- if(current_byte == EOF)
- break;
- // когда значение прочитанного байта равно первому байту
- // сигнатуры, инициируется чтение следующих трёх байт и склейка
- // их вместе с первым в одно значение для сравнения
- if(current_byte == 0x50)
- {
- //printf("%.2hhx", current_byte);
- //-1 так как нужен адрес, а не порядковый номер
- start_sign_byte = byte_counter - 1;
- sign_array[3] = current_byte;
- index = 2;
- while(index >= 0)
- {
- byte_counter++;
- current_byte = fgetc(file);
- if(current_byte == EOF) { eof_reached = 1; break; }
- //printf("%.2hhx", current_byte);
- sign_array[index--] = (unsigned char)current_byte;
- }
- //printf("\n");
- if(eof_reached) break;
- result_sign = *(int *)(sign_array);
- if(result_sign == ZIP_END_SIGN)
- {
- printf("---> Signature %X reached <---\n",result_sign);
- end_sign_byte = byte_counter - 1;
- file_has_zip_end = 1;
- break;
- }
- }
- }
- // вывод встроенного сообщения
- if(view_info)
- {
- if(file_has_zip_end)
- {
- printf("File has zip-end signature: %x\n", ZIP_END_SIGN);
- printf("Start signature byte number: %llu\n", start_sign_byte);
- printf("End signature byte number: %llu\n", end_sign_byte);
- }
- else
- {
- printf("File hasn't zip-end signature. Checked bytes: %llu\n", byte_counter - 1);
- }
- }
- fseek(file,0,0);
- return file_has_zip_end;
- }
- //*************************************************************************************************
- /* функция создаёт новый или использует существующий файл для записи потока
- байтов из скрытого участка jpg-файла, содержащего zip-архив
- */
- void pullOutHiddenZip(FILE * file, long unsigned start_position)
- {
- fseek(file, start_position, 0);
- // новый файл для записи
- FILE * pulled_out_zip = fopen("pulledOut.zip","wb");
- // поле для записи текущего байта файла
- int current_byte = 0;
- while(1)
- {
- current_byte = fgetc(file);
- if(current_byte == EOF)
- break;
- putc(current_byte, pulled_out_zip);
- }
- fseek(file, 0, 0);
- fclose(pulled_out_zip);
- }
Advertisement
Add Comment
Please, Sign In to add comment