Scorpunduk

FILEDIVINGTOOLS

Feb 22nd, 2023 (edited)
889
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 9.29 KB | Fixit | 0 0
  1. #include <stdio.h>
  2.  
  3. // сигнатура начала файла jpg
  4. #define JPG_START_SIGN 0xFFD8
  5.  
  6. // сигнатура завершения файла jpg
  7. #define JPG_END_SIGN 0xFFD9
  8.  
  9. /*  сигнатура завершения zip-файла, всегда присутствует в zip-файле,
  10.     даже если он пустой. Единственный верный признак,
  11.     так как иные сигнатуры могут различаться
  12. */
  13. #define ZIP_END_SIGN 0x504B0506
  14.  
  15.  
  16.  
  17. //*************************************************************************************************
  18. // тестовый прототип
  19. void filedivingtools_init()
  20. {
  21.     printf("init success...");
  22. }
  23.  
  24.  
  25. //*************************************************************************************************
  26. /* определяет является ли файл jpg
  27. */
  28. int isJPG(FILE * file, int view_info)
  29. {
  30.     char signature[2] = {0, 0};
  31.     short welded = 0;
  32.     int result = 0;
  33.  
  34.     signature[1] = (char)fgetc(file);
  35.     signature[0] = (char)fgetc(file);
  36.     welded = *(short *)(signature);
  37.     result = welded == (short)JPG_START_SIGN ? 1 : 0;
  38.  
  39.     if(view_info)
  40.     {
  41.         if(result)
  42.             printf
  43.             ("Start signature of file matches *.jpg: %hx\n", welded);
  44.         else
  45.             printf
  46.             ("Start signature of file doesn't matches *.jpeg: %hx\n", welded);
  47.     }
  48.  
  49.     // перед выходом из файла обязательно сбросить положение считываемого байта
  50.     // что даёт возможность в дальнейшем совершать обход по файлу сначала
  51.     fseek(file, 0, 0);
  52.     return result;
  53. }
  54.  
  55.  
  56.  
  57. //*************************************************************************************************
  58. /*  возвращает позицию последнего байта завершающей сигнатуры jpg (до EOF)
  59.     0 если сигнатура не была найдена
  60. */
  61. long long unsigned jpgEndPosition(FILE * file)
  62. {
  63.     // поле для записи текущего байта файла
  64.     int current_byte = 0;
  65.  
  66.     // счётчик байтов от начала файла при поиске сигнатуры
  67.     long long unsigned byte_counter = 0;
  68.  
  69.     // последний байт найденной сигнатуры
  70.     long long unsigned end_sign_byte = 0;
  71.  
  72.     // массив для записи байтов
  73.     unsigned char sign_array[2] = {0x00, 0x00};
  74.  
  75.     // поле для "склейки" байтов в двухбайтное значение
  76.     // для сравнения с JPG_END_SIGN
  77.     short result_sign = 0x0000;
  78.  
  79.     while(1)
  80.     {
  81.         current_byte = fgetc(file);
  82.         byte_counter++;
  83.         if(current_byte == EOF)
  84.         {
  85.             end_sign_byte = 0;
  86.             break;
  87.         }
  88.  
  89.         // на самом деле здесь можно было бы просто проверить следующий байт
  90.         // хотя по количеству действий будет одинково
  91.         if(current_byte == 0xFF)
  92.         {
  93.             sign_array[1] = (unsigned char)current_byte;
  94.             current_byte = fgetc(file);
  95.             byte_counter++;
  96.             if(current_byte == EOF)
  97.             {
  98.                 end_sign_byte = 0;
  99.                 break;
  100.             }
  101.             sign_array[0] = (unsigned char)current_byte;
  102.             result_sign = *(short *)(sign_array);
  103.             if(result_sign == (short)JPG_END_SIGN) // приведение так как переменная int
  104.             {
  105.                 end_sign_byte = byte_counter - 1;
  106.                 break;
  107.             }
  108.         }
  109.     }
  110.     fseek(file, 0, 0);
  111.     return end_sign_byte;
  112. }
  113.  
  114.  
  115.  
  116. //*************************************************************************************************
  117. /* подсчитывает количество байт в файле
  118. */
  119. long long unsigned int get_file_bytes_value(FILE * file, int view_info)
  120. {
  121.     long long unsigned int byte_counter = 0;
  122.     int current_byte = 0;
  123.     while(1)
  124.     {
  125.         current_byte = fgetc(file);
  126.         if(current_byte == EOF)
  127.             break;
  128.         byte_counter++;
  129.     }
  130.  
  131.     // перед выходом из файла обязательно сбросить положение считываемого байта
  132.     // что даёт возможность в дальнейшем совершать обход по файлу сначала
  133.     fseek(file,0,0);
  134.  
  135.     if(view_info)
  136.     {
  137.  
  138.     }
  139.     return byte_counter;
  140. }
  141.  
  142.  
  143.  
  144. //*************************************************************************************************
  145. /* Определяет содержит ли файл сигнатуру завершения zip-файла
  146. */
  147. int hasZIPinside(FILE * file, int view_info)
  148. {
  149.     // поле для записи текущего байта файла
  150.     int current_byte = 0;
  151.  
  152.     // счётчик байтов от начала файла при поиске сигнатуры
  153.     long long unsigned byte_counter = 0;
  154.  
  155.     // первый байт найденной сигнатуры
  156.     long long unsigned start_sign_byte = 0;
  157.  
  158.     // последний байт найденной сигнатуры
  159.     long long unsigned end_sign_byte = 0;
  160.  
  161.     // массив для записи байтов
  162.     unsigned char sign_array[4] = {0x00, 0x00, 0x00, 0x00};
  163.  
  164.     // индекс для обращения к элементам sign_array
  165.     // *важно чтобы это было знаковое значение, иначе бесконечный цикл
  166.     // *см. ниже
  167.     char index = 0;
  168.  
  169.     // поле для "склейки" байтов в четырёхбайтное значение
  170.     // для сравнения с ZIP_END_SIGN
  171.     int result_sign = 0x00000000;
  172.  
  173.     // флаг для оповещения внешнего цикла о достижении конца файла
  174.     // во внутреннем цикле
  175.     int eof_reached = 0;
  176.  
  177.     // значение 1 если в файле найдена сигнатура конца zip, 0 если иначе
  178.     int file_has_zip_end = 0;
  179.  
  180.     printf("------------------------------------------------------------\n");
  181.     printf("Search zip-end signature...\n");
  182.  
  183.     while(1)
  184.     {
  185.         current_byte = fgetc(file);
  186.         byte_counter++;
  187.         if(current_byte == EOF)
  188.             break;
  189.  
  190.         // когда значение прочитанного байта равно первому байту
  191.         // сигнатуры, инициируется чтение следующих трёх байт и склейка
  192.         // их вместе с первым в одно значение для сравнения
  193.         if(current_byte == 0x50)
  194.         {
  195.             //printf("%.2hhx", current_byte);
  196.             //-1 так как нужен адрес, а не порядковый номер
  197.             start_sign_byte = byte_counter - 1;
  198.             sign_array[3] = current_byte;
  199.             index = 2;
  200.             while(index >= 0)
  201.             {
  202.                 byte_counter++;
  203.                 current_byte = fgetc(file);
  204.                 if(current_byte == EOF) { eof_reached = 1; break; }
  205.                 //printf("%.2hhx", current_byte);
  206.                 sign_array[index--] = (unsigned char)current_byte;
  207.             }
  208.             //printf("\n");
  209.             if(eof_reached) break;
  210.             result_sign = *(int *)(sign_array);
  211.             if(result_sign == ZIP_END_SIGN)
  212.             {
  213.                 printf("---> Signature %X reached <---\n",result_sign);
  214.                 end_sign_byte = byte_counter - 1;
  215.                 file_has_zip_end = 1;
  216.                 break;
  217.             }
  218.         }
  219.     }
  220.  
  221.     // вывод встроенного сообщения
  222.     if(view_info)
  223.     {
  224.         if(file_has_zip_end)
  225.         {
  226.             printf("File has zip-end signature: %x\n", ZIP_END_SIGN);
  227.             printf("Start signature byte number: %llu\n", start_sign_byte);
  228.             printf("End signature byte number: %llu\n", end_sign_byte);
  229.         }
  230.         else
  231.         {
  232.             printf("File hasn't zip-end signature. Checked bytes: %llu\n", byte_counter - 1);
  233.         }
  234.     }
  235.  
  236.     fseek(file,0,0);
  237.     return file_has_zip_end;
  238. }
  239.  
  240.  
  241.  
  242. //*************************************************************************************************
  243. /*  функция создаёт новый или использует существующий файл для записи потока
  244.     байтов из скрытого участка jpg-файла, содержащего zip-архив
  245. */
  246. void pullOutHiddenZip(FILE * file, long unsigned start_position)
  247. {
  248.     fseek(file, start_position, 0);
  249.  
  250.     // новый файл для записи
  251.     FILE * pulled_out_zip = fopen("pulledOut.zip","wb");
  252.  
  253.     // поле для записи текущего байта файла
  254.     int current_byte = 0;
  255.  
  256.     while(1)
  257.     {
  258.         current_byte = fgetc(file);
  259.         if(current_byte == EOF)
  260.             break;
  261.         putc(current_byte, pulled_out_zip);
  262.     }
  263.  
  264.     fseek(file, 0, 0);
  265.     fclose(pulled_out_zip);
  266. }
  267.  
Advertisement
Add Comment
Please, Sign In to add comment