Сейчас на форуме: (+7 невидимых) |
![]() |
eXeL@B —› Вопросы новичков —› OllyDbg и Unknown commands |
Посл.ответ | Сообщение |
|
Создано: 15 сентября 2014 00:35 · Личное сообщение · #1 Приветствую. В отлаживаемом при помощи OllyDbg приложении есть несколько мест в дизассемблированном коде, которые не могут корректно отобразиться (OllyDbg выводит вместо них "???" в колонке "Disassembly" и "Unknown command" в колонке "Comment"). Отключение анализа ("Analysis" -> "Remove analysis from module" ) "превращает" эти строчки в "DB 66", "DB 0F" и т.д. Первый вопрос -- это баг / особенность OllyDbg или признак того, что исполняемый файл чем-то запакован? Если первое, то как его можно исправить и можно ли вообще (где-то встречал мнение, что это исправляет плагин phant0m, но включение в нём опции "fix OllyDbg bugs" не помогло)? Если второе, то почему тогда имеется возможность смотреть практически весь остальной диассемблированный код? В общем, смотрим дальше. Если заставить OllyDbg пробежаться по процедуре, которая содержит эти самые "неизвестные комманды", при помощи F7 - F8 хотя бы раз (для этого я включил опцию "Allow stepping into unknown commands"), то приложение ведёт себя так, как ожидается даже во все последующие обращения к данной процедуре. Да, необходимо использовать именно F7 - F8, т.к. в случае F9 эффект различается (например, после вызова процедуры в регистрах содержатся совершенно другие значения). Что самое интересное -- то, что получается в результате "забега" при помощи F7 - F8 -- как раз то поведение, которого я пытаюсь добиться, но почему оно работает именно в таком случае -- понять не могу никак. Можно было бы предположить, что именно в этом месте приложение проверяет наличие отладчика в системе и завершает выполнение процедуры, если его нет, но такое решение звучит очень странно, логичнее уж было делать наоборот. Что это может быть? Является ли подобное поведение какой-то известной Вам техникой защиты исполняемого файла или чем-то ещё? Встречались ли Вы с чем-то подобным? Заранее благодарю за возможные ответы. ![]() |
|
Создано: 15 сентября 2014 00:50 · Поправил: unknownproject · Личное сообщение · #2 |
|
Создано: 15 сентября 2014 00:56 · Личное сообщение · #3 |
|
Создано: 15 сентября 2014 01:24 · Поправил: unknownproject · Личное сообщение · #4 |
|
Создано: 15 сентября 2014 01:30 · Личное сообщение · #5 |
|
Создано: 15 сентября 2014 02:05 · Поправил: unknownproject · Личное сообщение · #6 b0r3d0m пишет: Хорошо, а как тогда хотя бы примерно можно объяснить поведение, описанное мной после этого? Похоже ли это на что-то, с чем Вы имели дело? ПО сути да.Вы поставили опцию, благодаря которой при трассировке игнорируются неизвестные команды.Так же их можно было превратить в ноп, хотя это может быть чревато, но лучше всего их пропускать.Если настройки отладчика не срабатывают, а такое бывает и очень часто, то находите эту неизвестную команду по ее адресу и ставите New origin после нее, т.е активной станет другая команда, которую требуется выполнить. ----- TEST YOUR MIGHT ![]() |
|
Создано: 15 сентября 2014 02:15 · Личное сообщение · #7 Хорошо, но самое странное то, что без отладчика приложение ведёт себя точно так же, как и в случае F9. Как можно это объяснить? Добавлено спустя 11 минут Я копнул ещё немного глубже и теперь совсем не понимаю, в чём может быть дело. Имеется код примерно следующего вида: ; ... CALL module_name.some_address TEST EAX, EAX ; ... На обе из представленных инструкций поставлены бряки. Результаты выполнения приложения отличаются в следующих ситуациях: - После бряка на CALL нажать F9 - После бряка на CALL нажать F7 и Ctrl-F9 Отличается даже содержимое регистров после вызова процедуры, вызываемой по данной инструкции CALL. Что это такое? ![]() |
|
Создано: 15 сентября 2014 02:49 · Поправил: unknownproject · Личное сообщение · #8 b0r3d0m пишет: - После бряка на CALL нажать F9 - После бряка на CALL нажать F7 и Ctrl-F9 Это связано с тем, что в первом случае Вы пропускаете выполнение функции, а во втором Вы ее выполняете покомандно, т.к. Вы трассируете внутрь нее и исполнение программы , соответственно, начинается с другого места.Отсюда и состояние регистров разное.Функция должна вернуть результат и сохранить его в соответствующие регистры. ----- TEST YOUR MIGHT ![]() |
|
Создано: 15 сентября 2014 12:38 · Личное сообщение · #9 |
|
Создано: 15 сентября 2014 13:14 · Личное сообщение · #10 |
|
Создано: 15 сентября 2014 13:33 · Личное сообщение · #11 Во-первых, спасибо большое всем, кто отвечает, для меня это очень важно. Hellspawn пишет: не пропускает функцию, а отладчик просто ждет выполнения функции/процедуры и дальнейшей остановки на бряке, который ставит сразу после CALL. Прошу прощения за непонимание, но всё же, в чём тогда принципиальная разница между F9 и Ctrl-F9 в моём случае? В официальной документации OllyDbg эффект от нажатия клавиши F9 описывается просто как "Continues program execution", а Ctrl-F9 -- "Execute till return, traces program without entering function calls or updating CPU till the next encountered return. As program is executed step-by-step, this may take some time. Press Esc to stop tracing". Не совсем понимаю, что имеется ввиду под "updating CPU", но всё остальное не выглядит каким-то уж очень странным. Или всё дело во фразе "traces program"? ![]() |
|
Создано: 15 сентября 2014 13:36 · Личное сообщение · #12 |
|
Создано: 15 сентября 2014 13:40 · Личное сообщение · #13 Hellspawn пишет: да по Ctrl-F9 оно трассирует до RET без захода в CALL А чем в моём случае пошаговое выполнение программы, которое осуществляется по нажатию Ctrl-F9, может отличаться от простого выполнения кода до бряка при помощи F9? Это разве вообще хоть на что-то может влиять, кроме скорости выполнения? ![]() |
|
Создано: 15 сентября 2014 14:16 · Личное сообщение · #14 |
|
Создано: 15 сентября 2014 14:53 · Личное сообщение · #15 Спасибо за ссылку, многие из них я уже читал. Посмотрел ещё раз и те, которые уже видел, и остальные, но ничего более подробного, чем "Ctrl-F9 выполняет код до первой встреченной инструкции RET" я так и не нашёл. Прошу прощения, не могли бы Вы привести ссылку на конкретную статью, чтобы я понял, где мне надо прочитать об этой особенности? ![]() |
|
Создано: 15 сентября 2014 16:25 · Личное сообщение · #16 |
|
Создано: 15 сентября 2014 16:32 · Поправил: b0r3d0m · Личное сообщение · #17 ClockMan пишет: Неправильно, это трассировка внутри функции CALL до выхода с неё, Спасибо за поправку. Хорошо, то, что это не выполнение кода, а его трассировка я понял (в отличие от F9, который производит лишь выполнение), но что от этого может измениться в вызываемой процедуре, ведь и то, и другое, по сути, тем или иным образом заставляет приложение выполнить данный участок кода? Первое, что я предположил -- это наличие инструкций наподобие RDTSC, которые бы смотрели на время выполнение инструкций и давали дальнейшему коду возможность вести себя по-другому, если оно трассируется при помощи того же Ctrl-F9, который, как видно из документации, выполняет инструкции довольно медленно. Как бы то ни было, в вызываемой процедуре RDTSC я не обнаружил. Чем трассировка, а не простое выполнение кода, может ещё повлиять на результат выполнения вызываемой процедуры? ![]() |
|
Создано: 15 сентября 2014 16:56 · Поправил: ClockMan · Личное сообщение · #18 b0r3d0m пишет: Чем трассировка, а не простое выполнение кода, может ещё повлиять на результат выполнения вызываемой процедуры? В функции которую мы трассируем по вызову Ctrl-F9 могут быть вложено множество CALL, с разной длиной кода. И насколько я помню для трассировки F7 используется метод INT3,для нормальной трассировки в опциях нужно зайти Debug>Use hardware breakpoints to step or trace code(поставить галочку) но для его работы нужно иметь один свободный аппаратный брекпоинт. Добавлено спустя 24 минуты Справка для ольки на Русском(работает только на ХР) ![]() Не хрена себе автодобавки сделали ![]() ![]() ![]() ![]() ----- Чтобы правильно задать вопрос, нужно знать большую часть ответа. Р.Шекли. ![]() |
|
Создано: 15 сентября 2014 17:20 · Поправил: b0r3d0m · Личное сообщение · #19 ClockMan пишет: В функции которую мы трассируем по вызову Ctrl-F9 могут быть вложено множество CALL, с разной длиной кода. Хорошо, и что? Он же их пропускает, судя по документации -- "Execute till return, traces program without entering function calls or updating CPU till the next encountered return". Я так понял, что под фразой "without entering function calls" здесь понимается аналог Step over для всех инструкций, верно? Если так, то, опять же, я полагал, что F9 сделает примерно то же самое, только не будет пошагово выполнять каждую инструкцию, а просто отдаст управление отлаживаемому приложению до следующего встреченного бряка или завершения приложения. Или в случае "without entering function calls" имеется ввиду отсутствие вызова процедур вообще, т.е. их код не будет выполнен? Если так, то звучит странно. Добавлено спустя 12 минут ClockMan пишет: И насколько я помню для трассировки F7 используется метод INT3,для нормальной трассировки в опциях нужно зайти Debug>Use hardware breakpoints to step or trace code(поставить галочку) но для его работы нужно иметь один свободный аппаратный брекпоинт А почему Вы называете это ненормальной трассировкой? Добавлено спустя 7 часов 29 минут Либо я не понимаю чего-то совсем фундаментального, либо я очень плохо изъясняю мысли. Что осталось непонятно по моей проблеме? Сможет ли кто-нибудь уделить немного своего времени, чтобы помочь мне, пожалуйста? ![]() |
|
Создано: 16 сентября 2014 05:42 · Поправил: dosprog · Личное сообщение · #20 b0r3d0m пишет: Сможет ли кто-нибудь уделить немного своего времени, чтобы помочь мне, пожалуйста? Да что тут разбираться.. Уже написали ведь: ClockMan пишет: И насколько я помню для трассировки F7 используется метод INT3,для нормальной трассировки в опциях нужно зайти Debug>Use hardware breakpoints to step or trace code(поставить галочку) но для его работы нужно иметь один свободный аппаратный брекпоинт. Установите хардверные брейкпоинты и всё. Если отладчик не смог верно проинтерпретировать опкод, значит он неверно определил его длину, а соответственно тулит инструкцию отладочного прерывания отфонаря в текущую инструкцию для исполнения, портит ей аргументы. Это же касается и Ctrl+F9. ![]() |
|
Создано: 16 сентября 2014 06:19 · Личное сообщение · #21 |
|
Создано: 16 сентября 2014 06:42 · Поправил: dosprog · Личное сообщение · #22 ClockMan пишет: Да хрен поймёшь что он вообще хочет, [...] Есть такое. Кстати, к выложенному вами ранее хелпу на русише нужен ещё файл оглавления. Иначе пользоваться тяжеловато. Вот он: ![]() ![]() |
|
Создано: 16 сентября 2014 09:17 · Поправил: b0r3d0m · Личное сообщение · #23 Ладно, забыли про "Unknown commands" -- оказалось, что дело вообще не в них. Я копнул ещё глужбе и локализовал место, где поведение различается, более детально. В общем, внутри той процедуры после всех этих "Unknown commands" есть некоторый CALL. Если поставить на него бряк и нажать F8 -- всё работает так, как ожидается. Если же нажать F9 -- нет. Что в таком случае вообще может различаться? Что там может детектиться и каким образом? Код процедуры довольно большой, поэтому выкладывать его пока не буду. Из того, что там есть -- INT 3 и LOCK INT 3, который OllyDbg помечает комментарием "Lock prefix is not allowed". Может ли из-за них наблюдаться подобная разница в поведении приложения? ClockMan пишет: Да хрен поймёшь что он вообще хочет Извиняюсь, если что-то по моим словам не понятно. Я не прошу решить задачу за меня, я лишь прошу подсказать направление мысли, в котором стоит что-то копать дальше. ClockMan пишет: может он вышел на код где детектится Virtual PC Так ведь даже если так, то почему поведение различается при нажатии F8 и F9? Ведь и в том, и в другом случае отлаживаемое приложение запущено под виртуальной машиной. ![]() |
|
Создано: 16 сентября 2014 09:26 · Личное сообщение · #24 |
![]() |
eXeL@B —› Вопросы новичков —› OllyDbg и Unknown commands |