Debug.exe ‑ программа отладчик,которую используют для проверки и отладки выполняемых файлов.
Использовалась при операционной системе MS-DOS . Под более поздние версии операционных систем
работает через эмулятор MS-DOS и имеет ограниченные возможности. Вызывается через командную сроку
DEBUG [[диск:][маршрут]имя_файла [параметры]].
Например: DEBUG C:\...\My.com
Данная программа является консольным приложением и предназначена для создания или изменения кода файлов. С помощью неё можно создавать простые приложение под MS-DOS и отслеживать их работу. Данный отладчик находится на самом низком уровне компиляторов assembler . Но обладает неплохими возможностями, такими как просмотр и изменение памяти, получение состояния регистров.
Команды debug.exe
Правила набора команд debug.exe:
· В debug.exe не различается регистр букв.
· Пробелы в командах используется только для разделения параметров.
· Вводимые числа должны быть в шестнадцатеричной системе счисления, причем без завершающей буквы h.
· Сегмент и смещение записываются с использованием двоеточия, в формате сегмент:смещение, например, CS:3C1 (смещение 3C1h в сегменте кода) или 40:17 (смещение 17h в сегменте, адрес начала которого - 40h).
После загрузки отладчика на экране появится приглашение, выглядящее в виде дефиса. Регистры CS , DS , ES , SS в этот момент инициализированы адресом 256-байтного префикса сегмента программы, а рабочая область в памяти будет начинаться с адреса этого префикса + 100h. Команды debug.exe вводятся сразу после приглашения на месте, которое отмечено курсором. Каждая команда состоит из идентификатора и параметров, идентификатор состоит из одной буквы.
Таблица 1. Краткая таблица всех команд debug.exe
Команда | Описание | Формат |
A (Assemble) | Транслирование команд ассемблера в машинный код; адрес по умолчанию - CS:0100h. | A [<адрес_начала_кода>] |
C (Compare) | Сравнение содержимого двух областей памяти; по умолчанию используется DS. В команде указывается либо длина участков, либо диапазон адресов. | C <начальный_адрес_1> L<длина> <начальный_адрес_2> C <начальный_адрес_1> <конечный_адрес_1> <начальный_адрес_2> |
D (Display/Dump) | Вывод содержимого области памяти в шестнадцатеричном и ASCII-форматах. По умолчанию используется DS; можно указывать длину или диапазон. | D [<начальный_адрес> ] D [начальный_адрес конечный_адрес] |
E (Enter) | Ввод в память данные или инструкции машинного кода; по умолчанию используется DS. | E [<адрес> [<инструкции/данные>]] |
F (Fill) | Заполнение области памяти данными из списка; по умолчанию используется DS. Использовать можно как длину, так и диапазон. | F <начальный_адрес_1> L<длина> "<данные>" F <начальный_адрес> <конечный_адрес> "<данные>" |
G (Go) | Выполнение отлаженной программы на машинном языке до указанной точки останова; по умолчанию используется CS. При этом убедитесь, что IP содержит корректный адрес. | G [=<начальный_адрес>] <адрес_останова> [<адрес_останова> ...] |
H (Hexadecimal) | Вычисление суммы и разности двух шестнадцатеричных величин. | H <величина_1> <величина_2> |
I (Input) | Считывание и вывод одного байта из порта. | I <адрес_порта> |
L (Load) | Загрузка файла или данных из секторов диска в память; по умолчанию - CS:100h. Файл можно указать с помощью команды N или аргумента при запуске debug.exe. | L [<адрес_в_памяти_для_загрузки>] L [<адрес_в_памяти_для_загрузки> [<номер_диска> <начальный_сектор> <количество_секторов>]] |
M (Move) | Копирование содержимого ячеек памяти; по умолчанию используется DS. Можно указывать как длину, так и диапазон. | M <начальный_адрес> L<длина> <адрес_назначения> M <начальный_адрес> <конечный_адрес> <адрес_назначения> |
N (Name) | Указание имени файла для команд L и W. | N <имя_файла> |
O (Output) | Отсылка байта в порт. | O <адрес_порта> <байт> |
P (Proceed) | Выполнение инструкций CALL, LOOP, INT или повторяемой строковой инструкции с префиксами REPnn, переходя к следующей инструкции. | P [=<адрес_начала>] [<количество_инструкций>] |
Q (Quit) | Завершение работы debug.exe. | Q |
R (Register) | Вывод содержимого регистров и следующей инструкции. | R <имя_регистра> |
S (Search) | Поиск в памяти символов из списка; по умолчанию используется DS. Можно указывать как длину, так и диапазон. | S <начальный_адрес> L<длина> "<данные>" S <начальный_адрес> <конечный_адрес> "<данные>" |
T (Trace) | Пошаговое выполнение программы. Как и в команде P, по умолчанию используется пара CS:IP. Замечу, что для выполнения прерываний лучше пользоваться командой P. | T [=<адрес_начала>] [<количество_выполняемых_команд>] |
U (Unassemble) | Дизассемблирование машинного кода; по умолчанию используется пара CS:IP. К сожалению, debug.exe некорректно дизассемблирует специфические команды процессоров 80286+, хотя они все равно выполняются корректно. | U [<начальный_адрес>] U [<начальный_адрес конечный_адрес>] |
W (Write) | Запись файла из debug.exe; необходимо обязательно задать имя файла командой N, если он не был загружен. А программы записываются только в виде файлов.COM! | W [<адрес> [<номер_диска> <начальный_сектор> <количество_секторов>]] |
Просмотр областей памяти
Рассмотрим подробно работу команды D , позволяющей просматривать содержимое отдельных областей памяти. Этот пример использует команду D для просмотра области памяти, начиная с 0159:0240:
Здесь на запрос просмотра участка памяти мы получили восемь строк, в которых указано содержимое выбранной области памяти. Каждая строка состоит из трех частей:
· Адрес первого слева показанного байта в формате сегмент:смещение .
· Шестнадцатеричное представление параграфа (16 байт), начинающегося с указанного в начале строки байта.
· Символы этого же параграфа в ASCII-формате.
Адрес, указанный в строке, относится исключительно к первому байту в параграфе, а адреса последующих байтов следует вычислять самостоятельно. Шестнадцатеричное представление содержит по два знака в каждом байте, а сами байты разделены пробелами для облегчения чтения. Кроме того, следует отметить, что восьмой и девятый байты разделены дефисом, разделяя тем самым параграф на две части и облегчая вычисление адресов байтов в параграфе.
Полезные приемы с командой D
Проверка параллельных и последовательных портов
Первые 16 байт области данных BIOS содержат адреса параллельных и последовательных портов. Поэтому с помощью следующей команды можно проверить эти порты:
Первые выведенные восемь байтов указывают на адреса последовательных портов COM1-COM4 . Следующие 8 байтов указывают на адреса параллельных портов LPT1-LPT4 . Например, если на вашем компьютере есть один параллельный порт, то первые два байта будут, скорее всего, такими: 7803. Адрес порта записывается в обращенной последовательности, т.е. 0378.
Проверка оборудования
Первые два байта, располагающиеся в BIOS по адресу 410h, содержат информацию об установленном в системе оборудовании. Находим эти байты командой:
Предположим, что первые два байта окажутся 23 44. Расшифруем эти байты для получения информации об установленных устройствах. Для этого обратим эти байты (44 23), затем переведем их в двоичную систему счисления. Получаем:
Значение бита | ||||||||||||||||
Позиция бита |
Что означают эти биты? Продолжаем расшифровывать:
Проверка состояния регистра клавиатуры
В области данных BIOS по адресу 417h находится первый байт, который хранит состояние регистра клавиатуры. Выключаем Num Lock и Caps Lock , затем набираем команду:
Первый байт будет равен 00. Включив Num Lock и Caps Lock , снова выполняем команду. Теперь первый байт должен равняться 60. Опытным путем установлено, что при включенном Num Lock первый байт равен 20, а при Caps Lock - 40.
Проверка состояния видеосистемы
По адресу 449h в BIOS находится первая область видеоданных. Для проверки набираем:
Первый байт показывает текущий видеорежим (к примеру, 03 - цветной), а второй - число столбцов (например, 50 - режим с 80 столбцами). Число строк можно найти по адресу 484h (40:84).
Проверка копирайта BIOS и серийного номера
Сведения об авторских правах на BIOS встроены в ROM BIOS по адресу FE00:0 . Строку с копирайтом можно легко найти в ASCII-последовательности, а серийный номер ‑ в виде шестнадцатеричного числа. Хотя, строка с указанием авторских прав может быть длинной и не умещаться в выведенную область памяти. В таком случае следует просто ввести еще раз D .
Проверка даты произвоства BIOS
Эта дата также записана в ROM BIOS начиная с адреса FFFF:5 . После выполнения соответствующей команды в ASCII-последовательности будет находиться эта дата, записанная в формате мм/дд/гг .
Непосредственный ввод программы в память с помощью debug.exe
debug.exe позволяет вводить программу непосредственно в память машины, а затем следить и управлять е выполнением. Мы будем вводить программу в машинных кодах, используя команду E . При этом будьте бдительны ‑ ввод ошибочных данных по ошибочному адресу чреват непредсказуемыми последствиями! Хотя к серьезным проблемам в системе это вряд ли приведет, но потерять все данные, введенные в debug.exe , можно запросто. Программа, которую необходимо ввести, использует данные, заложенные непосредственно в теле инструкций. Далее показан листинг программы на Ассемблере, в комментариях указаны аналоги команд языка в машинных кодах, а также объяснение каждой команды. Заметьте, что в числах нет символа h , поскольку, как было сказано выше, debug.exe понимает только числа в шестнадцатеричной системе.
MOV AX, 0123 ; код B82301: заносим значение 0123h в AX
ADD AX, 0025 ; код 052500: прибавляем 0225h к значению AX
MOV BX, AX ; код 8BD8: заносим значение AX в BX
ADD BX, AX ; код 03D8: прибавляем значение AX к BX
MOV CX, BX ; код 8BCB: заносим значение BX в CX
SUB CX, AX ; код 2BC8: отнимаем значение AX из CX
SUB AX, AX ; код 2BC0: очищаем AX
JMP 100 ; код EBEE: переходим к началу программы
Как можно заметить, каждая машинная инструкция имеет длину от 1 до 3 байтов. Первый байт указывает операцию, последующие ‑ ее операнды. Исполнение программы начинается соответственно с первой инструкции и последовательно проходит через все инструкции одну за другой. Теперь можно ввести программу в память. Разделим машинный код на три части по шесть байт и введем каждую, используя команду E и начиная с адреса CS:100 .
Теперь, когда программа введена в память, попробуем управлять ее выполнением. Для начала проверим текущее состояние регистров и флагов, для этого вводим команду R . Отладчик выведет содержимое регистров в шестнадцатеричной форме; на разных машинах содержимое регистров может различаться.
Итак, как можно видеть, debug.exe инициализировал сегменты DS , ES , SS , CS одним и тем же адресом. Регистр IP содержит 0100 , указывая на то, что инструкции выполняются со смещения 100h относительно CS (а мы, вводя инструкции в память, как раз указали этот адрес).
Здесь же указаны и значения флагов переполнения, направления, прерывания, знака, нуля, дополнительного переноса, четности и переноса:
После регистров и состояния флагов debug.exe выводит информацию о первой инструкции, которая будет выполняться:
· Адрес инструкции, в нашем случае это 0B12:0100, где 0B12 ‑ адрес сегмента кода.
· Машинный код, соответствующей этой инструкции (B82301).
· Собственно инструкция, записанная на ассемблере (MOV AX,0123).
Теперь, после анализа содержимого регистров и флагов, давайте перейдем к выполнению программы. Выполнять программу мы будем пошагово, используя команду T . Использовав в первый раз команду T , мы выполняем инструкцию MOV . Здесь машинный код операнда инструкции ‑ 2301 . Операция помещает 23 в AL (младшая половина AX ), а 01 ‑ в AH (старшая). После этого debug.exe снова выводит информацию о регистрах:
Теперь AX содержит 0123h , IP ‑ 0103h (следовательно, длина выполненной инструкции: 0103h - 0100h = 3 байта), а в качестве следующей инструкции указана операция ADD . Так, раз за разом выполняя команду T , мы дойдем до последней инструкции JMP 100 . Она установит регистр IP в 100h , и debug.exe вернется к началу программы. Возвращаясь к началу программы, следует заметить, что в DS , ES , SS и CS содержится один и тот же адрес. Дело в том, что debug.exe рассматривает введенные программы исключительно как программы .COM . А в программах .COM , в отличие от .EXE , стек, код и данные хранятся в одном сегменте.
Ассемблирование и дизассемблирование
В прошлом примере мы вводили программу в машинных кодах, однако, debug.exe вполне способен понимать инструкции, записанные на ассемблере. Для работы с такими программами в debug.exe используются команды A и U .
Команда A запрашивает инструкции на ассемблере и преобразовывает их в машинный код. Для начала инициализируем начальный адрес для ввода инструкций (100h):
Отладчик выведет адрес сегмента кода и смещения (например, 13F2:0100 ). Теперь мы должны ввести следующие инструкции на ассемблере в память, после каждой строки нажимая Enter :
После ввода последней инструкции нажимаем Enter дважды, чтобы указать отладчику, что мы закончили вводить текст программы. Теперь программу можно запускать, используя команды R для просмотра регистров и T для трассировки. Замечу, что в своих программах при наличии инструкций INT их следует обрабатывать не командой T , а командой P , которая обрабатывает все прерывание сразу.
Перейдем к процедуре дизассемблирования, а в качестве примера возьмем только что введенную программу. Используем адреса первой и последней инструкций для указания диапазона, который мы собираемся дизассемблировать, т.е. 100h и 107h .
После выполнения этой команды debug.exe выведет инструкции, находящиеся в указанном диапазоне, на ассемблере, в машинных кодах, а также адрес каждой инструкции:
Сохранение программы на диске
Сначала задается имя файла:
Затем в регистр СХ необходимо поместить размер программы в байтах. Он будет равен разности конечного и начального смещений. Теперь остается только осуществить запись на диск командой W и в результате увидеть записанное количество байтов. В итоге мы получаем программу, готовую к исполнению.
Выход осуществляется командой q . Пример:
0B3B:0100 mov ax,1234
0B3B:0103 mov ah, 4c
0B3B:0105 int 21
0B3B:0100 B83412 MOV AX,1234
0B3B:0103 B44C MOV AH,4C
0B3B:0105 CD21 INT 21
AX=0000 BX=0000 CX=0007 DX=0000 SP=FFEE BP=0000 SI=0000 DI=0000
DS=0B3B ES=0B3B SS=0B3B CS=0B3B IP=0100 NV UP EI PL NZ NA PO NC
0B3B:0100 B83412 MOV AX,1234
Запись 00007 байт
Для выполнения этой лабораторной работы понадобится несколько команд ассемблера:
MOV AH,<шестнадцатиричное число> - запись в регистр AH числа 02 для указания системной функции - вывод символа на экран;
MOV DL,<шестнадцатиричное число> - запись в регистр DL кода символа;
INT 21 - основное прерывание DOS (процедура), реализующее много различных функций; номер функции записывается предварительно в регистр AH; для распечатки символа на экране - в регистре AH функция 02, при этом в DL записывают предварительно код символа.
INT 20 - прерывание DOS, осуществляющее выход из программы (из.COM-программы).
Пример:
Вывести символ "*" на экран.
mov AH,02 ; системная функция 02 - вывод символа на экран
mov DL,2A ; ASCII-код звездочки
int 21h ; прерывание для вывода "*"
int 20h ; выход из программы
Практическое задание
Цель
Знакомство с отладчиком debug.exe. Получение практических навыков работы с данной программой.
Оборудование:
Персональный компьютер под управлением операционной системы Windows.
Программное обеспечение:
Программа Debug.
Вопросы к допуску
1. Для чего предназначена программа Debug?
2. Как запустить эту программу?
3. Каким образом вводятся команды в Debug?
4. Что такое идентификатор?
5. Как производится ввод программы в Debug?
Задание
· Изучить теоретический материал.
· Проделать описанные по ходу текста команды.
· Найдите сумму и разность 2-х чисел: 1-е число - номер в группе (переведенное в шестнадцатиричную форму), 2-е - число, противоположное номеру первой буквы фамилии в алфавите (отрицательное число в дополнительном коде). Сумму и разность переведите в десятичную форму.
· Просмотрите содержимое регистров микропроцессора, а также флагов и выпишите их в протокол. Какую функцию выполняет каждый из регистров? .
· Запишите в регистр AX первое число (из задания 3), а в регистр BX - второе (из задания 3). Введите в оперативную память в сегмент кода (смещение 100) машинную команду сложения регистров AX и BX. Просмотрите на экране ее ассемблерную форму. Выполните эту команду, результат переведите в десятичную форму.
· Введите в оперативную память в сегмент кода (смещение 100) набор команд ассемблера для распечатки символа на экране - первой буквы вашей фамилии. Проверьте программу в DEBUG. Затем запишите ее на диск в виде.COM-файла. Чему равен размер программы? Запустите ее на выполнение из DOS.
· Все действия опишите в отчете.
1. Название работы.
2. Цель работы.
3. Приборы и оборудование.
4. Краткие теоретические сведения.
5. Описание проделанных действий.
6. Текст созданной программы.
7. Выводы.
Контрольные вопросы
1. Какая команда производит ввод в память данные или инструкции машинного кода?
2. Как сравнить содержимое двух областей памяти?
3. Каким образом заполнить область памяти данными из списка?
4. Какая команда производит выполнение отлаженной программы на машинном языке?
5. Какая команда записывает файл из Debug?
6. Как производится ассемблирование и дизассемблирование?
Запуск Debug.exe, программы для проверки и отладки
исполнительных файлов MS-DOS. Выполненная без
параметров команда debug
запускает программу
Debug.exe и выводит приглашение команды debug
,
представленное дефисом (-).
debug [[диск : ][путь ] имя_файла [ параметры ]]
Команда debug это команда подсистемы MS-DOS, которая выполняется в среде WOW/NTVDM.
Параметры можно вводить через запятые или пробелы, но это требуется только для шестнадцатеричных значений. Например, следующие команды эквивалентны:
Существует несколько команд debug , которыми можно воспользоваться.
Создание двоичного кода процессоров 8086/8087/8088 непосредственно в памяти. Выполненная без параметров команда a начинает работу с точки последнего останова.
a [адрес ]
Адрес состоит из двух частей: первая содержит буквенное обозначение сегментного регистра или адрес сегмента из четырех цифр, а вторая содержит значение смещения. Адрес сегмента или сегментный регистр можно пропустить. По умолчанию для команд debug a , g , l , t , u и w адрес сегмента содержится в регистре CS. Для других подкоманд по умолчанию используется сегмент DS. Все числовые значения при этом представлены в шестнадцатеричном формате. Между именем сегмента и значением смещения следует вставлять двоеточие. Примеры правильных адресов:
Задайте мнемонику префикса инструкции перед кодом операции (т. е. opcode), к которой она относится. Команда a создает исполняемый машинный код из инструкций на языке ассемблера. Все числовые значения должны быть представлены в шестнадцатеричном формате и записаны как набор от 1 до 4 символов.
Мнемоники cs: , ds: , es: и ss: . Мнемоникой, вызывающей возврат управления в другой сегмент кода (far return), является retf . Мнемоники для работы со строками должны точно определять размер элементов строк. Например, для перемещения строк из слов (16 бит) следует использовать movsw , а для перемещения строк из байтов (8 бит) следует использовать movsb .
Ассемблер автоматически обрабатывает переходы и вызовы (т. е. префиксы short, near или far) в зависимости от смещения байтов. Имеется возможность переопределить переходы или вызовы с помощью префиксов near или far . Например:
A0100:0500
0100:0500 jmp 502 ; короткий (short) переход на 2 байта
0100:0502 jmp near 505 ; ближний (near) переход на 3 байта
0100:0505 jmp far 50a ; длинный (far) переход на 5 байтов
Вместо префикса near можно использовать сокращение ne .
Если операнды ссылаются на адреса слов или байтов в памяти, тип данных должен быть задан с использованием префикса word ptr или byte ptr , которые можно сократить до wo для word ptr и до by для byte ptr . Например:
dec wo
neg byte ptr
В программе Debug.exe используется общее соглашение о том, что операнды, указывающие на адрес в памяти, заключаются в квадратные скобки (). Это единственный способ, который позволяет различать непосредственные операнды и ссылки на области в памяти в Debug.exe. Например:
mov ax,21 ; загрузить число 21h в регистр AX
mov ax, ; загрузить содержимое
; памяти по адресу 21h
; в регистр AX
С командой a часто используются две псевдоинструкции: операция db , которая размещает байты непосредственно в памяти, и операция dw , которая размещает в памяти слова. Например:
db 1,2,3,4,"ЭТО ПРИМЕР"
db "ЭТО КАВЫЧКА: ""
db "ЭТО КАВЫЧКА: ""
dw 1000,2000,3000,"BACH"
Команда a допускает различное использование ссылок на регистры. Например:
add bx,34.
pop
push )
Кроме того, команда a поддерживает использование синонимов дополнительных кодов операций: Например:
loopz 100
loope 100
ja 200
jnbe 200
Для дополнительных кодов операций процессора 8087 необходимо задать префиксы wait или fwait . Например:
fwait fadd st,st(3) ; эта строка вставляет
; в код префикса fwait
Сравнение двух блоков памяти.
c диапазон адрес
Параметр диапазон используется в командах debug для задания диапазона памяти. Для задания диапазона можно использовать один из следующих форматов: начальный и конечный адрес или начальный адрес и длина (разделяются символом l ) диапазона. Например, обе следующих команды задают 16-разрядный диапазон, начинающийся с адреса CS:100:
Адрес состоит из двух частей: первая содержит буквенное обозначение сегментного регистра или адрес сегмента из четырех цифр, а вторая содержит значение смещения. Адрес сегмента или сегментный регистр могут быть пропущены. По умолчанию для команд debug a , g , l , t , u и w адрес сегмента содержится в регистре CS. Для других подкоманд по умолчанию используется сегмент DS. Все числовые значения при этом представлены в шестнадцатеричном формате. Между именем сегмента и значением смещения следует вставлять двоеточие. Следующие адреса являются допустимыми:
адрес1 байт1 байт2 адрес2
Чтобы сравнить блок памяти от 100h до 10Fh с блоком памяти от 300h до 30Fh, введите следующую команду:
c100,10f 300
Обе эти команды выведут следующие данные (предполагается, что DS = 197F):
197F:0100 4D E4 197F:0300
197F:0101 67 99 197F:0301
197F:0102 A3 27 197F:0302
197F:0103 35 F3 197F:0303
197F:0104 97 BD 197F:0304
197F:0105 04 35 197F:0305
197F:0107 76 71 197F:0307
197F:0108 E6 11 197F:0308
197F:0109 19 2C 197F:0309
197F:010A 80 0A 197F:030A
197F:010B 36 7F 197F:030B
197F:010C BE 22 197F:030C
197F:010D 83 93 197F:030D
197F:010E 49 77 197F:030E
197F:010F 4F 8A 197F:030F
Адреса 197F:0106 и 197F:0306 отсутствуют в списке. Это означает, что значения, расположенные по этим адресам, совпадают.
Просмотр содержимого заданного диапазона адресов памяти. Выполненная без параметров команда d выводит на экран содержимое 128 байт, начиная с конца диапазона адресов, заданного в предыдущей команде d .
d [диапазон ]
Параметр диапазон используется в подкомандах debug диапазон l
Введите следующую команду:
Команда debug.exe выводит содержимое диапазона в следующем формате:
04BA:0100 54 4F 4D 00 53 41 57 59-45 52 00 00 00 00 00 00.....
Команда Debug.exe выводит сведения в таком формате, если подкоманда d выполнена без параметров. Каждая строка на экране начинается с адреса, который отстоит от адреса предыдущей строки на 16 байт (или на 8 байт для экрана с 40 колонками). Для каждой последующей подкоманды d , вводимой без параметров, Debug.exe выводит следующую часть сведений непосредственно за предыдущей.
Чтобы вывести содержимое 20h байт, начиная с CS:100, введите следующую команду:
Чтобы вывести содержимое всех байт в диапазоне от 100h до 115h в сегменте CS, введите следующую команду:
Ввод данных в память по заданному адресу.
e адрес [список ]
Адрес a , g , l , t , u и w команды debug
При задании параметра адрес без указания параметра список Debug.exe выведет на экран адрес и его содержимое, затем повторит адрес на следующей строке и будет ждать ввода новой команды. В этот момент можно выполнить одно из следующих действий.
Если введен параметр список , подкоманда e последовательно заменяет существующие значения значениями из списка. При возникновении ошибки никакие значения не будут изменены.
Список может быть задан как шестнадцатеричными числами, так и строкой. При этом числа разделяются пробелами, запятыми или символами табуляции. Строки необходимо заключать в апострофы (т. е. " строка " ) или кавычки (т. е. " строка " ).
Введите следующую команду:
Debug.exe выведет содержимое первого байта в следующем формате:
Чтобы заменить это значение числом 41, введите 41 в позицию курсора, как показано ниже:
04BA:0100 EB.41 _
Последовательность байтов можно ввести в одной подкоманде e . Вместо нажатия клавиши Enter после нового значения, нажмите клавишу ПРОБЕЛ. Программа Debug.exe выведет следующее значение. В данном примере, если клавиша ПРОБЕЛ нажата три раза, Debug.exe выведет на экран следующие значения:
04BA:0100 EB.41 10. 00. BC._
Чтобы заменить шестнадцатеричное значение BC числом 42, введите 42 в позицию курсора, как показано ниже:
04BA:0100 EB.41 10. 00. BC.42 _
Чтобы изменить значение 10 на 6F, дважды нажмите клавишу МИНУС для возврата к адресу 0101 (значение 10). Программа Debug.exe выводит следующие сведения:
04BA:0100 EB.41 10. 00. BC.42-
04BA:0102 00.-
04BA:0101 10._
Введите 6F в позицию курсора для изменения значения, как показано ниже:
04BA:0101 10.6F _
Нажмите клавишу ENTER для завершения выполнения подкоманды e и возврата к приглашению программы debug .
Рассмотрим пример ввода строковой величины:
eds:100 "Это пример текста"
Эта строка будет занимать 24 байта, начиная с адреса DS:100.
Заполнение адресов в определенной области памяти заданными значениями.
f диапазон список
Параметр диапазон используется в подкомандах debug для задания диапазона памяти. Параметр диапазон можно задать в одном из следующих форматов: начальный адрес и конечный адрес или начальный адрес и длина (обозначаемая l ) диапазона. Например, оба следующих выражения задают диапазон из 16 байтов, начинающийся с адреса CS:100:
Данные можно задать в шестнадцатеричном или текстовом формате. Данные, ранее находившиеся по данному адресу, будут удалены.
Список может состоять из шестнадцатеричных чисел или строки, заключенной в кавычки (т. е. " строка " ).
Чтобы заполнить область памяти с 04BA:100 по 04BA:1FF пятью определенными значениями (например 42, 45, 52, 54, 41) и повторять этот набор, пока 100h байт не будут заполнены программой Debug.exe, введите следующую команду:
f04ba:100l100 42 45 52 54 41
Выполнение загруженной программы. Запущенная без параметров подкоманда g начинает выполнение с текущего адреса в реестрах CS:IP.
g [= адрес ] [точки_останова ]
Адрес состоит из двух частей: первая содержит буквенное обозначение сегментного регистра или адрес сегмента из четырех цифр, а вторая содержит значение смещения. Адрес сегмента или сегментный регистр могут быть пропущены. По умолчанию для подкоманд a , g , l , t , u и w команды debug адрес сегмента содержится в регистре CS. Для других подкоманд по умолчанию используется сегмент DS. Все числовые значения при этом представлены в шестнадцатеричном формате. Между именем сегмента и значением смещения следует вставлять двоеточие. Следующие адреса являются допустимыми:
Введите знак равенства (=) перед параметром адрес , чтобы отличить адрес от адресов точек останова (точки_останова ).
Выполнение программы будет остановлено в первой встретившейся точке останова, независимо от расположения этой точки останова в списке параметра точки_останова . Debug.exe заменяет код, находящийся в точках останова, на инструкции прерывания.
Когда выполнение программы дошло до точки останова, Debug.exe восстанавливает код в точках останова и выводит на экран содержимое всех регистров, все флаги состояния и деассемблированную инструкцию, которая была выполнена последней. Debug.exe выводит те же сведения, которые получают при использовании полкоманды r (регистр) и указании адреса данной точки останова.
Если программа не остановлена ни в одной точке, Debug.exe не заменяет коды прерываний первоначальными инструкциями.
Точки останова могут быть установлены только по адресам, содержащим первый байт кода операции 8086 (opcode). Если установлено больше 10 точек останова, выводится следующее сообщение:
Указатель на стек, задаваемый пользователем, должен быть допустимым, а емкость стека должна быть не менее 6 байт для подкоманды g . Для перехода к тестируемой программе в подкоманде g используется инструкция iret . Debug.exe устанавливает указатель на стек пользователя, помещает туда пользовательские флаги состояния, значение регистра кодового сегмента и указатель на текущую команду. (Если заданный пользователем стек неверен или имеет недостаточный объем, возможен сбой в операционной системе). Debug.exe записывает код прерывания (т. е. 0CCh) в указанные точки останова или адреса.
Не перезапускайте программу при получении следующего сообщения:
Program terminated normally
Чтобы правильно запустить программу, перезагрузите ее с помощью подкоманд n (name) и l (load).
Чтобы запустить текущую программу и выполнить ее до точки останова по адресу 7550 в сегменте CS, введите следующую команду.
Debug.exe выведет на экран содержимое регистров и состояние флагов, а затем остановит подкоманду g .
Чтобы установить две точки останова, введите следующую команду:
gcs:7550, cs:8000
Если подкоманда g введена снова после остановки в точке останова, выполнение начнется с инструкции, следующей за точкой останова, а не с обычного адреса начала программы.
Выполнение шестнадцатеричных арифметических операций над двумя заданными числами.
h число1 число2
Введите следующую команду:
Результаты вычислений Debug.exe будут выведены в виде:
Считывание и вывод на экран одного байта из указанного порта ввода.
i порт
Введите следующую команду:
Если находящаяся в порту величина равна 42h, Debug.exe считает ее и выведет в следующем виде:
Загрузка файла или содержимого сектора диска в память. Выполненная без параметров подкоманда l загружает файл, указанный в командной строке программы debug , в память, начиная с адреса CS:100. В регистрах BX и CX указывается количество загруженных байт. Если имя файла не было задано в командной строке debug , используется файл, ранее заданный при вызове последней подкоманды n .
l [адрес ]
l [адрес ] [диск ] [первый_сектор ] [ число ]
l [адрес ]
l [адрес ] [диск ] [первый_сектор ] [ число ]
Адрес состоит из двух частей: первая содержит буквенное обозначение сегментного регистра или адрес сегмента из четырех цифр, а вторая содержит значение смещения. Адрес сегмента или сегментный регистр могут быть пропущены. По умолчанию для подкоманд a , g , l , t , u и w команды debug адрес сегмента содержится в регистре CS. Для других подкоманд по умолчанию используется сегмент DS. All numeric values are in hexadecimal format. Между именем сегмента и значением смещения следует вставлять двоеточие. Следующие адреса являются допустимыми:
При вызове подкоманды l с указанием параметра адрес Debug.exe загрузит файл или содержимое сектора диска в область памяти, начиная с адреса .
При вызове подкоманды l со всеми параметрами Debug.exe загружает содержимое сектора диска, а не файла.
Каждый сектор в указанном диапазоне считывается с диска, заданного параметром диск . Debug.exe начинает загрузку с первого_сектора и последовательно загружает сектора в память, пока не будет загружено заданное число секторов.
Для файлов с расширением.exe параметр адрес игнорируется. В этом случае Debug.exe использует загрузочный адрес, задаваемый в заголовке.exe файла. При загрузке заголовок отделяется от самого.exe файла, загружаемого в память, поэтому размер файла, указанный в заголовке, и фактически занимаемый размер в памяти будут различаться. Для просмотра.exe файла целиком он может быть переименован в файл с другим расширением и затем просмотрен в программе Debug.
В программе Debug.exe файлы с расширением.hex распознаются как файлы в шестнадцатеричном формате. Подкоманду l можно запустить без параметров для загрузки такого шестнадцатеричного файла, начиная с адреса, указанного в данном файле. Если подкоманда l запущена с параметром адрес , начальная точка загрузки определяется как сумма заданного адреса и адреса, содержащегося в шестнадцатеричном файле.
В командной строке введите:
Введите следующую команду:
Чтобы загрузить файл File.com, введите следующую команду:
Debug.exe загружает этот файл и выводит приглашение debug .
Чтобы загрузить содержимое 109 (6Dh) секторов диска C, начиная с логического сектора 15 (0Fh), в область памяти, начиная с адреса 04BA:0100, введите следующую команду:
l04ba:100 2 0f 6d
Копирование содержимого одного блока памяти в другой.
m диапазон адрес
Параметр диапазон используется в подкомандах debug для задания диапазона памяти. Параметр диапазон можно задать в одном из следующих форматов: начальный адрес и конечный адрес или начальный адрес и длина (обозначаемая l ) диапазона. Например, оба следующих выражения задают диапазон из 16 байтов, начинающийся с адреса CS:100:
Адрес состоит из двух частей: первая содержит буквенное обозначение сегментного регистра или адрес сегмента из четырех цифр, а вторая содержит значение смещения. Адрес сегмента или сегментный регистр могут быть пропущены. По умолчанию для подкоманд a , g , l , t , u и w команды debug адрес сегмента содержится в регистре CS. Для других подкоманд по умолчанию используется сегмент DS. Все числовые значения при этом представлены в шестнадцатеричном формате. Между именем сегмента и значением смещения следует вставлять двоеточие. Следующие адреса являются допустимыми:
Если адреса в копируемом блоке памяти заданы так, что в этот блок не записываются новые данные, то информация в этом блоке не изменяется. Если же операция копирования является перекрывающей, перекрывающиеся данные перезаписываются. (Операция копирования является перекрывающей, если два блока памяти имеют общую часть).
Подкоманда m выполняет перекрывающее копирование без потери данных в области назначения. Содержимое адресов, которые будут перезаписаны, копируется в первую очередь. Если данные копируются из старших адресов в младшие адреса, операция копирования начинается с младшего адреса исходного блока и продолжается в направлении старшего адреса. И наоборот, если данные копируются из младших адресов в старшие, копирование начинается со старших адресов исходного блока и продолжается в направлении младшего адреса.
Чтобы скопировать содержимое адресов с CS:110 по CS:510, а затем с CS:10F по CS:50F и так далее, пока все содержимое адресов с CS:100 по CS:500 не будет скопировано, введите следующую команду:
mcs:100 110 cs:500
Чтобы просмотреть результаты, воспользуйтесь подкомандой d (dump), указав адреса, заданные в подкоманде m .
Задание имени исполняемого файла для команд debug l (load) или w (write) или задание параметров для отлаживаемого исполняемого файла. Выполненная без параметров подкоманда n очищает текущие значения.
n [путь ][исполняемый_файл ]
n [параметры_файла ]
Подкоманду n можно использовать двумя способами. Во-первых, для задания имени файла для последующих подкоманд l (load) или w (write). Если программа Debug.exe вызвана без задания имени файла для отладки, команда n имя_файла должна быть вызвана перед использованием команды l для загрузки файла. Имя файла форматируется соответствующим образом для контрольного блока файла (FCB) по адресу CS:5C. Во-вторых, подкоманда n может использоваться для задания параметров и ключей командной строки отлаживаемого файла.
В следующей таблице перечислены четыре области памяти, которые используются командой n .
Первое имя файла, задаваемое командой n , размещается в блоке управления файлом по адресу CS:5C. Если задано второе имя, оно помещается в блок управления файлом по адресу CS:6C. Количество символов в командной строке команды n (кроме первого символа, n ) сохраняется по адресу CS:80. Собственно командная строка n (снова без символа n ) сохраняется, начиная с адреса CS:81. Эти символы могут быть любыми параметрами и разделителями, которые допустимо вводить с командной строки в Windows 2000.
В этом примере запускается команда debug и загружается программа Prog.com для отладки. Чтобы указать два параметра для программы Prog.com и запустить эту программу, введите следующую команду:
debug prog.com
nparam1 param2
g
В этом случае подкоманда g (go) запускает программу так, как если бы она была запущена с командной строки в виде:
prog param1 param2
При тестировании и отладке создается среда времени исполнения для программы Prog.com.
В следующей последовательности команд первая подкоманда n задает имя файла File1.exe для последующей подкоманды l (load), которая загружает файл File1.exe в память. Вторая подкоманда n задает параметры для файла File1.exe. Наконец, подкоманда g запускает File1.exe так, как если бы с командной строки было бы введено File1 File2.dat File2.dat .
nfile1.exe
l
nfile2.dat file3.dat
g
После команды l во втором экземпляре команда n не используется. Если подкоманда w (write) используется во втором экземпляре подкоманды n , файл File1.exe (т. е. отлаживаемый) сохраняется под именем File2.dat. Чтобы этого не произошло, всегда вызывайте команду l или w сразу же после команды n в первой форме.
Вывод байта в порт вывода.
o порт байт
Чтобы отправить байт 4Fh в порт вывода по адресу 2F8h, введите следующую команду:
Выполнение цикла, строковой инструкции, программного прерывания или процедур, а также вход в другую инструкцию. Выполненная без параметров команда p выводит список реестров и их текущих значений.
p [= адрес ] [число ]
Адрес состоит из двух частей: первая содержит буквенное обозначение сегментного регистра или адрес сегмента из четырех цифр, а вторая содержит значение смещения. Адрес сегмента или сегментный регистр могут быть пропущены. По умолчанию для подкоманд a , g , l , t , u и w команды debug адрес сегмента содержится в регистре CS. Для других подкоманд по умолчанию используется сегмент DS. Все числовые значения при этом представлены в шестнадцатеричном формате. Между именем сегмента и значением смещения следует вставлять двоеточие. Следующие адреса являются допустимыми:
Если в параметре адрес не указан сегмент, Debug.exe использует регистр CS тестируемой программы. Если параметр адрес опущен, выполнение программы начинается с адреса, указываемого регистрами CS:IP. Чтобы отличить параметр адрес от параметра число , перед адресом обязательно должен быть введен знак равенства (=). В случае если инструкция по заданному адресу не является циклом, строковой инструкцией, программным прерыванием или процедурой, подкоманда p работает также, как подкоманда t (trace).
Если в программе Debug.exe управление передано тестируемой программе с помощью команды p , выполнение продолжается до тех пор, пока цикл, строковая инструкция, программное прерывание или процедура не будут закончены или пока не будет выполнено заданное количество инструкций. Затем управление возвращается к Debug.exe.
После запуска подкоманды p Debug.exe выводит на экран содержимое регистров, флаги состояния и следующую инструкцию в деассемблированном виде.
Предупреждение!
В этом примере тестируемая программа содержит инструкцию call по адресу CS:143F. Чтобы выполнить процедуру, указанную в call , и возвратиться в программу Debug.exe, введите следующую команду:
Результаты программы Debug.exe будут выведены в следующем формате:
AX=0000 BX=0000 CX=0000 DX=0000 SP=FFEE BP=0000 SI=0000 DI=0000
DS=2246 ES=2246 SS=2246 CS=2246 IP=1443 NV UP EI PL NZ AC PO NC
2246:1442 7505 JNZ 144A
Окончание работы программы Debug.exe без сохранения тестируемого файла и возврат в командную строку.
Редактирование содержимого одного или нескольких регистров ЦПУ. Выполненная без параметров команда r выводит содержимое всех регистров и флагов из временного хранилище регистра, состояния всех флагов и декодированную инструкцию в текущей области.
r [регистр ]
Если задан регистр, Debug.exe выводит на экран его 16-разрядное значение в шестнадцатеричном формате и двоеточие в качестве приглашения. Если требуется изменить значение содержащееся в регистре, введите новое значение и нажмите клавишу ENTER. В противном случае нажмите клавишу ENTER для возврата к приглашению программы debug .
В следующей таблице перечислены допустимые регистры x86 для параметра регистр .
Значение |
---|
ax |
bp |
bx |
cs |
cx |
di |
ds |
dx |
es |
f |
ip |
pc |
si |
sp |
ss |
Если задан недопустимый регистр, выводится следующее сообщение:
Ошибка: br
Если указать f вместо регистра, Debug.exe выводит на экран текущее значение каждого флага состояния в виде двухбуквенного кода и приглашение debug . Для изменения значения флага введите соответствующий двухбуквенный код, воспользовавшись следующей таблицей.
Новые значения флагов могут быть введены в любой последовательности. Между этими значениями не нужно вводить пробел. Чтобы завершить выполнение подкоманды r , нажмите клавишу ENTER. Флаги, новые значения для которых не вводились, останутся неизмененными.
При задании более одного значения для флага выводится следующее сообщение:
Ошибка: df
При вводе кода, не содержащегося в таблице, выводится следующее сообщение:
Ошибка: bf
В обоих случаях Debug.exe пропустит все значения, следующие после неверного ввода.
Когда запускается программа Debug.exe, сегментный регистр указывает на нижнюю границу свободной памяти, указатель инструкций устанавливается равным 0100h, все флаги состояния очищаются, оставшиеся регистры обнуляются, за исключением sp , который устанавливается равным FFEEh.
Если текущее положение указателя инструкций равно CS:11A, выводятся следующие сведения:
04BA:011A CD21 INT 21
Чтобы просмотреть только состояния флагов, введите следующую команду:
NV UP DI NG NZ AC PE NC - _
Введите одно и несколько допустимых значений флагов с пробелами или без них. Например:
nv up di ng nz ac pe nc - pleicy
Debug.exe завершит выполнение подкоманды r и выведет приглашение debug . Для просмотра изменений воспользуйтесь командой r или rf . Программа Debug.exe выводит следующие сведения:
NV UP EI PL NZ AC PE CY - _
Нажмите клавишу ENTER для возврата к приглашению программы debug .
Выполнение одной инструкции с выводом содержимого регистров, флагов состояния и декодированной формы выполняемой инструкции. При запуске подкоманды t без параметров выполнение начинается с адреса, указанного в регистрах CS:IP программы.
t [= адрес ] [число ]
Адрес состоит из двух частей: первая содержит буквенное обозначение сегментного регистра или адрес сегмента из четырех цифр, а вторая содержит значение смещения. Адрес сегмента или сегментный регистр могут быть пропущены. По умолчанию для подкоманд a , g , l , t , u и w команды debug адрес сегмента содержится в регистре CS. Для других подкоманд по умолчанию используется сегмент DS. Все числовые значения при этом представлены в шестнадцатеричном формате. Между именем сегмента и значением смещения следует вставлять двоеточие. Следующие адреса являются допустимыми:
Подкоманда t использует аппаратный режим трассировки микропроцессоров 8086 и 8088. Следовательно, также можно трассировать инструкции, хранимые в ПЗУ.
Если текущая позиция указателя кода является 04BA:011A, Debug.exe выведет следующие сведения:
AX=0E00 BX=00FF CX=0007 DX=01FF SP=039D BP=0000 SI=005C DI=0000
DS=04BA ES=04BA SS=04BA CS=O4BA IP=011A NV UP DI NG NZ AC PE NC
04BA:011A CD21 INT 21
Деассемблирование байтов и просмотр соответствующего исходного кода, включая адреса и двоичные значения. Деассемблированный код выводится в формате, похожем на распечатку ассемблерного файла. Выполненная без параметров подкоманда u деассемблирует 20h байт (значение по умолчанию), начиная с первого адреса после адреса, использованного в предыдущей подкоманде u .
u [диапазон ]
Параметр диапазон используется в подкомандах debug для задания диапазона памяти. Параметр диапазон можно задать в одном из следующих форматов: начальный адрес и конечный адрес или начальный адрес и длина (обозначаемая l ) диапазона. Например, оба следующих выражения задают диапазон из 16 байтов, начинающийся с адреса CS:100:
Чтобы деассемблировать 16 (10h) байт, начиная с адреса 04BA:0100, введите следующую команду:
Результаты программы Debug.exe выводятся в следующем формате:
04BA:0103 69 DB 69
04BA:0104 7665 JBE 016B
04BA:0109 65 DB 65
04BA:010A 63 DB 63
04BA:010B 69 DB 69
04BA:010C 66 DB 66
04BA:010D 69 DB 69
04BA:010E 63 DB 63
04BA:010F 61 DB 61
Чтобы просмотреть сведения только об адресах с 04BA:0100 по 04BA:0108, введите следующую команду:
Программа Debug.exe выводит следующие сведения:
04BA:0100 206472 AND ,AH
04BA:0103 69 DB 69
04BA:0104 7665 JBE 016B
04BA:0106 207370 AND ,DH
Запись файла или определенных секторов на диск. При запуске подкоманды w без параметров запись начинается с адреса CS:100.
w [адрес ]
w [адрес ] [диск ] [первый_сектор ] [ число ]
w [адрес ]
w [адрес ] [диск ] [первый_сектор ] [ число ]
Адрес состоит из двух частей: первая содержит буквенное обозначение сегментного регистра или адрес сегмента из четырех цифр, а вторая содержит значение смещения. Адрес сегмента или сегментный регистр могут быть пропущены. По умолчанию для подкоманд a , g , l , t , u и w команды debug адрес сегмента содержится в регистре CS. Для других подкоманд по умолчанию используется сегмент DS. Все числовые значения при этом представлены в шестнадцатеричном формате. Между именем сегмента и значением смещения следует вставлять двоеточие. Следующие адреса являются допустимыми:
Если используются подкоманды g (go), t (trace), p (proceed) или r (register), перед использованием команды w без параметров значения регистров BX:CX необходимо сбросить.
Если файл был изменен, но имя, размер и начальный адрес не менялись, Debug.exe позволяет записать файл в его исходное расположение на диске.
Файлы с расширениями.exe и.hex нельзя записать с помощью этой команды.
Предупреждение
Чтобы записать содержимое области памяти, начиная с адреса CS:100, на диск B и собрать данные из 2Bh секторов, начиная с логического сектора диска под номером 37h, введите следующую команду:
После окончания операции записи выводится приглашение программы debug .
Выделение заданного количества страниц памяти EMS. Выполненная без параметров подкоманда xa
xa [число_страниц ]
Чтобы выделить восемь страниц дополнительной памяти, введите следующую команду:
Если команда успешно выделит память, выводятся следующие сведения:
Создан дескриптор=0003
Освобождение дескриптора памяти EMS. Выполненная без параметров подкоманда xd проверяет наличие или отсутствие поддержки дополнительной памяти (EMS).
xd [дескриптор ]
Чтобы освободить дескриптор 0003, введите следующую команду:
Дескриптор 0003 освобожден
Отображение логической страницы памяти EMS, соответствующей заданному дескриптору, в физическую страницу памяти EMS. Выполненная без параметров подкоманда xm проверяет наличие или отсутствие поддержки памяти EMS.
xm [лог_страница ] [физ_страница ] [ дескриптор ]
Чтобы отобразить логическую страницу 5 дескриптора 0003 в физическую страницу 2, введите следующую команду:
При успешном выполнении программы Debug.exe будет выведено сообщение:
Логическая страница 05 отображена на физическую страницу 02
Вывод сведений о состоянии памяти EMS.
Для дескриптора xx выделено xx страниц
Физическая страница xx = Сегмент EMS xx
Выделено xx из xx страниц EMS
Выделено xx из xx дескрипторов EMS
Чтобы вывести сведения о состоянии памяти EMS, введите следующую команду:
Подкоманда xs выводит сведения в следующем виде:
Handle 0000 has 0000 pages allocated Для дескриптора 0001 выделено 0002 страниц Физическая страница 00 = Сегмент EMS C000 Физическая страница 01 = Сегмент EMS C400 Физическая страница 02 = Сегмент EMS C800 Физическая страница 03 = Сегмент EMS CC00 Выделено 2 из 80 страниц EMS Выделено 2 из FF дескрипторов EMS
Для вопросов, обсуждений, замечаний, предложений и т. п. можете использовать раздел форума этого сайта (требуется регистрация).
Привет, юный хакер! Ты уже многое знаешь, но крутой хакер никогда не останавливается на достигнутом. Эта статья посвящена работе с стандартным дебаггером системы ДОС. Ты скажешь: «На кой фиг мне это надо мне, крутому перцу?».
Представь ситуацию: ты приходишь в компьютерный клуб (интернет-кафе, к другу домой), а там на тачке дисководы сняты, сидюки заклеены, а пакость сделать все же хочется. Естественно, на любом «нормальном» компе нет никаких компиляторов С, ассемблеров… но почти на каждом «нормальном» компе есть ДОС! Да, именно ДОС, и его последователи — Винды всех типов а конкретнее программа
DEBUG.
Как? Набрать короткую (если времени мало, да и сил жалко), но неприятную программку, сохранить ее на диске и потом запустить, получив моральное удовлетворение. Посмотрим, как это делается, но для начала изучим несколько простых, но весьма полезных команд.
Итак, вы запустили программу DEBUG
Первая команда –D (dump)
Эта команда позволяет просмотреть некоторую область памяти, адрес которой задан в параметре
Для начала посмотрим ПЗУ BIOS:
Здесь вы видите фирму-производителя вашей
BIOS. А по адресу:
получаем интересную информацию о системе,
такую как дата создания БИОС, чипсет… А по данному адресу
(0000:046C) находится таймер БИОС. Отчетливо видно, что значения все время меняются.
Для программиста удобно просматривать сегменты команд, данных и стека (CS, DS и SS, соответственно).
Выше мы видим содержимое сегмента данных, т. е.
значения определенных переменных.
А тут представлено содержимое сегмента команд, т.е. машинные коды команд, готовых к исполнению.
Освоив команды просмотра памяти, впоследствии мы сможем эффективно отлаживать наши программы и просматривать введенный нами код перед исполнением (для нас сейчас это приоритетная задача).
Еще одна важная команда -R (register)
AX 1203
: 0
—
В данном фрагменте мы просматриваем регистр АХ и очищаем его (пишем в него 0).
Чтобы перейти к первой выполняемой команде (по адресу CS:100):
AX=0000 BX=0000 CX=0000 DX=0000 SP=FFEE BP=0000
SI=0000 DI=0000
DS=3B9A ES=3B9A SS=3B9A CS=3B9A IP=0100 NV UP EI PL NZ NA PO NC
3B9A:0100 E82421 CALL 2227
Третья команда –E (enter) Addres
Предназначена она для изменения значений в
памяти – с помощью нее можно уже вводить команды в машинных кодах. Замечание: при вводе данных сначала пишется младший байт
(по младшему адресу), затем – старший (по старшему), т. е.
чтобы записать по адресу DS:0000 число 1234h необходимо ввести:
E DS:0000 34 12
Например введем следующее:
E cs:100 B8 34 12
-D CS:100
А с помощью команды U (unassemble)
-U CS:100,102
3B9A:0100 B83412 MOV AX,1234
Таким же образом можно дизассемблировать любой участок памяти, что очень полезно.
Но вместо ввода команд на машинном языке, можно воспользоваться встроенным
ассемблером программы DEBUG. Для этого существует команда
-A (assemble)
A
0B3B:0100 mov ax,1234
0B3B:0103 mov ah, 4c
0B3B:0105 int 21
0B3B:0107
Затем в регистр СХ необходимо поместить размер программы в байтах. Он будет равен разности конечного и начального смещений. Теперь остается только осуществить запись на диск командой W и в результате увидеть записанное количество байтов. В итоге мы получаем программу, готовую к исполнению. Выход осуществляется командой q. Пример:
A
0B3B:0100 mov ax,1234
0B3B:0103 mov ah, 4c
0B3B:0105 int 21
0B3B:0107
-u CS:100, 106
0B3B:0103 B44C MOV AH,4C
0B3B:0105 CD21 INT 21
-r cx
CX 0000
:7
-r
AX=0000 BX=0000 CX=0007 DX=0000 SP=FFEE BP=0000 SI=0000 DI=0000
DS=0B3B ES=0B3B SS=0B3B CS=0B3B IP=0100 NV UP EI PL NZ NA PO NC
0B3B:0100 B83412 MOV AX,1234
-N my.com
-W
Запись 00007 байт
-q
В заключение можно сказать, что данный способ создания программ открывает новые возможности для любителей компьютерных пакостей, приколов, да и просто программистов-любителей – ведь теперь для создания небольших программ, вместо установки компиляторов, можно воспользоваться стандартными средствами системы, а DEBUG входит в поставку во все Винды вплоть до ХР. Я думаю, что это поможет вам веселее провести время за чужим компом, вызывая истинное удивление хозяина (дисков и дискет-то вы не приносили!!!) новыми эффектами работы его оборудования. Успехов, юные любители хакерного экстрима!
Лабораторная работа
"Изучение команд отладчика DEBUG"
Отладчик DEBUG предназначен для решения широкого круга задач. К ним относятся, например следующие задачи:
Изучение текущего содержимого оперативной памяти;
Редактирование отдельных секторов на флоппи-дисках и на винчестере;
Дизассемблирование.COM -файлов;
Разработка и отладка собственных программ на языке ассемблера;
Изучение работы программ и их модификация;
Тестирование периферийного оборудования для работы с портами ввода /вывода напрямую (в диалоговом режиме);
Изучение системы команд процессора, прерываний BIOS и MS-DOS.
При изучении схемотехники PC/AT необходим инструмент, позволяющий напрямую работать с периферийными портами и оперативной памятью, а также создавать короткие тестовые программы для генерации нужных сигналов на системной плате периферийных адаптерах. Отладчик наилучшим образом подходит для этих целей.
В версии MS-DOS 6.22 размер отладчика составляет 15718 байт. Существует два способа запуска отладчика: debug ENTER и debug filename ENTER. После запуска отладчика загружается в оперативную память, а содержимое сегментных регистров CS, DS, ES, SS на первый свободный параграф сразу после самого отладчика. Регистр IP устанавливается равным 100.
Отладчик DEBAG имеет специальный указатель адреса данных, который использует по умолчанию во многих командах отладчика.
После запуска отладчика слева на экране появляется черта (-) ,которая указывает на то, что отладчик ждёт команду. Все числа интерпретируются отладчиком в шестнадцатиричной системе исчисления.
Для исполнения любой команды надо нажать клавишу "Enter".
Рассмотрим непосредственно команды отладчика DEBUG .
А-команда ассемблирования(ASSEMBLE).
Эта команда позволяет вводить программы с использованием мнемкода команд процессора в оперативную память. Ввод команды отладчика
А < число >
заставляет его перейти в режим приема команд с клавиатуры и последовательного размещения их, начиная с адреса,равному указанному в команде. При вводе можно использовать две популярные инструкции ассемблера DB и DW . Например,
DB 1 , 2 ,3 ,"example"
DW 1000,2000,"FFFF"
Отладчик поддерживает мнемоники всех команд процессора 80286. .При ассемблировании команд JMP CALL по умолчанию, если это возможно, используется SHORT-вариант этих команд, но можно указывать перед адресом переход NEAR и FAR, что приведет к генерации соответствующих команд.
Сначала наберите A 100 ,затем введите программу
Выход из режима ввода программы осуществляется нажатием клавиши ENTER после перехода к пустой строке вслед за последней командой программы.
В данном примере показан метод организации задержки путем "прокрутки" двух циклов. Запустить эту программу можно, набрав команду
Здесь приведена программа забивки экрана символом "!"
Затем надо ввести программу
В конце программы в этих примерах стоит команда INT 20, обеспечивающая возврат управления обратно на монитор команд отладчика. Запуск этой программы осуществляется по команде G =100
MOV AX,21 ;Запись значения 21H в регистр AX
MOV AX, ;запись в АХ содержимого ячейки памяти с адресом 21H
С-сравнение(COMPARE).
Эта команда сравнивает побайтно две области памяти и печатает все различия между ними в форме
<адрес> <содержимое> <содержимое> <адрес>
В данной записи слева приведена информация о первой области памяти, а справа - о второй.
Сравнить два блока длиной 256 байт.Первый начинается с адреса 100, а второй - с 300.Для этого надо набрать
Другой вариант той же команды
Сравнить первые 100 -16 байт оперативной памяти с последними
C 0:0L100 F000:FF00
Эта команда может быть полезна, например, при проверке на идентичность двух дискетт. Для этого в соседние области памяти погружаются интересующие нас соответствующие блоки этих дискетт,которые затем анализируются командой С.
D-вывод на экран содержимого памяти (DUMP).
Эта команда даёт на дисплее коды из указанной области оперативной памяти, представляемых в шестнадцатиричной системе исчисления, а справа их представление в ASCII-символах. Кодовые комбинации, не имеющие символьного представления в стандарте ASCII, отображаются точками.
В строке умещается 16 байт, при этом справа указывается полный адрес самого левого байта. Таким образом, в одной строке приводится шестнадцатиричный дамп, а также ASCII-дамп шестнадцати байт оперативной памяти.
Если команда D дана без параметров, то всего на экране отображается 128 байт (80H) в восьми строках. В каждой строке имеется знак "-", разделяющий 16 байт пополам - между 8-ым и 9-ым байтами.
Для того, чтобы просмотреть указатели-вектора первых тридцати двух прерываний (20Н),надо ввести команду
Другой вариант без указания диапазона
Первые четыре байта дают вектор прерывания INT0 ,следующие четыре
Просмотр последних шестнадцати байт из ПЗУ:
Просмотр области оперативной памяти, используемой BIOS:
Если периодически несколько раз повторять эту команду, то при сравнении исходной и последующих распечаток имеются изменения в некоторых местах, в частности, происходит увеличение содержимого четверки байт начинающихся с адреса 40:006C. Дело в том,что именно по этому адресу хранится четырехбайтных счетчик системных часов.
Е- команда изменения содержимое памяти (ENTER) .
Ввод команды:
E <адрес>
Вызывает переход отладчика в режим редактирования отдельных байт. При этом печатается содержимое байта в шестнадцатиричной форме, за которым следует точка. После этого можно набрать величину нового содержимого байта, но можно и оставить содержимое байта прежним, не набирая ничего.
Затем необходимо набрать один из трех управляющих символов:
1)"пробел" - означает переход к редактированию следующего байта,
2)"ENTER". Это приведет к выходу из режима побайтного редактированию на командный уровень отладчика,
3)"-" . Нажатие этого знака приведет к переходу на редактирования предыдущего байта.
Изменим значение счетчика системных часов. Введем команду
И наберем четыре числа 70 70 70 70 , разделенных пробелами, затем символ возврата каретки. Далее необходимо выйти из отладчика и выполнить команду time операционной системы DOS.
F-команда заполнения (FILL).
Эта команда позволяет заполнить содержимое указанного диапазона оперативной памяти повторяющейся цепочкой байтов заданными значениями. В частности, когда цепочка состоит из одного байта, эта команда позволяет обнулить нужную область памяти, когда байт равен 0, а также занести во все биты единицу, заполняя байтом равным FF.
Команда имеет следующий синтаксис -
F<диапазон_памяти> <цепочка_байтов >
F 5000L1000 00FF
Заполнит отрезок памяти длиной 4096 байт (1000Н) повторяющейся парой байтов 00 FF , начиная с адреса
G- команда запуска программы (GO).
Эта команда предназначена для запуска программы на исполнение. При этом, если той области памяти, где хранятся данные, передается управление как программе, компьютер требует его повторный запуск. В случае, когда в программе имеются серьезные ошибки, попытка исполнить ее с помощью оператора G также приводит к зависанию компьютера.
Этот оператор используется в одной из следующих четырех форм:
Исполнение этого оператора сводится к передаче управления адресу CS:IP.
б)G= < адрес >
При этом производится запуск программы с указанного адреса.
Например, оператор
Приводит к запуску процедуры POST (программа самодиагностики ЭВМ
в) G < адрес >
В этом случае программа запускается с адреса CS:IP и при достижении команды с указанным адресом осуществляется останов (BREAK) исполнения программы. Распространенной ошибкой является пропуск знака равенства (=) при использовании команды G. В этом случае указанный адрес воспринимается как адрес останова, и если CS:IP указывает, например, на область данных, то компьютер "зависнет".
г) G=<адрес > <другой _адрес>
В этом случае производится запуск программы с указанного после знака = адреса в случае достижения программой команды с величиной адреса, указанного вторым (др. адрес), происходит останов.
Такой способ останова программы называется введением контрольной точки останова. При указании контрольной точки останова соответствующий байт команды по этому адресу заменяется командой INT3, имеет размер 1 байт. При достижении контрольной точки исходное значение байта восстанавливается.
Н- команда шестнадцатиричной арифметики (HEXARITHMETIC).
Эта команда позволяет получить сумму и разность указанных в команде шестнадцатиричных чисел.
Получаем 02A9 (сумма) и 0095 (разность).
I- команда ввода из порта (INPUT). Эта команда позволяет прочесть содержимое порта ввода с указанным адресом и вывести его на экран в шестнадцатиричном виде.
Синтаксис команды:
I<адрес порта>
Эта команда даст состояние младшего байта счетчика системных часов. Исполнение команды I42 , с её повторением даст нам младший и старший байты счетчика, связанного с динамиком.
N-команда указания имени (NAME).
В этой команде задаётся имя файла, который далее будет считываться с диска командой L, либо записываться на диск командой W.
Синтаксис этой команды следующий:
N <имя_файла >
Прочтем с диска в оперативную память файл TEST.COM. Для этого выполним
В регистровую пару BX:CX, будет занесена длина загруженного файла в байтах.
L-команда загрузки с диска (LOAD).
Эта команда позволяет загружать как логические сектора с флоппи-дисков и винчестеров, так и отдельные файлы
L<адрес> <номер_диска> <начальный_сектор> <число_секторов >
Здесь "адрес" означает начальный адрес в оперативной памяти, начиная с которого будет последовательно размещаться содержимое блоков-секторов. Переменная "номер диска" указывает с какого диска будет производится загрузка. Число 0 означает диск А, число 1-диск В, число 2- диск С и т.д. Следующие две переменные указывают с какого сектора начинается чтение и общее число прочитанных секторов.
Загрузить ВООТ-блок с флоппи-диска А, в оперативную память, начиная с с адреса DS:1000, для чего необходимо выполнить команду
Затем содержимое ВООТ-блока можно просмотреть на экране командой
А также дизассемблировать.
М-команда копирования содержимого части оперативной памяти (MOVE).
Синтаксис команды следующий
М<диапазон > <начальный_адрес>
Здесь "диапазон" указывает на копируемую область памяти, а "начальный адрес " - на адрес первого байта, начиная с которого размещаются скопированные данные. Эту команду можно использовать для временного хранения содержимого оперативной памяти с ее последующим восстановлением.
В начале рассмотрим содержимое памяти:
Затем сохраним часть памяти
Обнулим исходное содержимое
Проверим обнуление
И наконец восстановим исходное содержимое
Эту команду можно также использовать для редактирования программ, отлаживаемых или разрабатываемых в среде отладчика. Особенно она полезна при вставке новых операторов в тело программы.
Р-высокоуровневая трассировка (PROCEED).
Эта команда также, как команда Т, предназначена для трассировки программ.
Однако, в отличие от Т трассировки, эта трассировка менее детальна. Она отслеживает досконально подпрограммы и программные прерывания, а также циклы LOOP и строковые инструкции с повторением, но как и в случае Т-трассировки после каждой инструкции печатается содержимое всех регистров и следующей исполняемой инструкции.
Синтаксис команды
Р =<адрес> <число инструкций>
Можно опустить любой из двух параметров командной строки: "адрес" и/или "число инструкций". Параметр "адрес" задает начальный адрес, начиная с которого будет производиться трассировка, а параметр "число инструкций" будет указывать общее число инструкций. Обязателен ввод символа =при указании адреса для того, чтобы не спутать адрес с числом исполняемых инструкций.
Этот тип Р-трассировки крайне полезен при изучении общей логики выполнения программы, избавляя от утомительного отслеживания деталей. При начальном изучении программы необходимо начинать именно с Р- трассировки.
Q- команда выхода из отладчика (QUIT).
Команда Q приводит к выходу из отладчика на следующий верхний уровень. При этом рабочие файлы автоматически не сохраняются.
R-команда изменения содержимого регистров (RTGISTER), просмотр значений отдельных регистров и регистра флагов с возможностью их изменения.
Дает распечатку содержимого всех регистров, а также команды, на которую указывает CS: IP
R-<имя_регистра>
Дает распечатку содержимого указанного регистра, и потом печатает двоеточие на следующей строке. Перечислим возможные имена регистров
AX, BX, CX, DX, SP, BP, SI, DI, DS, ES, SS, CS, IP, F(регистр флагов)
При исполнении команды R F надо учитывать, что кодирование значений флагов производится весьма специфическим образом. Ниже приводится таблица кодировки, где символьная пара слева соответствует значению 1 флага (флаг установлен), а справа - значению 0:
Флаг переполнения OV NV
Флаг направления DN UP
Флаг маск. прерывания EI DI
Флаг знака NG PL
Флаг нуля ZR NZ
Флаг доп. Переноса AC NA
Флаг чётности PE PO
Флаг переноса CY NC
Значение флагов печатаются в строку. Сразу же за этим в строке печатается знак черты "-" , отладчик переходит в состояние ожидания ввода с клавиатуры. Нижеприведенная команда изменяет 1,3,5 и 7-й флаги:
OV DN EI NG ZR AC PE CY - PO NZ DI NV
Порядок следования обозначений флагов и пробелы при этом не имеют значения.
S- команда поиска упорядоченного набора байтов (SEARCH).
Эта команда позволяет провести поиск указанной цепочки байт в заданном диапазоне оперативной памяти имеет синтаксис.
S <диапазон_памяти> <цепочка_байтов>
Ответ выдается в виде списка адресов, начиная с которых располагается указанная цепочка байтов.
Предположим, что мы хотим определить встречается цепочка "DOS"(коды 44 4F 53) в первых 32К оперативной памяти. Для этого необходимо ввести команду
S 0:0L8000 44 4F 53
T- команда трассировки (TRACE).
Эта команда позволяет исполнить одну или несколько инструкций в режиме трассировки c печатью содержимого всех регистров и мнемоники следующей декодированной исполняет инструкции. После трассировки текущей инструкции указатель IP сдвигается так, что он указывает на следующую инструкцию.
Команда Т
Производит трассировку одной текущей инструкции, которую указывает CS:IP с соответствующим изменением IP.
Т <число>
Производит последовательную трассировку нескольких инструкций, общее число которых задается командой.
Т=<адрес>
Трассирует одну инструкцию по указанному адресу
Общий вид команды Т следующий:
Т=<адрес><число_инструкций>
Производит трассировку первой исполняемой инструкции при начальном запуске компьютера.
U- команда дизассемблирования (UNASSEMBLE).
Эта команда позволяет дизассемблировать программы, загруженные в рабочую область отладчика
Общий синтаксис:
U<начальный_адрес > <длина>
U<начальный_адрес> <конечный_адрес>
Вызывает дизассемблирование 32 байт, начиная с байта, на который указывает CS:IP с выводом результирующего на дисплей.
Если при запуске отладчика переадресовать вывод в файл, то можно получить листинг дизассемблированной программы. При этом команду U и Q (выход из отладчика) придется набирать "вслепую" без эхо-печати на дисплее.
W-команда записи на диск (WRITE).
Эта команда позволяет записывать на диск (флоппи-диск или винчестер) в последовательные блоки указанный диапазон оперативной памяти, а также записывать в файлы.
Запись в секторы на диск производится командой
W <адрес> <номер_диска> <начальный_сектор><число_секторов>
Эта команда записывает на диск не более 80Н секторов, число секторов не более 80.
Параметр "адрес команды" означает адрес оперативной памяти, начиная с которого содержимое памяти копируется на диск.
Параметр "номер диска" указывает драйв, на который производится запись (0-диск А:, 1-диск В:)
Параметр "начальный сектор" указывает номер логического сектора, начиная с которого будет производиться загрузка образа оперативной памяти.
Параметр "число секторов" указывает общее количество записываемых на диске секторов
Запись в файл на диске производится командой W без аргументов. Однако, предварительно необходимо командой N указать имя файла, куда будет производиться запись, а также в пару регистров BX:CX занести длину записываемого файла. Начало области памяти, откуда будет производиться запись, всегда по умолчанию является байтом с адресом CS:100.
Пример записи файла на диск:
BX 0000 - это старое значение содержимого регистра
: 0 - новое значение
: А - размер файла для записи 10 байт (0АH)
W - запись файла на диск, с которого загружен Debug.exe
1. Изучить команды программы DEBUG по описанию лаб. работы.
2. Загрузить с дискеты операционную систему MS DOS 6.22 , запустить программу debug.exe и проверить действие команд с примерами, отличающимися от приведенных в описании, записать эти примеры в отчёт по лаб. работе. При проверке работы программ на ассемблере рекомендуется использовать команды T и R.
3. Загрузить два массива памяти объёмом 10 байт с адреса 100Н и 200Н одинаковыми кодами 55Н (команды F и M), изменить содержимое одной ячейки памяти и с помощью команды C определить адрес этой ячейки памяти. Все действия отразить в отчёте.
4. Составить простую программу на ассемблере с выводом кодов на дисплей (см. пример 2 в разделе команды А), записать эту программу на дискету в виде файла iit.com, (использовать команду W без параметров) выйти из программы debug в DOS и запустить её, набрав в командной строке iit.com. Проверить правильность её работы. Войти в программу debug и загрузить в неё файл iit.com и проверить правильность загрузки командой U.