Куча с горкой Хаштамов Адиль (adi1@ok.kz) Хакер, номер #081, стр. 081-074-2 [функции для работы с heap] Теперь давай поговорим о функциях для работы с кучей. Я опишу самые главные системные вызовы: 1. Первая функция называется HeapCreate(). Она служит для создания частной области памяти. У нее 3 параметра. Рассмотрим их: * Флаг кучи, всего их два. Первый флаг - HEAP_GENERATE_EXCEPTIONS - указывает на то, что в случае ошибки будет сгенерирована структура исключительных ситуаций (SEH). Второй флаг - HEAP_NO_SERIALIZE - указывает на то, что будет отменен синхронизированный доступ к памяти. Данную опцию стоит применять в том случае, если ты уверен, что доступ к куче не имеют одновременно два потока. * Размер кучи. * Размер максимального значения кучи. Если поставить 0, то будет стоять ограничение равное максимальному значению всей виртуальной памяти системы (4Гб). Функция в качестве результата работы возвращает дескриптор, через который в дальнейшем будет выделяться память. Чтобы тебе было проще, покажу на примере, как выглядит вызов этой функции: HANDLE Heap1 = HeapCreate(HEAP_GENERATE_EXCEPTIONS, 700, 0); 2. Вторая функция используется для выделения блоков и называется HeapAlloc(). Она имеет 3 параметра: * Дескриптор области кучи (в нашем случае это Heap1). * Необязательные флаги, два из которых аналогичны функции HeapCreate(), а третий флаг - HEAP_ZERO_MEMORY - указывает на то, что выделенный блок заполняется нулями. * Объем запрашиваемой памяти. Пример вызова: char *HeapBlock1 = HeapAlloc(Heap1, HEAP_ZERO_MEMORY, 555); 3. Третья функция - освобождение блока HeapFree(). Она имеет тоже 3 параметра. * Дескриптор области. * Флаг. Может быть 0 или HEAP_NO_SERIALIZE. * Блок, который нужно освободить. Я рассказал тебе об основных функциях для работы с кучей в Windows. Понимание их работы уже очень скоро нам пригодится, потому что переходим к самому интересному - непосредственно к Heap Overflow. [переполнение кучи] Переполнение кучи схоже с переполнением стека. Отличительная особенность, как и следовало бы ожидать, заключается в том, что в данном случае мы имеем дело с кучей, а не со стеком :). Чтобы не вести абстрактных разговоров, приведу распространенный пример уязвимой программы. Всмотрись-ка в этот код: [уязвимый код программы] #include <stdio.h> #include <windows.h> int main ( int argc, char *argv[] ) { HANDLE Heap1 = HeapCreate(0, 700, 0); char* hblock1 = HeapAlloc(Heap1, HEAP_ZERO_MEMORY, 10); strcpy(hblock1, argv[1]); char* hblock2 = HeapAlloc(Heap1, HEAP_ZERO_MEMORY, 20); HeapFree(Heap1, 0, hblock1); HeapFree(Heap1, 0, hblock2); return 0; } Если ты внимательный человек и немного смыслишь в программировании, то мигом заметишь, что в этой программе присутствует баг - переполнение при использовании функции strcpy(). При копировании мы не учитываем длину входного параметра, который копируется в первый блок. Если ввести достаточно длинную строку, то когда данные переполнят первый блок, мы уже попадем во владения второго блока и будем иметь возможность управлять им. Это можно наглядно увидеть в любом отладчике, я буду использовать известный дебаггер OllyDbg. |