Textnew2
.pdfВ самом конце прохождения программы с помощью отладчика - когда будет достигнут ее конец, на экран выдается сообщение
Program exited with code число
где параметр число есть значение, переданное в регистре ebx при вызове первой функции (функции exit) Linux..
Следует иметь в виду, что программисту предоставляется возможность установки любого нужного ему множества контрольных точек. Для этого проще всего предварительно позаботиться о расстановке (в исходном тексте программы на ассемблере) меток в соответствующих местах программы и при работе отладчика задавать команды в виде
br имя_метки
Не нужные уже метки можно удалить командой clear в виде clear имя_метки
Можно временно выключать (выводить из использования) точки приостановки с помощью команд
disable номер_точки_приостанова
а повторно (или в очередной раз) включить ее в использование с помощью команды
enable номер_точки_приостанова
Команда print (в сокращенной форме задаваемая одной буквой p) может использовать кроме формата, задаваемого символом x (вывод в шестнадцатеричной системе), еще и другие форматы типа. Они задаются символами d, u, o, t и a. Формат d выводит значение как целое со знаком в десятичной системе, формат u задает целое как беззнаковое десятичное, формат o выводит целое в восьмеричной системе счисления, а формат t - в двоичной системе. Для указания вывода в виде отдельного символа служит формат c.
Собственно аргументом команды print могут быть не только регистры, но и имена областей данных, а также адреса, задаваемые в виде шестнадцатеричных констант.
Кроме того, имеется еще более мощная возможность отображения информации, но применимая только к памяти (но не к регистрам). Это команда examine, которая обычно задается единственным начальным символом сокращенного имени - символом x.
Общая форма этой команды имеет вид x/NFU ADDR
где параметр ADDR обозначает адрес места в памяти, параметр N задает число отображаемых элементов, параметр F заказывает формат вывода, а параметр U дает размер информационной единицы. Любой из параметров N, F, U может отсутствовать, тогда берется значение, ранее использованное перед этим или значение по умолчанию (если команда еще не использовалась).
Формат задается одним символом, который либо совпадает с символами формата для команды print, либо дает один из дополнительных форматов s или i. Формат i задает вывод в виде машинных команд, изображаемых ассемблерными мнемоко-
221
дами, а формат s соответствует ASCIIZ, т.е. символьной строке, заканчивающейся нулевым кодом.
Вкачестве символов размера информационного элемента допустимо использовать символы b, h и w. Символ b обозначает байты, h обозначает полуслова (два байта), а w - слова (четыре байта) - это и есть начальное значение по умолчанию.
Для продолжения автоматического выполнения команд с текущей точки приостановки (и, обычно, до следующей встречающейся точки приостановки) служит команда отладчика continue, задаваемая обычно единственным символом c.
Универсальный символический отладчик gdb имеет еще множество возможностей, как для отладки высокоуровневых программ, так и пригодных для ассемблерных программ. В частности, он включает средства, позволяющие отлаживать многопоточные приложения и параллельные процессы. В данном пособии нет технической возможности останавливаться на них.
9.2.Отладчики текстового режима для Windows
Всвязи со сложившейся спецификой операционных систем типа Windows, ориентированных в первую очередь на неквалифицированных пользователей и, поэтому, использующих преимущественно графический интерфейс, преобладающая часть отладчиков для этих ОС обеспечивают отладку только графических приложений. В частности только этими возможностями обладают отладчики известной фирмы Borland/Inprise.
К настоящему времени отдельные самостоятельные разработчики предлагают неплохие программные продукты - не очень известные среди корпоративных пользователей, но эффективные, надежные и, главное для высшей школы, - не требующие материальных затрат на их приобретение. В качестве такого программного инструмента рассмотрим отладчик OllyDbg, разработанный Oleh Yuschuk и доступный по электронному адресу на Internet сайте http://home.t-online.de/home/Ollydbg.
Отладчик OllyDbg, версию 1.09 которого мы рассматриваем, есть 32-битный отладчик ассемблерного уровня с внутренними средствами анализа кода для Microsoft Windows(R). Он не требует инсталляции и для использования его программные компоненты нужно просто поместить в отдельное оглавление. Данный отладчик представляет собой свободно распространяемое программное обеспечение (shareware) с авторскими правами - Copyright (C) 2000-2003 Oleh Yuschuk.
Имя исполняемого файла отладчика - OLLYDBG.EXE, по которому его и следует запускать. Имя исполняемого файла отлаживаемой программы может задаваться как аргумент строки вызова отладчика. Отладчик имеет очень широкие возможности, в том числе отладку графических приложений и библиотек динамической компоновки. Поэтому его пользовательский интерфейс основан на графическом окне приложения (а не текстовом окне, как ранее рассмотренный отладчики gdb для Linux).
Практически более удобно запускать отладчик из его собственного оглавления, как текущего при таком запуске (или с помощью ярлыка). Причем, запускать без
222
аргумента - имени исполняемого файла, а исполняемый файл задавать с помощью меню отладчика. Именно, после начального запуска программы OLLYDBG.EXE следует использовать раздел File в главном меню отладчика и пункт Open этого раздела для задания через диалоговую панель имени исполняемого файла - в любом желаемом оглавлении.
Основная информация, предоставляемая разработчику отладчиком, размещается в нескольких панелях основного окна отладчика. Основной панелью является панель, называемая окно CPU, которая предоставляет дизассемблированный текст исполняемого файла.
Работа отладчика OllyDbg управляется с помощью мыши и (или) с помощью клавиатуры, в частности управляющих комбинация "горячих" клавиш.
Точки приостановки (контрольные точки) устанавливаются выбором требуемой строки дизассемблированного текста в окне CPU и нажатием клавиши F2, причем эта клавиша действует как переключатель установки контрольной точки - повторное нажатие этой клавиши на строке с уже установленной контрольной точкой выключает ее (контрольная точка на данной строке изчезает).
Для удобства демонстрации конкретных средств отладки в качестве опорного примера возмем программу, приведенную на рис. 9.2.1.
; Вывод десятичного значения содержимого EAX в MS Windows EXTERN GetStdHandle, WriteFile, ExitProcess
SEGMENT CODE USE32 CLASS=CODE
..start:
push dword STD_OUTPUT_HANDLE call GetStdHandle
mov [hstdout],eax mov eax, 1000h
mov esi,10 ; base of position digit system mov ecx, 0 ; reset digit counter
pov: |
mov edx, 0 ; null into left part of devident |
|
div esi |
; divide for next digit = rest |
|
add dl, '0' |
|
|
push edx |
|
|
inc ecx |
; step into counter |
|
cmp eax, 0 |
|
jne pov
mov [cnt], ecx mov ebx, numtxt
izv: pop edx
mov byte [ebx],dl ; digit into array for text value inc ebx
loop izv ; izv,ecx
;--- WriteFile(hstdout, txt, 7, &actlen, NULL)
223
push dword 0 push dword actlen
push dword [cnt] ; number of bytes push dword numtxt ; address of txt push dword [hstdout] ; N handle=hstdout call WriteFile
; ExitProcess(0) push dword 0 call ExitProcess
SEGMENT DATA USE32 CLASS=DATA
numtxt times 10 db 0 ; may be <resb 10> but then - warning! cntdd 0
hstdout dd 0 actlen dd 0
STD_OUTPUT_HANDLE equ -11
Рис. 9.2.1. Пример программы PRIM4.asm для отладки
После запуска под отладчиком исполняемого файла, полученного ассемблированием и компоновкой (с помощью компоновщика TLINK32) программы с рис. 9.2.1, в панели CPU отладчика можно наблюдать следующий текст, приведенный на рис. 9.2.2.
00401000 |
|
68 F5FFFFFF |
PUSH |
-0B |
; DevType = |
|
STD_OUTPUT_HANDLE |
|
|
|
|
||
00401005 |
|
E8 62000000 |
CALL |
<JMP.&Kernel32.GetStdHandle> |
||
; GetStdHandle |
|
|
|
|
|
|
0040100A A3 0E204000 |
MOV DWORD PTR DS:[40200E],EAX |
|
||||
0040100F |
|
B8 00100000 |
MOV EAX,1000 |
|
||
00401014 |
|
BE 0A000000 |
MOV ESI,0A |
|
||
00401019 |
|
B9 00000000 |
MOV ECX,0 |
|
||
0040101E BA 00000000 |
MOV EDX,0 |
|
|
|||
00401023 |
|
F7F6 |
|
DIV ESI |
|
|
00401025 |
80C2 30 |
ADD DL,30 |
|
|
|
|
00401028 |
|
52 |
|
PUSH EDX |
|
|
00401029 |
|
41 |
|
INC ECX |
|
|
0040102A |
|
3D 00000000 |
CMP EAX,0 |
|
|
|
0040102F |
|
75 ED |
|
JNZ SHORT PRW.0040101E |
|
|
00401031 |
|
890D 0A204000 MOV DWORD PTR DS:[40200A],ECX |
||||
00401037 |
|
BB 00204000 |
MOV EBX,PRW.00402000 |
|
||
0040103C |
|
5A |
|
POP EDX |
|
|
0040103D |
|
8813 |
|
MOV BYTE PTR DS:[EBX],DL |
|
|
0040103F |
|
43 |
|
INC EBX |
|
|
00401040 |
|
E2 FA |
|
LOOPD SHORT PRW.0040103C |
|
224
00401042 |
68 00000000 |
PUSH 0 |
|
; |
|
pOverlapped = NULL |
|
|
|
|
|
00401047 |
68 12204000 |
PUSH PRW.00402012 |
|
; |
|
pBytesWritten = PRW.00402012 |
|
|
|
|
|
0040104C |
FF35 0A204000 PUSH DWORD PTR DS:[40200A] |
|
; |
||
nBytesToWrite = 0 |
|
|
|
|
|
00401052 |
68 00204000 |
PUSH PRW.00402000 |
|
; |
Buffer = |
PRW.00402000 |
|
|
|
|
|
00401057 |
FF35 0E204000 PUSH DWORD PTR DS:[40200E] |
|
; File |
||
= NULL |
|
|
|
|
|
0040105D E8 10000000 CALL <JMP.&Kernel32.WriteFile> |
; WriteFile |
||||
00401062 |
68 00000000 |
PUSH 0 |
|
; ExitCode = |
|
0 |
|
|
|
|
|
00401067 |
E8 0C000000 |
CALL <JMP.&Kernel32.ExitProcess> |
; |
||
ExitProcess |
|
|
|
|
|
0040106C |
$-FF25 38304000 JMP DWORD PTR DS:[<&Kernel32.GetStdHandl> |
||||
00401072 |
$-FF25 3C304000 JMP DWORD PTR DS:[<&Kernel32.WriteFile>] |
||||
00401078 |
.-FF25 40304000 JMP DWORD PTR DS:[<&Kernel32.ExitProcess> |
||||
|
Рис. 9.2.2. Содержимое окна CPU отладчика для примера, |
|
|
||
|
полученного компоновщиком TLINK32 |
|
|
|
При использовании компоновщика ALINK получается несколько иной исполняемый код, представленный на рис. 9.2.3.
00401000 |
|
68 F5FFFFFF PUSH -0B |
||
00401005 |
|
E8 F61F0000 |
CALL <JMP.&kernel32.GetStdHandle> |
|
0040100A |
|
A3 0E204000 |
MOV DWORD PTR DS:[40200E],EAX |
|
0040100F |
|
B8 00100000 MOV EAX,1000 |
||
00401014 |
|
BE 0A000000 MOV ESI,0A |
||
00401019 |
|
B9 00000000 MOV ECX,0 |
||
0040101E |
|
BA 00000000 |
MOV EDX,0 |
|
00401023 |
|
F7F6 |
|
DIV ESI |
0040102580C2 30 |
ADD DL,30 |
|
||
00401028 |
|
52 |
|
PUSH EDX |
00401029 |
41 |
INC ECX |
|
|
0040102A |
|
3D 00000000 |
CMP EAX,0 |
|
0040102F |
|
75 ED |
|
JNZ SHORT PR.0040101E |
00401031 |
|
890D 0A204000 MOV DWORD PTR DS:[40200A],ECX |
||
00401037 |
BB 00204000 |
MOV EBX,PR.00402000 |
||
0040103C |
|
5A |
|
POP EDX |
0040103D |
|
8813 |
|
MOV BYTE PTR DS:[EBX],DL |
0040103F |
|
43 |
|
INC EBX |
225
00401040 |
E2 FA |
LOOPD SHORT PR.0040103C |
|
0040104268 00000000 PUSH 0 |
|
|
|
00401047 |
68 12204000 |
|
PUSH PR.00402012 |
0040104C |
FF35 0A204000 |
PUSH DWORD PTR DS:[40200A] |
|
00401052 |
68 00204000 |
|
PUSH PR.00402000 |
00401057 |
FF35 0E204000 |
PUSH DWORD PTR DS:[40200E] |
|
0040105D |
E8 A41F0000 |
|
CALL <JMP.&kernel32.WriteFile> |
00401062 |
68 00000000 |
PUSH 0 |
|
00401067 |
E8 A01F0000 |
|
CALL <JMP.&kernel32.ExitProcess> |
0040106C |
0000 |
|
|
далее идут нулевые коды - не используемые программой.
Рис. 9.2.3. Содержимое окна CPU отладчика для примера,
полученного компоновщиком ALINK
Различия наблюдаемых исполняемых кодов связаны с теми частями наблюдаемых в отладчике кодов, которые не были явно заданы исходной программой, а обусловленны дополнительными построениями исполняемого файла по объектному. Эти построения - по месту размещения в памяти - отличаться для различных компоновшиков.
Заметим, что окно дизассемблирования CPU состоит из четырех столбцов. В первом из них для каждой строки приводится (виртуальный) адрес, с которого размещается содержимое этой строки при выполнении программы. Во втором столбце приводится шестнадцатеричный код содержимого этой строки, в третьем - дизассемблированное содержимое, записанное с помощью мнемокодов команд, обозначений регистров и вспомогательных операндов ассемблера. Кроме того, в этой же строке для операндов, задающих места переходов или вызываемых подпрограмм, в угловых скобках приведены обозначения соответствующих исполняемых файлов и имена доступных извне меток или подпрограмм в этих исполняемых файлах. В частности, в нашем примере для обращения к функциям API, находящимся в DLL библиотеки KERNEL32, используются программные переходники, которые представляют собой обращения по командам CALL к командам-переходникам в конце исполняемого кода. Эти команды-переходники являются, в свою очередь, косвенными безусловными переходами, которые осуществляют переходы по адресам, записанных в специальные поля и обеспечивающие действительные переходы на требуемые системные функции. (Тем самым, в реализацию пожеланий исходной программы система разработки вносит свои изменения - вместо прямых обращений к системным функциям используются упомянутые переходники.)
Для варианта, который использует компоновщик TLINK32, эти программные переходники размещаются сразу за основным исходным кодом - по адресам памяти с 0040106C по 0040107B. Для варианта, который использует компоновщик ALINK, такие программные переходники размещаются в другом месте, а именно (для данного примера) по адресами памяти с 00403000 по 0040300F и могут быть наблюдае-
226
мы в окне отладчика, когда при выполнении программы к ним осуществляется переход с помощью соответствующей директивы этого отладчика. Такой директивой может быть как покомандное выполнение (Step into в меню Debug отладчика или клавищей F7), либо же через контекстное меню при выделенной строке окна COU отладчика, которая обеспечивает переход на такой переходник (в нашем примере это вторая строка рассмотреннго исходного содержимого программы в указанном окне).
Для варианта компоновки ALINK коды указанных переходников отображаются в виде следующих строк
00403000 -FF25 48404000 JMP DWORD PTR DS:[<&kernel32.GetStdHandl>]
00403006 -FF25 4C404000 JMP DWORD PTR DS:[<&kernel32.WriteFile>]
0040300C -FF25 50404000 JMP DWORD PTR DS:[<&kernel32.ExitProcess>]
Последняя колонка панели CPU содержит пояснения, помогающие разработчику понять, что делает команда в рассматриваемой строке. Эти пояснения могут быть системным обозначением константы, используемой в команде строки, либо комментариями к используемым действиям и вызовам.
Для выполнения программы в пошаговом режиме служат клавиши F7 и F8. Первая из них задает пошаговое исполнение с пошаговым вхождением и выполнением вызываемых подпрограмм. Клавиша F8 задает пошаговый режим только для текущей программы (подпрограммы), при этом выполнение всех вызываемых подпрограмм осуществляется автоматически до момента выхода из них, так что отлаживаемые действия приостанавливаются на следующей за вызовом команде. Автоматическое выполнение программы задается клавишей F9, при этом выполнение происходит до первой встретившейся контрольной точки, до системного вызова, следствием которого является ожидание события (например, ввод данных) или завершения программы. Повторный запуск программы осуществляется горячей клавишей Ctrl-F2.
Текущее значение данных в рассматриваемый момент отладки программы можно получить из двух панелей отладчика: окна Register и окна Dump. Первое из них отображает текущие значения всех регистров, а окно предназначено для отображения участка памяти. Кроме того, при отладке в последнем столбце панели CPU в ряде случаев появляется поясняющая информация о данных, полученных в результате выполнения очередной команды.
Так при отладки рассматриваемой программы после второго прохождения команды в строке с адресом 0040103D (которая заносит код очередной цифры в область данных исходного кода с именем numtxt), в последнем столбце появляется примечание ASCII "40". (Сама эта команда дизассемблирована в окне CPU как MOV BYTE PTR DS:[EBX],DL. Примечение же появляется в другой строке, с действием которой это примечение прямо не связано.) Это примечание при очередном прохождении той же строки исходной команды
mov byte [ebx],dl
227
преобразуется в ASCII "409", при последующем прохождении - в ASCII "4096". Все это помогает разработчику быстро разобраться с формируемыми данными.
Отладчик OllyDbg имеет множество возможностей, познакомиться с которыми можно через его справочную систему. Уточним еще раз, что этот отладчик охватывает гораздо более широкий круг проблем отладки, чем требуется для простого программирования на ассемблере.
ЛИТЕРАТУРА (БИБЛИОГРАФИЧЕСКИЙ СПИСОК)
1.Абель П. Язык Ассемблера для IBM PC и программирования. -М.: Высшая школа. 1992. -447с.
2.Брэдли Д. Программирование на языке ассемблера для персональной ЭВМ фирмы IBM. -М.: Радио и связь, 1988. -448с.
3.Гордеев А.В., Молчанов А.Ю. Системное программное обеспечение. - СПб.: Питер, 2001. -736 с.
4.Данкан Р. Профессиональная работа в MS-DOS. - М.: Мир, 1993. -509 с.
5.Зубков С.В. Ассемблер для DOS, Windows и UNIX. - М.: ДМК Пресс, 2000.
6.Использование Turbo Assembler при разработке программ. - Киев: Диалектика, 1994. -288 с.
7.Нортон П., Соухэ Д. Язык ассемблера для IBM PC. -М.: Компьютер, 1993. -352с.
8.Рудаков П.И., Финогенов К.Г. Программируем на языке ассемблера IBM PC. -Об- нинск: Изд-во "Принтер", 1997. -584 с.
9.Рудаков П.И., Финогенов К.Г. Язык ассемблера: уроки программирования. - М.: ДИАЛОГ-МИФИ, 2001. -640 с.
10.Сван Т. Освоение Turbo Assembler. - Киев: Диалектика, 1996. -544 с.
11.Скэнлон Л. Персональные ЭВМ IBM PC и XT. Программирование на языке ассемблера. -М.: Радио и связь, 1989. -336с.
12.Финогенов К.Г. Справочник по системным функциям MS-DOS. М.: Радио и связь. Энтроп. 1995. -382с.
13.Финогенов К.Г. Основы языка ассемблера. - М.: Радио и связь, 1999. -288 с.
14.Флоренсов А.Н. Введение в системное программирование на основе 16-битных компьютеров типа IBM PC: Учеб. пос. - Омск, Изд-во ОмГТУ, 1996. -108 с.
15.Флоренсов А.Н. Введение в системное программирование для 32-разрядных компьютеров: Учеб. пос. - Омск, Изд-во ОмГТУ, 1998. -144 с.
16.Флоренсов А.Н. Системное программирование в многозадачных ОС. Семантический подход: Учеб. пос. - Омск, Изд-во ОмГТУ, 2000. -96 с.
17.Юров В. Assembler. - СПб.: Питер, 2000. - с.
18.Юров В. Ассемблер: практикум. - СПб.: Питер, 2001. - 400 с.
19.Юров В. Assembler: Специальный справочник. - СПб.: Питер, 200.
20.Юров В., Хорошенко С. Ассемблер: учебный курс. -СПб: Изд-во Питер, 1999. -672 с.
228
21.Кулаков В. Программирование на аппаратном уровне. Специальный справочник. -СПб.: Питер, 2001. -496 с.
22.http://www.phoenix.gb.net
ОГЛАВЛЕНИЕ
ВВЕДЕНИЕ...........................................................................................................................
.........
1.ОСНОВЫ ПРОГРАММИРОВАНИЯ НА ЯЗЫКАХ АССЕМБЛЕ-
РА ........................................
1.1. Общие принципы построения ассемблерных про-
грамм .......................................................
1.2. Понятие архитектуры компьютера............................................................
1.3. Регистры программиста в IA32 .................................................
1.4. Описание сегментной структуры программы .............................
2. ПРОСТЕЙШИЕ СРЕДСТВА АССЕМБЛЕРНЫХ ПРО-
ГРАММ ..................................................
2.1. Простейшие средства описания данных в ассемблерных програм-
мах ...........................
2.2. Обращения к функциям ОС посредством программных прерыва-
ний ..............................
2.3. Средства преобразования исходного текста в исполняемый
файл.........................
2.4. Управление строками при выводе и ввода данных .................................
2.5. Простейшие способы адресации ................
3. АРХИТЕКТУРНЫЕ ЭЛЕМЕНТЫ ДЛЯ ПОСТРОЕНИЯ ПРО-
ГРАММ .....................................
3.1. Организация условных перехо-
дов ..........................................................................................
3.2.Средства организации циклов .......................
3.3.Особенности команд умножения и деления..................................
3.4.Организация процедур ......................................................
3.5.Неарифметические операции над кодами......................................
4.ИСПОЛЬЗОВАНИЕ НЕЭЛЕМЕНТАРНЫХ СПОСОБОВ АДРЕСАЦИИ
4.1.Косвенно регистровая адресация и ее использование .................................
4.2.Использование индексной адресации данных ..........
4.3.Базовая и индексно базовая адресация ......................
4.4.Адресация с масштабированием ................................
5.ВЗАИМОДЕЙСТВИЕ МЕЖДУ ПРОГРАММНЫМИ ЕДИНИЦАМИ .......
229
5.1. Многомодульная разработка программ ..................................................................
5.2. Использование библиотек объектных модулей ...............
5.3. Организация стекового кадра подпрограммы ...............
5.4. Программный доступ к системным функциям MS Windows ................................
5.5. Особенности использования объектных файлов формата COFF ...........
5.6. Стандартный доступ к системным функциям Unix ...............................
6. ВСПОМОГАТЕЛЬНЫЕ СРЕДСТВА БАЗОВОЙ АРХИТЕКТУ-
РЫ .....................................
6.1. Использование строковых команд пересыл-
ки ...........................................................................
6.2. Применение строковых команд сравне-
ния ................................................................................
6.3. Лексический анализ символов на основе команды
XLAT .....................................................
6.4. Построение переключателей на основе косвенной адреса-
ции ...............................................
6.5. Программирование на стандартном ассемблере
AT&T ......................................................
7.ИСПОЛЬЗОВАНИЕ СИСТЕМНЫХ СРЕДСТВ АРХИТЕКТУРЫ ......
7.1.Состав системных средств ....................
7.2.Обработчики программных прерываний в MS-DOS .....
7.3.Особенности обработчиков аппаратных прерываний ...............
7.4.Обработка прерываний внесистемной программой реального режима...............
7.5.Построение программ защищенного режима ...............
7.6.Обработка прерываний в защищенном режиме ...............
7.7.Построение простейщего начального загрузчика ..............
8.БИБЛИОТЕКИ ДИНАМИЧЕСКОЙ КОМПАНОВКИ .........................
8.1.Понятие о статической и динамической компоновке .................
8.2.Динамическая компоновка времени загрузки .....................
8.3.Использование объектных модулей формата PE ...............
8.4.Динамическая компоновка времени выполнения ............
8.5.Использование процедур инициализации и завершения DLL ....
9.ИСПОЛЬЗОВАНИЕ ОТЛАДЧИКОВ ДЛЯ АССЕМБЛЕРНЫХ ПРОГРАММ..........
9.1.Особенности отладчика gdb для ассемблерных программ в
Linux .................................
9.2. Отладчики текстового режима для Windows .....................................................
Литература....................................................................................................
230