Введение в крэкинг с нуля, используя OllyDbg - Глава 9

  • На форуме работает ручное одобрение пользователей. Это значит, что, если Ваша причина регистрации не соответствует тематике форума, а также Вы используете временную почту, Ваша учётная запись будет отклонена без возможности повторной регистрации. В дальнейшем - пожизненная блокировка обоих аккаунтов за создание мультиаккаунта.
  • Мы обновили Tor зеркало до v3!
    Для входа используйте следующий url: darkv3nw2...bzad.onion/
  • Мы вновь вернули telegram чат форуму, вступайте, общайтесь, задавайте любые вопросы как администрации, так и пользователям!
    Ссылка: https://t.me/chat_dark_time

AnGel

Администратор
Команда форума

AnGel

Администратор
Команда форума
27 Авг 2015
3,411
2,025
Как и было обещано, теперь мы займёмся непосредственно крэкингом. Начнём с базовых понятий, не спеша, шаг за шагом пополняя наш крэкерский арсенал знаний. Теоретические пробелы мы постараемся заполнить по ходу дела.

Экспериментировать мы будем, естественно, с уже знакомым нам крэкми Cruehead'а, но не ограничимся рассмотрением различных способов взлома этого несложного крэкми - по ходу мы постараемся изучить стандартные приёмы, применимые в дальнейшем к более "продвинутым" жертвам.

Итак, давайте загрузим крэкми в отладчик.

На примере данного крекми можно рассмотреть несколько общих понятий.

Точка Входа (Entry Point). Адрес инструкции, с которой стартует программа. Не путать с понятием OEP (Original Entry Point), которое мы рассмотрим чуть позже. При загрузке приложения в OllyDbg, отладчик останавливается на точке входа, анализирует код и ждёт дальнейших инструкций от пользователя.

fc44547e4918d0b23eda148cc28d19c9.png -

В данном случае точка входа соответствует адресу 401000. Обычно в строке состояния выводится причина, по которой остановлен отладчик. Сейчас там находится сообщение о том, что мы находимся на точке входа:

994d3dcda0f10348334b20719945ae1d.png -

Почти все программы на старте останавливаются на точке входа. Есть такие, которые не останавливаются, т.к. используют способы обхода отладчика. Об этих способах мы поговорим позже. Пока что примите к сведению существование подобных приёмов антиотладки.

Давайте, заодно, рассмотрим понятие DLL (динамические библиотеки) и экспортируемые ими функции.

d7381183880ed574bf63b4f859d96906.png -

Обратите внимание на выделенную инструкцию. Вместо адреса, вроде CALL 401020, в данном случае указано имя внешней функции:

CALL LoadIconA
В крайнем правом столбике выводится какая-то дополнительная информация, но что представляет собой LoadIconA?

Операционная система Windows поддерживает так называемые динамические библиотеки (файлы с расширением DLL), которые имеют тотже формат, что и обычные исполнимые файлы EXE. В динамических библиотеках содержатся функции, которые могут быть использованы другими исполнимыми файлами (EXE и DLL). Вместо статического копирования одной и тойже функции в несколько экзешников, её можно поместить в DLL, а в экзешниках указать ссылки на эту DLL. Если обьём подобных функций велик, получается неплохая экономия на размере экзешников и, что более существенно, расходуемой памяти. Базовые функции для работы с файлами, динамической памятью, процессами и потоками, графикой, звуком, сетью и т.д. и т.п. реализованы в стандартных динамических библиотеках. LoadIconA как раз и является одной из стандартных функций, реализованной в одной из стандартных библиотек - в USER32.DLL. Стандартные функции ещё называют API.

Давайте рассмотрим пример другой API'шной функции - MessageBoxA.

В окне Command Bar вводим: ? MessageBoxA

bdf6903c04068e8ba2c10dccb9ae6491.png -

Получаем короткий отчёт, в котором первым делом указан настоящий адрес данной функции. Давайте пройдём по этому адресу, т.е. воспользуемся командой Go to - Expression и введём тот адрес, что выдал нам Command Bar.

52f2f9866789f8201791c684fa844667.png -

Вводим тот адрес, что выдал Command Bar (у Вас этот адрес может быть другим!)

88e489c0d5fe250363ae8f231e61c7f4.png -

Если у Вас установлена Windows 9x, этот фокус не сработает, о чём мы подробнее поговорим ниже.

78097c5843d732566b7c0ed625fcfba7.png -

Сразу видим, что функция принадлежит USER32.DLL, но мы это уже знали, ведь имя DLL обычно указывается вместе с именем функции в дизассемблере (вроде CALL USER32.MessageBoxA). Ещё можно заметить, что MessageBoxA - это обычная функция, которая начинается по текущему адресу и завершается инструкцией RET. Код данной функции находится в библиотеке, а не в экзешнике, что позволяет сэкономить на размере и упрощает работу крэкера :)

Чтоб вернуться к текущей инструкции, достаточно нажать МИНУС. В окне Go to - Expression можно было прямо ввести MessageBoxA.

b4f1c68132cea6fcbc286af8d86770ed.png -

133cb8d3ec28928eb8a46a1c29bb746d.png -

Вот, мы снова оказались внутри функции MessageBoxA из библиотеки USER32.DLL.

В имени функции важно правильно указывать строчные и прописные буквы (MessageBoxA и messageboxa - разные имена). Как же узнать правильный регистр той или иной буквы?

Нажимаем МИНУС - возвращаемся к точке входа.

102ef7c451cbea7d3689fd77d9ae1608.png -

Правая кнопка мыши в листинге: Search for - Name (label) in current module. Получаем полный список имён API'шных функций, задействованных в данном экзешнике.

59c8602adee18fc38b4dcfccff27c0b6.png -

Не нужно перечитывать весь список - чтобы найти нужную функцию, достаточно начать набирать её имя. Нажимаем M:

e146ed61cfbabf2a9895a46fb2c4975e.png -

Курсор позиционируется на первой функции, имя которой начинается на M.

e8cc96e0793dfa30af59b29211cefbe7.png -

В заголовке окна выводятся буквы, по которым осуществляется поиск.

459dd36bcf3c1c64df1c41c7af04c941.png -

Правая кнопка мыши по имени функции вызывает меню со следующими опциями:

4c4f477e342f31188f6e325ba92cf502.png -

Опция Follow import in Disassembler подгружает эту функцию в дизассемблер - это ещё один способ попасть внутрь API'шной функции.

db0d6a91ea9ff28d6c072cb8b3a32ff9.png -

Часто новички ошибочно задают поиск символов (Search for - Name (lable) in current module), находясь при этом внутри какой-либо внешней функции. К примеру, если мы воспользуемся данной опцией внутри функции MessageBoxA, мы получим список имён функций, которые импортирует библиотека USER32.DLL, а вовсе не подопытный эзешник. В меню чётко сказано, что поиск осуществляется в текущем модуле (current module), а текущем в данном случае окажется USER32, ведь функция MessageBoxA находится именно в нём.

9ea60163433a4d18e3bafb53d8cc2583.png -

Дабы избежать подобных ошибок, не забывайте поглядывать на заголовок окна отладчика - там отображается, в частности, имя текущего модуля.

4ab247153378526ecc90602c0f528c40.png -

Даже если мы просто заглянули во внешнюю функцию в дизассемблере, а не передали управление в отладчике, т.е. функция даже не выполняется ещё, текущим модулем всё равно окажется библиотека, в которой находится внешняя функция. В таком случае нужно понажимать на МИНУС пока Вы не окажитесь в "основном" модуле, чтобы воспользоваться такими опциями как Search for - Names и т.п.

Windows NT: 2000, XP и 2003

Дальнейшее обсуждение касается операционных систем NT: 2000, XP и 2003. Если у Вас мастдай (пардон, тут автор использовал термин Windows 95/98 - прим. пер.), смею порекомендовать перейти на любую из вышеперечисленных осей, т.к. на NT OllyDbg обладает бульшими возможностями (и глючит меньше - опять прим. пер.) Если такой возможности нет, можете пропустить дальнейшее обсуждение и перейти сразу к "Приложение. Windows 9x"

c5ee507a8f0dc58ba656a190565a0044.png -

В перечне API'шных функций, которые использует крэкми, есть ещё одна полезная опция в контекстном меню: Toggle breakpoint on import. Данная опция позволяет установить точку останова на вызове функции API.

Точку останова на вызовах конкретной API'шной функции можно установить и через Command Bar:

bp MessageBoxA
В отличие от bpx, bp ставит точку останова на первой инструкции внутри заданной функции, а не на самих инструкциях вызова (call или jmp) в текущем модуле. Давайте снова зайдём в функцию MessageBoxA (любым из вышеописанных способов) и удостоверимся, что на первой инструкции данной функции появилась точка останова. Так и есть:

fd0503639224607ebfaa12e5a058baff.png -

Таким образом, при вызове функции MessageBoxA, должна сработать точка останова. Давайте нажмём F9, чтобы запустить крэкми.

0454ca44b980a03bb5ecb17da5b755b7.png -

Появилось главное окно крэкми. В меню выбираем Help - Register:

ab42234a1e465a7280f8a1a8a89043ba.png -

Вводим произвольные данные в поля Name и Serial; нажимаем OK. В этот момент должен произойти вызов функции MessageBoxA, который должна зафиксировать наша точка останова... Ага, отладчик прервал выполнение! В правом нижнем углу светится надпись Paused (будто нам и так непонятно, что процесс остановлен - прим. пер.).

4e6951559ac51bcaeed69993cbaf57c3.png -

Левее указана причина, по которой произошла остановка.

f2d0abf1fbbdef3fbaaf8c901133a1a2.png -

Там написано: "Breakpoint at USER32.MessageBoxA", что значит "Точка останова на USER32.MessageBoxA". Наша точка останова сработала.

8fc5c21c26b543cfe70979e8f71ab67f.png -

В момент вызова функции можно посмотреть на значения аргументов данной функции. Аргументы API'шных функций обычно передаются через стек справа налево, согласно соглашению stdcall. Давайте рассмотрим их внимательно.

В самом верху стека хранится адрес возврата. В данном случае - 4013C1.

cda9c22d8f304cb9d07798c9c4ad5a05.png -

Когда мы проходили инструкции CALL и RET в подготовительной части этого цикла (Глава 7), мы имели возможность убедиться, что при вызове любой подпрограммы (т.е. функции) верхушка стека содержит адрес возврата - адрес, на который перейдёт управление, после завершения функции. В данном случае, после завершения MessageBoxA, управление перейдёт на адрес 4013C1.

Далее (т.е. ниже) идут аргументы функции. MessageBoxA принимает 4 аргумента (можете посмотреть описание функции API MessageBox в MSDN, чтобы убедиться): дескриптор родительского окна, текст сообщения, текст заголовка и стиль.

Текст сообщения - "No luck there, mate!" - констатирует, что Вы не угадали правильные параметры регистрации :)

Вот-вот вылезет роковое сообщение...

b828355b4eed6bfbe4dd7f34cf503f60.png -

Чтобы убедиться, что текущий вызов MessageBoxA - это тот самый MessageBox, что уведомляет нас о неправильно набранном серийнике, если у Вас есть сомнения... Давайте изолируем текущий вызов, поставив точку останова на инструкции RETN 10h, которую можно найти чуть ниже. Адрес инструкции возврата у Вас, возможно, будет отличаться, но, в любом случае, это должен быть первый RET внутри функции.

c5ae8e7603754dfee5c504e070ec7c34.png -

Нажимаем F9.

eb015c3bebfa591e729c62f714fa98d3.png -

Окно MessageBox появилось на экране. Текст заголовка и сообщения соответствует параметрам функции, которые мы только что перехватили: "Lo luck!" и "No luck there, mate!". Серийник не подошёл :)

Нажимаем "Да" - срабатывает точка останова на RETN 10h.

ffcc65a4c9390657620b54b3fface4b1.png -

Таким образом, можно заключить, что сообщение выскочило в процессе выполнения функции MessageBoxA.

Чем отличается RETN 10h от обычного RET? Обычный RET просто вернул бы управление на адрес возврата - 4013C1.

ad1e117323f7c86b7fd52bd329655a47.png -

Из стека извлекается адрес возврата. Указатель на верхушку стека перемещается на 4 байта вниз (точнее, в сторону старших адресов). Таким образом, ESP увеличивается на 4 в результате выполнения инструкции RET. В случае с RET 10h, в добавок к тому, что делает обычный RET, ESP увеличивается ещё на 10h. В общей сложности, к значению ESP прибавляется 10h + 4 = 14h = 20. Давайте проверим: нажимаем F7.

Дальнейшее обсуждение касается обоих семейств Windows: 9x и NT.

0a144697ad2a993fd975eaad2335c4dc.png -

Вот мы и вернулись из API-функции обратно в код крэкми. Обратите внимание, что указатель верхушки стека сдвинулся на 20 байт вниз, как и следовало ожидать, т.е. RET N не просто извлекает из стека адрес возврата, но и очищает аргументы, переданные в функцию, как того требует соглашение stdcall.

d58fa04d45f36534c9bb4f7b8acc909f.png -

В данный момент крэкми уже точно знает, что серийник не верен и даже успел нам об этом сообщить. На данном этапе уже поздно что-либо предпринимать. Нажимаем F9.

c3a7a1bc8bc260e3a76ce809372aab59.png -

30cda2b33bfb35911295d89edc5ad463.png -

Снова срабатывает точка останова. Оказывается, крэкми решил снова вывести сообщение о неправильном серийнике, будто мы успели забыть, что серийник не подошёл :)

e730af232941c997f5f3fb37a5cebc3f.png -

Адрес возврата на этот раз указывает на 40137D. Давайте посмотрим, что за код находится по этому адресу. Для этого можно воспользоваться опцией Go to - Expression: 40137D. Или прямо по правому щелчку в верхней ячейке стека - Follow in Disassembler.

f49f5f084f962807faa61b216f04df83.png -

Сразу над строчкой по адресу возврата (40137D) находится инструкция CALL, которая вызвала функцию MessageBox (401378).

35d2d998e4daaee451e25ad2372f4de2.png -

Чуть выше виден другой MessageBox, но с совершенно другим текстом: Great work, mate! Похоже, что это сообщение выскакивает, если серийник оказывается правильным :) Для начала было бы неплохо попасть на тот другой MessageBox, вместо того, что вот-вот покажется на экране.

1fd6036f4c63797342dc26d47f75ebae.png -

Предварительный анализ проделанный отладчиком показывает, что данный код входит в состав функции, о чём свидетельствует жирная скобка в колонке с машинным кодом. Таких функций несколько: одна начинается по адресу 401362 и содержит сообщение "No luck...", другая - "Great work..." и начинается по адресу 40134D.

Если выделить первую строчку функции "No luck..." (по адресу 401362), в окне подсказки покажется следующая информация:

9ce32a77eb3804f7c8a5463569d00928.png -

Отладчик в курсе откуда вызывается данная функция, но так бывает только с прямыми вызовами! Щелчёк правой кнопкой мыши - Go to - CALL from 401245.

6375b8c7d380f64e1a144bd1aa989c40.png -

302e3b3570400c300c5c3d6c716b82cc.png -

Занятненько... Перед нами типичный код сравнения некоторого значения, в результате которого вызывается одна из тех двух функций с сообщениями: "No luck..." и "Great work...". Такое нельзя пропускать! Ставим точку останова на условный переход.

350e706eb552901f0f2b41b1c6e83711.png -

За одно, убираем точки останова на MessageBox. Это можно сделать через окно , т.е. Breakpoints:

ffd88eb23b9a790abd7a86be65acce0c.png -

d2db2ea09e6a86d14038f36e90f91e05.png -

Правая кнопка мыши - Remove. Таким образом убираем обе точки останова на MessageBox и оставляем только свежепоставленную точку на том подозрительном условном переходе.

ddf09e23333efd1a0f77770ef5ec873e.png -

Командуем Run (F9), принимаем сообщение "No luck...", которое мы только что трассировали. Снова вводим имя и серийник (используйте те же, что и на снимке).

828594cb78e43646c23fa391bd739c07.png -

Нажимаем OK.

1ddd1fbe8bd7fc53e3a3ed1af8243ca3.png -

Переход не осуществляется, т.к. предварительное сравнение EAX и EBX обернулось неравенством. Таким образом, выполняется вызов CALL 401362 - там нехорошее сообщение, если кто-то уже забыл. Можете нажать правую кнопку мыши - Follow и освежить память.

d62dce8f8a5b3794933c37dcbd604a56.png -

А что будет, если повлиять на условие перехода, изменив значение флага Z? Двойной щелчёк по флагу в окне регистров меняет его текущее состояние на протовоположное.

a42a9a9324fe7e6478f36146b3c26295.png -

Установленный флаг Z означает, что EAX = EBX, т.е. разность EAX - EBX равна нулю. Переход осуществляется.

4994e82c2fce34dc56ed870176bda2e1.png -

Теперь вызовется другая функция. Смотрим через Follow:

360c1368fd5ca6650afb931193fd0873.png -

Нажимаем Run (F9) :)))

fe0842364ba63d89528f3f9d586efd26.png -

Значит, то сравнение является ключевым моментом в проверке правильности серийника. Если значения EAX и EBX равны, выскакивает "хорошее" сообщение, иначе выводится "Lo luck...". Раньше мы заметили, что "нехорошие" сообщения в коде имеются в двух экземплярах, но в последний раз выскочило только одно из них. Когда крэкми замечает, что в имени есть цифры (в ricnar456 как раз они есть), сначала выводится одно сообщение, а потом, после ключевого сравнения, выводится ещё одно. Давайте проверим ещё раз.

d06b09624b020884d8527a1497161ea7.png -

Вводим имя, содержащее цифры. Нажимаем OK.

4308d0b106334066d9381b4b06155c74.png -

Появляется сообщение о неправильном серийнике и уже ПОСЛЕ этого срабатывает точка останова на условном переходе!

58fd9d150ffbe1d2f2ad213316eb8a61.png -

Потом появляется окончательное сообщение. Когда мы первый раз остановились на входе в MessageBox (на начальной стадии данного пособия), это был тот первый MessageBox, т.е. не окончательный.

0a72b99df13c2771789aef0b2d186c90.png -

Адрес возврата соответствовал 4013C1.

27ec32da37b8d794513a97485a3fbb22.png -

В окне дизассемблера выделена функция (см. жирную скобку), начинающаяся по адресу 40137E и заканчивающаяся по адресу 4013C1: там находится завершающий RET сразу после вызова MessageBox.

Обратите внимание, что по адресу 4013AC есть стрелочка (>), а это значит, что данный адрес используется в каком-то прямом переходе. Давайте выделим эту строчку, чтобы узнать где находится этот переход.

1537beb58d75d3425d4f8e78daf36d9b.png -

Перед нами ещё одно сравнение и условный переход, который приводит к отображению нехорошего сообщения. Давайте поставим точку останова в этом месте.

81ee458bbf8e01ab2bdbd5a51a10b417.png -

Снова пускаем приложение (RUN); принимаем сообщение; опять вводим наши дежурные данные регистрации (имя содержащее цифры!) и опять нажимаем OK.

65048ebd9758811b8255b010704063ae.png -

Данный код проверяет все буквы в имени пользователя. Злосчастный переход осуществляется, как только встретится цифра. При каждом прохождении цикла срабатывает точка останова. Нажмите F9 - остановка произойдёт уже на 2й букве.

На седьмом прохождении цикла (первая цифра в имени ricnar456 - это ‘4’ и занимает 7ую позицию) переход будет осуществлён, но мы этому воспрепятствуем :)

aecde993436e6ccb1670b9103b77b25b.png -

33711e7dea72ef328d3628627c413267.png -

Условный переход JB осуществляется в зависимости от состояния флага C. Делаем двойной щелчёк по этому флагу, чтобы изменить его состояние.

4763a34309bc543425f4c5f26400ff3a.png -

Таким образом, переход не будет выполнен. Повторяем фокус с флагом для 2х оставшихся цифер, чтобы не сработал этот переход.

cdf34b1de975fac6a171b7dc7c3bb75f.png -

Далее мы попадаем на сравнение EAX и EBX, где нужно повлиять на флаг Z, как в прошлый раз, чтобы переход осуществился.

ef6600536fa8f0e2e96e490c765f3038.png -

Нажимаем F9.

dce29b7a56392a52fa6a3661ccc8dfcd.png -

Не будем же мы всё время ручками менять флаги C и Z?! Настало время рассмотреть каким образом это дело можно зафиксировать, чтобы крэкми безропотно принимал любой серийник, причём вне отладчика.

Выделяем первый условный переход (где мы поставили точку останова).

057507b065e6e452154d4ac3afcb0f59.png -

Чтоб этот переход не выполнялся никогда, независимо от состояния флага C, его можно просто и грубо забить инструкциями NOP. Нажимаем на данном переходе пробел и вводим NOP.

3868544532e044ab21297f1f488b8b0e.png -

db8dbabc06c88156c80f5e3c83bf9562.png -

Точку останова уже можно убрать. Для этого достаточно нажать F2.

3f6d76a1fe436105c22da5ce212bfdc8.png -

Идём ко второму ключевому условному переходу.

897306354db292089666617de556fd2e.png -

В данном случае нам нужно, чтобы переход всегда выполнялся. Для этого его можно сделать безусловным, т.е. поменять JE на JMP.

566402137d0d8ac6917e1e2dea26f43d.png -

00d1029fcfae9a3424775065527c1424.png -

Давайте снимем и эту точку останова (F2). Пока ещё не выходим из OllyDbg! Чтобы опробовать в свободном полёте наши достижения, нажимаем F9.

f2328fe84d6474de72be6adce470fa0c.png -

Нажимаем OK.

f9d14cd8a2bcaa5a782a078afbb44afb.png -

Все изменения проделанные через опцию Assemble (пробел) улетучиваются при закрытии программы в отладчике. Эти изменения осуществляются в памяти и никак не влияют на оригинальный образ в экзешнике. Чтобы применить изменения к образу в экзешнике, делаем следующие манипуляции:

ce217e7d58ca05264fd3e991d06f6e23.png -

Правый щелчёк в любом месте листинга - Copy to executable - All modifications. Далее выводится следующий запрос:

c0a11988e965ae5a83af6b19b159ee9b.png -

Выбираем опцию Copy all чтобы перенести все изменения (в данном случае ими являются двойной NOP и один JMP).

7dd7fbe81c39ef4362dab2e38f045d08.png -

Открывается новое окно, в котором нужно опять сделать правый щелчёк - Save file.

094072bc8946b85132a1d5936e7a5a95.png -

8310cf2711070a31163b9e29c470b049.png -

Сохраняем файл под НОВЫМ именем (старый экзешник нам ещё пригодится, да и перезаписать его всё равно не получится, т.к. он всё ещё загружен операционной системой). Назовём новый экзешник CRACKME2.EXE.

9d1dd4f2eba349840497a931ab421dc4.png -

Вот, теперь можно, наконец, закрыть OllyDbg.

785ff576e4d75bc402a20e32fd3b0a5f.png -

Запускаем новую версию крэкми (уже вне отладчика) и проверяем, что регистрация проходит успешно при указании любого серийника.

8d7acff8e581833591feac3fbeb87302.png - Задаём Help - Register:

bb59e91eacd188b12b7c47b1fcb1a64f.png - Нажимаем OK.

1a27fe85599ba4f2cf70593c7921a2cd.png -

Вот мы и пропатчили крэкми! Но этого мало - в дальнейшем попробуем реверсировать полностью алгоритм проверки серийника, чтобы получить настоящие регистрационные данные, без использования патча. Но для этого надо ещё многому научиться.

Приложение. Windows 9x

В мастдае возможности отладчика ограничены. К примеру, нельзя ставить точки останова прямо на вызовы API-функций, как было показано на примере MessageBox в NT/XP. При выполнении поиска API-функций по импорту:

c7941f8ef615de8ec5d7ad1ed86b29a2.png -

Получаем аналогичный список импортируемых символов, но опция Toggle breakpoint on import не будет доступна, т.к. 9x не позволяет ставить точки останова прямо на внешние функции.

8e8392ba2dd3183aabda7f36b6edec34.png -

В остальном, контекстное меню будет сходным с полнофункциональным вариантом в NT.

8059465140f35d89c4178db2bf4ba840.png -

Таким образом, вызовы API-функций могут идти в обход точек останова. Достаточно вызвать функцию косвенным образом, чтобы анализатор не смог его автоматически засечь, и точка останова уже не сработает. Досадное ограничение, в общем.

Вместо одной точки останова на начало функции MessageBox в данном случае Вам придётся поставить 3 точки останова (F2): по одной на каждый вызов MessageBox, которые выводятся в списке внешних символов.

4af21106c64ef7ce13dfa9d75a1ae8da.png -

Нажимаем Run (F9); выбираем опцию Help - Register; вводим следующие регистрационные данные:

07a4077d93b045e73e4d97c81d7da46e.png -

Нажимаем OK - срабатывает одна из точек останова.

ed5a0bcee0c9240501950f58563447fd.png -

В NT/XP в этом месте мы ставили ещё одну точку останова на инструкции RET, внутри функции MessageBox. В 9х мы это не можем сделать, т.к. внутрь функции нас не пускают. Поэтому ограничимся точкой останова на следующей после CALL инструкции, т.е. уже после возвращения из функции.

95f79f8363ca10900b6f2ac3cf13c53c.png -

Аналогично поступаем в любой подобной ситуации по ходу развития учебного цикла. В 9х вместо точек останова на обращениях к внешим функциям, их приходится ставить на ссылки в конкретных вызовах. Теперь можете вернуться к основному материалу статьи , где написано:

Дальнейшее обсуждение касается обоих семейств Windows: 9x и NT.
 

О нас

  • Наше сообщество существует уже много лет и гордится тем, что предлагает непредвзятое, критическое обсуждение различных тем среди людей разных слоев общества. Мы работаем каждый день, чтобы убедиться, что наше сообщество является одним из лучших.

    Dark-Time 2015 - 2022

    При поддержке: XenForo.Info

Быстрая навигация

Меню пользователя