Искажение TOC как средство борьбы с несанкционированным копированием диска
( Часть 1 )
Автор статьи: Крис Касперски
Источник: Журнал "Системный администратор"
Уже давно
Утихло поле боя,
Но сорок тысяч
Воинов Китая
Погибли здесь,
Пожертвовав собою...
Ду Фо «Оплакиваю поражение при Чэньтао»
Искажение TOC – жестокий, уродливый но на удивление широко распространенный прием, использующийся в доброй половине защитных механизмов. Штатные копировщики на таких дисках в буквальном смысле слова сходят с ума и едут крышей. Копировщики защищенных дисков (Clone CD, Alcohol 120%) к искаженному TOC относятся гораздо лояльнее, но требуют для своей работы определенного сочетания пишущего и читающего приводов, да и в этом случае копируют такой диск не всегда.
Пишущий привод обязательно должен поддерживать режим RAW DAO (Disc At Once), в котором весь диск записывается за один проход лазера. Режим RAW SAO (Session At Once) для этих целей совершенно непригоден, поскольку предписывает приводу писать сначала содержимое сессии, а потом – TOC. Как следствие – приводу приходится самостоятельно анализировать TOC, чтобы определить стартовый адрес сессии и ее длину. Попытка записать искаженный TOC в режиме SAO в общем случае приводит к непредсказуемому поведению привода и о работоспособной копии защищенного диска нечего и думать! Первая встретившаяся приводу сессия с искаженным TOC обычно оказывается и последней, т.к. остальные сессии писать уже некуда (искажение TOC обычно преследует цель увеличения размера сессии до нескольких гигабайт).
Читающий привод помимо режима «сырого» чтения (который поддерживают практически все приводы) должен уметь распознавать искаженный TOC, автоматически переходя в этом случае на использование «резервного» средства адресации – Q-канала подкода. В противном случае сессия, содержащая искаженный TOC, окажется недоступной для чтения даже на секторном уровне.
Таким образом, копирование дисков с искаженным TOC осуществимо не на всяком оборудовании и порядка 1/3 моделей «писцов» для этих целей непригодны. Узнать, поддерживает ли выбранная вами модель привода режим RAW DAO или нет, можно, в частности, из раздела «Tech support» справки Clone CD, где перечислены характеристики достаточно большого количества всевозможных приводов (впрочем, моих приводов там, увы, нет). Другой путь – «скормить» приводу SCSI/ATAPI команду 46h (GET CONFIGURATION) и посмотреть, что он ответит. Из двух моих «писцов» режим RAW DAO поддерживает один лишь NEC. С определением возможности чтения искаженных сессий дела обстоят на порядок сложнее, ибо данная особенность поведения является исключительно внутренней характеристикой привода и не афишируется ни самим приводом, ни его производителями. Приходится выяснять эту информацию экспериментально. Возьмите диск с чудовищно искаженным TOC (о том, как его создать, рассказано ниже), воткните его в привод и попробуйте прочесть несколько секторов из искаженной сессии. Реакция приводов может быть самой разнообразной. Тот же PHILIPS в зависимости от «настроения» своих электронных цепей то рапортует об ошибке чтения, то возвращает совершенно бессмысленный мусор, в котором не угадывается даже синхропоследовательность, возглавляющая заголовок сырого сектора.
Основной недостаток защитных механизмов с искаженным TOC состоит в том, что некоторые приводы такие диски просто «не видят» и потому не могут их воспроизвести. Легальный пользователь, испытавший несовместимость защиты со своей аппаратурой, в лучшем случае обложит ее разработчика матом и поспешит вернуть диск продавцу… если, конечно, сможет вытащить эту «бяку» из недр CD-ROM, и не факт, что у него получится, поскольку микропроцессорная начинка некоторых приводов при попытке анализа искаженного TOC просто «зависает» и привод полностью абстрагируется от всех раздражителей внешнего мира, не реагируя в том числе и на настойчивые попытки пользователя сделать диску «EJECT». Дырку для аварийного выброса диска, правда, еще никто не отменял[1], но, по слухам, не везде она есть (хотя лично мне приводов без дырки еще не встречалось), а там где есть – зачастую оказывается скрытой за декоративной панелью или – что более вероятно – пользователь может вообще не знать, что это за отверстие такое, для чего оно предназначено и как им, собственно, следует пользоваться. На «Макинтошах» таких дырок нет – это точно (или же «Маковские» пользователи все сплошь идиоты). Во всяком случае, количество судебных исков, поданных последними, в буквальном смысле слова не поддается ни разуму, ни исчислению. Самое интересное, что подавляющее большинство этих исков были удовлетворены и разработчикам пришлось оплатить и «ремонт» аппаратуры, и моральный ущерб, и собственно сами судебные издержки. (Между нами говоря, снятие защиты с дисков, записанных с грубыми нарушениями стандарта, коими, в частности, и являются диски с искаженным TOC, не считается взломом, и не преследуется по закону, поэтому ломайте, ломайте и еще раз ломайте).
Создание защищенного диска искаженным TOC
Для создания защищенного диска с искаженным TOC нам понадобится: любая программа записи на диск, умеющая создавать многосессионные диски (например, Roxio Easy CD Creator), копировщик защищенных дисков, сохраняющий содержимое TOC в текстовом файле, доступном для редактирования (мы выбираем Clone CD), и, естественно, сам пишущий привод, поддерживающий режим сырой записи в режиме DAO. Для облегчения восприятия материала все действия будут расписаны по шагам, хотя это выглядит и не слишком литературно.
Шаг первый
Достаем из упаковки CD-R болванку или – что даже лучше – засовываем в привод потертый жизнью CD-RW диск и записываем на него пару сессий в штатном режиме. Будет лучше (вернее, нагляднее), если вторая сессия будет включать в себя файлы первой сессии – той самой сессии, чей TOC мы и собираемся искажать. Интересно, сможет ли привод прочесть ее содержимое или нет?
Шаг второй
Запускаем Clone CD и просим его создать образ оригинального диска (выбираемый профиль настроек на данном этапе некритичен, поскольку диск еще не защищен, то с равным успехом можно использовать как «CD с данными», так и «Protected PC Game»; галочку «создавать Cue-Sheet» взводить необязательно – все равно она действительна лишь на односессионных CD).
Шаг третий
Если все сделано правильно и программно-аппаратное обеспечение во всей своей совокупности работает нормально, на жестком диске должны образоваться три файла: IMAGE.CCD, – несущий в себе содержимое Q-канала подкода Lead-In области или, попросту говоря, TOC; IMAGE.IMG – «сырой» образ диска со всеми секторами от 00:00:02 до «сколько-на-диске-есть-там» и IMAGE.SUB – содержимое полей подкода «программной» части диска. Последний файл в принципе может и отсутствовать (он создается только, если взведена галочка «Чтение субканалов из треков с данными»), но это некритично, т.к. сейчас нас в первую очередь интересуют не каналы подкода, а сам TOC!
Откроем файл IMAGE.CCD в любом текстовом редакторе и попытаемся перевести расклад геометрии диска на человеческий язык.
Листинг 1. Содержимое неискаженного TOC в сыром виде. Обобщенно говоря, диск содержит две секции – по одному треку каждая. Абсолютный адрес начала первого трека 00:00:02, абсолютный адрес Lead-out-области первой сессии 00:29:33 (адрес последнего сектора трека на две секунды короче), абсолютный адрес начала второго трека 03:01:33, а абсолютный адрес Lead-out второй сессии 03:24:33. Максимально достижимая емкость диска 22:14:34 (хотя на самом диске и написано, что он 23-минутный).
[CloneCD] ; данные о Clone CD
Version=3 ; версия Clone CD.
[Disc] ; данные диска
TocEntries=12 ; количество элементов TOC
Sessions=2 ; количество сессий = 2
DataTracksScrambled=0 ; поле DVD (см. inf-8090), для CD эта информация лишена
смысла
CDTextLength=0 ; CD-Text в полях подкода Lead-in-области отсутствует
[Session 1] ; данные сессии 1
PreGapMode=1 ; тип трека Mode 1 (трек с данными, 2048 байт данных)
PreGapSubC=0 ; данных подканала нет
[Session 2] ; данные сессии 2
PreGapMode=1 ; тип трека Mode 1 (трек с данными, 2048 байт данных)
PreGapSubC=0 ; данных подканала нет
[Entry 0] ; данные элемента TOC №0
Session=1 ; элемент сессии 1
Point=0xa0 ; номер первого трека сессии 1 в PMin/тип диска в PSec
ADR=0x01 ; q-Mode == 1
Control=0x04 ; диск с данными, запрещенный для копирования
TrackNo=0 ; трек, который мы сейчас читаем, – это Lead-in-трек
(т.е. TOC)
AMin=0 ; \
ASec=0 ; + абсолютный адрес текущего трека
AFrame=0 ; /
ALBA=-150 ; LBA-адрес текущего трека
Zero=0 ; это поле должно быть равно нулю, как оно и есть
PMin=1 ; номер первого трека сессии 1
PSec=0 ; тип диска CD-DA и CD-ROM-диск в Mode 1
PFrame=0 ; не несет никакой полезной информации
PLBA=4350 ; номер трека, представленный Clone CD как LBA-адрес,
т.е. глупость
[Entry 1] ; данные элемента TOC №1
Session=1 ; элемент сессии 1
Point=0xa1 ; номер последнего трека сессии 1 в PMin
ADR=0x01 ; q-Mode == 1
Control=0x04 ; диск с данными, запрещенный для копирования
TrackNo=0 ; трек, который мы сейчас читаем, – это Lead-in-трек
(т.е. TOC)
AMin=0 ; \
ASec=0 ; + абсолютный адрес текущего трека
AFrame=0 ; /
ALBA=-150 ; LBA-адрес текущего трека
Zero=0 ; это поле должно быть равно нулю, как оно и есть
PMin=1 ; номер последнего трека сессии 1
(в сессии только один трек)
PSec=0 ; не несет никакой полезной информации
PFrame=0 ; не несет никакой полезной информации
PLBA=4350 ; номер трека, представленный Clone CD как LBA-адрес,
т.е. глупость
[Entry 2] ; данные элемента TOC №2
Session=1 ; элемент сессии 1
Point=0xa2 ; положение Lead-out-области в PMin:PSec:PFrame
ADR=0x01 ; q-Mode == 1
Control=0x04 ; диск с данными, запрещенный для копирования
TrackNo=0 ; трек, который мы сейчас читаем, – это Lead-in-трек
(т.е. TOC)
AMin=0 ; \
ASec=0 ; + - абсолютный адрес текущего трека
AFrame=0 ; /
ALBA=-150 ; LBA-адрес текущего трека
Zero=0 ; это поле должно быть равно нулю, как оно и есть
PMin=0 ; \
PSec=29 ; + - абсолютный адрес Lead-out-области сессии 1
PFrame=33 ; /
PLBA=2058 ; LBA-адрес Lead-out-области сессии 1
[Entry 3] ; данные элемента TOC №3
Session=1 ; элемент сессии 1
Point=0x01 ; данные трека 1 сессии 1
ADR=0x01 ; q-Mode == 1
Control=0x04 ; диск с данными, запрещенный для копирования
TrackNo=0 ; трек, который мы сейчас читаем, – это Lead-in-трек
(т.е. TOC)
AMin=0 ; \
ASec=0 ; + - абсолютный адрес текущего трека
AFrame=0 ; /
ALBA=-150 ; LBA-адрес текущего трека
Zero=0 ; это поле должно быть равно нулю, как оно и есть
PMin=0 ; \
PSec=2 ; + - абсолютный адрес начала трека 1 сессии 1
PFrame=0 ; /
PLBA=0 ; LBA-адрес начала трека 1 сессии 1
[Entry 4] ; данные элемента TOC №4
Session=1 ; элемент сессии 1
Point=0xb0 ; позиция следующий записываемой области в
AMin:ASec:AFrame
ADR=0x05 ; q-Mode == 1
Control=0x04 ; диск с данными, запрещенный для копирования
TrackNo=0 ; трек, который мы сейчас читаем, – это Lead-in-трек
(т.е. TOC)
AMin=2 ; \
ASec=59 ; + - абсолютный адрес следующей записываемой области
AFrame=33 ; /
ALBA=13308 ; LBA-адрес следующей записываемой области
Zero=3 ; кол-во pointer в Mode 5
PMin=22 ; \
PSec=14 ; + - абсолютный адрес максимальной записываемой области
PFrame=34 ; /
PLBA=99934 ; LBA-адрес максимальной записываемой области
[Entry 5] ; данные элемента TOC №5
Session=1 ; элемент сессии 1
Point=0xc0 ; стартовый адрес Lead-in-области Hybrid-диска
(если он есть)
ADR=0x05 ; Mode 5 (Оранжевая книга)
Control=0x04 ; диск с данными, запрещенный для копирования
TrackNo=0 ; трек, который мы сейчас читаем, – это Lead-in-трек
(т.е. TOC)
AMin=162 ; рекомендуемая мощность лазера для записи
ASec=128 ; Application code
AFrame=140 ; зарезервировано
ALBA=288590 ; LBA-"адрес" трех предыдущих полей
Zero=0 ; зарезервировано
PMin=97 ; \
PSec=27 ; + - абсолютный адрес Lead-in-области Hybrid-диска
(адрес лежит за пределами диска, т.е. Hybrid-диска нет)
PFrame=21 ; /
PLBA=-11604 ; LBA-адрес Lead-in-области Hybrid
(вычислен с переполнением)
[Entry 6] ; данные элемента TOC №6
Session=1 ; элемент сессии 1
Point=0xc1 ; копия ATIP-информации
ADR=0x05 ; -+
Control=0x04 ; -+
TrackNo=0 ; -+
AMin=4 ; -+
ASec=120 ; -+
AFrame=96 ; -+
ALBA=26946 ; -+ – ATIP-информация
Zero=0 ; -+
PMin=0 ; -+
PSec=0 ; -+
PFrame=0 ; -+
PLBA=-150 ; -+
[Entry 7] ; данные элемента TOC №7
Session=2 ; элемент сессии 2 (вот мы и добрались до сессии 2!)
Point=0xa0 ; номер первого трека сессии 2 в PMin/тип диска в PSec
ADR=0x01 ; q-Mode == 1
Control=0x04 ; диск с данными, запрещенный для копирования
TrackNo=0 ; трек, который мы сейчас читаем, – это Lead-in-трек
(т.е. TOC)
AMin=0 ; \
ASec=0 ; + - абсолютный адрес текущего трека
AFrame=0 ; /
ALBA=-150 ; LBA-адрес текущего трека
Zero=0 ; это поле должно быть равно нулю, как оно и есть
PMin=2 ; номер первого трека сессии 2 (нумерация треков сквозная!)
PSec=0 ; тип диска CD-DA и CD-ROM-диск в Mode 1
PFrame=0 ; не несет никакой полезной информации
PLBA=8850 ; номер трека, представленный Clone CD как LBA-адрес,
т.е. глупость
[Entry 8] ; данные элемента TOC №8
Session=2 ; элемент сессии 2
Point=0xa1 ; номер последнего трека сессии 2 в PMin
ADR=0x01 ; q-Mode == 1
Control=0x04 ; диск с данными, запрещенный для копирования
TrackNo=0 ; трек, который мы сейчас читаем, – это Lead-in-трек
AMin=0 ; \
ASec=0 ; + - абсолютный адрес текущего трека
AFrame=0 ; /
ALBA=-150 ; LBA-адрес текущего трека
Zero=0 ; это поле должно быть равно нулю, как оно и есть
PMin=2 ; номер последнего трека сессии 2 (в сессии только
один трек)
PSec=0 ; не несет никакой полезной информации
PFrame=0 ; не несет никакой полезной информации
PLBA=8850 ; номер трека, представленный Clone CD как LBA-адрес,
т.е. глупость
[Entry 9] ; данные элемента TOC №9
Session=2 ; элемент сессии 2
Point=0xa2 ; положение Lead-out-области в PMin:PSec:PFrame
ADR=0x01 ; q-Mode == 1
Control=0x04 ; диск с данными, запрещенный для копирования
TrackNo=0 ; трек, который мы сейчас читаем, – это Lead-in-трек
AMin=0 ; \
ASec=0 ; + - абсолютный адрес текущего трека
AFrame=0 ; /
ALBA=-150 ; LBA-адрес текущего трека
Zero=0 ; это поле должно быть равно нулю, как оно и есть
PMin=3 ; \
PSec=24 ; + - абсолютный адрес Lead-out-области сессии 2
PFrame=23 ; /
PLBA=15173 ; LBA-адрес Lead-out-области сессии 2
[Entry 10] ; данные элемента TOC №10
Session=2 ; элемент сессии 2
Point=0x02 ; данные трека 2 сессии 2
ADR=0x01 ; q-Mode == 1
Control=0x04 ; диск с данными, запрещенный для копирования
TrackNo=0 ; трек, который мы сейчас читаем, – это Lead-in-трек
AMin=0 ; \
ASec=0 ; + - абсолютный адрес текущего трека
AFrame=0 ; /
ALBA=-150 ; LBA-адрес текущего трека
Zero=0 ; это поле должно быть равно нулю, как оно и есть
PMin=3 ; \
PSec=1 ; + - абсолютный адрес начала трека 2 сессии 2
PFrame=33 ; /
PLBA=13458 ; LBA-адрес начала трека 2 сессии 2
[Entry 11] ; данные элемента TOC №11
Session=2 ; элемент сессии 2
Point=0xb0 ; адрес следующей записываемой области в AMin:ASec:AFrame
ADR=0x05 ; Mode 5
Control=0x04 ; диск с данными, запрещенный для копирования
TrackNo=0 ; трек, который мы сейчас читаем, – это Lead-in-трек
(т.е. TOC)
AMin=4 ; \
ASec=54 ; + - абсолютный адрес следующей записываемой области
AFrame=23 ; /
ALBA=21923 ; LBA-адрес следующей записываемой области
Zero=1 ; количество pointer Mode 5
PMin=22 ; \
PSec=14 ; + - абсолютный адрес последней возможной
Lead-out-области (на самом диске написано
23 мин., это ж как надо округлять 22:14:34)
PFrame=34 ; /
PLBA=99934 ; LBA-адрес последней возможной Lead-out-области
[TRACK 1] ; данные трека 1
MODE=1 ; режим Mode 1
INDEX 1=0 ; post-gap?
[TRACK 2] ; данные трека 2
MODE=1 ; режим Mode 1
INDEX 1=0 ; post-gap?
Давайте теперь немного поиздеваемся над TOC и увеличим стартовый адрес первого трека так, чтобы он вышел далеко за пределы первой сессии и попал… ну, собственно, куда нибудь он все равно попадет. Чтобы быстро отыскать соответствующую ему запись, воспользуемся контекстным поиском. Жмем и вводим «point=0x1»:
Листинг 2. Атрибуты трека 1.
[Entry 3] ; данные элемента TOC №3
Session=1 ; элемент сессии 1
Point=0x01 ; данные трека 1 сессии 1
ADR=0x01 ; q-Mode == 1
Control=0x04 ; диск с данными, запрещенный для копирования
TrackNo=0 ; трек, который мы сейчас читаем, – это Lead-in-трек (т.е. TOC)
AMin=0 ; \
ASec=0 ; + - абсолютный адрес текущего трека
AFrame=0 ; /
ALBA=-150 ; LBA-адрес текущего трека
Zero=0 ; это поле должно быть равно нулю, как оно и есть
PMin=0 ; \
PSec=2 ; + - абсолютный адрес начала трека 1 сессии 1
PFrame=0 ; /
PLBA=0 ; LBA-адрес начала трека 1 сессии 1
_____________________
←
| →
¯¯¯¯¯¯¯¯¯¯¯
Материалы в этом разделе:
и b ( New! )
|
| |
|
|
( /
) |
() |
()
| |