Мое почтение всем. Понадобилось отладить пользовательское приложение (конкретно -- java.exe) с помощью удаленной отладки из WinDbg. Что делаю: Запускаю Java с помощью самописной программы, которая делает CreateProcess(..., CREATE_SUSPENDED, ...); и спрашивает меня, когда сделать ResumeThread. В WinDbg делаю !process, чтобы найти EPROCESS Java, затем '.process EPROCESS', '.cache forcedecodeuser' и далее bp /pEPROCESS addr (пробовал bpa virt. addr), 'g' и затем говорю своей программе, чтобы запустила основной поток Java. Беда в том, что Java отрабатывает, а точка останова -- нет. Пробовал ставить точку останова на библиотеку, которая всегда загружается, на точку входа -- тот же самый результат. В чем может быть дело? Заранее благодарен.
Попробуй так: Код (Text): .process /r/p PRC_ADDR ba e 1 CODE_ADDR Подробности http://rsdn.ru/forum/winapi/3797140.1.aspx
Ага, почитал, спасибо. Удалось добиться стабильной работы, но появилось несколько вопросов: 1. Будет ли работать 'ba e 1 /pEPROCESS'? Тогда не придется делать '.process /p/r EPROCESS', насколько я понимаю. 2. Почему не работает sxe ld:modulename? Т.к пункт 2 не работает, приходится отлавливать загрузку целевой библиотеки с помощью останова на ntdll!LdrLoadDll. но беда в том, что '!peb' показывает, что библиотека загружена, а символ все равно не виден. 'x ntdll!*' говорит: "Couldn't resolve 'x ntdll'". Кроме того, WinDbg не показывает код в точке останова, вместо него вопросы, а при попытке сделать 'Step Into' я оказываюсь в KiUserExceptionDispatcher с такой EXCEPTION_RECORD: 0x004088ec -- это адрес инструкции, на которой стояла точка останова. В общем, пока довольно странно все.
Mika0x65 может это пригодится java опенсорс, пересобири c int3 на нужной функе и отлаживай с символами
Вопросы вместо памяти WinDbg вывод в случае отсутствия подкаченных страниц на данный момент в памяти. Поэтому я и посоветовал использовать аппаратные точки останова. Символы для ntdll.dll скорее всего не загружены по той же причине: образ еще не присутствует в памяти. Во первых есть комманда .pagein Во вторых: зачем вам удалять гланды через ж0пу? Используйте user mod'ый отладчик в режиме attach'а к созданному процессу. Если вы отлаживаете удаленную машину, внедряя свою dll в запускаемый процесс, и хотите видеть символы, не перенося их на целевую машину, то используйте удаленную отладку: команда .server
0x6b65 Вот тут непонятно -- я ведь и поставил аппаратную точку останова ('ba'). Т.е. когда она сработает, код должен быть уже в памяти, т.к. он начал исполняться. Единственный вариант, когда она может сработать еще -- при чтении этой ячейки памяти, но, думаю, WinDbg отличает чтение от исполнение (хочется верить). А ректальный способ отладки связан с тем, что программа под отладчиком ведет себя не так, как без него. Кроме того, хочется научиться работать с WinDbg. Clerk Я когда-то пробовал отлаживать Java с помощью Olly 1.10. В итоге отладил из WinDbg, но в пользовательском режиме. Вроде, Olly 2.0 лучше умеет отлаживать крупные процессы, но я еще к ней не привык .
Аппаратная точка останова на исполнение срабатывает при попытке процессора исполнить код по заданному виртуальному адресу. Даже если реально указано 0, то точка сработает на попытке восполнения кода по адресу 0, даже если по этому адресу ничего не замаплено. Т.е. до его реального чтения. Поэтому ситуация вполне нормальная. Как нормально и то, что при трассировке такого кода отладчик попадает в обработчик исключений. Для того, что бы видеть тот код, который хочется отлаживать, в своей тулзе, которая создает целевой процесс, можно вызвать чтение памяти этого процесса по интересующим адресам, что бы исключение уже произошло и код был доступен из kernel mod'ного отладчика.
А, кажется, понял. Получается, что приоритет #DB выше приоритета #PF? Да, тогда действительно неприятно. Попробую исправить ситуацию с помощью .pagein для начала. Насколько я понимаю, должно помочь? Написать OpenProcess/ReadProcessMemory/etc не проблема, но, думаю, удобнее решать такие вопросы из отладчика, чем каждый раз переписывать утилиту.
Еще вопрос: делаю .pagein, говорит, надо 'go', в общем, все по документации. Делаю 'g', отладчик немного думает и останавливается в DebugBreak-как-то-там. Как попасть обратно в пользовательский режим?
Что значит "пользовательский режим"? Отладчик как работал в ядре, так и продолжает работать в ядре. И останавливается он после подкачки в том процессе, который был указан.
Clerk Да, отладчик не знает причину по которой он не смог прочесть/записать память по указанному виртуальному адресу. Но механизм принудительной подкачки есть - .pagein. Фактически, человек сам должен сам анализировать: отсутствует память по виртуальному адресу или просто физические страницы выгружены. К сожалению, WinDbg никак не обрабатывает ошибки записи 0xcc (int 3) по адресам выгруженной памяти.
0x6b65 Пусть юзает олли, если возникают проблемы с подкачкой при отладке юзермодных приложений это вобще ппц. Локально сиська норм, виндбг это костыль, который нужен только в очень редких случаях.
Clerk У него, похоже, какой-то протектор на отлаживаемом PE'шнике: Думаю, если переубедить человека отлаживать олли, то жди нового топика: "Как снять защиту от активного отладчика", но уже в ветке RESEARCH
Насчет целей немного не так, но научиться отладке в WinDbg я хочу. По совету знакомого поставил точку останова не на первой инструкции, а на второй. Помогло. Видимо, код начал исполняться и загрузился в память. Из интересных наблюдений: после '.pagein' команда 'u' показала не тот код, что и Olly, а код с явной ошибкой (первый байт инструкции был обнулен!). Пока проблема решилась сама собой, но появилась другая -- не могу поставить точку останова на символ LdrLoadDll, говорит, ntdll!LdrLoadDll не найден. В чем дело пока не знаю, буду разбираться, если что -- отпишусь с вопросом. Всем спасибо за помощь.