Рассылка закрыта
При закрытии подписчики были переданы в рассылку "Всё о работе в Интернет" на которую и рекомендуем вам подписаться.
Вы можете найти рассылки сходной тематики в Каталоге рассылок.
Секреты Windows: статьи о реестре, rundll32.exe, программах Недокументированные возможности Windows XP. Другое. Часть 2
Вот и закончился очередной опрос, результаты которого окажутся судьбоносными для нашего сайта и этой рассылки - "Содержимое какой из книг вы бы хотели прочитать в будущих статьях нашего сайта?". И что вы думаете? Абсолютное большинство посетителей наконец взялось за ум и проголосовало за книгу "Реестр Windows Vista. На 100%" =) Благодарим всех, кто отдал свои голоса за понравившуюся книгу - а тех, кто проголосовал за книгу "Реестр Windows Vista. На 100%" еще и награждаем
первой частью этой книги. Другие наши рассылки: Новости нашего сайта: Продолжение, начало в выпусках: 1 В конец записи
оцените: 1 2 3 4 5 Книга "Недокументированные возможности Windows XP. Библиотека пользователя", Глава 4. Другие возможности Windows XP. Часть 2. Программа Debug. Следующей возможностью, которую хотелось бы описать, является способ создания программ Win32 с помощью стандартного отладчика командной строки debug.exe. Но сначала хотелось бы пояснить, зачем вообще упоминается об этом отладчике — согласитесь, существуют компьютеры общего пользования, на которые пользователь не имеет права ничего устанавливать. На них нет CD-ROM, нет флоппи-дисковода, нет Интернет или нельзя скачивать с Интернет файлы. В общем, администраторы сделали так, чтобы нельзя было устанавливать свои файлы, в том числе вирусы, перехватчики клавиатуры, троянские кони. Но уже стало стандартом, что программа debug.exe входит в поставку Windows и о ней теперь знает все меньшее и меньшее количество администраторов… Это был тонкий намек администраторам подобных общественных компьютеров. Отладчик debug.exe входит в стандартную поставку всех версий Windows (находится в каталоге %systemroot%\system32) и предназначен для отладки DOS-приложений на языке ассемблер или машинном языке. Итак, давайте запустим командную строку и введем название команды — debug.exe. После этого мы попадем в среду программы, о чем можно узнать из появившегося приветствия в виде черточки. А теперь давайте посмотрим на сам код простенькой программы Win32, вызывающей стандартное окно приветствия. Данный код был взят из статьи журнала Ваш компьютер за 2003 год Листинг. Программа Win32 типа Hello, World! f 0 400 0 f 1000 1200 0 a 0 db 4d,5a a 3c db 40 a 40 db 50,45,0,0 dw 14c,1 a 54 dw e0,10f,10b a 68 dw 10d0 a 74 dw 0,40,1000,0,200,0 dw 4,0,0,0,4 a 90 dw 2000,0,200,0,0,0,2 a b4 dw 10 a c0 dw 1090,0,3c a 140 dw 1000,0,1000,0,200,0,200,0 a 15c dw 20,e000 a 1010 db 54,68,69,73,20,54,69,74,6c,65,3f a 1020 db 54,68,69,73,20,4d,65,73,73,61,67,65,3f a 1040 db 55,53,45,52,33,32,2e,64,6c,6c a 1050 db 4b,45,52,4e,45,4c,33,32,2e,64,6c,6c a 1060 db 0,0,4d,65,73,73,61,67,65,42,6f,78,41 a 1070 db 0,0,45,78,69,74,50,72,6f,63,65,73,73 a 1080 dw 1060,0,0,0,1070,0,0,0 a 1000 dw 1060,0,0,0,1070,0,0,0 a 1090 dw 1080,0,0,0,0,0,1040,0,1000,0 dw 1088,0,0,0,0,0,1050,0,1008,0 a 10d0 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,15,8,10,40,0 m 1000 1200 200 m 0 400 100 n «путь и имя создаваемого файла.bin» r cx 400 w q Вот и весь код программы, написанной на машинном языке и вызывающей окно, отображенное на рисунке 4.03. Рисунок 1 Рис. 4.03 Результат выполнения нашей программы Команды программы
А теперь давайте попробуем разобраться в этом коде. Для начала опишем команды дебаггера, применяемые в нем. F «начальный адрес» «конечный адрес» «заполнитель» Данная команда заполняет «заполнителем» диапазон памяти, начиная с «начального адреса» и заканчивая «конечным адресом». A «адрес» Данная команда говорит дебаггеру о том, что вы хотите изменить содержимое, записанное в памяти, начиная с указанного «адреса». После ее ввода перед вами появится приглашение, указывающее, какой участок памяти в данный момент редактируется. Чтобы сказать дебаггеру, что вы уже отредактировали необходимый вам участок памяти, нужно в пустой строке нажать клавишу ENTER. Также можно ввести данную команду без значения адреса — в этом случае вы будет редактировать значение адреса памяти, применяемого при последней операции останова. m «начальный адрес» «конечный адрес» «адрес назначения» Данная команда копирует содержимое диапазона памяти, начиная с «начального адреса» и заканчивая «конечным адресом» в область памяти, начинающуюся с адреса назначения. N «путь и имя файла» Данная команда указывает, как будет называться создаваемый дебаггером файл (и в каком каталоге он будет находиться). Следует учитывать, что дебаггер создавался для приложений DOS, поэтому он не может создавать exe-файлы — именно поэтому в коде мы и создаем bin-файл (после его создания нужно будет переименовать расширение .bin на расширение .exe). Также данная команда применяется для загрузки файла и указания параметров запуска файла (в этом случае после команды n должны идти аргументы программы). R «регистр» Данная команда говорит дебаггеру о том, что мы хотим изменить содержимое конкретного регистра процессора. В контексте приведенного кода мы изменяет содержимое регистра CX. После ввода команды появится приглашение (в виде двоеточия) для ввода нового содержимого регистра. Если ввести команду без указания конкретного регистра, тогда перед нами отобразится содержимое всех регистров процессора, всех флагов (определяют, было ли зарегистрировано переполнение при выполнении операции с числами, является ли число четным и т.д.) и содержимое данной области памяти. Также можно отредактировать установки флагов. Для этого нужно ввести такую разновидность команды: r f, после чего перед вами отобразится установка флагов в текущий момент и приглашение для редактирования флагов. Чтобы отредактировать один из флагов, нужно ввести в приглашении противоположный ему флаг. Например, для флага cy (перенос) нужно указать флаг nc (нет переноса). W «адрес» И, наконец-то, этой командой мы записываем содержимое памяти на диск в виде программы Win32. Без аргумента данная команда начинает запись файла с адреса памяти CS:100, но можно самому указать адрес памяти, с которого будет начинаться запись. Q А эта команда закрывает окно дебаггера. Описание кода
Теперь, когда мы знаем описание необходимых команд, можно заняться описанием самого кода программы. И описывать его мы будем так: сначала указывать адрес памяти (или команду), а потом кратко говорить о том, для чего мы записываем по этому адресу памяти данные. Еще, перед описанием кода, стоит сказать о командах db и dw, с которых начинается запись значений в адреса памяти — эти команды указывают на размер одной записываемой нами ячейки (ячейки отделяются запятыми). Если указана первая команда, тогда одна ячейка будет занимать в памяти 1 байт, а если указана вторая команда, то одна ячейка будет занимать 2 байта. Кстати, и еще одно — все значения в коде приведены в шестнадцатеричном виде и значения пишутся в обратном порядке. Сначала мы заполняем нулями (то есть, очищаем) диапазоны памяти от 0 до 400 и от 1000 до 1200. В первом диапазоне будет содержаться сама наша программа, а второй диапазон будет рабочим — именно в нем, для удобства, мы и будем вначале собирать программу. Начиная с адреса 0 и заканчивая адресом 15с, мы формируем заголовок PE-файла: вначале пишется заголовок DOS-файла (адрес 0, записываем «MZ»), потом указываем, с какого адреса будет начинаться заголовок PE-файла (содержимое адреса 3c) и в этом адресе пишем сам заголовок PE-файла (адрес 40, записываем «Р»,«Е»,0,0). По этому же адресу мы записываем идентификатор процессора, для которого предназначена программа (для i386 вводится 14с) и число секций, из которых она будет состоять. Дальше, по адресу 54, мы указываем размер NT-заголовка, флаги программы и «магическое значение». Если значения предыдущих адресов были статичны, то содержимое адреса 68 зависит от самой программы — оно указывает на адрес точки входа в программу. Начиная с этого адреса мы будем вводить сам код программы. По адресу 74 мы вводим базовый адрес загрузки (0,40), выравнивание в памяти и в файле (1000,0,200,0), а также версию ОС и версию подсистемы (4,0,0,0,4). По адресу 90 указывается размер образа с заголовками в памяти (2000), размер заголовка в файле (200) и подсистема (2). По адресу b4 указывается количество входов в каталоге смещений (10), а по адресу c0 описываются сами входы в каталог (мы используем только один): адрес таблицы импорта (1090) и ее размер (3с). По адресу 140 начинается таблица объектов (опять имеет один вход): занимаемый объем памяти (1000), с какого адреса начинается (1000), сколько места занимает в файле (200) и по какому смещению в нем находится (200). И последний адрес заголовка — 15с. В нем хранятся флаги (секция кодовая, имеет разрешения на чтение, запись и исполнение). После формирования заголовка мы формируем данные программы — в диапазоне адресов от 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,15,8,10,40,0 Так мы вызываем функцию MessegeBoxA и передаем ей необходимые параметры: сначала помещаем значение 24 (указывает, что вызываемое окно имеет две кнопки и значок вопроса), потом адрес заголовка, адрес сообщения, и 0 (дескриптор родительского объекта, которого у нас нет). Если описать приведенный код более просто, то получится:
Аналогично вызывается функция ExitProcess. Вот и все. Теперь только осталось скопировать диапазон адресов от 1000 до 1200, содержащий нашу программу, в память, начиная с адреса 200. А потом сместить всю нашу программу но 100, так как при сохранении файла дебаггер обрезает первые 100h байт памяти. Простой пример
Конечно, приведенный выше пример довольно сложен — ведь он написан на машинном языке и в шестнадцатеричном виде. Но его можно упростить, ведь дебаггер в Windows XP поддерживает как Ascii-символы, так и язык ассемблера. Вот упрощением мы сейчас и займемся. Например, создадим программу, которая будет открывать созданный нами ранее файл (если он будет называться hello.exe и находиться на диске d:) Листинг. Создание простого файла, открывающего другой файл Очистка памяти и описание заголовка файла аналогично приведенному выше примеру, поэтому эту часть кода мы пропустим. a 1010 db "D:\HELLO.EXE" a 1040 db "SHELL32.DLL" a 1050 db "KERNEL32.DLL" a 1060 db 0,0,"ShellExecuteA" a 1070 db 0,0,"ExitProcess" a 1080 dw 1060,0,0,0,1070,0,0,0 a 1000 dw 1060,0,0,0,1070,0,0,0 a 1090 dw 1080,0,0,0,0,0,1040,0,1000,0 dw 1088,0,0,0,0,0,1050,0,1008,0 a 10d0 xor bx,bx push bx push bx push bx db 68,10,10,40,0 push bx push bx db ff,15,0,10,40,0 push bx db ff,15,8,10,40,0 m 1000 1200 200 m 0 400 100 n d:\rr.bin r cx 400 w Согласитесь, уже проще — ведь теперь не нужно вводить текстовую информацию в шестнадцатеричном виде. А если учесть еще одну возможность командной строки, то станет совершенно просто. Все дело, в том, что совершенно необязательно вводить данный текст в дебаггере, ведь можно воспользоваться блокнотом, а потом просто скопировать введенный текст в буфер обмена, запустить debug.exe и нажать правую кнопку мыши в области его окна, чтобы дебаггер начал обработку команд из буфера обмена. При этом только следует убедиться, что режим быстрой вставки в командной строке включен (параметр dword типа QUICKEDIT, расположенный в ветви реестра HKEY_CURRENT_USER\CONSOLE, должен быть равен 1) Код приведенных выше программ можно взять из диска, поставляемого вместе с книгой — он находится в двух текстовых файлах, расположенных в каталоге DEBUG. Другие команды программы
Программа debug.exe содержит и другие возможные команды, но в контексте данной книги они описаны не будут. Если вас заинтересовала приведенная в разделе информация, тогда для начала предлагаю посмотреть описание команд программы debug.exe в ЦЕНТРЕ СПРАВКИ И ПОДДЕРЖКИ операционной системы Windows XP. Продолжение следует Оригинал статьи: http://www.onestyle.com.ua/txt.php?u=163
|
В избранное | ||