Пт, 15.12.2017, 08:30
Форум інформатиків України
Головна Реєстрація Вхід
Вітаю Вас, Гість · RSS
Вітання на форумі
Незнайомець
Вітаємо на форумі,
Незнайомцю!

   
зареєструйтесь
Перед реєстрацією обов’язково прочитайте:
Оновлення Учасники Пошук
Особисті повідомлення
Видавництво ’’Аспект’’ Видавництво

Сторінка 2 з 3«123»
Модератор форуму: Bandalak, Ktara, НІКОЛЯ, volevikt 
Форум інформатиків » РОЗДІЛ VIІІ: ОБМІН ДОСВІДОМ (УРОКИ, ФАКУЛЬТАТИВИ, ПОЗАКЛАСНА РОБОТА) » 8.6 Факультатив з програмування » Низькорівнева мова програмування - Асемблер (Обговорення що до використання та застосування)
Низькорівнева мова програмування - Асемблер
НІКОЛЯ Дата: Ср, 13.05.2009, 15:56 | Повідомлення № 1
Знавець вірусів
Повідомлень: 2877
Нагороди: 17
Рейтинг: 201
Еволюція засобів проектування програм протягом останніх десятиліть здатна здивувати будь-яку людину, програмного забезпечення, що займається розробкою. Особливо це стосується написання програм для операційних систем сімейства Windows. Сучасні інструментальні засоби настільки розвинені, що розробник програмного забезпечення може отримати готову програму за допомогою декількох клацань. Величезна кількість книг, статей і початкових текстів програмної коди присвячено проектуванню програм на Pascal, Basic і інших мовах програмування. Мова низького рівня — мова асемблера — після смерті" MS-DOS, здавалося, доживає останні дні. Але всупереч прогнозам він не зійшов з арени і продовжує вельми широко використовуватися при розробці програм. У чому ж секрет живучості цієї мови?
Відповідь досить проста і може бути сформульований однією пропозицією: мова асемблера — це мова, на якій "говорить" процесор, і зникнути він може тільки разом із зникненням процесорів! З цієї ж причини асемблер має одну фундаментальну перевагу перед мовами високого рівня: він найшвидший. Більшість додатків, що працюють в режимі реального часу, або написані на асемблері, або використовують в критичних ділянках коди асемблерні модулі.
Нерідко можна чути твердження про те, що процес розробки програм на мові асемблера дуже трудомісткий і віднімає масу часу. Ще однією перешкодою для роботи з асемблером рахують його складність. І, нарешті, як аргумент приводиться твердження, що розробка додатків на асемблері сильно утруднена через відсутність сучасних інструментальних засобів для проектування і відладки.
Такі твердження, взагалі-то, не відповідають дійсності. Мова асемблера не складніше за інші мови програмування і досить легко освоюється як досвідченими, так і початкуючими програмістами. Крім того, останніми роками з'явилися дуже могутні інструментальні засоби розробки програм на асемблері, і це вимушує по-іншому поглянути на процес розробки програм на цій мові. Серед таких інструментальних засобів проектування можна назвати макроасемблер



Сайт по Асемблеру ТУТ

НІКОЛЯ Дата: Чт, 14.05.2009, 23:05 | Повідомлення № 16
Знавець вірусів
Повідомлень: 2877
Нагороди: 17
Рейтинг: 201
Quote (NatVovk)
Скажу прямо і відверто (хоча це знову здасться комусь агресивністю): можна, звичайно й зайця навчити курити, але для чого?

Для того що, ми учим майбутніх програмістів та викладачів вищих навчальних закладів, майбутніх геніїв.
Quote (NatVovk)
А на чому конкретно показувати це? Як на мою думку, то на Паскалі — те що доктор прописав.

Коли доктор не задовольняє потреб клієнта його змінюють на іншого, доволі поширена практика,
Quote (NatVovk)
Не забуваймо, що середня загальноосвітня школа має давати БАЗОВІ знання.

Цікава думка! Приходить до мене дитина яка має всі задатки Майбутнього фахівця в області прграмування і говорить що хоче вивчити наприклад джаву
А МЕНІ ЇЇ ПРИЙДЕТЬСЯ ВІДПОВІСТИ ЩО; ЧЕКАЙ КОЛИ ЗАКІНЧИШ ШКОЛУ ПОСТУПИШ В ВНЗ А ПОТІМ ВЧИТЕМЕШ бо дяді які сидять в міністерськіх кабінетах не дозволяють вчити в такому віці такі сирйозні речі . НОНСЕНС.


Відредаговано: НІКОЛЯ - Чт, 14.05.2009, 23:06
PanPete Дата: Пт, 15.05.2009, 10:36 | Повідомлення № 17
Наполегливий учасник
Повідомлень: 797
Нагороди: 1
Рейтинг: 45
Quote (НІКОЛЯ)
Приходить до мене дитина яка має всі задатки Майбутнього фахівця в області прграмування і говорить що хоче вивчити наприклад джаву

<_< Вам необхідно провести анкетування і перевести вивчення інформатики на індивідуальні заняття з учнями за виявленими інтересами.
А якщо серйозно - ваше бачення місця вивченння асемблера в шкільні програмі (вік, підготовчий базис, необхідний час, тощо)
НІКОЛЯ Дата: Пт, 15.05.2009, 10:54 | Повідомлення № 18
Знавець вірусів
Повідомлень: 2877
Нагороди: 17
Рейтинг: 201
Quote (PanPete)
вік, підготовчий базис, необхідний час, тощо)

Хвора тема .Що до виділення часу то у відповідь на запитання від дирекції почув " Якщо бажаєте або на факультативі або в особистий час тоість після уроків залишайтесь і будласка ми тільки за" а що до віку з-алежить від розвитку та бажання дітей , Як ви розумієте дитина мусить бути розвинена як в математиці ,інформатиці так і фізиці для вивчення . А ще способність осмислити структурізацію та основний принцип роботи інакше це пуста затія . Таких дітей одиниці але наше завдання підтримати бажання дитини та дати їм можливість спрбувати себе. Навчивши всьому що можемо дати. Даже за рахунок власного часу. В мене щас такіх дітей троє. І я у власний час безкоштовно стараюсь донести все що знаю сам до їх світлих голів .


Відредаговано: НІКОЛЯ - Пт, 15.05.2009, 11:44
NatVovk Дата: Пт, 15.05.2009, 12:33 | Повідомлення № 19
Гол. ред. "Інформатики"
Повідомлень: 168
Нагороди: 0
Рейтинг: 10
Quote (НІКОЛЯ)
В мене щас такіх дітей троє. І я у власний час безкоштовно стараюсь донести все що знаю сам до їх світлих голів

НІКОЛЯ, коли я тут сперечалася щодо доцільності асемблерів, то мала на увазі, що для масового учня це не вихід, але якщо у Вас є трое вмотивованих учнів, які прагнуть (і це головне) освоїти трішки більше, ніж пропонує стандартна програма, то з ними обов’язково потрібно займатися. Як на мене, то факультатив — це найкраще. Адже на факультатив можуть приходити учні з різних класів. А такі з’являться, коли Ви з цими трьома почнете займатися.
Тут хочеться згадати Лебедєва (творець МЕСМ і БЕСМ), так от, коли йому було років 9-10, він вже сам сконструював радіокерований іграшковий кораблик, який запускав у ставку. Батьки від нього вже почали ховати книжки (адже дитина читала вдень і вночі), вони турбувалися за його здоров’я. Але й це не допомогло. Він читав з лихтариком під ковдрою.
Отже, коли є такі діти, то наш обов’язок їх навчити всьому, що самі знаємо.
VicS13 Дата: Пт, 15.05.2009, 13:02 | Повідомлення № 20
Тут живе...
Повідомлень: 103
Нагороди: 0
Рейтинг: 6
В любом случае считаю, что изучение ассемблера современного х86 процессора немного сложновато для средней школы.
Но повторюсь. Выход есть и это ассемблер микроконтроллеров. Куча выгод:
- простая архитектура
- простой набор периферии:
- небольшой набор ассемблерных инструкций.
- Компиляторы, отладчики, эмуляторы разные под вин и линукс.
- Наглядность....

Применение именно микроконтроллеров при изучении ассемблера будет тем мостиком, который позволит в кратчайшие сроки изучить ассемблер взрослых машин (при необходимости) и научит детей именно ОТВЕТСТВЕННОСТИ за качество своего кода, его оптимизацию.
Это и будут именно те БАЗОВЫЕ знания для учащихся.....
Именно программирование развивает у ученика мышление всех типов и форм, а не создание презентации из готового шаблона.....

Плюс переход на язык более высокого уровня значительно упростится. К примеру понимание сути сишного указателя значительно ускорится....

PanPete Дата: Пт, 15.05.2009, 13:51 | Повідомлення № 21
Наполегливий учасник
Повідомлень: 797
Нагороди: 1
Рейтинг: 45
Quote (VicS13)
Выход есть и это ассемблер микроконтроллеров

При цьому в школі можна започаткувати роботу творчої групи з робототехніки (ідея була озвучена на одній з віток форуму, вибачте, але не памятаю на якій)


Відредаговано: PanPete - Пт, 15.05.2009, 13:51
НІКОЛЯ Дата: Пт, 15.05.2009, 13:51 | Повідомлення № 22
Знавець вірусів
Повідомлень: 2877
Нагороди: 17
Рейтинг: 201
Quote (NatVovk)
Адже на факультатив можуть приходити учні з різних класів. А такі з’являться, коли Ви з цими трьома почнете займатися.

На міжшкільному факультативі в мене й так 32 дітей а от справді з вродженими задатками майбутніх геніїв тільки троє. Що саме цікаво в ціх дітей нема зациклення на вузькі спеціалізації вони практично та теоретично стараютья охопити весь спетр, рухаючись в багатох напрямках відразу.
Спочатку я думав що це минеця але вже 2 роки не минається тож щас вимушений уділяти їм їм трохи більше часу. Двоє планують на слдуючий рік поступати в ВНЗ. Буду готувати, може колись скажуть спасибі. :)

Quote (VicS13)
Плюс переход на язык более высокого уровня значительно упростится. К примеру понимание сути сишного указателя значительно ускорится....

Практично всі троє учать вже другий рік одночасно з мови мене спочатку скажу чесно це дивувало і я вагавсь чи це буде їм під силу .
З часом зрозумів що зробив правильно що не обмежував що до навчання одного напрямку .
А бува ставлять такі запитання що мені самому доводиться призадуматись .
Або видають цікаві концепсії які скажу відверто дорослим людям з досвідом в голову не завжди прийти можуть .
Отакі то справи.


Відредаговано: НІКОЛЯ - Пт, 15.05.2009, 14:00
VicS13 Дата: Пт, 15.05.2009, 20:55 | Повідомлення № 23
Тут живе...
Повідомлень: 103
Нагороди: 0
Рейтинг: 6
Quote (НІКОЛЯ)
Або видають цікаві концепсії які скажу відверто дорослим людям з досвідом в голову не завжди прийти можуть .

Ой какая правда....... 100 раз такое было со мной.
Взрослый человек зациклен в рамках своего жизненного опыта.... Он находится в своём опыте как в коконе.... Вернее как мумия в своих бинтах.....

Додано (15.05.2009, 20:55)
---------------------------------------------
PanPete, Робототехника - это вообще песня. Хотя в школе сложновато.... В плане часов и оплаты...
Вот мне бы в своём дворце пионеров было бы самое то..... Но.... Необходимость капиталовложений, на которые нет средств, приводит в уныние......

AAN Дата: Нд, 17.05.2009, 20:07 | Повідомлення № 24
Тут підглядає ...
Повідомлень: 166
Нагороди: 2
Рейтинг: 30
Покупаю журнал «Компьютер» (не методический). В 3-4 номере за 2009 год интересная статья «Языки программирования: какой изучать?» про ассемблер тоже есть заметка. Тут же нашла ссылку на книгу по ассемблеру и другие языки http://amonit.sulfurzona.com/index.php?art=7
NatVovk Дата: Пн, 18.05.2009, 21:36 | Повідомлення № 25
Гол. ред. "Інформатики"
Повідомлень: 168
Нагороди: 0
Рейтинг: 10
Вперше (десь у 2001-2002 році) такий матеріал (про асемблери), я запропонувала написати своєму колишньому співробітникові, але він не встиг завершити роботу, його не стало з нами.
Вдруге про асемблери я замовила матеріал дуже чудовому науковцю, але результат такий самий.
Тепер боюся комусь пропонувати. Та й сама боюся братися за таку дуже цікаву й дуже непросту тему, хоча в аспірантурі колись вивчали дуже непогано.
Ірина Дата: Сб, 08.08.2009, 19:46 | Повідомлення № 26
Профі в програмуванні та безпеці
Повідомлень: 140
Нагороди: 0
Рейтинг: 15
Вспомните, с чего начинаются едва ли не все платные программы: с предложения зарегистрироваться. Это предложение может быть написано аршинными буквами в отдельном окне, появляющемся при запуске, или же в виде маленького MessageBox’а, выскакивающего в самый неподходящий момент во время работы. Оно может быть мерцающим баннером вверху или внизу экрана. Но, как бы оно ни выглядело, цель его существования во всех этих случаях одна: раздражать и давить на психику незарегистрированного пользователя, дабы он, зажав в кулак свои кровные, отправился на почту и перевел их автору программы в знак благодарности за будущее избавление от назойливого окна. Однако далеко не у всех людей, созерцавших эти безыскусные творения, возникали столь теплые чувства к разработчику. И эти раздраженные пользователи дали надоедливым окнам то самое имя, под которым они и известны современному крэкеру. Называются эти окна «nag screens» (от английского «nag» - «надоедать, приставать, придираться»), речь как раз пойдет о способах борьбы с такими окнами.

[spoiler]Прежде чем переходить к рассмотрению методов борьбы с нежелательными окнами и конкретных примеров их применения, рассмотрим проблему баннеров и nag screen’ов, что называется, в перспективе. Я бы выделила четыре подхода к задаче ликвидации рекламных вставок в программах:
1. Изменение свойств объектов (окон, визуальных компонентов) таким образом, чтобы они не отображались на экране. На практике это может быть достигнуто тремя способами: выносом нежелательного объекта за пределы экрана (проще всего использовать отрицательные координаты – при любых размерах монитора объект все равно будет за пределами видимой части экрана); изменением размеров объекта (к примеру, дочерние окна нулевой длины и ширины на экране не видны); модификацией шаблонов диалогов с тем, чтобы придать нежелательным объектам свойства невидимости и неактивности.
2. Удаление шаблонов объектов из исполняемого файла.
3. Модификация кода с целью предотвратить создание или отображение нежелательного объекта.
4. Модификация кода таким образом, чтобы нежелательный объект самоликвидировался сразу после появления.
Вот о первых двух подходах, в основном, и пойдет речь в этой главе.

Ради того, чтобы упростить жизнь программистам, в ОС Windows реализована возможность интегрировать в исполняемый файл ресурсы всевозможных типов – текстовые строки, иконки, изображения в стандартных форматах и, что самое интересное, так называемые «шаблоны» (templates) диалоговых окон. Эти шаблоны описывают внешний вид диалогов: размеры, атрибуты, находящиеся внутри диалога управляющие элементы (меню, кнопки, поля редактирования и т.п.) и надписи на этих элементах. При помощи соответствующих функций Windows API на основе этих шаблонов могут быть созданы реальные окна, внешний вид которых будет в точности соответствовать их описанию внутри шаблона. Открыв такой исполняемый файл при помощи какого-либо редактора ресурсов (наиболее известны Resource Hacker, Restorator и eXeScope), Вы можете попытаться модифицировать ресурсы программы, например, перевести все надписи на русский язык (если быть до конца точным, то у ресурсов имеется еще один атрибут – идентификатор языка, который, возможно, также потребуется модифицировать). Если Вы все сделаете правильно, и редактор ресурсов корректно сохранит изменения, после запуска программы соответствующие надписи будут русифицированы. Таким же образом Вы можете изменять расположение и свойства элементов интерфейса (например, наличие рамки и ее цвет) в диалоговых окнах. Более того, Вы можете заменить не только надписи, но и хранящиеся в ресурсах изображения, своими собственными. Нужно отметить, что ресурсы могут храниться не только внутри исполняемого файла, но и в любом другом файле формата Portable Executable. Чаще всего это делается для облегчения локализации – реализовать выбор одной из возможных ресурсных DLL гораздо проще, чем выпускать множество локализованных версий одного и того же исполняемого файла. Кроме того, ресурсные DLL – довольно удобный способ хранения «шкурок» (skin’ов) для приложений, использующих эту технологию модификации интерфейса.

Вообще все ресурсы делятся на типы, среди которых есть такие, как иконки (RT_ICON), курсоры (RT_CURSOR), шаблоны диалоговых окон (RT_DIALOG) и многое другое. Для идентификации каждого конкретного ресурса среди других ресурсов того же типа используются числовые либо символьные идентификаторы. Именно на основе идентификаторов программа и различает ресурсы между собой. Что интересно, программе совершенно нет дела до тех данных, которые прячутся за идентификаторами – поэтому, поменяв местами идентификаторы у пары однотипных ресурсов, можно получить весьма занятные эффекты: например, вместо сообщения об успешном завершении той или иной операции будет появляться сообщение об ошибке (и наоборот).

Теперь немного поговорим о том, какие тайны скрываются в недрах шаблонов диалоговых окон. Прежде всего, умение обращаться с шаблонами позволит Вам полностью преобразить интерфейсы очень многих программ, причем сделать это с минимальными затратами сил. Большинство редакторов ресурсов умеют не только декодировать шаблоны в исходный текст, понятный компиляторам ресурсов (при желании Вы можете «одолжить» особенно понравившееся окно из чужой программы), но и непосредственно показывать, как этот диалог будет выглядеть на мониторе. А наиболее продвинутые редакторы позволяют даже править эти шаблоны визуальными средствами. Кто знаком с современными визуальными средствами разработки, тот, наверняка, догадался, о чем идет речь. А те, кто не догадался, могут просто взять Калькулятор из состава Windows 2003 , программку Resource Hacker и вдоволь поэкспериментировать над первой программой при помощи второй: например, поменять местами все кнопки в Калькуляторе. Причем настоятельно рекомендую Вам попытаться проделать эту операцию не только тасканием-бросанием кнопок а-ля Visual Basic, но и через ручную правку ресурсного скрипта (resource script).

Но махинации с кнопками – это, в общем-то, мелочи, несмотря на тот могучий эффект, который производит «обработанный напильником» Калькулятор на неподготовленного пользователя. Гораздо более важно другое – а именно то, что управляющие элементы шаблона также имеют свои собственные идентификаторы, по которым программа различает управляющие элементы между собой и «общается» с ними. И эти идентификаторы также можно менять при помощи редактора ресурсов. Попробуйте проделать над несчастным Калькулятором еще один опыт – поменяйте местами значения идентификаторов у двух кнопок, например, у единицы и семерки. Запустив Калькулятор, Вы увидите, что единица и семерка действительно поменялись местами! Кроме идентификатора Вы можете менять и другие атрибуты кнопок (более корректно называть их не атрибутами кнопок, а стилями окна) – видимость, наличие рамки, способ выравнивания текста и многое другое. И из этой возможности следуют кое-какие выводы чисто практического свойства.

Довольно часто авторы shareware пользуются следующим приемом: сразу после запуска программы выводится nag screen, кнопка закрытия которого изначально неактивна и активизируется лишь спустя несколько секунд. Внутри программы это может быть реализовано следующим образом: в шаблоне, по которому создается nag screen, стиль этой кнопки изначально определен как неактивный (он называется WS_DISABLED). После создания окна запускается таймер, который через установленное время активизирует нужную кнопку, и пользователь получает возможность закрыть окно. Однако если мы уберем у кнопки стиль WS_DISABLED, пользователю больше не потребуется ждать несколько томительных секунд, чтобы получить возможность нажать на кнопку. Аналогичным же образом иногда удается включить неактивные функциональные элементы не только на nag screen’ах, но и непосредственно в самой ломаемой программе. Увы, всвязи с появлением некоторого количества программ, способных принудительно включать неактивные элементы управления, закрывать «лишние» окна и проделывать прочие столь же милые вещицы (ваш покорный слуга со своим проектом Sign 0f Misery тоже отметился на этом поприще), авторы shareware все чаще вводят различные дополнительные проверки, призванные оградить назязчивую рекламу от священного права пользователя эту рекламу не смотреть.

Однако самое интересное заключено даже не в манипуляциях с идентификаторами и стилями. Куда более важным представляется вопрос – а что если просто взять и удалить из секции ресурсов «лишний» диалог? Будем рассуждать логически: создание диалоговых окон производится при помощи семейства функций CreateDialog*** (которые затем требуют принудительно отобразить окно при помощи ShowWindow) либо при помощи DialogBox*** (это семейство функций все операции по отображению окна берет на себя). Причем для создания модальных окон (т.е. таких, которые пользователь не смог бы проигнорировать) чаще используется именно второе семейство функций.

Предположим, что программа попыталась создать nag screen на основе шаблона диалога при помощи функции DialogBoxParam (или любой другой функции из семейства DialogBox***), и у нее это не получилось. Большинству разработчиков такой вариант обычно даже в голову не приходит – а потому и проверку на существование шаблона nag screen’а программа обычно не делает, а сразу переходит созданию и выводу окна на экран. Что бы Вы сделали, если бы Вас попросили создать окно на основе «никакого» шаблона? Правильно, абсолютно ничего! Вот и Windows поступает точно так же – а именно, ничего не делает. Хотя на самом деле такое «ничего» все-таки может иметь далеко идущие последствия: ни разу не выполнится, к примеру, оконная процедура выдранного с корнем диалога, что, в свою очередь может повлечь за собой труднопредсказуемые эффекты. Вспомните принцип минимального вмешательства – и ужаснитесь тому, что предлагаю Вам содеять: вырвать из программы особо ценный (с точки зрения разработчика, разумеется) ресурс, отключить «не глядя» оконную процедуру, спровоцировать передачу некорректных данных как минимум в одну функцию WinAPI…

Но «суха теория, мой друг…», а потому все же посмотрим, что там у нас выросло на зеленеющем «древе жизни». В качестве наглядного пособия я возьму программу SkyMap Pro 8 Demo, которая обладает одним весьма ценным для нас качеством – наличием nag screen’а, шаблон которого упрятан глубоко в недрах секции ресурсов и имеет идентификатор 3006. В качестве орудия, при помощи которого производилась ампутация надоедливого диалога, я воспользовался программой Resource Hacker (в принципе, подошел бы и любой другой редактор ресурсов). Сама операция заняла не более 15 секунд, после чего исполняемый файл «похудел» на 4 килобайта. После того, как я произвел пробный запуск исправленной программы, оказалось, что nag screen как рукой сняло – и мне для этого не потребовались отладчики, дизассемблеры и прочая крэкерская «тяжелая артиллерия»! Видите: все далеко не так страшно, как может показаться. В принципе, если Вы считаете, что выдирание диалога с корнем – слишком уж варварская операция, шаблон можно оставить на месте, лишь заменив его идентификатор на другой, не используемый в программе. Результат будет аналогичный – программа не сможет найти ресурс с измененным идентификатором и не создаст nag screen. Этот прием даже предпочтительнее – практика показала, что не всегда и не во всех редакторах ресурсов операция удаления проходит успешно.

А ведь есть еще и третий путь избавиться от диалога путем изменения идентификатора! Ничто не мешает исправить идентификатор не в секции ресурсов, а непосредственно в исполняемом коде, в том месте, где этот идентификатор передается в функции WinAPI. Поскольку наш идентификатор имеет довольно редкое значение 3006, он как нельзя лучше подходит для поиска внутри исполняемого файла. Найдя среди всех подходящих значений то, которое отвечает за создание nag screen’а – замените его каким-нибудь другим, не указывающим ни на один диалог, например – на 12345. Когда Вы запустите исправленное приложение, оно, конечно, попытается найти и загрузить шаблон с ID=12345 – но у программы это все равно не получится. Впрочем, я считаю такой путь излишне изощренным и рассказал о нем главным образом в познавательных целях – гораздо проще забить вызов функции создания диалога и все, что с ней связано, nop’ами и получить тот же самый эффект.

Успешность такого метода борьбы с «лишними» окнами, вообще, сильно зависит от внутренней логики приложения. Nag screen, к примеру, может оказаться не «пустышкой», предназначенной исключительно для раздражения пользователя, а исполнять какие-либо неочевидные функции. Например, на обработку сообщения WM_INITDIALOG в оконной процедуре nag screen’а может быть подвешена инициализация каких-либо критически важных для программы структур. В общем случае такая инициализация может происходить при возникновении практически любого события связанного с этим окном: при нажатии на какую-либо кнопку в окне, при закрытии окна, в момент поступления первого сообщения [/spoiler]

Додано (08.08.2009, 19:30)
---------------------------------------------
[spoiler]WM_PAINT – перечислять варианты можно очень долго. И если просто удалить nag screen, это «волшебное» событие не произойдет – следовательно, не будет произведена инициализация, отчего, в итоге, программа будет работать некорректно, если вообще будет работать.

На практике такая защитная техника в чистом виде встречается достаточно редко – ведь программисту, использовавшему подобный прием, придется учитывать при программировании различия в работе между полной/зарегистрированной (без nag screen’а) и урезанной/незарегистрированной версиями программы. Тем не менее, если Вы все же столкнетесь с реализацией такого алгоритма, Вам вряд ли станет легче от осознания редкости встреченной проблемы. Поэтому давайте подумаем о том, как эту проблему можно было бы решить. В теории решение довольно простое: Вам нужно найти функции, которые выполняют все нужные действия по инициализации, и вызвать их вручную. На практике Вам скорее всего понадобится добраться до цикла выборки сообщений внутри оконной процедуры и проанализировать его содержимое. Обратите также внимание на следующий факт: если Вам удалась обнаружить, что инициализация программы происходит в ответ на WM_INITDIALOG, из этого отнюдь не следует, что Вам необходимо выполнить все действия, которые программа выполняет при поступлении этого сообщения. Посмотрите на следующий пример:

.IF uMsg==WM_INITDIALOG
invoke GetDlgItem, hWnd, TRIALUSE_BTN
invoke SetFocus,eax
invoke InitProgram

После того, как мы умозрительно удалили диалог, которому должно было поступать сообщение, попытка установить фокус на кнопку TRIALUSE_BTN становится совершенно бессмысленна – поскольку больше нет диалога, нет и кнопки которая в этом диалоговом окне находилась. Поэтому в нашем простейшем примере вместо вызова функций создания диалога было бы достаточно просто написать call InitProgram, а все лишние байты забить nop’ами. Однако представьте себе, что оконная процедура содержит какие-либо локальные переменные (например, вычисленное ранее число дней до истечения триального срока), используемые внутри InitProgram или же проделывает какие-либо операции с созданным диалогом – и Вы поймете, почему простейший путь не является лучшим. Что делать в таком случае? Из каждой безвыходной ситуации есть как минимум два выхода. Можно углубиться в дебри процедуры InitProgram и проверить, не обращается ли она к каким-либо объектам, которые мы так лихо снесли вместе с диалогом и потом долго заниматься художественной штопкой машинного кода. Я сам пару раз применял такую технику и могу сказать определенно: этот процесс мне совершенно не понравился. Поэтому мы поступим хитрее – попробуем поискать другое, более простое решение.

Практически в любом nag screen’е изначально заложен способ от него избавиться. Этим способом может быть клик по кнопке в диалоге, нажатие «горячей клавиши» или же истечение определенного времени с момента появления окна. Все эти случаи объединяет одно - nag screen ждет некоего события, наступление которого станет для него сигналом к исчезновению. «Приемник» этого сигнала, который и выполняет все действия по убиранию nag screen’а с экрана, чаще всего прячется во все той же оконной процедуре, о которой уже столько раз говорилось и еще не раз будет сказано. Для тех, кто не особо интересовался программированием с использованием «чистого» WinAPI, дам некоторые пояснения относительно традиционного устройства оконной процедуры.

«Сердцем» оконной процедуры, несомненно, является обработка сообщений, поступающих от окна, которая на ассемблере выглядит приблизительно так:

.IF uMsg==WM_DESTROY
invoke PostQuitMessage,NULL
.ELSEIF uMsg==WM_INITDIALOG
...
.ELSEIF uMsg==WM_COMMAND
mov eax,wParam
.IF ax==ID1
...
.ELSEIF ax==ID2
...
.ENDIF
.ELSE
invoke DefWindowProc,hWnd,uMsg,wParam,lParam
ret
.ENDIF

Додано (08.08.2009, 19:39)
---------------------------------------------
[spoiler]Не вдаваясь в подробности (которые Вы можете найти в документации и в книгах по программированию под Windows), скажу, что обычно все самое интересное - обработка нажатий на кнопки или реакция на выбор пунктов меню - скрывается в блоке, анализирующем сообщение WM_COMMAND. Внутри этого блока обычно выполняется последовательное сравнение параметров сообщения wParam и lParam с идентификаторами и хэндлами управляющих элементов (кнопок, элементов меню, тулбаров и т.п.). Если значения хэндла и идентификатора указывают, что пользователь нажал на некий элемент - программа выполняет соответствующие действия. Допустим, что мы знаем, где располагается оконная процедура интересующего нас окна. Что мы можем сделать с нашей находкой? Самое простое – это, конечно, возможность менять местами функции управляющих элементов: если в приведенном выше примере поменять местами значения ID1 и ID2, соответственно изменятся и функции элементов с идентификаторами ID1 и ID2. Менее очевиден, но тоже достаточно прост для понимания тот факт, что можно «переключить» реакцию программы с одного сообщения на другое. К примеру, заменив в нашем примере WM_INITDIALOG на WM_PAINT, мы заставим процедуру инициализации выполняться не единожды при создании диалога, а при поступлении каждой команды на перерисовку содержимого окна. Зачем такое может понадобиться? С точки зрения среднего программиста это действо совершенно нелогично, нефункционально, и даже более того – опасно. Но крэкинг – это искусство, существующее по ту сторону обычного программирования. И именно благодаря своей «потусторонней» сущности даже во внешне бессмысленных операциях крэкер способен узреть потаенные возможности и раскрыть их к своей пользе.

Итак, представим также, что кнопка ID1 закрывает nag screen (на самом деле представлять придется только Вам – у меня код этого примера сейчас перед глазами). Наша задача – убрать nag screen любыми доступными средствами. Как можно решить эту задачу? Да очень просто - базовую идею я описал парой строчек выше. Перво-наперво заменим в оконной процедуре константу WM_COMMAND на WM_PAINT. Следующее, что нам нужно – это чтобы оконная процедура реагировала на сообщение WM_PAINT как на нажатие кнопки с идентификатором ID1. Добиться этого можно, подправив условие IF ax==ID1 таким образом, чтобы оно выполнялось в любом случае, независимо от величины wParam. Думаю, проделать такой фокус не составит никакого труда даже для самого начинающего крэкера, только-только научившегося заменять условный переход на безусловный. Если в оконной процедуре присутствует «настоящий» обработчик WM_PAINT, есть смысл при помощи безусловного перехода выполнить и его – ради соблюдения принципа минимального вмешательства. На этом нашу миссию можно считать завершенной – после внесенных исправлений nag screen будет закрываться сам собой сразу же после появления. Главная хитрость заключается в том, что как только nag screen пытается стать видимым (а Вы когда-нибудь видели невидимые nag screen’ы?), окно этого screen’а автоматически получит команду на перерисовку содержимого клиентской области - сообщение WM_PAINT. Мы же, движимые возвышенными эстетическими чувствами, протестующими против созерцания рекламных банальностей, преобразовали это безобидное сообщение в приказ немедленно убрать раздражающее окно с экрана.

Все, о чем я говорила выше, относится к классическим средствам работы с окнами и диалогами Windows и к объектно-ориентированным «оберткам» для WinAPI. Однако фирма Borland внесла в такую консервативную область, как графические интерфейсы Windows-программ, заметное оживление. Я имею в виду прежде всего фирменную борландовскую разработку: Visual Component Library (она же VCL) – объектно-ориентированную библиотеку, предназначенную для создания графического интерфейса. Впервые эта библиотека появилась в Delphi 1 и с тех пор стала неотъемлемой частью всех версий Delphi и C++ Builder. В VCL широко используются такие нетрадиционные для Windows вещи, как «безоконные» управляющие элементы (non-windowed controls), по сути представляющие собой картинки на экране, и потому напрямую не подчиняющиеся функциям WinAPI. Другим новшеством, внедренным Borland, является специфический формат хранения шаблонов форм – они хранятся как данные типа RCData, причем в качестве идентификаторов используются названия классов этих форм: к примеру, шаблон формы класса TMyForm хранится в ресурсах под именем TMYFORM. Ну и, наконец, VCL отличается от большинства библиотек аналогичной направленности обширной и довольно сложной иерархией классов[/spoiler]

Додано (08.08.2009, 19:39)
---------------------------------------------
[spoiler]Давайте возьмем какую-нибудь программу на Delphi (я взяла одну из своих разработок) и попробуем повторить эксперимент с удалением шаблона какого-нибудь диалога. Открываем файл программы в Resource Hacker, выбираем любую понравившуюся форму – и видим, что Resource Hacker нещадно глючит, пытаясь перевести шаблон из внутреннего борландовского формата в более удобочитаемое нечто. На самом деле Resource Hacker довольно успешно понимает формат Borland’овских шаблонов – просто я использовала слишком новую версию Delphi, о которой наш редактор ресурсов, увы, ничего не знает. Кстати, если взглянуть на тот же ресурс в шестнадцатиричном редакторе, Вы увидите перед собой малопонятную кучу байт, в которую вкраплены имена компонентов и их свойств, а также текстовые значения. Но мы пока не будем пытаться дешифровать шаблон, а просто удалим его. Удаляем, запускаем, пытаемся вызвать соответствующее окно – и получаем сообщение Resource <имя удаленного нами ресурса> not found. Да, это определенно не то, о чем мы мечтали – nag screen, конечно, исчез, но окошко с сообщением об ошибке смотрится ничуть не лучше. Увы, так просто от nag screen’ов в программах на Delphi не избавиться.

Поскольку Resource Hacker показал себя не с лучшей стороны, внесем коррективы в наш инструментарий: возьмем eXeScope 6.41 (последняя версия на момент написания данной главы) – эта программа более-менее успешно переваривает шаблоны Delphi 7 с надписями в кодировке Unicode. Если Вы не хотите нарушать ничьих авторских прав хотя бы в процессе обучения, раздобудьте для экспериментов мою программку InqSoft Window Scanner – лицензионное соглашение дает Вам полный карт-бланш на ее ломание в учебных целях. Распакуйте ее UPX’ом, откройте полученный исполняемый файл в eXeScope и найдите шаблон формы TAboutForm. Вы увидите что-то вроде:

object AboutForm: TAboutForm
Left = 265
Top = 185
BorderIcons = [biSystemMenu]
BorderStyle = bsSingle
Caption = #1054' '#1087#1088#1086#1075#1088#1072#1084#1084#1077'...'
ClientHeight = 192
ClientWidth = 318
...
end

Если Вы раньше программировали на Delphi или C++ Builder, Вы наверняка уже догадались, что это – текст типичного dfm-файла, в котором описан шаблон формы вместе со всеми ее компонентами, как визуальными, так и не очень. Если же Вы не программировали ни на Delphi, ни на C++ Builder – Вам будет непросто разобраться в ломании программ, написанных при помощи этих средств разработки. Однако в этой главе мы будем разбирать достаточно простые вещи, для понимания которых достаточно знания английского языка, основ ООП и знакомства с любым визуальным средством разработки. В конце-концов, тот, кто умеет помещать управляющие элементы на шаблоны диалогов в RadAsm’е, вряд ли испытает какие-либо трудности в понимании того, как бросать точно такие же компоненты на формы в Delphi. Но в общем случае работает совершенно обратное правило: чтобы эффективно исследовать программу, необходимо иметь представление об инструментах, с использованием которых эта программа была написана. То есть, чтобы взломать программу, написанную на С++ Builder, нужно знать характерные особенности С++ Builder.

Одной из таких характерных особенностей, к примеру, является то, что имена классов окон (понятие «класс окна» здесь используется в том же смысле, что и в документации по Windows API) в Delphi/С++ Builder начинаются с буквы T и совпадают с именами классов форм. Проще говоря, если программа создает окно как экземпляр класса TMyForm, то имя класса окна, возвращаемое WinAPI’шной функцией GetClassName, тоже будет TMyForm. Собственно, InqSoft Window Scanner в качестве объекта для экспериментов я посоветовал не случайно – эта программа, помимо прочих функций, как раз умеет определять имена классов окон. Как Вы помните, имена классов форм в программе совпадают со строковыми идентификаторами шаблонов этих форм в секции ресурсов, поэтому «подглядев» средствами WinAPI имя класса окна, Вы смело можете шерстить секцию ресурсов на предмет наличия ресурса типа RCDATA с соответствующим идентификатором, и, скорее всего, Вы такой ресурс обнаружите.

Строго говоря, использование механизмов наследования в Delphi/C++ Builder позволяет создавать формы, у которых имя класса окна отличается от символьного идентификатора шаблона, но в большинстве программ эта возможность не используется. Да и распознать форму-наследника по dfm-описанию родителя обычно бывает не так уж сложно, поэтому я не буду заострять внимание на этом достаточно специфическом случае.

Итак, что нам показал eXeScope? А показал он описание формы и свойства всех ее компонентов, причем в самом что ни на есть текстовом виде. Вы наверняка уже поняли, что слово object начинает описание объекта (или компонента, если быть до конца точным), а слово end это описание завершает. И что строки вроде Left = 265, BorderIcons = [biSystemMenu] или BorderStyle = bsSingle представляют собой ни что иное, как имена свойств компонентов и значения этих свойств, как они были заданы во время разработки приложения. И, что самое приятное, Вы можете не только смотреть на эти свойства, но и редактировать их. Исправить числовые или текстовые значения – дело нехитрое, стираем старое значение, вписываем новое, сохраняем результат, и можно любоваться эффектом. Но вот если понадобится исправить свойство вроде BorderStyle – скорее всего придется заглянуть в документацию по Delphi, чтобы узнать, что такое bsSingle и какие еще значения может принимать это свойство. Пока что все довольно просто – и чем-то напоминает наши эксперименты по редактированию шаблонов диалогов в Калькуляторе.[/spoiler]

Додано (08.08.2009, 19:46)
---------------------------------------------
[spoiler]Впрочем, сказав, что изменить значение свойства – дело нехитрое, я была не совсем права. Состояние современного инструментария таково, что если пользоваться специализированными программами (тем же eXeScope, например), то эта операция не всегда выполняется корректно. Поэтому на практике мне нередко приходилось пользоваться следующим приемом – оригинальное значение я читала при помощи eXeScope, но вот новые данные вписывала уже в шестнадцатиричном редакторе; о том, как я определяла, какие байты и где надо было менять, я думаю, в очередной раз повторяться не стоит. В самых тяжелых случаях можно даже экспортировать шаблон формы в dfm-файл, а затем попытаться при помощи той же версии Delphi/C++ Builder впихнуть этот dfm-файл в тестовый проект, откомпилировать и затем перенести шаблон формы из тестового проекта на его «родное» место в подопытной программе. При этом, разумеется, придется обеспечить совпадение версий компилятора и, если на форме имеются нестандартные компоненты, раздобыть и установить точно такие же. Как Вы догадываетесь, весь этот процесс весьма хлопотный, и такая игра вряд ли стоит свеч – я подобную «хирургическую операцию» по пересадке ресурсов проделывал лишь единожды, и то в основном в порядке эксперимента. Но вот изучение тестовых примеров перед тем, как начинать править свойства – вещь очень и очень полезная, поскольку помимо чисто практической пользы это помогает лучше понять внутреннюю логику инструментальных средств, при помощи которых создана программа.

После того, как мы убедились в возможности редактировать отдельные свойства компонентов, было бы нелишне узнать, что произойдет в том случае, если удалить описание какого-либо свойства. Как ни странно, если выполнить удаление корректно – то обычно ничего страшного не случается. Хотя, справедливости ради надо отметить, что в некоторых случаях удаление свойства приводит к катастрофическим последствиям – прежде всего, когда удаляемое свойство ссылается на другой компонент. Но, к счастью, такие специфические компоненты чаще всего не имеют никакого отношения в nag screen’ам и баннерам.

Причина «нечувствительности» программ к исчезновению свойств следующая: в Delphi и С++ Builder создание объекта на основе шаблона производится в два этапа. На первом этапе собственно создается объект, а все его свойства и внутренние структуры инициализируются значениями по умолчанию. И лишь на втором этапе новые значения свойств, которые хранятся в шаблоне диалога, помещаются на место значений по умолчанию. Неудивительно и то, что в eXeScope Вы видите у каждого компонента намного меньше свойств, чем видит разработчик, редактируя форму в IDE: для уменьшения объема исполняемого файла в ресурсах сохраняются не все значения свойств, а только те, которые отличаются от значений по умолчанию. Например, в приведенном выше отрывке описания формы AboutForm Вы не увидите свойство AutoSize, несмотря на то, что такое свойство у формы имеется. Причина этого проста: значение свойства AutoSize по умолчанию было равно false, и автору (то есть мне) не пришлось его менять, поскольку оно вполне меня устраивало.

Итак, теперь мы знаем, что описания свойств удалять можно. Осталось лишь разобраться, зачем это нам может понадобиться. В этот раз я отступлю от принципа «сначала - теория, потом - практика» и начну с описания небольшого эксперимента. Возьмите все тот же InqSoft Window Scanner, запустите и нажмите в нем кнопку «О программе…». Вы увидите окно с информацией о программе, в левой части которого будет находиться логотип. А теперь представьте себе, что это не безобидная картинка, которая никому не мешает, а ужасный черно-зелено-оранжевый баннер размером в пол-экрана, от которого мы хотели бы избавиться.

Следующим шагом будет определение идентификатора шаблона. Запустите вторую копию Window Scanner’а и «просканируйте» окно «О программе…». В очередной раз убедившись, что класс окна носит имя TAboutForm (да, я знаю, что написала про это несчастное окно уже как минимум пять килобайт – но мы будем действовать так, как будто видим программу впервые), лезем в секцию ресурсов и ищем там шаблон формы, спрятавшийся за идентификатором TABOUTFORM. Теперь нам нужно найти в шаблоне формы описание нашего «баннера». Нетрудно догадаться, что в этой роли выступает объект Image1 (поскольку картинка на форме одна, догадаться, что Image1 и есть наш «баннер», нетрудно). Дешифрованное описание этого объекта выглядит следующим образом:

object Image1: TImage
Left = 0
Top = 0
Width = 57
Height = 192
AutoSize = True
Picture.Data = {
0A544A504547496D616765F5260000FFD8FFE000104A46494600010200000100
............
3EEBFFD9}
end

Теперь можно сделать то, ради чего мы и затевали все эти поиски: удалите свойство Picture.Data, запустите программу и посмотрите, что случилось с нашей формой. А случилось именно то, чего мы и хотели добиться - логотип исчез, как будто его и не было. Сам объект, разумеется, никуда не делся – мы лишь удалили связанное с ним изображение, «подчистив» свойство Picture. Вспомните, что я говорил о двух этапах создания форм в Delphi - и Вы легко поймете, каким образом изменилась логика работы программы: стерев значение, которое было назначено свойству Picture.Data программистом, Вы не оставили программе иного выхода, как использовать значение этого свойства по умолчанию. А значением по умолчанию в нашем случае оказалось «никакое» изображение (т.е. отсутствие изображения), которое программа успешно отобразила. Более того, удалять можно не только свойства объектов, но и объекты целиком. Однако такое действо является куда более грубым вмешательством в код программы, да и ограничений в этом случае намного больше.

А теперь давайте посмотрим, как простым редактированием ресурсов можно избавиться от настоящего, вполне реального баннера. Для этого нам потребуется программа Ghost Installer Free Edition. XML-редактор, входящий в состав этой программы, как раз содержит баннер. И этот баннер, кроме того, что занимает довольно много места внизу экрана и сокращает поле редактирования, еще и постоянно мерцает, раздражая пользователя. Так что если Вы активно пользуетесь бесплатной редакцией Ghost Installer’а, Вам придется либо проявлять чудеса терпеливости, либо спасти огромное количество нервных клеток, избавившись от созерцания зловредного баннера.

Сначала при помощи InqSoft Window Scanner определим имя класса окна той формы, которую мы собираемся править: TfrmProjectSource. Заодно будет нелишне просканировать и сам баннер – вдруг это позволит нам узнать хотя бы тип компонента, на основе которого этот баннер был создан. А если нам удастся узнать тип компонента, это заметно облегчит задачу поиска самого компонента в дешифрованном шаблоне формы. Пробуем просканировать окно баннера, и узнаем, что на самом деле наш баннер – ни что иное, как кусок Internet Explorer’а, засунутый в программу при помощи технологии ActiveX. Чтож, с первого захода мы получили явно недостаточно полезной информации. Поэтому попробуем копнуть глубже и просканить всю ветку дерева окон, имеющую отношение к нашему баннеру. InqSoft Window Scanner выдал следующий результат:

+[00050356] {TPanel}
*[00010414] {TElSplitter}
+[00050370] {TPanel}
+[0001040E] {TPanel}
+[00010410] Panel1 {TPanel}
+[0043036A] {Shell Embedding}
+[000103D4] {Shell DocObject View}
*[00010412] {Internet Explorer_Server}

Что это значит? Всего лишь то, что наш ошметок Internet Explorer’а лежит на компоненте Panel1 типа TPanel (тут программист явно поленился стереть свойство Caption у объекта Panel1, чем сильно облегчил нам задачу поиска нужного объекта). Сам объект Panel1 в свою очередь лежит на другой панели, которая лежит на панели, которая… В общем, всяких панелей там много, и разбираться в них можно долго. Поэтому я предлагаю начать наше расследование с той панели, которую мы идентифицировали однозначно. Откроем файл GIEditor.exe в Restorator 2.52 (да, Вам опять придется обновить инструментарий – практика показала, что eXeScope с редактированием шаблона в данной программе не справился, а вот Restorator сработал как нельзя лучше), выберем шаблон нашей формы и в этом шаблоне найдем следующее:

object panMainBanner: TPanel
Left = 0
Top = 287
Width = 553
Height = 126
Align = alBottom
BevelOuter = bvNone
TabOrder = 1
object Panel1: TPanel
Left = 0
Top = 4
Width = 553
Height = 122
Align = alBottom
BevelOuter = bvLowered
Caption = 'Panel1'
TabOrder = 0
object webMainBanner: TEmbeddedWB
Left = 1
Top = 1
Width = 551
Height = 120
Align = alClient
...
end
end
end

Как видно из приведенного куска текста, это и есть описание нашей Panel1, баннера, который на этой панели находится (как оказалось, он представлен объектом webMainBanner типа TEmbeddedWB) и некой панели panMainBanner, на которой лежит Panel1. Было бы логично предположить, что имя panMainBanner расшифровывается как panel for Main Banner («панель для главного баннера»), и что если ликвидировать эту панель вместе со всем ее содержимым, то назойливое мерцание баннера более не будет смущать наш взор. Сказано – сделано, переходим в режим редактирования и удаляем вышеприведенный блок текста из ресурса. Сохраняем, запускаем – и получаем GPF. Чтож, как я и предупреждал, безоглядное удаление компонентов – операция отнюдь не безобидная. Поэтому давайте поищем другой путь.

В самом начале главы я выделила четыре подхода к проблеме, и мы только что испробовали тот из них, который стоит под номером два. Это, конечно, было несколько непоследовательно с моей стороны, но иначе Вы бы не смогли поэкспериментировать с удалением объектов и увидеть, к чему это иногда приводит. И вот пришло время пойти правильным путем. Действительно – это ведь всего лишь баннер, он не выпрыгивает в самый неподходящий момент на передний план, не блокирует работу с программой, даже не требует, чтобы по нему кликали. Так что нам нет принципиальной необходимости совершенно изничтожать этот баннер –достаточно просто его

Відредаговано: Ірина - Сб, 08.08.2009, 19:37
Ірина Дата: Сб, 08.08.2009, 21:22 | Повідомлення № 27
Профі в програмуванні та безпеці
Повідомлень: 140
Нагороди: 0
Рейтинг: 15
Камянець – Подольский как будто и не очень вдалеке от меня а вот перечисленных вами лиц я лично не знаю.
Да я как будто и не сегодня из-за парты встала. Странно но их постов и комментариев в теме ассемблера я не вижу. Я воще там вижу посты только преподавателей, из которых знаю тока троих лично.
Но может занятые, теперь пора отпусков и отдыха, хотя тема как будто создана раньше.


Відредаговано: Ірина - Сб, 08.08.2009, 21:29
pasichov Дата: Нд, 09.08.2009, 13:54 | Повідомлення № 28
Наполегливий учасник
Повідомлень: 946
Нагороди: 3
Рейтинг: 70
Quote (VicS13)
Именно программирование развивает у ученика мышление всех типов и форм, а не создание презентации из готового шаблона.....

Именно эту мысль я отставиаю и ПОДДЕРЖИВАЮ на 100%!!!!
Quote (VicS13)

Плюс переход на язык более высокого уровня значительно упростится. К примеру понимание сути сишного указателя значительно ускорится....

И это верно! Вот только я многократно пробовал затевать спецкурс по низкоуровневому программированию - получаєтся плохо...трудновато для школьника. Они не видят смысла - нет ни олимпиад, ни конкурсов, а детям, "заточенным" на интеллектуальную деятельность, нужен МОТИВ. Начинают "спрыгивать" туда, где есть "выход". Правда, сильный мотив - наличие в городе крупной компании Инновин, в которой масса творческих сотрудников занимается разработкой програмно-аппаратных комплексов на базе микроконтроллеров, рынок труда есть... но дети еще в силу возрастных особенностей понимают это весьма умозрительно...
Ірина Дата: Пн, 21.12.2009, 11:50 | Повідомлення № 29
Профі в програмуванні та безпеці
Повідомлень: 140
Нагороди: 0
Рейтинг: 15
Поиск в тексте программы констант или обращений к переменным, отвечающих за реализацию ограничений в незарегистрированных и демонстрационных программах. Нередко также возникает необходимость извлечь из программы какие-либо данные, и, возможно, заменить их своими собственными.

Поробуем всё это на практике. ;)
Принцип, которым нужно руководствоваться, если приходится прибегать к модификации данных или исполняемого кода. Это принцип минимального вмешательства, который можно сформулировать так:
Чем меньше изменений внесено в логику программы, тем менее вероятно, что эти изменения приведут к некорректной работе программы.

Приблизительный рейтинг изменений по степени их влияния на логику программы (от минимального к максимальному) выглядит следующим образом:

- Модификация константы
- Изменение значения предварительно инициализированной переменной
- Изменение условия перехода на противоположное
- Удаление линейной, то есть не содержащей ветвлений и вызовов нетривиальных подпрограмм, последовательности команд
- Дописывание в программу собственного кода; изменение значения, возвращаемого функцией
- Модификация внедренного в программу ресурса, важного для логики программы (т.е. такого, изменение которого меняет поведение программы)
- Удаление из программы логического блока (например, вызова нетривиальной функции); удаление внедренного в программу ресурса

Этот принцип, как любое другое широкое обобщение, требует достаточно осторожного отношения и в некоторых случаях может повести Вас по неоптимальному пути. Но на практике принцип минимального вмешательства обычно работает вполне успешно. Да и с точки зрения простого здравого смысла очевидно, что найти и исправить условие, которое проверяет зарегистрированность программы – прием куда более безобидный и надежный, чем вырывание с корнем nag-screen’ов и триальных ограничений при помощи глубокого патчинга.

Как я уже говорила, многие незарегистрированные программы содержат количественные ограничения. Даже число жизней в компьютерной игре можно отнести к ограничениям количественного характера (как ни странно, крэкинг иногда применяется в качестве средства для беспроблемного прохождения компьютерных игр; «вечная жизнь» и «бесконечное оружие» - это тоже один из аспектов крэкинга, возможно даже самый старый). к сожалению, все чаще встречаются случаи, когда манипуляции с системным временем, файлами и реестром не помогают: это всевозможные ограничения на продолжительность одного сеанса работы с программой, на максимальное количество создаваемых или обрабатываемых документов, на число записей в базе данных и т.п. Посмотрим каким образом хранится информация внутри программ и что с этой информацией можно сделать.

Наверное, наиболее распространенным типом данных, используемым в программах, в настоящее время являются целые числа. Абсолютное большинство существующих процессоров, в том числе и наши любимые x86, изначально ориентировались на работу с целыми числами определенной разрядности (в настоящее время на платформе x86 наиболее актуальны 32-битные целые со знаком или без). Именно целые числа являются наиболее естественных форматом для хранения всевозможных счетчиков и контрольных сумм. Однако возможны и более неординарные применения: в тридцати двух битах можно успешно хранить числа с фиксированной точкой и даже логические значения. Когда я переходила от программирования под ДОС к программированию под Win32, меня сильно удивляла расточительность фирмы Microsoft, отводившей под простую булевскую переменную целых 4 байта, и только более глубокое изучение архитектуры 32-разрядных процессоров и ассемблера расставило все по своим местам.

Что Вы будете делать, если Вам потребуется найти в программе сравнение чего-либо (например, регистра или содержимого ячейки памяти) с определенной целочисленной константой? Для некоторых целых чисел достаточно обычного поиска блока двоичных данных в файле. Однако двоичный поиск далеко не со всеми числами работает одинаково хорошо: если Вы ищете число 3B9ACA00h, вероятность ложного срабатывания будет весьма небольшой, но вот если Вы попытаетесь найти в исполняемом файле число 10 или 15, то, скорее всего, просто устанете нажимать на кнопку «Найти далее». Если вспомнить, что числа 10 и 15 могут храниться не только как 32-битные, но и как одно- и двухбайтные, становится ясно, что двоичный поиск небольших чисел в исполняемых файлах – далеко не самая лучшая идея. Кроме того, при таком способе поиска никак не учитывается структура исполняемого файла программы, поскольку Вы ищете нужную Вам константу не только в коде программы, но и в PE-заголовке, секции данных, секции ресурсов и прочих областях, имеющих к коду программы самое отдаленное отношение. Хотя в принципе эта проблема, конечно, решаема: нужно лишь ограничить область поиска секциями, содержащими данные и код.

Однако есть и другой, более эффективный метод поиска в программе известных заранее значений. Как ни странно, но в реальных программах широко используется лишь сравнительно небольшой набор целочисленных констант: это, прежде всего, небольшие положительные числа от 0 до 7 (а также небольшие отрицательные от -3 до -1) и степени двойки: 8, 16, 32 и т.д. Другие константы в программах встречаются значительно реже. Попробуйте сами провести эксперимент – дизассемблируйте какую-нибудь достаточно большую программу и найти в ней какое-нибудь сравнительно небольшое число, например, 32h, которое в этой программе заведомо имеется. Для этого эксперимента я написала простейшую программку на Delphi 7, вся функциональность которой концентрировался в следующем коде, имитирующем простейшее ограничение на число строк в документе:

procedure TForm1.Button1Click(Sender: TObject);
begin
if Memo1.Lines.Count>50 then
begin
Application.MessageBox('More than 50 items not available','Demo version');
Close;
end
else Memo1.Lines.Add(Edit1.Text);
end;

В результате компиляции этот весьма нехитрый текст превратился в исполняемый файл размером более 350 килобайт (я намеренно создала проект с визуальными компонентами, а также использовал режим компиляции без runtime packages, чтобы мой собственный код составлял в исполняемом файле очень малую долю по сравнению с библиотеками Delphi). Затем я дизассемблировала откомпилированную программу при помощи W32Dasm и получила листинг текст длиной более 180 000 строк. Казалось бы, обнаружить область, где происходит сравнение с числом 50 в этом листинге ничуть не проще, чем найти иголку в стоге сена. Но я воспользовалась функцией поиска в тексте строки, в качестве параметра поиска указав 00000032 (так в W32Dasm отображается число 50; заодно это позволило отсеять команды вроде mov eax,[ebx+32h], обычно использующиеся для доступа к элементам массивов и полям структур). Реальность превзошла самые смелые ожидания: четырехбайтное число 32h встретилось в листинге всего два (!!!) раза:

:004478C6 6A32 push 00000032
и
:004505BB 83F832 cmp eax, 00000032

Чтобы догадаться, что нужное нам сравнение выполняется во второй строке, достаточно самых минимальных познаний в ассемблере. Из этого следует вывод: поиск нужной константы в дизассемблированной программе вполне реален, даже несмотря на огромный объем листинга.

Далее: Вам наверняка интересен не сам факт наличия константы где-то в недрах кода, а то, в каком контексте эта постоянная используется. Иными словами, если Вы знаете, что программа сравнивает число записей в базе данных с некоторым значением (в нашем случае - 32h), то среди всех строк, в которых присутствует эта константа, в первую очередь следует рассматривать команды сравнения (cmp) и вычисления разности (sub и sbc). Хотя нельзя забывать о существовании менее очевидных способов сравнения, например, таких:

mov ebx,50
cmp eax, ebx

или

push 50
push eax
call Compare2dwords

Ну и, раз уж речь зашла о сравнениях, нельзя не упомянуть об альтернативных вариантах реализации этой, казалось бы, нехитрой операции. Поразмыслим над приведенным выше примером сравнения содержимого регистра eax с числом 50. В самом деле, условия eax>50 и eax>=51 в приложении к целым числам имеют один и тот же смысл, а код

cmp eax,50
jg my_label

работает совершенно аналогично коду

cmp eax,51
jge my_label

Если необходимо выяснить, больше ли содержимое регистра EAX, чем 31, или нет, то проверка может выглядеть даже так:

and eax, 0FFFFFFE0h
jnz my_label

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

if my_var=[число] then <переменная_равна_числу>
else if my_var>[число] then <переменная_больше_числа>
else <переменная_меньше_числа>

На ассемблере эта конструкция тоже реализуется в три строчки, однако операция сравнения здесь требуется всего одна:

cmp my_var,[число]
jz is_equal
jg is_more_than

Додано (21.12.2009, 11:50)
---------------------------------------------
Всеми этими примерами я хотела продемонстрировать ту идею, что практически любая операция с численными данными быть реализована несколькими разными способами, и когда Вы будете искать константы в дизассемблированном тексте, этот факт тоже надо учитывать.

Если рассматривать области возможного практического применения вышеописанного приема, то лучше всего поиск известной константы в дизассемблированном тексте работает на триальных ограничениях типа «не допускается создание больше N элементов в базе данных». Как правило, N больше 7 и является целым числом, что облегчает поиск нужной константы. Исходя из принципа минимального вмешательства, для обезвреживания таких ограничений я предпочитаю исправлять не команды сравнения, а сами константы. Действительно, если программа для проектирования интерьера комнаты не способна работать более, чем с 20 объектами, для практического применения она вряд ли будет пригодна. Но вот та же программа, где максимальное количество обрабатываемых объектов увеличено до двух с хвостиком миллиардов наверняка удовлетворит даже самого взыскательного пользователя.

Одним из наиболее частых вопросов, звучит так: «Программа работает 30 дней, но я так и не нашел в листинге сравнения с числом 30. Что делать?». Один из факторов я уже описала выше – там могло быть сравнение не с числом 30, а с числом 31. Однако этим список возможных причин неудачи не исчерпывается. Как мы все знаем, день состоит из 24 часов, каждый из которых состоит из 60 минут, каждая из которых состоит из 60 секунд. Более того, продолжительность секунд также может измеряться во всевозможных «условных единицах», например, в миллисекундах. Тысячные доли секунд, в частности, используются в таких функциях WinAPI, как SetTimer (таймеры Windows часто используются для установки ограничений на продолжительность одного сеанса работы с программой) или Sleep. А вот в функциях, возвращающих время в виде структуры типа FILETIME, используются уже другие «условные единицы», равные ста наносекундам. Так что пресловутые 30 дней – это не только 30 дней, но еще и 720 часов, 43200 минут, 2592000 секунд, ну и так далее. И каждое из этих значений может быть использовано в программе как один из аргументов операции сравнения. Надо отметить, что в «условных единицах» может быть представлено не только время, но и многие другие величины: масса, географические координаты, денежные единицы и т.д.

Раз уж речь зашла о представлении временных отрезков внутри программ, уместно будет рассказать и о тонкостях использования таймеров. Наверняка Вы встречали программы, в которых после запуска окно с предложением о регистрации висит на экране в течение некоторого времени (иногда еще в этом окне идет обратный отсчет секунд), и при этом его невозможно закрыть. Подобные «спецэффекты» по усмотрению разработчика могут сопровождать вызов каких-либо функций программы, сохранение файлов или завершение приложения – это не суть важно. Важно другое: все эти временные задержки так или иначе используют средства измерения времени. В ОС Windows существует два наиболее популярных способа отсчета отрезков времени: использование функций задержки (в частности, функции Sleep) и использование всевозможных таймеров.

Вообще в Windows существует несколько разновидностей таймеров – кроме обычного таймера, создаваемого функцией SetTimer, существует еще высокоточный мультимедийный таймер и специфические таймерные функции DirectX. Эти таймеры срабатывают с некоторой заданной частотой, вызывая функцию-обработчик (она же callback-функция), внутри которой и выполняются необходимые действия, например, тот же обратный отсчет секунд до исчезновения окна с предложением зарегистрироваться. Периодичность срабатывания таймера почти всегда является константой, однако взаимосвязь между тем, что происходит внутри программы и тем, что Вы можете видеть на экране, не всегда очевидна. Чтобы пояснить эту мысль и заодно продемонстрировать на практике, как можно обращаться с таймерами, приведу несколько примеров.

Первый пример – простейший: программа, которая при запуске в течение пяти секунд показывала баннер, при этом поверх баннера выводился обратный счетчик секунд. Регистрация в программе не предусматривалась. Дизассемблирование показало, что таймер срабатывает каждые 1000 миллисекунд, при каждом вызове callback-функции значение переменной, изначально равной пяти, уменьшалось на единицу, и результат проверялся на равенство с нулем. В той конкретной программе баннер можно было просто «выломать», убрав функцию создания и отображения рекламного окна, но в общем случае это решение было бы не лучшим (вспомните принцип минимального вмешательства). И вот почему: на последнее срабатывание таймера могло быть «подвешено» не только закрытие окна с баннером, но и инициализация каких-либо объектов внутри программы или другие критичные действия, без которых программа могла бы работать некорректно. Так что немного усложним задачу – будем считать, что полностью убирать вызов окна с рекламой нельзя. Первое, что нам приходит в голову – уменьшить число секунд, в течение которых показывается баннер. Сказано – сделано, цифру 5 исправляем на единицу. Однако баннер все равно висит целую секунду – ведь первое срабатывание таймера наступает только через секунду после его создания. Теперь уменьшим период таймера до нуля (хотя лучше все-таки до одной миллисекунды, «таймер с периодом 0 миллисекунд», согласитесь, штука довольно странная). В результате мы получили баннер, появляющийся при запуске программы лишь на мгновение и не заставляющий тратить целых пять секунд на праздное разглядывание рекламных лозунгов.

В качестве второго примера я возьму одну из старых версий TVTools. В справке к программе было четко указано, что незарегистрированная версия работает только 10 минут; дизассемблирование и анализ листинга выявили, что программа создает два таймера с периодами 60 секунд (что навело меня на мысли о защитном назначении этого таймера) и 2 секунды. Без особых сложностей обезвредив первый таймер, я запустила программу и обнаружила, что она все равно больше 10 минут не работала. Тогда я более пристально изучила callback-функцию второго таймера, и наткнулась в ней на такой код:

inc dword_40D5A7
cmp dword_40D5A7, 136h
jbe short loc_405CAA

Нетрудно догадаться, что это увеличение некоего счетчика, который затем сравнивается с числом 310. Поскольку период таймера – 2 секунды, а 310*2=620 (т.е. чуть больше 10 минут), логично было предположить, что это и есть второй уровень защиты, дублировавший первый. Очевидно, что если бы я приняла на веру, что программа перестает работать ровно через 10 минут (а не через 10 минут 20 секунд, как это оказалось в действительности) и стала бы искать сравнение с числом 300, я бы не смогла обнаружить таким способом вторую проверку времени работы программы. Этот пример демонстрирует один из неочевидных приемов, который может быть использован для реализации такой, казалось бы, простой операции, как отсчет 10-минутного интервала. Также из этих примеров следует и другой, не менее важный вывод: далеко не всегда следует искать известную константу, чтобы найти код, в которой она используется. Иногда следует поступать прямо противоположным образом – сначала искать код, выполняющий нужные действия, и лишь затем выяснять, какая константа внутри этого кода ответственна за интересующие нас действия.

Поиск констант с плавающей точкой – занятие с одной стороны более сложное, чем поиск целочисленной константы, но с другой – куда более простое. В чем сложность и в чем простота этого занятия? По традиции начнем с плохого. Во-первых, формат представления чисел с плавающей точкой весьма нетривиален, и Вы вряд ли сможете в уме привести шестнадцатиричный дамп такого числа в «человеческий» вид (возьмите документацию по процессорам Intel и попробуйте перевести число 1.23 в машинное представление, а затем проделать обратную операцию – Вы сами убедитесь, насколько сложна эта задача). Более того, даже целые числа в представлении с плавающей точкой выглядят весьма неординарно: к примеру, дамп самого что ни на есть обычного числа 123, приведенного к типу Double, выглядит как 00 00 00 00 00 C0 5E 40. Если Вы способны с первого взгляда отличить число с плавающей точкой от кода программы или каких-либо иных данных и оценить величину этого числа – я рад за Вас, но большинство людей, к сожалению, такими способностями не обладают.

Во-вторых, при работе с дробными числами нередко возникают проблемы, связанные с машинным округлением и потерей точности. Самым ярким примером, наверное, может служить особенность математических программ ПЗУ некоторых моделей Spectrum: с точки зрения такого Спектрума выражение 1/2=0.5 было ложным. Это, конечно, было давно, но не следует считать, что современные компьютеры полностью свободны от этой проблемы. И вот практическое тому подтверждение.

Откомпилируйте под Delphi следующий код: i:=sin(1); i:=arcsin(i) и посмотрите, как будет меняться результат при изменении типа переменной I от Single до Extended. Например, если I имеет тип single, в результате вычислений получим, что arcsin(sin(1))= 0,999999940395355. Такие «спецэффекты» – следствие все той же потери точности в процессе вычислений.

В-третьих, округлением чисел процессор может заниматься не только по собственному желанию, но и по велению программы. К примеру, в большинстве бухгалтерских программ всевозможные ставки налогов выводятся с точностью до копеек. Однако из того, что Вы видите на экране число 10.26, совершенно не следует, что результат расчетов представлен в памяти ЭВМ именно как 10.26. Реальное значение соответствующей переменной может быть равно 10.258 или 10.26167, которое и участвует в реальных расчетах, и лишь при выводе на экран для удобства пользователя было произведено округление до двух знаков после запятой.

Я не случайно столько места уделила округлению и точности представления чисел – именно эти особенности чисел с плавающей точкой в наибольшей мере затрудняют поиск нужных значений в памяти программы. Программисты знают, что при работе с действительными числами для проверки условия равенства некоторой вычисляемой величины другой величине не рекомендуется использовать сравнения вида f(a)=b. Причина этого лежит все в той же проблеме округления и потери точности расчетах – вспомните вышеприведенные примеры со Спектрумом или арксинусом синуса единицы. Вместо простой проверки равенства обычно используется условие «значения считаются равными, если абсолютная величина разности между ними не превышает некоторой величины»: abs(f(a)-b)<=delta, где delta – максимально допустимая величина разности, после которой числа не считаются равными. Поэтому если Вы хотите найти в памяти некоторое число с плавающей точкой F, Вы в действительности должны искать все числа из промежутка [F-delta; F+delta], причем определить значение delta чаще всего можно лишь опытным путем. Это утверждение распространяется и на тот случай, когда Вы знаете округленное значение переменной, но в этом случае величина delta будет зависеть от того, до скольки знаков округлено значение переменной. Так, если число округлено до сотых, нетрудно догадаться, что delta=0.005.

Вот тут-то Вы и столкнетесь с чисто практической проблемой неприспособленности существующих отладчиков к поиску чисел с плавающей точкой. Сама по себе функция поиска действительных чисел в адресном пространстве программы в отладчиках встречается редко, а уж отладчиков, поддерживающих поиск чисел из заданного промежутка, я вообще не встречал. Поэтому Вам, вероятно, придется для этой цели написать собственный инструмент либо искать способ получить нужную информацию каким-то другим путем.

И, наконец, нельзя забывать, что кроме стандартных для платформы x86 типов Single, Double и Extended (32-, 64- и 80-битных соответственно) существует еще несколько довольно экзотических, но все еще используемых форматов. Это, к примеру, Currency (64-битные, с фиксированным положением десятичной точки) или 48-битные паскалевские Real. Возможно также использование «самодельных» форматов; особенно часто встречаются числа с фиксированным положением десятичной точки (обычно такое делается для повышения скорости работы программы и применяется в основном в процедурах кодирования/декодирования аудио- и видеоинформации). Знать о таких вещах совсем не лишне, хотя, конечно, вероятность столкнуться с такими числами в современных программах довольно низка.

Додано (21.12.2009, 11:50)
---------------------------------------------
Теперь немного поговорим о том хорошем, что есть в числах с плавающей точкой. Как известно, изначально в процессорах x86 встроенных аппаратных и программных средств для обработки чисел с плавающей точкой не предусматривалось. Низкая скорость расчетов, в которых использовались действительные числа, вызвала к жизни математические сопроцессоры, как традиционные x87, так и весьма экзотические девайсы Weitek. Победившая линейка сопроцессоров x87 (они с некоторых пор стали интегрироваться в ядро процессора и потому перестали существовать как отдельные устройства) имела следующую особенность: новые «математические» команды активно использовали для обмена информацией оперативную память. Посмотрите, к примеру, на важнейшие команды сопроцессора fst и fld – в качестве параметра этих команд могут выступать указатели на области памяти, которые предполагается использовать для чтения/записи данных. Более того, использование указателей в качестве одного из параметров характерно и для многих других команд сопроцессора. Поэтому ищите ссылки, используемые командами сопроцессора в качестве параметров – и Вы легко доберетесь до данных, на которые эти ссылки указывают.

Из этого следует вывод: хороший дизассемблер или отладчик способен «догадаться», что по адресу, указанному в аргументах этих команд, находится число с плавающей точкой и отобразить это число. Если же Ваш дизассемблер/отладчик об этом не догадывается – Вам придется вручную (точнее говоря, при помощи соответствующих программ) вычислить значение, которое находится по этому адресу. И пока Вы будете копировать байтики из одной программы в другую, у Вас будет достаточно времени подумать об обновлении инструментария.

Но и здесь не обошлось без ложки дегтя – компиляторы фирмы Borland, видимо, ради особой оригинальности, для загрузки констант в стек сопроцессора могут воспользоваться комбинациями вроде

mov [i],$9999999a
mov [i+$4],$c1999999
mov word ptr [i+$8],$4002
fld tbyte ptr [i]
Хотя, казалось бы, ничто не мешало положить несчастное число в секцию инициализированных данных… Тут уж не до «умного» поиска – разобраться бы, чего и куда вообще загружается. Хотя, при желании и умении обращаться с регулярными выражениями (или умении программировать) можно искать даже в таком коде.

Другим свойством действительных чисел, облегчающим автоматический поиск известной величины, является само их внутреннее устройство. Достаточно большая длина этих чисел (32 бита, а чаше всего – 64 или 80) и сложный формат хранения позволяет искать числа с плавающей точкой в любых файлах, в том числе и в исполняемых файлах программ, непосредственно в двоичном виде, причем вероятность ложного срабатывания будет незначительной. Даже существование нескольких различных форматов представления действительных чисел не представляет серьезного препятствия – соответствующая программа очень проста и пишется за считанные минуты. Народная мудрость гласит: «лучше один раз увидеть, чем сто раз услышать», поэтому в качестве практики я рекомендую Вам самим написать и отладить такую программу – это не только усовершенствует Ваши навыки в программировании, но и позволит поближе познакомиться с миром действительных чисел. Затем, если захотите, Вы сможете доработать эту программу таким образом, чтобы она могла осуществлять нечеткий поиск в файле, о котором я говорила выше, то есть поиск всех значений, подходящих под заданный пользователем интервал.

И, наконец, рассмотрим третий из наиболее часто встречающихся простых типов данных: текстовые данные. Вообще, методы представления текстовых строк и массивов в коде программ имеют давние и богатые традиции. Наиболее старым способом является выделение под строку участка фиксированного размера, причем неиспользуемая часть блока заполняется «нулевыми» символами. В чистом виде этот прием уже давно не встречается (из примеров вспоминаются разве что старые реализации классического Паскаля), но нечто подобное иногда используется в программах на Си для хранения массивов строк – под хранение каждого из элементов массива отводится блок фиксированного размера, хотя сами элементы, по сути, являются ASCIIZ-строками.

Хранение строк в блоках фиксированного размера имело два принципиальных недостатка: неэффективное расходование памяти при хранении большого числа строк различной длины и жесткое ограничение на максимальную длину строки. Всех этих недостатков были лишены строки с завершающим символом. Идея была проста – выбирается какой-либо малоиспользуемый символ, который интерпретируется программой как признак конца строки. В языке Си таким символом стал символ с кодом 0 (а строки, оканчивающиеся нулем, окрестили ASCIIZ-строками); некоторые системные функции MS-DOS в качестве завершающего символа использовали символ “$”. Несмотря на ряд недостатков, строки с завершающим символом претерпели ряд усовершенствований и используются до сих пор. С началом активного использования UNICODE появилась модификация строк с завершающим символом и для этой кодировки. Зная образ мышления программистов на Си, нетрудно догадаться, что в качестве завершающего символа была использована пара нулевых байтов: (0,0). Нужно отметить, что если возникает необходимость укоротить такую строку в тексте программы на несколько символов, то обычно для этого достаточно всего лишь вписать в нужную позицию завершающий символ. То есть, если у Вас есть программа, написанная на C/С++, в заголовке окна которой написано что-то вроде «Cool Program - Unregistered», и Вы не хотите видеть напоминание о том, что она «Unregistered», просто замените в файле программы пробел после слова Program на символ с кодом 0. После этого слово «Unregistered» Вы почти наверняка больше не увидите. Этим же способом ненужную строку можно вообще превратить в пустую, просто поставив в ее начало завершающий символ!

Описанная техника укорачивания и «обнуления» строк пригодна не только для того, чтобы убирать неэстетичные надписи в заголовках программ, в действительности ее возможности гораздо шире. Приведу пару примеров из собственной практики. Один раз мне в руки попалась некая программа, которая очень любила при печати документов в заголовок вставлять надпись «This report created by demo version …» шрифтом аршинного размера. Разумеется, мне это не понравилось и при помощи нехитрых манипуляций в шестнадцатиричном редакторе я «обнулила» строку с надписью, оскорблявшей мои эстетические чувства. В другом случае я подобным же образом расправилась с одной программой-генератором справок, которая считала, что незарегистрированность – это повод вставлять рекламный текст в каждую статью справочной системы. Небольшой memory patch, исправлявший в программе «на лету» несколько байт, смог убедить капризную программу в ее принципиальной неправоте.

Более эффективными по сравнению с ASCIIZ-строками являются строки с указанием длины. Такие строки позволяют использовать в тексте все 256 ASCII-символов, хранить не только текстовые, но и любые другие двоичные данные, а также применять по отношению к этим данным строковые функции. Кроме того, вычисление длины строки требует лишь одной операции чтения данных по ссылке, в отличие от ASCIIZ-строк, где для определения длины необходимо последовательно сканировать все символы строки до тех пор, пока не встретится завершающий символ. Как такового, стандарта на строки с указанием длины не существует – можно лишь говорить о конкретных реализациях таких строк в различных компиляторах и библиотеках. В частности, в коде программ на Delphi 7 строковые константы хранятся следующим образом:
• 4 байта: длина строки в байтах (для UNICODE-текстов это значение в два раза больше длины строки в символах).
• Содержимое строки.
• Завершающий символ (#0 для ANSI-строк, #0#0 для UNICODE-строк). Завершающий символ никак не используется в «родных» функциях и процедурах Delphi, но значительно упрощает вызов функций WinAPI (которые используют строки с завершающим символом) и использование сторонних библиотек.
Зная все это, нетрудно разработать способ укорачивания Delphiйских строк: для этого требуется изменить длину строки в первых четырех байтах и поставить еще один завершающий символ в нужную позицию. Надо отметить, что тексты-свойства компонентов в ресурсах программ на Delphi хранятся в несколько ином формате, поэтому прежде чем пытаться вмешиваться в код программы, стоит побольше узнать об особенностях реализации встроенных типов в компиляторе, при помощи которого создана исследуемая программа.

Поиск текстовых констант в программе – совсем не такое простое дело, как это могло бы показаться с первого взгляда. Прежде всего, не следует полагаться на «интеллектуальность» дизассемблера: поиск текстовых строк при дизассемблировании обычно основан на анализе ссылок, встречающихся в коде программы. Поэтому, если в коде программы нет прямой ссылки на строку, дизассемблер эту строку может просто «не увидеть». Чтобы убедиться в этом, рассмотрим несложный пример:

.data
line1 db "Line 1",0
line2 db "Line 2",0
line3 db "Line 3",0
LineArr dd OFFSET line1, OFFSET line2, OFFSET line3

.code

GetMsgAddr proc MessageIndex:DWORD
mov ebx,MessageIndex
mov eax, OFFSET LineArr
mov eax,[eax+ebx*4]
ret
GetMsgAddr endp

Этот код представляет собой максимально упрощенную реализацию списка сообщений и функции, получающей адрес текстовой строки по номеру сообщения. Откомпилировав этот пример, загрузим его в W32Dasm и посмотрим, что получится. Получилось следующее: дизассемблер успешно распознал строку «Line 1», но строки «Line 2» и «Line 3» не обнаружил. А вот IDA успешно распознал все три строки, и создал для них именованные метки. Впрочем, и IDA при большом желании можно обмануть: достаточно лишь вписать перед текстом самой строки ее длину в байтах (именно так хранит строки Delphi). После этого IDA хотя и обнаруживает сам факт наличия текстовых строк в программе (в окне Strings эти строки видны), но в дизассемблированном тексте программы эти строки выглядят как последовательность db… , которые нужно приводить в желаемый вид вручную. Кстати, W32Dasm после этой модификации не увидит вообще ни одной строки. Если же Вам и этого мало, вместо «Line 1» напишите «Строка 1» - все тексты на русском языке знаменитый дизассемблер гордо проигнорирует. И это только начало. А ведь текстовые строки могут находиться не только в сегменте кода/инициализированных данных, но и в секции ресурсов программы…

Здесь могут помочь специализированные программы, сканирующие указанный файл и вычленяющие из него все текстовые строки (или то, что похоже на текстовые строки). Кроме того Вам потребуются смещения этих строк от начала файла, поэтому Ваш инструмент должен предоставлять и такой сервис. Однако использование таких программ (и самостоятельное их написание) осложняется двумя факторами: разнообразием существующих кодировок текста и существованием национальных символов в некоторых языках (классический strings.exe и многие другие подобные программы «не понимают» русскую секцию UNICODE). Те же проблемы с UNICODE и национальными кодировками характерны и для программного обеспечения, осуществляющего поиск в текстовых файлах. К тому же русские тексты в UNICODE совершенно нечитабельны в шестнадцатиричных редакторах и просмотрщиках. Все это необходимо учитывать при выборе инструментов поиска текстовых строк, а выбранный инструмент перед использованием желательно проверить на подходящем «пробном камне».

Напоследок расскажу про весьма простой, но весьма эффективный в некоторых случаях способ поиска численных переменных в работающей программе. Этот способ основан на многократном сканировании адресного пространства программы, отслеживании и анализе всех изменений в этом пространстве. Лучше всего этот прием работает на программах, в которых установлено ограничение на количество тех или иных действий, вроде ограничения на число записей, добавляемых в документ. И используется для этого совсем не крэкерский инструментарий. Вы, наверное, знакомы с программами типа Game Wizard или ArtMoney, которые позволяют искать в работающей компьютерной игре количество денег или оставшихся жизней. Для тех, кто не сталкивался с такими программами, вкратце опишу алгоритм их работы:

1. Пользователь выбирает из списка работающих в данный момент программ подопытную игру.
2. Пользователь вводит в программу поиска начальное количество денег (хитов и т.п.), которое в данный момент существует в игре.
3. Программа сканирует адресное пространство и строит список всех значений (точнее, адресов, по которым расположены эти значения), совпадающих с введенными пользователем.
4. Пользователь выполняет в игре какое-либо действие, в результате которого количество денег изменяется.
5. В программу поиска вводится новое количество денег.
6. Программа проверяет все значения из построенного списка и исключает из него те значения, которые не соответствуют введенному пользователем.
7. Пункты 4-6 повторяются до тех пор, пока список адресов не укоротится настолько, чтобы можно было проверить назначение каждого элемента списка вручную.
8. Пользователь проверяет каждый элемент списка, записывая по найденным адресам новые значения и наблюдая, как это повлияет на количество денег в игре.

Вы наверняка уже догадались, что защищенная программа ничем в принципе не отличается от компьютерной игры, а число добавленных в документ записей – это то же самое, что количество виртуальных «золотых монет». И потому, воспользовавшись соответствующей программой (например, все той же ArtMoney), можно определить адреса всех переменных, которые могут хранить счетчик добавленных в документ записей. Дальнейшие действия зависят исключительно от Вашего желания – можно поставить аппаратную точку останова на чтение из этой переменной и попытаться добраться до команды сравнения существующего числа записей с максимальным. Можно погрузиться в изучение дизассемблерного листинга в поисках команды увеличения переменной и сделать так, чтобы значение счетчика не увеличивалось. Можно даже попробовать модифицировать счетчик из ArtMoney, посмотреть, что из этого получится, и если из этого получится что-то хорошее – написать memory patch, каждые 100 миллисекунд обнуляющий счетчик.
;)

Відредаговано: Ірина - Пн, 21.12.2009, 11:49
НІКОЛЯ Дата: Пн, 21.12.2009, 14:02 | Повідомлення № 30
Знавець вірусів
Повідомлень: 2877
Нагороди: 17
Рейтинг: 201
Quote (Ірина)
Можно даже попробовать модифицировать счетчик из ArtMoney, посмотреть, что из этого получится, и если из этого получится что-то хорошее – написать memory patch, каждые 100 миллисекунд обнуляющий счетчик.

Ірино не балуйтесь ;) Ми з вами домовились. Що до тем та повідомлень крекінг сніферінг не для цього форуму B)
Форум інформатиків » РОЗДІЛ VIІІ: ОБМІН ДОСВІДОМ (УРОКИ, ФАКУЛЬТАТИВИ, ПОЗАКЛАСНА РОБОТА) » 8.6 Факультатив з програмування » Низькорівнева мова програмування - Асемблер (Обговорення що до використання та застосування)
Сторінка 2 з 3«123»
Пошук:


© Форум інформатиків України, 2007-2017.