Где-то в глубинах WndProc что-то у меня не так - не правильно срабатывает. Загрузил отладочную версию в OllyDbg но вижу там только от начала WinMain и до конца цикла обработки сообщений. То есть до ExitProcess. А дальше с обоих сторон какой-то неизвестный мне код (в основном какие-то INT3). Как я понимаю WndProc загрузилась в памяти довольно далеко от WinMain, но как ее найти?
- После запуска проги в OllyDbg (если создается окно) нажать на тулбаре W (Windows) и правой кнопкой выбрать Follow ClassProc - Поставить бряк на RegisterClass, там параметром структура WNDCLASS, второе поле lpfnWndProc - адрес WndProc - Часто WndProc имеет такое начало: Код (Text): 004020B5 /. 55 PUSH EBP 004020B6 |. 89E5 MOV EBP,ESP 004020B8 |. 53 PUSH EBX 004020B9 |. 56 PUSH ESI 004020BA |. 57 PUSH EDI 004020BB |. 837D 0C 01 CMP DWORD PTR [EBP+C],1 004020BF |. 74 42 JE SHORT 00402103 004020C1 |. 837D 0C 05 CMP DWORD PTR [EBP+C],5 004020C5 |. 0F84 D6000000 JE 004021A1 004020CB |. 837D 0C 07 CMP DWORD PTR [EBP+C],7 004020CF |. 0F84 04010000 JE 004021D9 004020D5 |. 817D 0C 11010000 CMP DWORD PTR [EBP+C],111 004020DC |. 0F84 07010000 JE 004021E9 004020E2 |. 837D 0C 02 CMP DWORD PTR [EBP+C],2 004020E6 |. 0F84 46010000 JE 00402232 - Есть ещё способы, но обычно определяют на глаз
Нахожу структуру WNDCLASS. Там 3-е поле такое: 0A 10 40 00. Иду по адресу 0040100А и там вижу такое: 0040100А | E9 | DB E9 | И что это означает? Таких команд в моей программе не было! При попытке поставить бряк на эту строчку OllyDbg ругается что я пытаюсь ставить бряк на данные! Кстати адресом выше оказалась команда: jmp MyProg.WinMain то есть точка входа в программу.
Andrystepa Прога на VC++ написана? Может сначала всё-таки попробовать вижуальным отладчиком её помучать? Собирайте в релиз чтоб меньше было "неизвестного кода". INT3 - это классический заполнитель дыр от выравнивания в секции кода. Его обычно линкер вставляет, реже - компилятор. Я бы добавил первой строчкой кода в эту функцию __asm int 3 Так отладчик сам остановится на первом вызове этой функции. Как только он остановится, можно убрать int 3 (заменить 0xCC на 0x90) и работать дальше.
Программа написана в RadASm для Masm32. А есть ли способ сделать так, чтобы оконная процедура загружалась рядом с WinMain?
Расположи в исходнике их друг за другом. Обычно они и в ехе будут рядом стоять. А вообще WndProc - это всего лишь метка, адрес, поэтому очень просто её адрес определяется так: Код (Text): WndProc proc hwnd:DWORD, uMsg:DWORD, wParam:DWORD, lParam:DWORD mov eax,uMsg .if eax==WM_CREATE lea eax,WndProc PrintHex eax И Radasm сам напишет тебе адрес WndProc в окне Output.
Для masm может помочь такое решение: для ml.exe добавить ключ /Zi для link.exe добавить ключ /debug открыть скомпилированную прогу в OllyDbg выбрать View -> Source files ну и в исходнике найти WndProc не проблема ЗЫ: а fasm позволяет вывести адреса нужных меток сразу на этапе компиляции.
В масме можно создать файл листинга (добавить в командную строку ml.exe директиву /Fl) и посмотреть в нём адрес метки WndProc.