Шутливый PNG

Используйте этот файл осознанно и никому не передавайте, чтобы не нарушить чью-то комфортную работу компьютера. Файл подкачки не освобождается, проверял в Linux, но даже с этой проблемой Linux работает без проблем.

Вот, 1 апреля, можно и подшутить над своим компьютером, дав ему несовсем вменяемый файл png. Объясняю как это сделать.

Впервую очередь, чтобы без лишних усилий, мы просто берем и скачиваем исходники libpng16. Исходники нам нужны, чтобы присвоить правильные CRC сумму для заголовка картинки.

Идем в файл pngrutil.c и ищем функцию png_crc_error и в конце функции добавляем printf

...
   if (need_crc != 0)      
   {
      crc = png_get_uint_32(crc_bytes);
      printf ("valid crc: %08x; current crc: %08x\n", png_ptr->crc, crc);
      return crc != png_ptr->crc;
   }
...

Теперь нам нужен редактор картинок. Для этих целей я пользуюсь Aseprite. Создаем картинку 8×8 пикселей и экспортируем её в png формат. Размер моей картинки оказался всего 119 байт.

Пишем небольшую программу для чтения png заголовка.

#include 
#include 
#include 
#include "png.h"

static int read_png_file (const char *filename, uint32_t *pWidth, uint32_t *pHeight)
{
	FILE *infile = fopen (filename, "r+");

	uint8_t sig[8];
	fread(sig, 1, 8, infile);
	if (!png_check_sig(sig, 8))
		return 1;   /* bad signature */

	static png_structp png_ptr;
	static png_infop info_ptr;

    png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL,
      NULL);
    if (!png_ptr)
        return 4;   /* out of memory */

    info_ptr = png_create_info_struct(png_ptr);
    if (!info_ptr) {
        png_destroy_read_struct(&png_ptr, NULL, NULL);
        return 4;   /* out of memory */
    }

    if (setjmp(png_jmpbuf(png_ptr))) {
        png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
        return 2;
    }

    png_init_io(png_ptr, infile);
    png_set_sig_bytes(png_ptr, 8);
    png_read_info(png_ptr, info_ptr);

    uint32_t width, height, bit_depth, color_type;

    png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth,
	    &color_type, NULL, NULL, NULL);

    *pWidth = width;
    *pHeight = height;

    fclose (infile);

    return 0;
}

int main (int argc, char **argv)
{
	if (argc < 2) {
		fprintf (stderr, "Need png file\n");
		exit (0);
	}

	char *filename = argv[1];

	int width, height;
	int ret = read_png_file (filename, &width, &height);
	printf ("ret: %d\n", ret);

}

Далее компилируем с помощью Makefile

all:
        gcc main.c -I. -Wl,-rpath=. -L. -lpng16 -o app

Теперь откроем ghex и посмотрим на данные.

ghex
ghex

По адресам 0×14 и 0×18 находятся размеры в пикселях, в данном случае у нас 8×8 пикселей. Мы хотим, к примеру, чтобы программа выделяла 16 гигов памяти. Опытным путем я вычислил, что 16 гигабайт с небольшим выделяется, если задать размер 65535×65535, но можно и больше. Если для двух пикселей задать размер в 0×1FFFF на 0×1FFFF, то выделиться 65 гигабайт.

Как видим, там где 16-ая система счисления, число показывает FFFF. Вписываем в наш файл. Получается так.

8504327f93a218b988bbece31aa07294.png

Теперь нам надо запустить программу, чтобы узнать crc сумму.

valid crc: b605d950; current crc: 096af32a

Меняем байты, начиная с адреса 0×1d.

Теперь открываем картинку и смотрим.

htop
htop

Как видно, память увеличилась. Плюс ко всему, если ваш файловый менеджер поддерживает пиктограммы, то он выделит сразу большой объем памяти, пока не сделает мини картинку.

Такая ситуация также наблюдается и в Windows.

Habrahabr.ru прочитано 6613 раз