Всем привет! Недавно столкнулся с DOS-программой, которая привязана к дискете. Вот что удалось накопать: используется функция BIOS int 13h для чтения дискеты со след параметрами: AH=04 - тип операции (04=Верификация сектора) AL=01 - число секторов CH=50 - номер дорожки CL=09 - номер начального сектора DH=00 - номер головки DL=00 - номер дисковода После отработки int 13h AX=0200 - Не найден адресный маркер на диске. Теперь вопрос: кто знает как отвязать прогу от проверки ключевой дискеты? Была идея отформатировать саму дискету с нестандартным размером сектора...
Trasher Сорри за опепятку. Небось все под "скользящей" строкой дешифрования-зашифрования в обработчике int1 замурцовано?
crypto Смутно представляю себе что это такое По-моему нет там "дешифрования-расшифрования"... На int 13h сразу вышел.Использовал отладчик из старых версий антивируса Касперского.Он позволяет сразу выбрать int и поставить на него точку останова.
Trasher На дискетах (особливо на 5-дюймовых) помимо программно или аппаратно созданного уникального признака использовалось зашифрование программы. При загрузке такие программы переназначали 1 и 3-е прерывание (и некоторые другие), обработчик 1-го прерывания расшифровывал, исполнял и зашифровывал очередную инструкцию (это и есть "скользящая" строка), при этом выполнялось чтение секретной части диска, проверка и в зависимости от проверки программа либо раскрывалась и запускалась, либо обламывалась. Использовалась подобная идея, например, в защитах SHIELD, VANGUARD, CERBER. А то что ты попал на обработку 13-го прерывания, еще ни о чем не говорит, может и подстава. Нужно смотреть, как все это реализовано с самого начала.
Обрати внимание, что читается область за пределами стандартной дискеты (трек 50h = 80), там может быть записан ключ.
crypto Спасибо за разъяснения! DeGlucker Значит оригинальная дискета имеет нестандартное форматирование? Ведь обычная на 1.44Мб имеет 0-79 дорожек... Теоретически могу получить доступ к оригинальной дискете и посмотреть что к чему, но товарищ, который просил посмотреть эту прогу что-то жлобит принести дискету
Trasher Естественно, такой признак как-правило трудно или даже невозможно воспроизвести програмнно. Прежде, чем просить дискету, лучше потратить некоторое время на изучение загрузчика. Тогда и станет понятно, нужна дискета или нет. А то, что товарщ жлобит, тоже понятно - на дискету в закрытый сектор может записываться некая информация (к примеру, количество оставшихся запусков), дискету неаккуратным обращением можно разрушить,...
Как насчет того, чтобы написать резидент, возвращающий значения, устраивающие искомую программу? В случае с Mecom (экономическая игра под дос), защита которой основывалась на чтении (они не проверяли содержимое) доп. сектора, все было успешно. Фильтровал вызовы инт13, в иных случаях отдавал упр-е старым обработчикам, в случае вызова с нестандартными параметрами возвращал не-CarryFlag.
crypto Можно подробнее, пожалуйста, про перехват прерываний. В смысле как это выглядит в общем виде... Сам ничего интересного не нашел по этой теме. _edge Как понять какие значения ее устроят? Про оригинальную дискету уже было сказано...
Попробовал поменять значения регистров перед выполнением инта 13... Поменял CH с 50h на 20h (номер дорожки). Теперь вместо "ILLEGAL COPY PROGRAM STOPPED" прога выдает "EQUIPMENT ERROR PROGRAM STOPPED"
В моем случае программу устроило успешное выполнение вызова i13. Ломаемая прога тупо вызывала "читай сектор", если CF, начинала орать. Я же ей clc/retf. Как будто он прочитался. В моем случае она не проверяла, что же собственно "считалось". Может экзешник пропатчить, заменив jz на jnz? (явно направить ход исполнения на "все успешно"). Тем более, она verify делает, ей похоже до содержимого дела нет. Пример перехвата инт21 для .com (учебный, но смысл ясен) Код (Text): _code segment assume cs:_code,ds:_code org 100h start: jmp setup ; здесь будем хранить cs:ip старого обраб. old21 dd ? ; новый обработчик new21 proc far assume cs:_code,ds:nothing pushf push ax push dx cmp ah,4fh jne loc01 mov ah,02h mov dx,2bh pushf call old21 loc01: pop dx pop ax popf pushf call old21 retf 0002h ;<-- может быть правильно через iret, не помню уже new21 endp setup: ; сохр. старый вектор прерывания mov ax,3521h int 21h mov word ptr old21[0],bx mov word ptr old21[2],es ; уст. новый mov ax,2521h mov dx,offset new21 int 21h ; выйти и оставить резидентом mov dx,offset setup int 27h _code ends end start
На предмет пропатчивания я уже лазил отладчиком, однако не нашел чего-либо подозрительного (хотя не факт что такого там нет ). К тому же непривычна DOS'овская 16-битная адресация (или правильно говорить 20-битная?). _edge Каким образом сделать перехват нужного инта? Подскажи, пожалуйста. Возможно так оно и есть, что прога только лишь проверяет наличие нестандартной разметки флопа...
Trasher Собственно, о прерываниях все уже сказано. С помощью сервисного прерывания 21h определяешь вектор нужного тебе прерывания (скажем, 13h), сохраняешь его, назначаешь собственный обработчик, в котором будет в конце вызов старого обработчика. Потом все это дело восстанавливаешь.
Переделал по-быстрому код, что приводил _edge: Код (Text): _code segment assume cs:_code,ds:_code org 100h start: jmp setup ; Здесь будем хранить cs:ip старого обраб. oldint13 dd ? ; Новый обработчик new13 proc far assume cs:_code,ds:nothing pushf cmp ax,0401h ; Пользователь вызывает нашу функцию? je is_check call oldint13 ; Или переходим на исходный int 13h retf is_check: xor ah,ah clc popf retf new13 endp setup: ; Сохраняем старый вектор прерывания mov ax,3513h int 21h mov word ptr oldint13[0],bx ; Смещение mov word ptr oldint13[2],es ; Сегмент ; Усанавливаем новый mov ax,2513h mov dx,offset new13 int 21h ; TERMINATE and STAY RESIDENT :) mov ax,3100h mov dx,0004h int 21h _code ends end start Запускаю эту программу и следом подопытную... И ничего: черный экран и курсор. Помогает только перезагрузка(если под реальным ДОС или VMWare). Подскажите, пожалуйста, может криво накодил...
Trasher А прежний обработчик нафиг? Уж если хочешь сбросить флажок, то сбрось его после вызова прежнего обработчика. ЗЫ Все-таки разберись, что делает старый, а потом переходи к кодированию.
crypto, видимо, ты был прав. Потрейсил прогу в самом начале, она перехватывает следущие прерывания: 00h - ошибка деления 1Bh - Ctrl-Break прерывание 1Ch - Прерывание от таймера 66h - не используется Будем смотреть...
По просьбе ТС смотрел код. Выяснилось, что написан на Форте (версия прошита в коде). Нашел даже место, где вызывается 13-е прерывание, но ничего путного из этого не выходит. Кто знаком с Фортом, представляют, о чем я говорю. Может быть есть спецы по нему? А то не очень хочется изучать эту хренову стековую машину.