FE23 LOOCH DISASMДИЗАССЕМБЛЕР
|
Главная | Загрузка | Инструкция | Карта сайта |
БЫСТРЫЙ СТАРТУРОК ТРЕТИЙСодержание
1. Постановка учебной задачи
По-прежнему нашим учебным исследуемым файлом будет файл
Загляните еще раз на страницу "Основные понятия", вспомните, что означает в программе FE23 это понятие - "первый проход дизасма". После того, как мы пройдем дизасмом все процедуры, мы сможем получить распечатку с ассемблерным текстом (асм. текстом) для любой процедуры, которая нас заинтересует. Но, быть может, мы замахнулись на слишком сложную задачу - узнать адреса абсолютно всех процедур. Хорошо, пусть задача будет немного попроще. Мы пройдем дизасмом столько процедур, сколько у нас получится. Но все же мы хотим пройти как можно больше процедур.
Примечание 2. Где начало и где конец
Неплохо бы для начала соориентироваться. Узнать, где в файле
Для учебной задачи такая подсказка у нас есть. В программу FE23
специально вставлены две маленькие пустые процедуры, одна в самом
начале исходных кодов, другая в самом конце.
(Не будем отвлекаться и обсуждать, как это сделано.
Сделать это было очень легко.)
Таким образом, все собственные процедуры программы FE23 размещены
в исполняемом файле
Вы уже знаете
( Урок второй )
что в программе FE23 можно по команде
Итак, мы теперь знаем, где начало и где конец всех собственных
процедур.
Адреса в этой распечаке - виртуальные, с добавлением базового
адреса
Еще в этом нашем уроке нам пригодятся вот эти строчки
из той же распечатки "Probe":
Головная процедура WinMain расположена в самом начале, сразу за "самой первой" процедурой пустышкой.
Нам пора уже запускать программу FE23. Задаем имя исследуемого
файла
Теперь взгляните на таблицу секций. Обратите внимание, что адрес
самой первой процедуры - это самое начало секции кодов
И еще интересный момент. Адрес точки входа в программу
Неплохо на будущее знать о таком факте. Что адрес точки входа тоже может в каких-то случаях подсказать, где заканчиваются собственные процедуры исследуемой программы. 3. Выбор параметров дизасмаМы собираемся запустить первый проход дизасма, начиная от точки входа. Пусть программа FE23 найдет нам в исследуемом файле все те процедуры, которые она сумеет найти самостоятельно в автоматическом режиме. Перед стартом первого прохода дизасма нам нужно не забыть про установку параметров. Все подробности про параметры дизасма, которые полезно знать при первом проходе дизасма, можно посмотреть на странице Настройки дизасма и арифметика адресов . Поэтому сейчас мы не будем уделять этому вопросу много времени. Скажем только основное. Если хотите, Вы сами можете поэкспериментировать, задавая разные значения параметров. Параметр
|
Параметры дизассемблирования Предельный размер луча = 512 Предельное количество лучей = 150 Создавать заявки для CALL = ДА Печатать ассемблерный текст = НЕТ |
Теперь можно стартовать первый проход дизасма.
Выбираем в главном меню команду
Вот конец распечатки в протоколе. (Но список оставшихся
заявок мы здесь существенно сократили).
Лучи: 150 пройдено, 150 предел, 193 всего в списке СТОП: Достигнут предел по количеству лучей Пройдено лучей 150 Остались невыполненные заявки: vir_addr file_idx proc type 1 0041BCF6 0001B0F6 015 REQU_NEXT 2 0041BCFE 0001B0FE 015 REQU_JCC 3 0041BD2B 0001B12B 015 REQU_JCC 4 00417710 00016B10 016 REQU_CALL 5 0041B670 0001AA70 017 REQU_CALL .............................................. .............................................. 36 0041CA20 0001BE20 048 REQU_CALL 37 0041C990 0001BD90 049 REQU_CALL КОНЕЦ ДИЗАССЕМБЛИРОВАНИЯ РАБОТА ЗАКОНЧЕНА |
В план нашего урока не входит обсуждение механизма заявок в программе FE23. Любознательные пользователи сами смогут с этим поэкспериментировать и разобраться. Программа сообщает достаточно информации, чтобы понять этот механизм.
Мы остановились, чтобы немного осмотреться.
Запросим сразу "общие сведения" - команда меню
ОБЩИЕ СВЕДЕНИЯ Имя проекта (---) Исследуемый Файл H:/FE/C/23/Release/fe23_10.exe Найдено процедур 49 Пройдено процедур 15 Пройдено лучей 193 Найдено CALL's 113 Невыполненных заявок 37 |
Мы прошли 150 лучей. Но в списке лучей их оказалось больше, там уже 193 луча. Так получается из-за того, что некоторые созданные лучи были затем разделены на две части, на два луча. Потому что встретилась команда передачи управления, ведущая внутрь луча.
Еще стоит посмотреть прямо сейчас на список процедур.
Даем из главного меню команду
Список процедур S/N - порядковый номер, присвоенный процедуре Addr - адрес входа в процедуру pass - первый луч данной процедуры уже пройден дизасмом Cnt - количество вызовов для данной процедуры из других процедур Calls - адреса процедур, вызываемых из данной процедуры S/N Addr Cnt Calls 001 00417C00 pass 0 19A80 17DA0 1A990 1B940 1B510 1AE70 1B260 1B170 1AE40 1B110 01010 002 00419A80 pass 1 19AC0 003 00417DA0 pass 5 1BB20 1BB60 004 0041A990 pass 1 17710 17DA0 005 0041B940 pass 1 1B670 006 0041B510 pass 1 17710 17A10 007 0041AE70 pass 2 1AEB0 008 0041B260 pass 1 1B300 17710 17DA0 009 0041B170 pass 1 17710 17DA0 17A10 010 0041AE40 pass 1 1AF60 011 0041B110 pass 1 1B130 012 00401010 pass 1 0EDE0 08950 08BB0 08C10 14F90 03960 091D0 0D6C0 0F970 11C90 12C00 13A40 15230 15A10 012C0 15250 11CD0 15BD0 08930 01D00 152D0 02650 01E00 01EA0 10740 013 00419AC0 pass 1 014 0041BB20 pass 1 1BB60 015 0041BB60 pass 3 1CA20 1C990 016 00417710 7 017 0041B670 1 018 00417A10 2 019 0041AEB0 1 020 0041B300 2 021 0041AF60 2 022 0041B130 1 023 0040EDE0 1 024 00408950 1 025 00408BB0 1 026 00408C10 1 027 00414F90 1 028 00403960 1 029 004091D0 1 030 0040D6C0 1 031 0040F970 1 032 00411C90 1 033 00412C00 1 034 00413A40 1 035 00415230 1 036 00415A10 1 037 004012C0 1 038 00415250 1 039 00411CD0 1 040 00415BD0 1 041 00408930 2 042 00401D00 2 043 004152D0 1 044 00402650 1 045 00401E00 1 046 00401EA0 1 047 00410740 1 048 0041CA20 1 049 0041C990 1 |
Поясним, что словом "pass" помечены те процедуры, которые пройдены дизасмом. Точнее, у которых пройден дизасмом хотя бы один луч. Процедуры, которые расположены в конце списка, еше не пройдены дизасмом.
Сразу бросается в глаза, как мало еще мы прошли процедур по сравнению с тем, сколько процедур мы уже обнаружили.
Обратим внимание, что на этой распечатке для каждой процедуры показано, какие процедуры вызываются из данной процедуры. Приведен список адресов вызываемых процедур. (Для компактности в этих адресах убраны старшие цифры).
Много вызовов идет из процедуры 001. Мы начинали дизасм от точки входа, поэтому порядковый номер 001 получила та процедура, на которую указывает адрес точки входа. Мы уже поняли (см. выше), что это библиотечная процедура, добавленная компилятором.
Но больше всего разных процедур вызывается из процедуры с порядковым номером 012. Адрес этой процедуры 00401010 нам уже знаком, зто головная процедура WinMain нашей исследуемой программы. Очень часто для разных программ именно так и бывает, что из головной процедуры идет много вызовов для других процедур. И тогда сразу видно, которая из процедур является головной.
Теперь мы объсним, как было обещано, почему мы для первого запуска дизасма поставили предел именно в 150 лучей. Мы хотели, чтобы после этого первого запуска была уже пройдена процедура 012, то есть, WinMain.
Будем продолжать выполнять первый проход дизасма.
Но перед этим увеличим значенияе параметра
Теперь параметры дизасма выглядят так:
Параметры дизассемблирования Предельный размер луча = 512 Предельное количество лучей = 500 Создавать заявки для CALL = ДА Печатать ассемблерный текст = НЕТ |
Для продолжения дизасма по оставшимся невыполненным заявкам
есть специаьная команда в главном меню
Благополучно прошли 500 лучей. Но в очереди остались еще заявки.
Еще раз даем ту же команду
Пройдено лучей 374 Все заявки выполнены КОНЕЦ ДИЗАССЕМБЛИРОВАНИЯ РАБОТА ЗАКОНЧЕНА |
Итак, мы начали от входной точки и прошли все лучи и процедуры, какие удалось пройти в автоматическом режиме.
Всего мы прошли ( 150 + 500 + 374 ), итого это 1024 луча. Если потребуется повторить, мы сразу поставим предел, ну, скажем, 1100 лучей. (Хотя можно, конечно, вообще отключить эту защиту, поставить 999999 ...).
Можно заготовить прозапас строчки для командного файла.
На случай, если потребуется повторить тот первый проход дизасма,
который мы сейчас проделали.
Файл cmd_01.cmd Командный файл Программа исследует самое себя ------------------------------------------------ .z. .z. exam_file H:/FE/C/23/RELEASE/fe23_10.exe .z. .z. looch_size 512 .z. looch_nums 1100 .z. do_calls .z. no_asmtext .z. .z. entry_point .z. ------------------------------------------------ |
Те строчки, которые начинаются не с символов
Пустые строчки, которые начинаются с
В команде
При выполнеии первого прохода дизасма у нас появляются накопленные данные, то есть, разные сведения об исследуемом файле.
Посмотрим общие сведения о накопленных данных - даем команду
ОБЩИЕ СВЕДЕНИЯ Имя проекта (---) Исследуемый Файл H:/FE/C/23/RELEASE/fe23_10.exe Найдено процедур 110 Пройдено процедур 110 Пройдено лучей 1309 Найдено CALL's 411 Невыполненных заявок 0 |
У нас сейчас есть 110 процедур и 1309 лучей.
Можно запросить список всех процедур - это команда
Мы уже смотрели на эту распечатку после прохода дизасмом
первой порции из 150 лучей. Теперь эта распечатка стала
существенно длиннее. И она стала более интересной.
Приведем ее здесь полностью.
Список процедур S/N - порядковый номер, присвоенный процедуре Addr - адрес входа в процедуру pass - первый луч данной процедуры уже пройден дизасмом Cnt - количество вызовов для данной процедуры из других процедур Calls - адреса процедур, вызываемых из данной процедуры S/N Addr Cnt Calls 001 00417C00 pass 0 19A80 17DA0 1A990 1B940 1B510 1AE70 1B260 1B170 1AE40 1B110 01010 002 00419A80 pass 1 19AC0 003 00417DA0 pass 5 1BB20 1BB60 004 0041A990 pass 1 17710 17DA0 005 0041B940 pass 1 1B670 006 0041B510 pass 1 17710 17A10 007 0041AE70 pass 2 1AEB0 008 0041B260 pass 1 1B300 17710 17DA0 009 0041B170 pass 1 17710 17DA0 17A10 010 0041AE40 pass 1 1AF60 011 0041B110 pass 1 1B130 012 00401010 pass 1 0EDE0 08950 08BB0 08C10 14F90 03960 091D0 0D6C0 0F970 11C90 12C00 13A40 15230 15A10 012C0 15250 11CD0 15BD0 08930 01D00 152D0 02650 01E00 01EA0 10740 013 00419AC0 pass 2 014 0041BB20 pass 1 1BB60 015 0041BB60 pass 3 1CA20 1C990 016 00417710 pass 14 17730 017 0041B670 pass 1 1B860 1B910 1B8B0 018 00417A10 pass 5 19D60 19DC0 019 0041AEB0 pass 1 1AF60 020 0041B300 pass 2 021 0041AF60 pass 4 022 0041B130 pass 1 023 0040EDE0 pass 1 0F790 024 00408950 pass 1 025 00408BB0 pass 1 177F0 088A0 026 00408C10 pass 1 178E0 089D0 17890 027 00414F90 pass 1 028 00403960 pass 1 17710 029 004091D0 pass 1 030 0040D6C0 pass 1 0D6D0 0DAD0 031 0040F970 pass 1 032 00411C90 pass 1 033 00412C00 pass 1 034 00413A40 pass 1 035 00415230 pass 1 036 00415A10 pass 1 037 004012C0 pass 1 08930 038 00415250 pass 1 08930 039 00411CD0 pass 1 08930 040 00415BD0 pass 1 08930 041 00408930 pass 8 042 00401D00 pass 2 043 004152D0 pass 1 15810 157C0 158E0 044 00402650 pass 1 08AD0 08B20 045 00401E00 pass 1 08B20 08AD0 046 00401EA0 pass 1 08B20 08AD0 047 00410740 pass 1 14FE0 08B20 08AD0 048 0041CA20 pass 1 049 0041C990 pass 1 050 00417730 pass 1 17780 19A60 051 0041B860 pass 1 052 0041B910 pass 2 053 0041B8B0 pass 2 054 00419D60 pass 2 055 00419DC0 pass 3 19C90 056 0040F790 pass 2 17490 057 004177F0 pass 1 177C0 058 004088A0 pass 1 174E0 08930 059 004178E0 pass 15 1AE10 1ADB0 1AB90 1A8D0 060 004089D0 pass 1 08960 061 00417890 pass 4 18CD0 1A780 18D70 062 0040D6D0 pass 1 063 0040DAD0 pass 1 064 00415810 pass 1 065 004157C0 pass 1 15170 066 004158E0 pass 1 067 00408AD0 pass 31 15900 08EE0 08F00 068 00408B20 pass 22 08AD0 069 00414FE0 pass 1 17710 070 00417780 pass 1 19E20 071 00419A60 pass 3 072 00419C90 pass 1 19C30 073 00417490 pass 1 17DD0 074 004177C0 pass 1 1A480 1A2B0 075 004174E0 pass 1 18DD0 178E0 076 0041AE10 pass 2 077 0041ADB0 pass 3 17710 078 0041AB90 pass 4 1A8D0 1C660 079 0041A8D0 pass 3 1C8E0 1C660 080 00408960 pass 1 081 00418CD0 pass 1 1AE10 17710 082 0041A780 pass 1 1A680 1AB90 178E0 083 00418D70 pass 1 1A680 084 00415170 pass 1 17710 17A60 085 00415900 pass 1 086 00408EE0 pass 1 17890 087 00408F00 pass 1 17890 088 00419E20 pass 3 1A060 19AC0 089 00419C30 pass 1 090 00417DD0 pass 1 19980 18BA0 18B80 176E0 18B50 091 0041A480 pass 1 17710 092 0041A2B0 pass 1 1C2A0 093 00418DD0 pass 1 094 0041C660 pass 3 095 0041C8E0 pass 1 096 0041A680 pass 3 1AB90 097 00417A60 pass 1 17710 17A10 19D60 1A1E0 19E20 19DC0 19A60 098 0041A060 pass 2 099 00419980 pass 3 1C170 100 00418BA0 pass 2 18B50 176E0 101 00418B80 pass 3 1BF50 102 004176E0 pass 4 19980 103 00418B50 pass 5 1BE60 104 0041C2A0 pass 1 105 0041A1E0 pass 1 106 0041C170 pass 1 1BFE0 17A10 107 0041BF50 pass 1 1ADB0 108 0041BE60 pass 1 1ADB0 1CB30 109 0041BFE0 pass 1 19E20 19A60 110 0041CB30 pass 1 1C660 1A8D0 |
Заметим, что все процедуры, которые есть в этом списке, отмечены словом "pass", то есть, все они уже пройдены дизасмом.
Мы можем сделать распечатку асм. текста для каждой процедуры. А также распечатку схемы лучей и переходом между лучами, иначе говоря, получить блок-схему для любой процедуры.
О том, как делать такие распечатки для процедур, мы расскажем дальше, в следующем разделе.
Теперь посмотрим еще на один список - список всех вызовов CALL. Такой список тоже собирается во время выполнения первого прохода дизасма.
Этот список у нас получился довольно длинным. В табличке общих сведений сказано, что в этом списке сейчас накоплено 411 элементов.
Получить распечатку с этим списком можно по команде
Из этого длинного списка мы здесь приводим только отдельные
фрагменты.
Список всех вызовов CALL Proc - порядковый номер процедуры, откуда идет вызов Addr - адрес команды CALL Type - тип вызова S/N - порядковый номер по списку собственных или импортируемых Name - имя (если известно) или адрес Proc Addr Type S/N Name 1 001 00417c26 import 062 GetVersion 2 001 00417c57 own 002 p_002 00419A80 3 001 00417c62 own 003 p_003 00417DA0 4 001 00417c71 own 004 p_004 0041A990 5 001 00417c76 own 005 p_005 0041B940 6 001 00417c7b import 063 GetCommandLineA 7 001 00417c86 own 006 p_006 0041B510 8 001 00417c9f own 007 p_007 0041AE70 9 001 00417ca7 own 008 p_008 0041B260 10 001 00417cac own 009 p_009 0041B170 11 001 00417cb1 own 010 p_010 0041AE40 12 001 00417cdc own 011 p_011 0041B110 13 001 00417d12 import 064 GetStartupInfoA 14 001 00417d33 import 065 GetModuleHandleA 15 001 00417d3a own 012 p_012 00401010 16 001 00417d43 own 007 p_007 0041AE70 17 002 00419a89 import 056 HeapCreate 18 002 00419a99 own 013 p_013 00419AC0 19 002 00419aa8 import 061 HeapDestroy ................................................ ................................................ 183 037 004012fa unknown --- unknown 184 037 0040130c unknown --- unknown 185 037 00401319 unknown --- unknown 186 037 00401334 import 076 RegisterClassA 187 037 00401344 own 041 p_041 00408930 188 037 00401381 unknown --- unknown 189 037 0040138d unknown --- unknown 190 037 00401394 unknown --- unknown 191 037 004013ab import 076 RegisterClassA 192 037 004013bb own 041 p_041 00408930 193 038 0041527d import 073 LoadIconA 194 038 0041528d import 077 LoadCursorA 195 038 004152ac import 076 RegisterClassA 196 038 004152bc own 041 p_041 00408930 197 039 00411d01 import 073 LoadIconA 198 039 00411d11 import 077 LoadCursorA 199 039 00411d30 import 076 RegisterClassA 200 039 00411d40 own 041 p_041 00408930 201 040 00415c01 import 073 LoadIconA 202 040 00415c11 import 077 LoadCursorA 203 040 00415c20 import 015 CreateSolidBrush 204 040 00415c3b import 076 RegisterClassA 205 040 00415c4b own 041 p_041 00408930 ................................................ ................................................ 400 107 0041bf76 own 077 p_077 0041ADB0 401 108 0041be95 own 077 p_077 0041ADB0 402 108 0041beb0 own 110 p_110 0041CB30 403 109 0041c01e own 088 p_088 00419E20 404 109 0041c04e unknown --- unknown 405 109 0041c060 own 071 p_071 00419A60 406 110 0041cbc7 import 026 ReadFile 407 110 0041cbd1 import 028 GetLastError 408 110 0041cc06 own 094 p_094 0041C660 409 110 0041cca7 import 026 ReadFile 410 110 0041ccb1 import 028 GetLastError 411 110 0041cd05 own 079 p_079 0041A8D0 |
Здесь в колонке "тип вызова" (Type) могут быть указаны следующие типы:
И, наконец, можно посмотреть на обзорный экран. Там можно найти любую процедуру из тех, что уже были пройдены дизасмом. Посмотреть, много ли лучей в этой процедуре. Заглянуть в асм. текст для каждого луча.
Все сведения на обзорном экране расположены в порядке адресов. Поэтому нужную процедуру следует искать по ее адресу, этот адрес есть в списке процедур.
Этот раздел можно было бы назвать иначе:
"Распечатки для отдельных процедур"
И такое название было бы даже более понятным. Но тут было важно, чтобы в названии этого раздела обязательно присутствовало это слово - "кластер".
На странице "Основные понятия" Вы можете прочитать, зачем предлагается создавать кластеры из нескольких процедур. Но прочитать это Вы сможете и позже, после нашего урока.
А пока будет вполне достаточно, если Вы запомните, что кластер в программе FE23 - это всего навсего группа из нескольких процедур. И распечатки нужно делать для кластера, а не для одной отдельной процедуры. Хотя можно создать и такой кластер, в котором будет всего одна процедура.
Распечатки мы сделаем для четырех процедур. Их порядковые номера 037, 038, 039, 040. Далее, по ходу нашего урока, станет понятно, почему мы выбрали именно эти процедуры.
Для кластера нужно придумать имя. Не будем долго думать, просто возьмем первые буквы слова "cluster" и номер первой процедуры. Имя для кластера будет такое "CLU_037".
Команда для создания кластеров - это
Примечание
Правила работы в этом окошке - стандартные для Windows.
Чтобы выбрать не одну строку, а сразу несколько, нужно удерживать
нажатой клавишу "Ctrl" и кликать мышкой на нужные строки.
Если нужные строки расположены подряд, то можно выбрать мышкой
первую строку, затем, удерживая "Shift", выбрать последнюю строку.
В протоколе при этом появится вот такое сообщение:
Выбор кластера для работы Кластер: CLU_037 Это новый кластер Процедуры кластера: 037 004012C0 passed 038 00415250 passed 039 00411CD0 passed 040 00415BD0 passed |
Здесь слово "passed" означает, что для данной процедуры уже был сделан первый проход дизасма (хотя бы для одного первого луча). Распечатки можно получать только для тех процедур, которые пройдены дизасмом.
Итак, кластер мы приготовили.
Дальнейшее все очень просто.
В главном меню выбираем команду
Вот одна из этих процедур (мы скопировали сюда ту, что покороче,
это процедура с номером 038).
|
Затем точно также, но по другой команде
|
И получим еще распечатку по команде
|
Отыскать адрес оконной процедуры можно разными способами.
Например, с помощью программы
Но мы попытаемся самостоятельно получить адрес этой оконной процедуры, используя те накопленные данные, которыми мы уже располагаем после выполнения первого прохода дизасма от точки входа.
Причем эта наша учебная задачка имеет готовый ответ, как это
бывает в школьных учебниках.
Ведь в самом начале нашего урока мы уже получили распечатку
по команде
Головная процедура =WinMain= 00401010 Оконная процедура главного окна =MainWndProc= 004013E0 |
Итак, приступаем к решению этой задачи.
Путь к решению будет такой. Мы знаем, что для создания окна должен быть заранее определен класс этого окна. Чтобы зарегистрировать класс окна применяется API функция RegisterClass. Вот мы и поищем вызовы этой функции. Искать будем в списке вызовов CALL, распечатку этого списка мы уже сделали. (В приведенной выше неполной распечтаке этого списка нужный нам фрагмент есть).
Увы, по части сервиса в программе FE23 пока не густо. Так что искать придется глазками. Хотя у нас в компьютере есть не только FE23. Если сбросить распечатку в файл, то можно посмотреть на этот файл каким-нибудь редактором, в котором есть поиск.
Нам повезло. В списке вызовов CALL есть вызовы для
функции RegisterClass. Выписываем эти строчки:
Proc Addr Type S/N Name 186 037 00401334 import 076 RegisterClassA 191 037 004013ab import 076 RegisterClassA 195 038 004152ac import 076 RegisterClassA 199 039 00411d30 import 076 RegisterClassA 204 040 00415c3b import 076 RegisterClassA |
Напомним, что в этой таблице колонка Proc - это номер процедуры, а колонка Addr - это виртуальный адрес внутри процедуры, то место, где стоит команда CALL.
Как раз для этих четырех процедур мы уже сделали распечатку асм. текста. Правда, в этой распечатке не подписаны имена импортируемых функций. (Это одна из многочисленных недоделок программы FE23). Но эти имена функций есть на распечатках со схемами лучей. Так что можно соориентироваться по этим схемам.
Асм. текст мы можем смотреть не только на распечатках, но еще и на обзорном экране, это кому как больше нравится. По виртуальному адресу мы можем быстро найти нужное место на обзорном экране.
А теперь нужно проявить наше умение быстро разобраться в асм. тексте, не делая досконального изучения всех строк процедуры. Перед нами пять очень похожих участков кода, это нам поможет. Мы помним, что перед вызовом функции RegisterClass требуется заполнить некоторую структуру данных. Вот в этой структуре и находится то поле, куда заносится адрес оконной процедуры. Этот адрес мы сразу опознаем, зная диапазон адресов секции кодов.
Все, этих сведений вполне достаточно для решения задачи. Смотрим на асм. текст. и выписываем адреса пяти оконных процедур.
Наверное будет разумно предположить, что оконная процедура главного окна регистрировалась первой. Тогда ее адрес равен 4013E0. Сверяемся с ответом - смотрим на распечатку "probe". Мы нашли правильный ответ.
Эта учебная страница уже получилась довольно длинной. Так что мы будем заканчивать этот урок. В заключение мы лишь запишем, какие еще здесь могли бы быть работы в продолжение этого урока.
Главная | Загрузка | Инструкция | Карта сайта |