!(D

2008.09.20

Содержимое это страницы сильно устарело и не поддерживается!

Все замечания по поводу содержимого будут игнорироваться.

Страница оставлена исключительно только для истории.


Необходимое предисловие

Многие современные игры при установке полностью ставятся на винчестер, но для запуска требуют оригинальный CD-диск, для того чтобы убедиться, что они "не пиратские". Так как все файлы необходимые для работы игры уже на жёстком диске, то не вижу особого смысла каждый раз при запуске пихать диск в дисковод. Многие делают образ CD на жёсткий диск, но это, на мой взгляд, не лучшее решение проблемы (хотя самое простое), так как этот самый образ сожрёт 640 или 700 метров, а если ещё предположить, что хочется поставить несколько таких игр... Короче, бесполезно расходуемое пространство. Бесспорно самый лучший вариант - это если игра предлагает выбрать размер установки. Очень удобно - поставил где-то 30 метров нужных файлов, а остальное и не жалко на жёсткий диск в виде образов закинуть, чтобы дисковод не шумел. Но, к сожалению, как уже отмечено, практически все современные игры ставятся полностью...


Внимание!

Прежде чем начинать отучать от диска убедитесь в том, что игра вообще идёт без него. Что на диске не находятся какие-нибудь файлы (видео, музыка, текстуры и т.д.) необходимые для работы игры!


Рассматривать будем на примере игры Mafia.

Взять уже готовый "No CD" для этой игры можно в разделе B3/\OM.


Инструментарий

Итак, что нам нужно:

  1. FAR
  2. HIEW
  3. IDA
  4. Минимальное знание языка Assembler

Пункты 1-3 берутся тут: Li№KZ.

Вот, есть конспект курса, который мне когда-то преподавали - не вредно будет ознакомиться для начала: Ассемблер (конспект).


Порядок действий

Таков:

  1. Устанавливаем игру.
  2. Вытаскиваем диск и запускаем.
  3. Получаем примерно такое сообщение (для игры Mafia):
    Please insert MAFIA CD 1
    Теперь записываем куда-нибудь это сообщение (текст).
    *) Есть несколько видов защит. Тут рассмотрен самый простой. Всякие защиты а-ля StarForce, SafeDisk и т.д. рассматриваться не будут, так как с ними куда больше геммора. Так что делаете так:
  4. Запускаем FAR.
  5. Лезем в каталог, куда установлена игра.
  6. Находим там файл, который запускают. В нашем случае это Game.exe
  7. Нажимаем на нём F3 и смотрим, теперь, если справа есть жёлтые стрелочки от переноса ">", то нажимаем F2, чтобы они исчезли.
  8. Нажимаем F7 и вводим: "Please". Потом нажимаем ENTER.
  9. Если строка не найдена, то:
    • .EXE файл защищён какой-то защитой - это тема для другой статьи (вероятность для современных игр - 90%)
    • .EXE файл зажат каким-то архиватором исполняемых файлов (вероятность - 5%, скорее на нём защита + он ещё зажат)
    • данная строка находится в UNICODE кодировке, когда на 1 символ сообщения приходится 2 байта, т.е. на самом деле она выглядит как-то так (вероятность 4%):
      P0l0e0a0s0e0...
      Где 0 - не символ '0' (номер 48), а 0 и есть (номер 0). Но с такой строкой будет сложнее найти где она выводится. Ещё будут запарки, если строка русская, а-ля "Вставьте диск"...
    • строки нету в этом файле - значит нужно смотреть во всех других файлах, так как они могут оказаться исполняемыми (вероятность 1%, но мне такая штука попадалась)
    В любом случае, если эту строку не нашли - то облом (убедитесь, на всякий пожарный, что правильно её набрали при поиске).
    Если же строка найдена, то:
  10. Запускаем IDA, жмём на кнопку New выбираем файл Game.exe и ждём, пока он проAutoAnalysis'зируется.
  11. Теперь нажимаем ALT+T и вводим это самое слово "Please" (не забывайте про регистр букв - первая должна быть заглавной! Или уберите галочку с Case sensitive). После это жмём ENTER и ждём пока сообщение найдётся.
  12. Если не находится - значит авторы программы что-то по намудрили, чтобы всё так просто не было. Тогда тоже облом.
  13. Но мы взламываем Mafia, так что у нас находится вот такое дело:
    00565EA0 ; --------------- S U B R O U T I N E -------------------
    00565EA0
    00565EA0
    00565EA0 sub_565EA0 proc near ; CODE XREF: sub_5404E0+40p
    00565EA0 ; sub_5BE440+67p
    00565EA0 push esi 00565EA1 mov esi, ds:MessageBoxA
    00565EA7
    00565EA7 loc_565EA7: ; CODE XREF: sub_565EA0+2Fj
    00565EA7 call sub_565F10
    00565EAC test al, al
    00565EAE jnz short loc_565ED5
    00565EB0 mov eax, dword_646E10
    00565EB5 test eax, eax
    00565EB7 jz short loc_565EBF
    00565EB9 mov ecx, [eax]
    00565EBB push eax
    00565EBC call dword ptr [ecx+3Ch]
    00565EBF
    00565EBF loc_565EBF: ; CODE XREF: sub_565EA0+17j
    00565EBF push 15h
    00565EC1 push 0
    00565EC3 push offset aPleaseInsertMa ; "Please insert MAFIA CD 1"
    00565EC8 push 0
    00565ECA call esi ; MessageBoxA
    00565ECC cmp eax, 2
    00565ECF jnz short loc_565EA7
    00565ED1 xor al, al
    00565ED3 pop esi
    00565ED4 retn
    00565ED5 ; -------------------------------------------------------
    00565ED5
    00565ED5 loc_565ED5: ; CODE XREF: sub_565EA0+Ej
    00565ED5 mov al, 1
    00565ED7 pop esi
    00565ED8 retn
    00565ED8
    00565ED8 ; -------------------------------------------------------
    
  14. Строчка 00565EC3 - это засовывание адреса нашей строки. А дальше, как видно, идёт вызов MessageBox - вывод окна с сообщением.
  15. Идём от этой строки вверх - нам нужно найти место, где идёт переход на этот кусок кода.
  16. 00565EB7 - стоит джамп на это место. Но нам он не нужен, либо мы сразу через него прыгаем на вывод этого сообщения, либо, если он не выполнится, перед этим будет вызов какой-то функции и, опять-таки, попадаем после этого на вывод сообщения. Так что роем дальше.
  17. Вот оно - 00565EAE (обратите внимание, что при его выполнении мы перелетаем место вывода сообщения и выхода (retn) из этого участка кода и работаем дальше). Есть два вида замены условных переходов:
    • условный переход заменяется на NOP (No OPerator) (учтите, что условный переход занимает два байта, а NOP - один, так что придётся править оба)
    • условный переход заменяется на безусловный переход JMPS (JuMP Short)
    Первый необходим, когда нам не нужно переходить, а второй - наоборот, когда нужно переходить. В нашем случае нам нужен второй вариант, так как нам не нужно попадать на вывод окна и последующий выход.
  18. Возвращаемся в FAR.
  19. Делаем резервную копию файла Game.exe, скажем в файл 1.exe
  20. Запускаем HIEW:
    hiew.exe 1.exe
  21. Нажимаем два раза ENTER.
  22. Нажимаем F5.
  23. Переходим на нужный нам адрес. Для этого нужно ввести:
    .00565EAE
    и нажать ENTER.
    Обратите внимание на точку перед адресом - она обязательна!
    Оба! А HIEW-то, совсем по-другому команды перехода интерпретирует. Ну да ладно - смысл один.
  24. Жмём F3 - начать изменения.
  25. Жмём TAB.
  26. Теперь заменяем команду JNE на JMPS, а адрес оставляем старый. Жмём ENTER.
  27. Теперь жмём ESC.
  28. Затем обязательно F9 - чтобы сохранить изменения.
  29. Теперь F10 - выходим из HIEW.
  30. Запускаем файл 1.exe и получаем нужный результат - игра идёт без диска.
  31. Ещё можно переименовать Game.exe в _Game.exe (резервная копия ещё никому не мешала) и после этого 1.exe в Game.exe - тогда можно будет без проблем пользоваться ярлыками, которые установились вместе с игрой.
  32. Готово.

Насчёт смены на NOP. Если нужно не переходить, а продолжать работу, то тогда нужно условный переход менять на NOP. Это команда языка Assembler, которая ничего не делает. Так вот, как тогда изменится наша тактика: делаем всё до шага 24) включительно, но не нажимаем TAB! А вместо этого набираем два раза (так как условный переход занимает два байта): 90 и снова 90 (90 - это шестнадцатеричный код команды NOP). После этого делаем все с шага 28) и дальше.


Если что-то не получилось - это не мои проблемы!
Учите Assembler! Читайте документации!
Это очевидно, но не все защиты так просто сломать!

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

А с меня хватит и этой статьи.

Всем удачи!