1. Метод решения задачи
довольно прост и основывается на использовании TLS-callback
функций. Цитата из MSDN: «Метод локального хранилища потока
позволяет каждому потоку многопоточного процесса выделять адреса
для хранения данных для определенного потока». TLS поддерживает
вызов callback-функций, указатели на адреса которых хранятся в
специальной TLS-таблице, причем вызов этот происходит еще до
выполнения инструкций, располагающихся на точке входа. Такую
функцию мы и создадим, чтобы изменить код программы. Будем
использовать для экспериментов написанный на ассемблере файл,
выдающий окно с сообщением «Hello, World» (его можно найти на
нашем DVD).

Создаем TLS-директорию в любой существующей
секции. Не залезая в дебри, открываем PE-файл при помощи
OllyDbg, выделяем 16 нулевых байт, располагающихся ниже кода
(они выравнивают размер секции), и при помощи команды «Binary ->
Edit» контекстного меню вносим следующую последовательность: «00
11 40 00 10 11 40 00 4D 10 40 00 36 10 40 00» (для другого
приложения адреса могут быть иными). Первый и второй адрес —
00401100 и 00401110 — являются адресами начала и конца
выделяемой для потока области данных. По адресу 0040104D будет
записано значение-индекс (его возвратит функция, выделившая блок
памяти для потока). Наконец, 00401036 — это адрес таблицы
callback-функций.

2. Приступим к формированию таблицы
callback-функций. Переходим к адресу 00401036, выделяем 6 байт,
выбираем из контекстного меню команду «Binary -> Edit». Вводим
значение «40 10 40 00 00 00». Первые 4 байта указывают на адрес
callback-функции. Последние два нулевых байта указывают на
окончание таблицы callback-функций.

3. Можно размещать код функции по адресу
00401040. Его функциональность может быть любой; в нашем случае
мы изменим инструкцию, передающую один из параметров API-функции
MessageBoxA – «PUSH 0». Она располагается прямо на точке входа,
по адресу 00401000. Изменять ее на «PUSH 1» (значение указывает
на то, что окошко с сообщением «Hello, World», выдаваемое
программой, будет иметь не одну, а две кнопки – «Ok» и «Отмена»)
будет следующий callback-код:

00401040 MOV EAX,00401000;
помещаем в EAX адрес точки входа
00401045 MOV EBX,0068016A; новый машинный код инструкции,
первоначальный имел вид 0068006A
0040104A MOV DWORD PTR DS:[EAX],EBX; производим патчинг
инструкции
0040104C RETN; возвращаемся из функции

Сохраняем файл (команда Copy to executable -> All
modifications контекстного меню правой кнопки мыши).

4. Теперь необходимо внести адрес
TLS-директории в PE-заголовок исследуемого файла. В окне дампа
переходим к адресу 00400000, в окне дампа выбираем Special -> PE
Header, чтобы отладчик рассматривал данные как PE-заголовок.
Прокручиваем дамп чуть ниже, пока не встретим сигнатуру PE. В
списке полей структуры ищем поле TLS Table address и при помощи
комбинации клавиш <Ctrl+E> открываем меню редактирования. Адрес,
по которому располагалась размещенная нами таблица, имел
значение 00401026. Вспоминая, что в PE-заголовок нужно вводить
смещения, а не абсолютные адреса, отнимаем от значения 00401026
значение ImageBase (00400000) и получаем значение 00001026.
Таким образом, вводим в окно редактирования последовательность
26 10 00 00. Из контекстного меню выбираем Copy to executable
File; в появившемся окне снова нажимаем на правую кнопку мыши и
выбираем из меню Save file. Сохраняем файл. Запуск удается
успешно, программа отображает кнопки Ok и Отмена, хотя
первоначально отображалась лишь одна кнопка.

1 комментарий

  1. WhiteW0lf

    14.02.2017 at 23:41

    А может кто-нибудь кинуть исходник программы? Или объяснить почему в п.1 выбраны такие адреса 00401100 и 00401110?

Оставить мнение

Check Also

WWW: Carbon — сервис для создания идеальных скриншотов кода

В теории сделать скриншот кода, чтобы кому-то показать, — задача несложная. В реальности р…