Казуальні гра - комп'ютерна гра, призначена для широкого кола користувачів. Сам термін "казуальна" походить від латинського слова "casualis", що означає "випадковий". Таким чином, казуальна гра - це гра, в яку грають від випадку до випадку, мимохідь, найчастіше, щоб якось вбити час. Подібними іграшками є творіння компанії невософт. Тільки ось дають вони пограти всього годину, а потім просять грошей. Сьогодні ми з цим розберемося!
Трохи теорії
Взагалі, казуальні ігри за своїм рівнем складності годяться практично для будь-якої категорії користувачів комп'ютера. Найчастіше час на проходження таких ігор невелика, а тому вони добре підходять для тих, хто не може приділяти грі багато часу. Компанія невософт є одним з провідних розробників казуальних ігор в світі (і, зокрема, російською мовою). Здавалося б, така серйозна компанія повинна приділяти підвищену увагу захисту свого програмного забезпечення, для її злому повинно знадобитися багато сил і часу. Сьогодні ми спростуємо цей факт і покажемо, як відучити їх дітище клянчити наші з вами кровні гроші. Розробники компанії невософт тримають під своїм чуйним наглядом тисячі ігор, при цьому дають народу випробувати їх дітище протягом однієї години. Після 60 хвилин, коли людина тільки входить у смак, висвічується не дуже приємна табличка, яка просить грошей. Так уже склалося, що російська людина не любить платити за софт, але розробники ігор іноді просто не залишають нам вибору. Для певної гри потрібно знайти свій кряк, на пошуки якого іноді йдуть дорогоцінні хвилини і години, а якщо гра нова, то ймовірність знайти його зводиться до нуля.
Підготовка операційного столу
В якості піддослідного для нашого дослідження, якого ми будемо відучувати від "шкідливої звички", я вибрав гру "Півцарства за принцесу". Мій вибір припав на неї, тому що саме вона й наштовхнула мене на думку про дослідження захисту ігор від невософт. Пізніше з'ясувалося, що принцип захисту у інших ігор цього виробника абсолютно ідентичний.
Так склалося, що на момент вивчення під моєю рукою не було жодної програми для злому: ні дизассемблера, ні отладчика; був тільки набір програм, що стоять на машині практично у кожного користувача. У цей набір увійшли Total Commander і "Диспетчер завдань" - саме цими програмами ми і будемо користуватися в момент вивчення гри. Здавалося б, що можна зробити за допомогою цих програм? Виявилося, що при наявності допитливого розуму і крапельки уважності цього цілком достатньо, щоб змусити гру працювати без обмеження за часом. В якості платформи для написання "таблетки" я вибрав Delphi 7. Всі інструменти розкладені на операційному столі, пацієнт міцно прив'язаний - можна приступати до дослідження. А тепер про все по порядку ...
Скальпель, тампон, спирт, ще спирт, огірок ... Пом'янімо!
Встановлюємо і запускаємо гру. Бачимо гарне віконце, в якому красується час, відведений нам для її тестування. Сміливо тикаємо мишкою по кнопці "грати" і починаємо спостерігати, що коїться в системі. Звернемо гру на час і заглянемо в "Диспетчер завдань". Погляд падає на невідомий нам процес з розширенням *. tmp. Що ж, давай глянемо, що це за фрукт, і як він тут опинився. Тикаємо в властивості процесу і вчитуємося в інформацію, яку нам видали. Місце розташування файлу говорить про те, що ми на вірному шляху. Відкриваємо папку з цим файлом і перейменовуємо його в exe'шнік (до речі, файл є прихованим, так що не забудь поставити галочку на "відображати приховані файли" у відповідних властивостях). Тикаємо в нього два рази лівою кнопкою миші і бачимо гарну картину - гра запускається, причому ніяких вікон для реєстрації не вискакує. Здавалося б, мета нашого експерименту досягнуто, гра більше не вимагає реєстрації і працює без обмеження за часом. Але цей спосіб занадто нудний і незручний. Тому будемо шукати спосіб спростити ці дії.
Розтин показав, що пацієнт помер від розтину
Основна наша мета - навчиться відучувати іграшки NevoSoft'a від грошей у два кліка, тому почнемо розбиратися, звідки береться той злощасний файл з розширенням *. tmp. Не бійся, читати тонни мануалів не доведеться, головне - мати трішки терпіння і крапельку уважності. Шукати довго не доводиться, бо в папці з файлом *. tmp лежить незрозуміло навіщо потрібний файл nsgame.dat, який за розміром збігається з нашою іграшкою з точністю до байта. Можна припустити, що ланчер просто перейменовує nsgame.dat в *. tmp і запускає його. Але в процесі перевірки нашого припущення тебе чекає великий облом - нас посилають куди подалі, повідомляючи про те, що програма не є виконуваним файлом.
Турбуватися не будемо, а замість цього беремо лопату більше, та гостріше і починаємо копати глибше. Перше, що спадає на думку - порівняти ці два файли і подивитися, в чому ж їх відмінність. Відкриємо Total Commander і скористаємося внутрішньої утилітою для порівняння файлів. Результати порівняння дуже цікаві, тому що спостерігається гарна картина: з періодичністю в 2 байти йде відмінність і збіг. У наявності криптографія виконуваного файлу, але як провести зворотний процес, адже ми вирішили відмовитися від отладчиков і дизассемблеров? Відповідь дуже проста - потрібно згадати алгоритми шифрування. Найпростішим і одним з найефективніших (при правильному використанні) криптоалгоритмів є так зване XOR-шифрування. Нагадаю, у цьому методі побайтно проводиться булева операція XOR. Першою змінної є байт для шифрування, а другий - ключ. Але перед нами тут же постає ще одне питання - де взяти ключ для дешифрування? Відповідь проста. Потрібно лише згадати булеву алгебру, і ключ нам дадуть у відкритому вигляді.
Crypted = uncrypted XOR key;
Key = crypted XOR uncrypted
Спробуємо дістати заповітний ключик. Для цього проведемо побітно операцію XOR між виконуваним файлом і тимчасовим файлом. За ідеєю, на виході отримаємо ключ для дешифрування, за допомогою якого можна буде клацати гри як горішки. XOR'іть будемо тільки перші 256 байт, так як мало хто в наш час використовує ключі більшої довжини.
var
i, o: TFileStream;
bi, bo: byte;
x, ii, cc: integer;
begin
if open.Execute then
begin
SetCurrentDir ('C: \ Ігри від NevoSoft \ Peacecraft \
game ');
/ / Переходимо в папку з грою
if not (fileexists ('nsgame.dat')) then exit;
i: = TFileStream.Create ('nsgame.dat', fmOpenRead);
o: = TFileStream.Create (open.FileName, fmOpenRead);
x: = 0; ii: = 0; cc: = 0;
/ / Перебираємо 256 байт
for x: = 0 to 255 do
begin
i.read (bi, 1);
o.read (bo, 1);
key.Caption: = format ('% s% x', [key.Caption, (bi
xor bo)]);
inc (cc);
if cc mod 8 = 0 then key.Caption: = key.
Caption + # 13 # 10;
end;
i.Free;
o.Free;
end;
Як виявилося, ключ, що використовується для шифрування, не дуже-то великий: довжина його складає всього 4 байта. Забігаючи вперед, скажу, що для кожної гри від компанії невософт існує унікальний ключ шифрування. Як же його обчислити?!
Заглиблюватися в нетрі не варто. Насправді все дуже просто - для отримання ключа беремо від сигнатури PE-заголовка перші 2 байта і проводимо операцію XOR. У багатьох виникне питання: чому потрібно проводити операцію XOR тільки на 2 байти, адже довжина ключа - 4 байти? Відповідь проста - 3-й і 4-й байти в ключі завжди рівні $ 00.
const
ckey = # 77 # 90; / / сигнатура PE-файлу
begin
i: = TFileStream.Create (FileName, fmOpenRead);
for x: = 1 to 2 do
begin
i.Read (tmp, 1);
tmp: = ord (ckey [x]) xor tmp;
key: = key + chr (tmp);
end;
key: = key + # 0 # 0;
Тепер в наших руках є заповітний ключ-монтування, і можна сміливо приступати до написання самої програми для злому.
Ми писали, ми писали, наші пальчики втомилися ...
Ми вже маємо достатньо інформації для написання універсального зломщика. Що ж, не будемо даремно гаяти час. Приступимо ...
procedure wrap (filename: string);
var
i, o: TFileStream;
bi, bo, tmp: byte;
x, ii: integer;
key: string [4];
buffer: TMemoryStream;
const
ckey = # 77 # 90; / / сигнатура PE-заголовка
begin
if not (fileexists (filename)) then exit; / / невелика перевірка ніколи не зашкодить =)
i: = TFileStream.Create (filename, fmOpenRead); / / відкриваємо на читання піддослідного
o: = TFileStream.Create (ChangeFileExt (filename,
'. Exe'), fmCreate); / / і на запис новий файл
buffer: = TMemoryStream.Create;
for x: = 1 to 2 do / / обчислюємо крипто-ключ
begin
i.Read (tmp, 1);
tmp: = ord (ckey [x]) xor tmp;
key: = key + chr (tmp);
end;
key: = key + # 0 # 0;
i.Seek (0, soFromBeginning);
x: = 0; ii: = 0;
while i.Position <i.Size do / / дешіфруем файл з вказаним
ключем
begin
inc (ii);
i.Read (bi, 1);
bo: = bi xor ord (key [ii]);
buffer.Write (bo, 1);
inc (x);
if ii = 4 then ii: = 0;
end;
o.Write (Buffer.Memory ^, Buffer.size);
i.Free;
o.Free;
buffer.Free;
showmessage ('Wrapping done');
end;
Звучить барабанна дріб - запускаємо отриманий файл ... Але чомусь нам знову пропонують пройти у бік лісу. Що, де, коли ми пропустили?! Адже начебто всі правильно зробили! Але не будемо турбуватися. Взявши в руки чергову баночку пива, продовжимо вивчати піддослідного і спробуємо знайти наш промах. Знову відкриваємо Total Commander і проводимо роботу над помилками, порівнюючи нормальну гру з файлом, який у нас вийшов. На перший погляд файли однакові з точністю до одного байта. Але варто тільки натиснути кнопку "знайти перше різниця", Total Commander повідомляє, що, починаючи з зсуву $ 43000, файли не збігаються.
Отже, можна припустити, що шифрується не весь файл, а тільки перші $ 43000 байт. Тому беремо в руки молоток і зубило і виправляємо помилки в нашому коді, змусивши дешифрувати тільки перші $ 43000 байт.
while i.Position <i.Size do
begin
inc (ii);
i.Read (bi, 1);
if x <$ 43000 then
begin
bo: = bi xor ord (key [ii]);
buffer.Write (bo, 1);
end
else
buffer.Write (bi, 1);
inc (x);
if ii = 4 then ii: = 0;
end;
Запускаємо наш "зломщик" (втім, ці дії складно назвати зломом, так як ми не модифікуємо жодного байта, безпосередньо відноситься до гри, а лише відновлюємо вихідне додаток шляхом дешифрування). Пару секунд очікування; запускаємо гру. Нашій радості немає меж, тому що тепер гра абсолютно незалежна від NevoSoft'овского ланчера, який канючить у нас гроші. Тепер можна розслабитися і, відкинувшись у крісло, насолоджуватися улюбленою іграшкою.
Висновок
Відмінність хакера від звичайної людини полягає не тільки у високому рівні знань IT-технологій, а в першу чергу в його допитливості і здатності знаходити нестандартний підхід до звичайних справ. Дослідження, яке ми зараз зробили, доводить ще один факт - для злому не завжди потрібно годинами сидіти в відладчик, вишукуючи заповітні байти, які потрібно пофіксити, іноді можна обійтися і тими програмами, які у нас завжди під рукою. За сим прощаюсь і рекомендую завжди дотримуватися ст. 272-274 КК РФ - і буде тобі щастя!