Описание кода

Описание кода

Теперь, когда вы знаете описание необходимых команд, можно заняться описанием самого кода программы. И описывать его будем так: сначала указывается адрес памяти (или команда), а потом кратко говорится о том, для чего мы записываем по этому адресу памяти данные.

ПРИМЕЧАНИЕ

Еще перед описанием кода стоит сказать о командах db и dw, с которых начинается запись значений в адреса памяти — эти команды указывают на размер одной записываемой ячейки (ячейки отделяются запятыми). Если указана первая команда, то одна ячейка будет занимать в памяти 1 байт, а если указана вторая команда, то одна ячейка будет занимать 2 байта.

И еще одно — все значения в коде приведены в шестнадцатиричном виде и пишутся в обратном порядке.

Сначала нужно заполнить нулями (то есть очистить) диапазоны памяти от 0 до 400 и от 1000 до 1200. В первом диапазоне будет содержаться сама программа, а второй диапазон будет рабочим — именно в нем для удобства и будет вначале собрана программа.

Начиная с адреса 0 и заканчивая адресом 15c, формируется заголовок РЕ-файла: вначале пишется заголовок DOS-файла (адрес 0, записывается MZ), потом указывается, с какого адреса будет начинаться заголовок РЕ-файла (содержимое адреса 3c), и в этом адресе пишется сам заголовок РЕ-файла (адрес 40, записывается «Р», «Е», 0,0). По этому же адресу записывается идентификатор процессора, для которого предназначена программа (для i386 вводится 14c), и количество секций, из которых она будет состоять. Дальше, по адресу 54, указывается размер NT-заголовка, флаги программы и «магическое значение». Если значения предыдущих адресов были статичны, то содержимое адреса 68 зависит от самой программы — оно указывает на адрес точки входа в программу. Начиная с этого адреса, будет вводиться сам код программы. По адресу 74 вводится базовый адрес загрузки (0,40), выравнивание в памяти и в файле (1000,0,200,0), а также версия операционной системы и версия подсистемы (4,0,0,0,4). По адресу 90 указывается размер образа с заголовками в памяти (2000), размер заголовка в файле (200) и подсистема (2). По адресу b4 указывается количество входов в каталоге смещений (10), а по адресу c0 описываются сами входы в каталог (мы используем только один): адрес таблицы импорта (1090) и ее размер (3c). По адресу 140 начинается таблица объектов (опять имеет один вход): занимаемый объем памяти (1000), с какого адреса начинается (1000), сколько места занимает в файле (200) и по какому смещению в нем находится (200). И последний адрес заголовка — 15c. В нем хранятся флаги (секция кодовая, имеет разрешения на чтение, запись и исполнение).

После формирования заголовка формируются данные программы — в диапазоне адресов от 1010 до 1070. Сначала записывается заголовок сообщения и его текст (адреса 1010 и 1020), потом названия библиотек, из которых будут взяты функции MessageBox (выводит наше окно) и ExitProcess (завершает программу) (адрес 1040 — USER32.DLL, а адрес 1050 — KERNEL32.DLL). И наконец, сами названия функций (адрес 1060 — MessageBoxA и адрес 1070 — ExitProcess), которые пишутся с учетом регистра.

Теперь нужно сформировать таблицу поиска, импортируемых адресов и таблицу импорта.

Таблица поиска содержит адреса функций и способ их поиска в библиотеках (по порядковым номерам или именам). В нашем случае будем вести поиск по именам, поэтому таблица поиска, расположенная по адресу 1080, принимает такой вид: 1060,0,0,0,1070,0,0,0. Здесь 1060,0 указывает на функцию MessageBoxA (0 отделяет названия функций между собой), потом идет 0,0 — разграничитель между функциями различных библиотек, а 1070,0 — адрес функции ExitProcess из другой библиотеки. Следует также учитывать, что первые два байта перед названиями функций должны быть равны 0 — они являются индексом, по которому в библиотеке должны находиться функции, но поскольку индекс неизвестен, нужно оставить эти поля пустыми, чтобы загрузчик сам нашел в библиотеках данные функции.

Таблица импортируемых адресов располагается в самом начале секции (в нашем случае по адресу 1000) и содержит адреса импортируемых функций — аналог таблицы поиска.

Таблица импорта связывает библиотеки с таблицами поиска и импортируемых адресов (в коде начинается по адресу 1090). Каждая строка таблицы описывает одну библиотеку (сначала содержится адрес начала описания функций из библиотеки в таблице поиска (1080,0), потом два пустых поля (0,0,0,0), потом адрес, хранящий название библиотеки (1040,0), и адрес начала описания функций данной библиотеки в таблице импортируемых адресов (1000,0)). Аналогично описывается библиотека KERNEL32.DLL. После описания всех библиотек нужно оставить еще одну пустую строку таблицы импорта, то есть следующие 20 байт. Итого размер таблицы импорта равен 3Ч5Ч4 = 60, а в шестнадцатиричном виде — 3c, что мы и вводили в заголовке PE по адресу c0.

И наконец, последняя часть кода — сам код. Он начинается с адреса 10d0, который и является точкой входа в программу — ее мы и указывали в заголовке PE файла по адресу 68.

Код довольно прост, но написан на машинном языке:

db 6a,24

db 68,10,10,40,0

db 68,20,10,40,0

db 6a,0

db ff,15,0,10,40,0

db 6a,0

db ff,5,8,10,40,0

Так вызывается функция MessageBoxA и ей передаются необходимые параметры: сначала помещается значение 24 (указывает, что вызываемое окно имеет две кнопки и значок вопроса), потом адрес заголовка, адрес сообщения и 0 (дескриптор родительского объекта, которого у нас нет). Если описать приведенный код более просто, то получится:

? Push 24 — поместить в стек значение 24;

? Push offset «переменная с заголовком окна» — поместить в стек адрес памяти, содержащий заголовок окна;

? Push offset «переменная с сообщением окна» — поместить в стек адрес памяти, хранящий сообщение окна;

? Push 0 — поместить в стек 0;

? Call «адрес памяти, содержащий название функции».

Аналогично вызывается функция ExitProcess.

Вот и все. Теперь только осталось скопировать диапазон адресов от 1000 до 1200, хранящий нашу программу, в память, начиная с адреса 200, а потом сместить всю программу на 100, так как при сохранении файла отладчик обрезает первые 100h байт памяти. 

Поделитесь на страничке

Следующая глава >

Похожие главы из других книг:

Описание модели XML DOM

Из книги автора

Описание модели XML DOM Парсер MSXML поддерживает много объектов, определяемых в модели XML DOM, с помощью которых можно решать связанные с XML задачи различного уровня сложности. Нам в дальнейшем для написания сценариев, которые осуществляют просмотр записной книжки в XML-формате,


6.2. Описание объектов

Из книги автора

6.2. Описание объектов После того как вы определили основные параметры Samba-сервера, можно описывать объекты, к которым может получать доступ пользователь. Эти делается в отдельных разделах, которые идут после секции [Global], которую мы рассмотрели в разд.


Описание каталогов

Из книги автора

Описание каталогов В состав URL входит от двух до четырех компонентов.• Протокол. Первый компонент URL (например, http:// или ftp://) определяет протокол, используемый для взаимодействия. В данной главе в основном обсуждаются серверы, поддерживающие протокол HTTP (в этом случае


1.3.1. Описание дистрибутива

Из книги автора

1.3.1. Описание дистрибутива Название проекта Fedora Core не имеет никакого отношения к знакомому нам с детских дет произведению К.И. Чуковского «Федорино горе». Fedora Core является наследницей линейки RedHat (бесплатной), a Fedora означает фетровая шляпа (против Красной Шапочки RedHat)Fedora Core


28. Описание

Из книги автора

28. Описание Имя вводится в программе с помощью описания, которое задает его тип и, возможно, начальную величину. Даны понятия описания, определения, области видимости имен, времени существования объектов и типов.Перед использованием имени (идентификатора) в C++ программе


Описание указателей

Из книги автора

Описание указателей      Мы знаем, как описывать переменные типа int и других типов. Но как описать переменную типа "указатель"? На первый взгляд это можно сделать так: pointer ptr;       /* неправильный способ описания указателя */Почему нельзя использовать такую запись? Потому


Описание работы пакета OOoFBTools I Конвертер ExportToFB21 1. Описание

Из книги автора

Описание работы пакета OOoFBTools I Конвертер ExportToFB21 1. Описание 1.1. НазначениеКроссплатформенный конвертер ExportToFB21 предназначен для конвертации документов из форматов, поддерживаемых OpenOffice.org Writer в формат fb2.1.Т.о. входные форматы документов для ExportToFB21 следующие:.doc, dot, rtf, txt,


8.11 Описание Asm

Из книги автора

8.11 Описание Asm Описание Asm имеет видasm ( строка );Смысл описания asm неопределен. Обычно оно используется для передачи информации ассемблеру через компилятор.9. ОператорыОператоры выполняются последовательно во всех случаях кроме особо


Общее описание

Из книги автора

Общее описание Электронный задачник Programming Taskbook предназначен для обучения программированию на языках Pascal, Visual Basic, C++, C#, Visual Basic .NET, Python и Java. Он содержит 1300 учебных заданий, охватывающих все основные разделы базового курса программирования: от скалярных типов и


Общее описание

Из книги автора

Общее описание При запуске программы, использующей электронный задачник Programming Taskbook, на экране возникает окно задачника. В зависимости от текущей настройки, окно может отображаться либо в режиме с фиксированной компоновкой, либо в режиме с динамической компоновкой.


Описание

Из книги автора

Описание Описание фактически является заголовком вашей работы. Оно выполняет такую же функцию, как ключевые слова. Но если «ключевики» представляют собой простой непоследовательный большой набор слов, характеризующих детали изображения, то описание является связной


Описание

Из книги автора

Описание На названии (или описании) в первую очередь попадаются начинающие микростоковые фотографы и те, у кого в школе не было проблем с описанием картин на уроках русского языка. Если вам отказали по причине ошибки в названии изображения, значит, вы слишком увлеклись