Двойной щелчок по той или
Двойной щелчок по той или иной секции переместит указатель на то место дизассемблированного листинга, где эта секция начинается.
Делаем кликаем .data и перемещаемся вот в это место нашего листинга: .data:00403000 ; Segment type: Pure data .data:00403000 _data segment para public 'DATA' use32 .data:00403000 assume cs:_data .data:00403000 ;org 403000h .data:00403000 unk_403000 db 54h ; T ; DATA XREF: start+2B^o .data:00403001 db 79h ; y .data:00403002 db 70h ; p .data:00403003 db 65h ; e .data:00403004 db 20h ; .data:00403005 db 73h ; s .data:00403006 db 6Fh ; o .data:00403007 db 6Dh ; m .data:00403008 db 65h ; e .data:00403009 db 74h ; t .data:0040300A db 68h ; h .data:0040300B db 69h ; i .data:0040300C db 6Eh ; n .data:0040300D db 67h ; g .data:0040300E db 20h ; .data:0040300F db 3Eh ; > .data:00403010 db 20h ; .data:00403011 unk_403011 db 59h ; Y ; DATA XREF: start+6D^o .data:00403012 db 6Fh ; o .data:00403013 db 75h ; u .data:00403014 db 20h ; .data:00403015 db 74h ; t .data:00403016 db 79h ; y .data:00403017 db 70h ; p .data:00403018 db 65h ; e .data:00403019 db 64h ; d .data:0040301A db 20h ; .data:0040301B db 3Eh ; > .data:0040301C db 20h ; .data:0040301D unk_40301D db 49h ; I ; DATA XREF: start+9^o .data:0040301E db 6Eh ; n .data:0040301F db 70h ; p .data:00403020 db 75h ; u .data:00403021 db 74h ; t .data:00403022 db 20h ; .data:00403023 db 26h ; & .data:00403024 db 20h ; .data:00403025 db 4Fh ; O .data:00403026 db 75h ; u .data:00403027 db 74h ; t .data:00403028 db 70h ; p .data:00403029 db 75h ; u .data:0040302A db 74h ; t .data:0040302B db 0 ; .data:0040302C align 200h .data:0040302C _data ends .data:0040302C .data:0040302C .data:0040302C end start...
Что мы видим? Длиннющую простыню из байтов! Ида нам подсказывает, какой символ соответствует тому или иному шестнадцатеричному значению. Не нужно быть семи пядей во лбу, чтобы догадаться, что эта простыня соответствует следующему куску нашего исходника: .data
Msg1 db "Type something > " Msg2 db "You typed > " ConsoleTitle db 'Input & Output',0
Для начала рассмотрим команду display memory (отобразить память). Ее синтаксис: D[size] [address [l length]]
Если ее использовать без параметров, то просто будет отображаться следующая страница дампа. Необязательный параметр size - это размерность, в которой выводится дамп. Вот расшифровка его значений: b Byte W Word D Double Word S Short Real L Long Real T 10-Byte Real
Размерности byte, word и double word вам, конечно же, хорошо знакомы. А вот загадочные short long и 10-byte real мы рассмотрим немного позже.
Обратите внимание на то, что первый параметр (размерность) мы должны писать "в одно слово" c, собственно, самой командой "d", т.е. - "db", "dw", "dd" и т.д.
Необязательный параметр address - это адрес памяти, дамп которого вы хотите получить. Притом вовсе необязательно писать адрес цифрами - "составные" адреса сайс также принимает "за милую душу".
Таким образом, если мы введем команду: DD EIP
то увидим дамп той области памяти, в которой в настоящее время располагается секция кода нашей программы (конечно, если после всплытия отладчика на точке входа вы ничего не успели напортачить).
Если же мы начнем использовать параметр length, то данные, запрашиваемые с использованием этого параметра, начнут отображаться в командной строке. Например, команда DW EIP L 1000
выведет в командную строку 1000 байтов памяти, начиная с текущего значения регистра EIP, группированных пословно, и вы будете вынуждены несколько раз нажать на any key, прежде чем все это просмотрите. По большому секрету скажу, что нажатие на ESC сразу же прервет просмотр.
Перед тем, как мы пойдем дальше и разберемся-таки с локальными переменными – пара слов для особо продвинутых:
В защищённом режиме (или в реальном режиме с префиксами смены разрядности) базой может служить любой регистр, поэтому, если мы точно знаем состояние регистра ESP (т.е. мы точно знаем, сколько раз мы делали push, а сколько pop), то для доступа к фрейму можно использовать ESP (при этом индексы одной и той же перменной в разных местах процедуры могут отличаться из-за промежуточных push/pop). Собсно, подобного рода оптимизацией занимаются, насколько я знаю, последние версии BC и VC. А в их "асмах" появилась директива "фраме-поин-оммисинс" как раз для таких извратов и предназначенная.
Однако, здесь есть недостатки по сравнению с использованием более-менее статичного EBP, как об этом было упомянуто выше: во-первых, с [ESP] инструкции длиннее, во-вторых, нужно быть очень аккуратным в подсчёте промежуточных push/pop, чтобы верно подставлять смещение до аргумента или переменной в [ESP+xx] (а ведь есть относительно непредсказуемые инструкции вида push [esp+xxx]). Наконец, поскольку индекс xx может постоянно меняться, поэтому использовать встроенные директивы типа ARGS или даже вручную раставленные EQU становится малореальным. Поэтому возможность использования ESP в качестве базы (при ручной кодогенерации – глюкалово полное) отнюдь не умаляет полезности EBP.
Содержание раздела