Cd-check игры Петька 4: День независимости Автор: SLV Эта прикольная игра сделана популярной русской фирмой "Бука". Файлов у неё много, аж на 2 диска, да ещё она не хочет запускаться без II компакта (вернее поначалу не хотела:)). Так вот, надо сделать так, чтоб дисков не было, а игра была, ака CD_CHECK. При запуске игры (без наличия диска в приводе) выходит MessageBox с текстом 'Отсутствует CD с игрой' + #13 + 'Вставьте его в CD-ROM и нажмите OK' (*). Для начала поменяем букву cD-ROM-а. Я поменял на Z:\. Вставляем диск и... игра запускается. Значит надо отлавливать/искать API функции, используемые игрой для проверки диска на готовность. Как далее выяснится этот вызов будет из модуля SDL.dll. Можно покопаться и в нём, но есть и другой подход: надо дизассемблировать exe-шник и поискать там строку находящююся в MessageBox-е (*). Так и поступим, откроем файл petka4.exe в W32DASM-ме. Открыли. Search>FindText. Поищем текст (*). Нашли! В листинге фраза повторяется 1 раз. Видим такой код: :0040A9EC 52 push edx :0040A9ED E87E90FFFF call 00403A70 :0040A9F2 83C404 add esp, 00000004 :0040A9F5 83F8FF cmp eax, FFFFFFFF :0040A9F8 751E jne 0040AA18 * Referenced by a (U)nconditional or (C)onditional Jump at Address: |:0040AA16(C) | :0040A9FA 6A01 push 00000001 * Possible StringData Ref from Data Obj ->"Отсутствует CD с игрой Вставьте " ->"его в CD-ROM и нажмите OK" :0040A9FC 6824FA4700 push 0047FA24 :0040AA01 E88A8DFFFF call 00403790 :0040AA06 8D442408 lea eax, dword ptr [esp+08] :0040AA0A 50 push eax :0040AA0B E86090FFFF call 00403A70 :0040AA10 83C40C add esp, 0000000C :0040AA13 83F8FF cmp eax, FFFFFFFF :0040AA16 74E2 je 0040A9FA (В листинге русские буквы отображены корректно, но в W32DASM-е они будут кракозябрами.) С первого взгляда может показаться, что если поменять je 0040A9FA на jne 0040A9FA, но проблема будет решена, но это не правильный ход. Функция по адресу 00403A70 возвращает в eax некоторое значение, которое сравнивается с FFFFFFFF, т.е. для успешного преодоления условного перехода eax должен содержать от 1 до FFFFFFFF. Следовательно неообходимо зайти в call: * Referenced by a CALL at Addresses: |:0040952B , :0040A577 , :0040A5B0 , :0040A9E0 , :0040AA01 (**) :00403790 8A442408 mov al, byte ptr [esp+08] :00403794 84C0 test al, al :00403796 7419 je 004037B1 :00403798 8B442404 mov eax, dword ptr [esp+04] :0040379C 6A31 push 00000031 ... ... ... ... ... ... ... ... ... и дописать с самого начала следующие строки: xor eax,eax ; Обнуление значения регистра inc eax ; EAX=EAX + 1 ret ; Выход из процедуры Этот способ эффективен (и работоспособен) потому, что функция по адресу 00403790 вызывается из нескольких мест (**), а значит проверка диска на готовность проверяется также не единожды.