2003 г
Искажение TOC'а как средство борьбы с несанкционированным копированием диска
Крис Касперски
|
Уже давно
Утихло поле боя,
Но сорок тысяч
Воинов Китая
Погибли здесь,
Пожертвовав собою...
|
Ду Фо
"Оплакиваю поражение при Чэньтао"
Искажение 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'a в текстовом файле, доступном для редактирования (мы выбираем Clone CD) и, естественно, сам пишущий привод,
поддерживающий режим сырой записи в режиме DAO. Для облегчения восприятия материала все действия будут
расписаны по шагам, хотя это выглядит и не слишком литературно.
Шаг первый
Достаем из упаковки CD-R болванку (еще девочку)
или – что даже лучше – засовываем в привод потертый жизнью CD-RW диск (нет, это не проститутка, это
просто 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 в любом текстовом
редакторе и попытаемся перевести расклад геометрии диска на человеческий язык.
[CloneCD] |
; |
данные о Clone CD |
Version=3 |
; |
версия Clone CD. Идет лесом |
|
|
|
[Disc] |
; |
данные диска |
TocEntries=12 |
; |
кол-во элементов TOC'a |
Sessions=2 |
; |
кол-во сессий = 2 |
DataTracksScrambled=0 |
; |
поле DVD (см. inf-8090), для CD эта информация лишена смысла |
CDTextLength=0 |
; |
CD-Text'a в полях подкода 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'a No.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 |
; |
номер трека представленный CloneCD как LBA-адрес, т.е. чушь |
|
|
|
[Entry 1] |
; |
данные элемента TOC'a No.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 |
; |
номер трека представленный CloneCD как LBA-адрес, т.е. чушь |
|
|
|
[Entry 2] |
; |
данные элемента TOC'a No.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'a No.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'a No.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'a No.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 диска |
PFrame=21 |
; |
/ (адрес лежит за пределами диска, т.е. Hybrid-диска нет) |
PLBA=-11604 |
; |
LBA-адрес Lead-in области Hybrid'a(вычислен с переполнением) |
|
|
|
[Entry 6] |
; |
данные элемента TOC'a No.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'a No.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 |
; |
номер трека представленный CloneCD как LBA-адрес, т.е. чушь |
|
|
|
[Entry 8] |
; |
данные элемента TOC'a No.8 |
Session=2 |
; |
элемент сессии 2 |
Point=0xa1 |
; |
номер последнего трека сессии 2 в 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=2 |
; |
номер последнего трека сессии 2 (в сессии только один трек) |
PSec=0 |
; |
не несет никакой полезной информации |
PFrame=0 |
; |
не несет никакой полезной информации |
PLBA=8850 |
; |
номер трека представленный CloneCD как LBA-адрес, т.е. чушь |
|
|
|
[Entry 9] |
; |
данные элемента TOC'a No.9 |
Session=2 |
; |
элемент сессии 2 |
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=3 |
; |
\ |
PSec=24 |
; |
+ - абсолютный адрес Lead-out области сессии 2 |
PFrame=23 |
; |
/ |
PLBA=15173 |
; |
LBA-адрес Lead-out области сессии 2 |
|
|
|
[Entry 10] |
; |
данные элемента TOC'a No.10 |
Session=2 |
; |
элемент сессии 2 |
Point=0x02 |
; |
данные трека 2 сессии 2 |
ADR=0x01 |
; |
q-Mode == 1 |
Control=0x04 |
; |
диск с данными, запрещенный ;-) для копирования |
TrackNo=0 |
; |
трек, который мы сейчас читаем – это Lead-in трек (т.е. TOC) |
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'a No.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 области |
PFrame=34 |
; |
/ ( на самом диске написано 23мин, это ж как надо округлять 22:14: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? |
Листинг 1 Содержимое неискаженного TOC'a в сыром виде. Обобщенно
говоря, диск содержит две секции – по одному треку каждая. Абсолютный
адрес начала первого трека – 00:00:02, абсолютный адрес Lead-out области первой сессии – 00:29:33 (адрес последнего
сектора трека на две секунды короче), абсолютный адрес начала второго
трека – 03:01:33, а абсолютный адрес Lead-out
второй сессии – 03:24:33. Максимально достижимая емкость диска –
22:14:34 (хотя на самом диске и написано, что он 23-минутный)
Давайте теперь немного поиздевается над TOC'ом
и увеличим стартовый адрес первого трека так, чтобы он вышел далеко за пределы
первой сессии и попал… ну, собственно, куда-нибудь он все равно попадет. Чтобы
быстро отыскать соответствующую ему запись, воспользуется контекстным поиском.
Жмем <F7> и вводим "point=0x1":
[Entry 3] |
; |
данные элемента TOC'a No.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 |
Листинг 2 Атрибуты трека 1
Как мы видим, здесь присутствует как абсолютный,
измеряемый в минутах/секундах/фреймах, так и LBA-адрес трека, представляющий собой не что иное, как порядковый
номер сектора, считая от нуля. На самом деле, LBA-адрес – это
"отсебятина", добавляемая в файл самим Clone CD и в TOC'е LBA-адрес не храниться. Судя по всему, Clone CD вычисляет LBA-адрес, исходя из
соображений удобства (работать с LBA-адресацией, действительно, намного комфортнее). Однако при
внесении каких-либо изменений в CCD-файл, за согласованием обоих типов адресов нам придется следить самостоятельно. Для
перевода абсолютных адресов в LBA
можно воспользоваться следующей формулой: Logical Sector Address = ((( Minute * 60) + Seconds) * 75 + Frame) – 150.
Ниже представлен вид атрибутов трека 1 до и после искажения:
[Entry 3] |
|
[Entry 3] |
Session=1 |
|
Session=1 |
Point=0x01 |
|
Point=0x01 |
ADR=0x01 |
|
ADR=0x01 |
Control=0x04 |
|
Control=0x04 |
TrackNo=0 |
|
TrackNo=0 |
AMin=0 |
|
AMin=0 |
ASec=0 |
|
ASec=0 |
AFrame=0 |
|
AFrame=0 |
ALBA=-150 |
|
ALBA=-150 |
Zero=0 |
|
Zero=0 |
PMin=0 |
-> |
PMin=10 |
PSec=2 |
-> |
PSec=2 |
PFrame=0 |
-> |
PFrame=0 |
PLBA=0 |
-> |
PLBA=-1 |
Листинг 3 Атрибуты трека 1 до искажения (слева) и после искажения (справа)
На самом деле коварный автор схитрил и вместо вычислений LBA-адреса заложился на тот факт, что его версия Clone CD
всегда использует абсолютные адреса, а LBA – игнорирует. Выбор абсолютного адреса первого трека – произвольный, но
осуществленный с таким расчетом, чтобы искаженный адрес гарантированно вылетал
за границы первой сессии, Lead-out область которой находится по адресу 00:29:33 (см. элемент TOC'а №2).
Шаг четвертый
Теперь
смонтируем искаженный образ диска на виртуальный привод, создаваемый программой
Alcohol 120%, и
посмотрим, что из этого получилось. Конечно, нет никакой уверенности в том, что
виртуальный привод поведет себя, как настоящий, но ведь и настоящие приводы на
искаженных дисках ведут себя по-разному! Поэтому использовать Алкоголь в
качестве рабочего "макетника" вполне допустимо, тем более что это
экономит уйму времени и болванок, ведь монтирование виртуального диска в
отличии от "прожига" болванки осуществляется мгновенно, если,
конечно, оно вообще осуществляется… Вплоть до версии 1.4.3 включительно –
самой свежей версии на момент написания этих строк – Алкоголик органически
не переваривал искаженные образы дисков и отказывался их монтировать, апеллируя
к недоступности образа файла: "Unabletomountimage. File not accessible". Судя по всему,
Алкоголик понимает искаженный TOC
слишком буквально, пытаясь отыскать в файле-образе то, чего там заведомо нет
(трека, начинающегося с адреса 10:02:00 и заканчивающегося адресом 00:29:33,
там нет точно!)
Какая жалость!
Возможность монтирования дисковых образов с искаженным TOC'ом позволила бы нам преодолевать
защиту от копирования на любых пишущих приводах, а не только на тех, что
поддерживают режим RAW DAO, –
просто сбрасываем образ защищенного диска на болванку в виде обыкновенного
файла и динамически монтируем его Алкоголем по мере необходимости. Выходит, что
на проверку Алкоголик оказывается гораздо менее крут, чем это кажется!
Шаг пятый
В порядке эксперимента
попробуем "прожечь" искаженный образ в режиме RAW SAO, в котором, как уже было
сказано выше, корректная запись сессий с искаженным TOC'ом невозможна. Для гарантированного
исключения возможных побочных эффектов желательно использовать привод, не поддерживающий
RAW DAO чисто физически (ну мало ли, вдруг копировщик в плане проявления чудес искусственного
интеллекта автоматически перейдет на более подходящий режим записи, игнорируя наши установки).
Мастер записи образов копировщика Alcohol 120% выдает следующую информацию о записываемом образе:
Тип: |
Файл-образ CloneCD |
Путь: |
L:\ |
Имя: |
Image.ccd |
|
Image.img |
|
Image.sub |
Размер: |
8.81 MB |
Сессий: |
2 |
Треков: |
2 |
Сессия 01: |
|
Трек 01: |
Mode 1, Длина: -42942(8191.92 GB), Адрес: 045000 |
Сессия 02: |
|
Трек 02: |
Mode 1, Длина: 001715(3.3 MB), Адрес: 013458 |
Листинг 4 Cводная информация по записываемому образу, выдаваемая Алкоголем
Обратите внимание на
размеры и адрес первого трека первой сессии (они выделены жирным шрифтом)
Вот это номер!
Если верить Алкоголю, то длина первого трека составляет целых 8 терабайт.
Этот чудовищный объем не то что на CD-, на DVD-диск
не залезет! На самом деле длина треков в TOC'е нигде явным образом не хранится, но вычисляется как разница
стартовых адресов двух смежных треков (если же сессия содержит всего один трек,
в ход идет адрес Lead-out области, примыкающей к
треку). Искажение стартового адреса первого трека привело к тому, что разница
стартовых адресов Lead-out области и этого самого
трека стала отрицательной. Действительно, 00:29:33 – 10:02:00 = 2058 – 45000 == – 42942,
а если вспомнить, что LBA-адреса
по стандарту выражаются 32-разрядными неотрицательными числами, становится
понятно, как Алкоголик получил такой неестественно огромный объем
(отрицательные числа –
это такие числа, чей старший бит взведен, отсюда – маленькое отрицательное
число – это очччень большое положительное). Расчеты показывают, что
заявленное Алкоголиком значение в 8-терабайт достигается лишь при использовании
43-битных переменных. Вот это да! Алкоголик спроектирован с закладом на будущее
(а в будущем нас, как известно, ждут диски с объемами от 30 и более гигабайт,
для адресации которых 32-бит оказывается уже недостаточно, плюс еще необходимо
учесть резерв, предназначенный для "отлова" отрицательных длин,
образовавшихся в результате жестоких извращений с TOC'ом, ведь Алкоголь – это
защищенный копировщик!)
И вот
наступает волнующий момент – момент заливки искаженного образа на CD-R/CD-RW
диск (внимание! используя CD-RW диск вы должны отдавать себе отчет в
том, что можете его безвозвратно потерять! Если ваш единственный пишущий привод
откажется опознавать такой диск, очистка последнего окажется невозможной!).
Благополучно проглотив искаженный образ, Алкоголь, безо всяких препирательств
со своей стороны, зажигает огонек индикации записи (если, конечно, на вашем
приводе он есть) и приступает к делу. Проходит минута, другая… а индикатор
прогресса по прежнему остается на нуле. К исходу шестой минуты, когда пишущая
головка достигает кромки диска, процесс записи аварийно прерывается приводом, и
Алкоголь, издав грустное "бэмц", сигнализирует об аппаратной ошибке.
Просмотр "недорезанного" диска на приводах ASUS и NEC
обнаруживает лишь первую сессию, а от второй не видно и следа. С приводом PHILIPS дела обстоят еще
хуже – он вообще отказывается признавать засунутую в него шутку лазерным
диском и после непродолжительного скрежета своих механических внутренностей,
сопровождаемого натужными завываниями перебирающего различные скорости мотора,
индикатор "DISC IN" прощально гаснет. "Прощально" в том смысле, что с испорченной болванкой вам придется
расстаться. Конечно, если это всего лишь дешевый CD-R, то туда ему и дорога, но потерять CD-RW – жалко.
К счастью, на NEC'е очистка диска протекает успешно, и воодушевленные этим обстоятельством, мы продолжаем свои издевательства вновь.
Копировщик Clone CD ведет себя в этом отношении иначе.
Во-первых, он оценивает длину искаженного трека в 4.294.868.664 байт (см. листинг,
приведенный ниже), что указывает на использование 32-разрядных переменных и
вытекающую отсюда невозможность отличать положительные длины от отрицательных.
ИНФОРМАЦИЯ О ФАЙЛЕ-ОБРАЗЕ:
Число сессий: 2
Занято на диске: 34850 Кбайт
Секторов: 15173
Время: 03:22:23 (мин:сек:кадр)
ИНФОРМАЦИЯ О СЕССИИ 1:
Размер сессии: 4726 Кбайт
Число треков: 1
Pregap: Данные Mode 1, размер: 103359 Кбайт
Track 1: Данные Mode 1, размер: 4294868664 Кбайт
ИНФОРМАЦИЯ О СЕССИИ 2:
Размер сессии: 3939 Кбайт
Число треков: 1
Track 2: Данные Mode 1, размер: 3939 Кбайт
Листинг 5 Cводная информация по записываемому образу, выдаваемая Clone CD. Обратите внимание на
размер первого трека первой сессии (он выделен жирным шрифтом)
Во-вторых, обнаружив, что запись искаженного TOC'a на данном приводе невозможна, Clone CD корректирует TOC так,
чтобы его облик принял человеческий вид. В результате, процесс
"прожига" протекает без каких-либо ошибок и мы получаем как будто бы работоспособный диск.
Стартовый адрес первого трека начинается там, где кончается Lead-in область первой сессии (точнее, pre-gap первого трека начинается там, где кончается post-gapLead-in
области первой сессии, но это уже детали). Такой диск нормально читается в
любом приводе CD-ROM, но! Если защитный механизм прочитает содержимое TOC'а,
он легко обнаружит, что имеет дело с копией, но не оригиналом. Спрашивается: и
на кой черт нам такое копирование нужно?! Хоть бы предупреждение было какое…
Ладно, профессионалы запросто определят, в чем подвох, но в каком положении
окажутся новички и/или просто квалифицированные пользователи, использующие Clone CD для своих нужд?
Мрак, одним словом…
Правда, в режиме RAW DAO нарезка искаженного образа протекает отлично: Clone CD не вносит в TOC никакой отсебятины,
благодаря чему у нас образуется действительно защищенный CD, который мы сейчас и будем ломать.
Шаг шестой
Просмотр защищенного диска под приводом NEC показывает все файлы, даже те, что принадлежат первому треку – тому самому
треку, чей стартовый адрес жестоко искажен. Двойной щелчок мышью доказывает,
что файлы не только присутствуют в каталоге, но и успешно открываются
ассоциированными с ними приложениями и, судя по всему, выглядят вполне
нормально. Нашу душу начинают грызть смутные сомнения: действительно ли пишущий
привод записал стартовый адрес первого трека таким, который мы просили или
молчаливо исправил его налету?
Для ответа на этот вопрос мы должны исследовать геометрию диска, т. е., попросту говоря,
прочитать TOC. Запускам уже полюбившийся нам Roxio Easy CD Creator
и в меню "CD" находим пункт "CD Information".
Щелкаем по нему мышкой, и на экран тут же выпрыгивает диалоговое окно с
раскладкой диска (внимание! не все
программы способы "переваривать" искаженный TOC! Easy CD Creator это умеет, а вот Record NOW! – нет.
Как и следовало ожидать, стартовый адрес первого трека лежит далеко за
пределами своей "родной" сессии, и его длина, будучи выражена
положительным числом, значительно превышает доступную емкость диска
(см. рис. ниже). Так что все наши волнения абсолютно безосновательны!
![](img_1.gif)
Рисунок 1 Отрицательная длина первого трека сводит штатный копировщик с ума
Постойте, но
как же тогда осуществляется доступ к содержимому первого трека? А кто вам
вообще сказал, что лазерный диск адресуется по трекам?! Основной адресацией
лазерного диска с данными является сектор.
Абсолютный же адрес всякого сектора однозначно определяется принадлежащим ему Q-каналом подкода (с учетом
несовпадения границ секций и секторов максимально возможное расхождение,
допускаемое стандартом, составляет 1 сек, т. е. 75 секторов,
поэтому этот способ используется лишь для грубого позиционирования оптической
головки). Точная наводка на цель выполняется непосредственно по самому
секторному заголовку, в явном виде содержащему его абсолютный адрес. Номера
треков в процессе обработки сектора вообще не участвуют, вернее могут
и не участвовать… Но могут ведь и участвовать! Все зависит от
электронной начинки привода и его микропрограммной прошивки. Как именно они в
этом участвуют, – сие есть великая тайна разработчиков привода и простым
смертным ее понять не дано. Но так или иначе, встретив некорректный TOC некоторые приводы
запутываются, и в стройных битовых рядах возникает настоящая сумятица.
Результаты
тестирования трех моих приводов следующие: NEC, как уже говорилось выше, показывает содержимое обоих секций,
корректно обрабатывая их содержимое. ASUS показывает только первую – искаженную – сессию и в
упор не видит вторую, делая ее недоступной даже на секторном уровне. Зато файлы
первой сессии обрабатываются вполне корректно. PHILPS, напротив, видит обе сессии, но
корректно обрабатывает файлы лишь последней из них (т.е. той, что не искажена).
Искаженная сессия доступна на секторном уровне, но нестабильно. Иногда без
всяких видимых причин, Филька едет крышей и возвращает лишенный всякого смысла
мусор.
Мораль: защитные механизмы, базирующиеся на
искаженном TOC' e не могут закладываться ни на одну из сессий. Поэтому обе сессии должны дублировать
содержимое друг друга – авось хоть одну из них привод пользователя да
прочтет. Какой же тогда в этой защите смысл? А вот какой – пускай
защита не может без риска для жизни привязаться к сессиям, она может
привязаться к сырому содержимому TOC"a.
О том как осуществить такую привязку на практике мы поговорим чуточку позже, а
пока попробуем скопировать защищенный диск нашими фаворитами – Clone CD и Alcohol 120%.
Автоматическое копирование и обсуждение его результатов
В какой бы привод защищенный диск не был вставлен, Clone CD выдает неизменно постоянный результат, не имеющий
ничего общего с реальной действительностью. По его скромному мнению, диск
содержит всего одну сессию с общей протяженностью в 4,6 мегабайт, но зато
размер единственного трека последней составляет ни много ни мало –
3,9 терабайт!
ИНФОРМАЦИЯ О CD В ДИСКОВОДЕ:
Число сессий:
Занято на диске: 4726 Кбайт
Секторов: 2058
Время: 00:27:33 (мин:сек:кадр)
ИНФОРМАЦИЯ О СЕССИИ 1:
Размер сессии: 4726 Кбайт
Число треков: 1
Pregap: Данные Mode 1, размер: 103359 Кбайт
Track 1: Data, размер: 4294868664 Кбайт
Листинг 6 таким видит защищенный диск копировщик Clone CD. Обратите внимание, что он распознал лишь одну сессию из двух (первую),
да и то неправильно
Еще до
завершения процесса копирования нас начинают одолевать стойкие сомнения или, я
бы даже сказал, непоколебимая уверенность, в том, что диск будет скопирован
неправильно. И действительно, чего мы опасались, то мы и получили! Давайте
создадим образ скопированного диска в плане сравнения копии TOC'а с оригиналом.
[CloneCD] |
; |
данные о копировщике |
Version=3 |
; |
версия Clone CD |
|
|
|
[Disc] |
; |
данные о диске |
TocEntries=7 |
; |
кол-во элементов TOC'a == 7 (в оригинале было 12) |
Sessions=1 |
; |
кол-во сессий == 1 (в оригинале было 2) |
DataTracksScrambled=0 |
; |
поле DVD |
CDTextLength=0 |
; |
CD-Text'a в полях подкода Lead-in области нету |
|
|
|
[Session 1] |
; |
данные сессии 1 |
PreGapMode=1 |
; |
тип трека == Mode 1 |
PreGapSubC=0 |
; |
данных подканала - нет |
|
|
|
[Entry 0] |
; |
данные элемента TOC'a No.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 |
; |
номер трека представленный CloneCD как LBA-адрес, т.е. чушь |
|
|
|
[Entry 1] |
; |
данные элемента TOC'a No.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 |
; |
номер трека представленный CloneCD как LBA-адрес, т.е. чушь |
|
|
|
[Entry 2] |
; |
данные элемента TOC'a No.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'a No.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=10 |
; |
\ |
PSec=2 |
; |
+ - абсолютный адрес начала трека 1 сессии 1 |
PFrame=0 |
; |
/ |
PLBA=45000 |
; |
LBA-адрес начала трека 1 сессии 1 |
|
|
|
[Entry 4] |
; |
данные элемента TOC'a No.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'a No.5 |
Session=1 |
; |
элемент сессии 1 |
Point=0xc0 |
; |
стартовый адрес Lead-in области Hybrid диска (если он есть) |
ADR=0x05 |
; |
Mode 5 (Оранжевая книга) |
Control=0x04 |
; |
диск с данными, запрещенный ;-) для копирования |
TrackNo=0 |
; |
трек, который мы сейчас читаем - это Lead-in трек (т.е. TOC) |
AMin=162 |
; |
рекомендуемая мощность лазера для |
ASec=200 |
; |
Application code (в оригинале здесь было 128) |
AFrame=224 |
; |
в оригинале здесь было 140 |
ALBA=294074 |
; |
LBA-"адрес" трех предыдущих полей |
Zero=0 |
; |
зарезервировано |
PMin=97 |
; |
\ |
PSec=27 |
; |
+ - абсолютный адрес Lead-in области Hybrid диска |
PFrame=21 |
; |
/ (адрес лежит за пределами диска, т.е. Hybrid-диска нет) |
PLBA=-11604 |
; |
LBA-адрес Lead-in области Hybrid'a(вычислен с переполнением) |
|
|
|
[Entry 6] |
; |
данные элемента TOC'a No.6 |
Session=1 |
; |
элемент сессии 1 |
Point=0xc1 |
; |
копия ATIP-информации |
ADR=0x05 |
; |
-+ |
Control=0x04 |
; |
-+ |
TrackNo=0 |
; |
-+ |
AMin=4 |
|
; -+ |
ASec=192 |
; |
-+ |
AFrame=150 |
; |
-+- ATIP (изменена!) |
ALBA=32400 |
; |
-+ |
Zero=0 |
; |
-+ |
PMin=0 |
; |
-+ |
PSec=0 |
; |
-+ |
PFrame=0 |
; |
-+ |
PLBA=-150 |
|
|
|
|
|
[TRACK 1] |
|
|
MODE=0 |
|
|
INDEX 1=45000 |
|
|
Листинг 7 образ защищенного диска, снятый программой Clone CD (несоответствующие поля выделены жирным шрифтом)
Сокращение
сессий с двух до одной очень сильно смущает. Куда девалась вторая –
неискаженная(!) – сессия вообще непонятно. И хотя искаженные данные
первого трека сохранились, оказались неожиданно измененными поля ApplicationCode и ATIP (и это несмотря на то, что запись
производилась на ту же самую CD-RW болванку, что и раньше,
хотя и ее "прожиг" осуществлялся различными приводами).
Как следствие:
скопированный диск оказывается работоспособен не на всех приводах (ASUS и NEC его прочитают, а вот PHILIPS – нет), к тому
же защите ничего не стоит прочитать текущий TOC и сравнить его с эталонным.
Короче говоря,
"факир был пьян и фокус не удался". Что ж, попробуем обратиться за
помощью к Алкоголю – уж он-то должен наверняка с этим справиться.
Действительно, Алкоголь видит обе сессии: как искаженную, так и
неискаженную, ‑ однако по малопонятным причинам сохраняет в образ
лишь вторую из них (Clone CD
сохранял первую). Ну что это за зоопарк, а? Содержимое TOC'а скопированного диска можно даже и
не сравнивать – там будет далеко не то, что защита собирается ожидать. И
напрасно! Содержимое TOC'а,
снятое Алкоголем, практически полностью соответствует оригиналу. Единственно, в
чем ошибся Алкоголь, – определил тип pre-gap
обоих треков не как Mode 1,
а как Mode 2.
Впрочем, в силу отсутствия в образе первой сессии, полученная с его помощью
копия диска все равно оказывается неработоспособной.
![](img_2.jpg)
Рисунок 2 Алкоголик видит обе сессии защищенного диска, но…
![](img_3.jpg)
Рисунок 3 копирует лишь вторую из них, а первую нагло пропускает
А ведь
заявлялось, что Clone CD/Alcohol 120% способны копировать
любые существующие на сегодняшний момент защищенные диски, и вдруг на поверку
оказывается, что даже такую простую защиту, которую может создать на кончике
пенька любой программист, они преодолеть ни вместе, ни по раздельности не в
состоянии! Причем аппаратура, на которой все эти эксперименты и осуществлялись,
возможность корректного копирования искаженного диска гарантированно
поддерживает (сам проверял), и потому отмахнуться физическими ограничениями
приводов разработчикам обоих копировщиков уже не удастся!
Даже не
верится, что такой простой прием "ослепляет" лучшие копировщики
защищенных дисков! Неужели и вправду, создание некопируемых дисков вполне
осуществимо на обыкновенном бытовом оборудовании?! Да! Именно так! Конечно, не
стоит путать некопируемость диска автоматическими копировщиками с
принципиальной невозможностью получения его идентичной копии. В ручном режиме
копирование таких дисков вполне осуществимо (правда, при условии, что ваш
пишущий привод поддерживает режим RAW DAO, а читающий – читает сектора из обеих секций) и
сейчас мы продемонстрируем как.
Так как же все-таки скопировать такой диск?
Конечно, с
помощью "Добермана Пинчера" (или любого другого блочного копировщика
файлов), HIEW'а, двух
образов защищенного диска (один – с первой сессией – от Clone CD, другой – со второй
сессией – от Алкоголя) и еще чьей-то матери мы можем воссоздать идентичную
копию оригинального диска путем их совокупного (не путать с совокупленным)
объединения, но… это будет как-то не по-хакерски, да и вообще не красиво.
Чтобы не писать свою собственную программу "прожига" диска ограничимся использованием Clone CD.
При условии, что подсунутый ему образ диска запечатлен правильно, Clone CD обычно
справляется с прожигом на ура. Итак, у нас есть более и менее верный файл image.ccd, содержащий TOC, но недостает файла образа image.img. Попробуем его получить? Будем
отталкиваться от того, что LBA-адреса
всех секторов диска пронумерованы последовательно, включая области, занятые Lead-In/Lead-Out
и прочим служебным барахлом. Разумеется, непосредственное чтение служебных
областей диска на сектором уровне невозможно, но… именно на этом мы и
собираемся сыграть! Последовательно читая диск с первого по последний сектор,
мы обнаружим, что сектора с LBA-адресами
с 0- по 2055 сектор включительно читаются без каких-либо проблем, после чего
наступает сумеречная зона нечитающихся секторов, протянувшаяся вплоть до
сектора 13307. Здесь сектора либо совсем не читаются, либо возвращаются в
сильно мутированном виде, легко опознаваемом по отсутствию правильной
синхро-последовательности в их заголовке. Наконец, с адреса 13308 чтение вновь
продолжается без каких-либо проблем.
Судя по всему,
мы имеет дело с двухсессионным диском, а сумеречная зона между сессиями есть ни
что иное, как Lead-Out/Lead-In. Накинув два сектора на post-gap
(при условии, что он записан с соблюдением Стандарта), получаем, что LBA-адрес последнего
значимого сектора первой сессии составляет: 2057 или, в пересчете на абсолютные
единицы, – 00 минут, 29 секунд и еще 32 фрейма. Соответственно, LBA-адрес первого сектора
второй сессии равен: 13308 + 150 (pre-gap) == 13458 или
3 минуты, 1 секунда, 33 фрейма. Конечно, если исследуемый диск
содержит большое количество ошибок, то его анализ значительно усложняется,
т. к. физические дефекты на секторном уровне могут выглядеть точно так же,
как Lead-In/Lead-Out области, конечно, при том условии, что дефективные области
имеют соответствующую протяженность – а это вряд ли.
Отбросив сектора, расположенные в зонах pre- и post-gap (т.е. 150 секторов
от конца первой читаемой области и ровно столько же от начала следующей), мы
должны объединить их в один файл, используя для этой цели любой файловый
копировщик (например, штатную команду MS-DOScopyfile_1
/b + file_2 image.img). Остается прочитать сырой TOCSCSI/ATAPI
командой READ TOC
(opcode: 43h, format: 2h) и записать его в image.ccd файл в соответствии с синтаксисом Clone CD. Как альтернативный вариант –
можно воспользоваться ccd-файлом, сформированным программой Alcohol, предварительно скорректировав pre-gapMode (как уже сказано выше,
Алкоголик определил его неправильно, перепутав Mode 1 с Mode 2). Согласно стандарту, режим
сектора задается пятнадцатым, считая от нуля, байтом его заголовка. Если этот
байт равен одному (что, собственно, и наблюдается в нашем случае), то и Mode сектора будет 1, но не 2.
При условии,
что все сделано правильно, после записи собственноручно сформированного образа
диска, мы получаем практически идентичный оригинал. Просто? Да проще простого!
И написать автоматический копировщик, автоматизирующий наш труд, можно
буквально за несколько часов! Если чтение "сырых" секторов с диска
представляет для вас проблему, воспользуйтесь исходными текстами утилит ASPI32.raw/SPTI.raw,
как раз такое чтение и осуществляющих.
Так что искажение TOC'a – не очень-то надежный
прием защиты от копирования, как не крути. Правда, от обычных пользователей,
вооруженных Clone CD/Alcohol'ем он все-таки
спасает, а больше от защиты зачастую и не требуется.
Пример реализации защиты на программном уровне
Покажем теперь, как такая защита может быть реализована на программном уровне. Самое
простое, что можно сделать – отправить приводу команду "сырого" чтения TOC (opcode: 43h, format: 2h)
и сравнить возращенный ею результат с эталоном. Какие именно поля TOC'a защита будет проверять – это ее
личное дело. По минимуму достаточно проверить количество сессий и стартовый
адрес искаженного трека. По максимуму можно контролировать весь TOC целиком. Естественно, от
побайтового сравнения контролируемого TOC'a с оригиналом настоятельно рекомендуется воздержаться, – т. к. это
неявно закладывает защиту на особенности микропрограммной прошивки читающего
привода. Стандарт ничего не говорит о том, в каком порядке должно возвращается
содержимое TOC'а и потому его бинарное представление может варьироваться от привода к приводу.
Грамотно спроектированная защита должна анализировать только те поля, к содержимому которых она привязывается явно.
Демонстрационный пример, приведенный ниже, как раз и иллюстрирует технику корректной привязки к TOC'у. Разумеется, явная
проверка целости TOC'а может быть элементарно обнаружена хакером и выкинута из программы, как
ненужная, поэтому не стоит копировать этот демонстрационный пример один к
одному в свои программы. Лучше используйте значения полей TOC'а, как рабочие константы, жизненно
необходимые для нормальной работоспособности программы, – в этом случае
сличение паспортов с лицами будет не столь наглядным. Естественно, явная
проверка оригинальности диска все равно обязана быть, но ее основная цель
отнюдь не защитить программу от взлома, а довести до сведения пользователя, что
проверяемый диск с точки зрения защиты не является лицензионным.
/*----------------------------------------------------------------------------
*
* crack me 9822C095h
* ==================
*
* демонстрация техники привязки к искаженному TOC'у;для работе программе
* требуется лазерный диск, прожженный соответствующим образом
*
----------------------------------------------------------------------------*/
#include <stdio.h>
#include <windows.h>
#include "CD.h"
#include "SPTI.h"
#include "ASPI32.h"
// параметры защищенного диска, которые мы будем проверять
//------------------------------------------------------–
#define _N_SESSION 2 // кол-восессий
#define _TRACK 1 // номер проверяемого трека
#define _TRACK_LBA 0x6B124 // стартовый LBA-адрестрека _TRACK
// параметры программы
//--------------------
#define MAX_TRY 3 // мак. кол-во попыток чтения TOC'a
#define TRY_DELAY 100 // задержка между попытками
#define MAX_TOC_SIZE (2352) // максимальный размер TOC'a
main(int argc, char **argv)
{
long a, real_len, try = 1; // основныепеременные
unsigned char TOC[MAX_TOC_SIZE]; // сюдабудетчитаться TOC
unsigned char CDB[ATAPI_CDB_SIZE];// SCSI CDBблокдля SCSI/ATAPI устройств
// TITLE
fprintf(stderr,"crackme 9822C095 by Kris Kaspersky\n");
if (argc <2)
{
fprintf(stderr,"USAGE:crackme.9822C095h.exe drive\n");
fprintf(stderr,"\tdrive - \\\\.\\X: or Trg.Lun\n");
return -1;
}
// инициализациябуферов
memset(CDB, 0, ATAPI_CDB_SIZE); memset(TOC, 0, MAX_TOC_SIZE);
// готовим CDB-блок
CDB[0] = 0x43; // READ TOC
CDB[2] = 0x2; // RAW TOC
CDB[6] = 0; // номер первой сессии
CDB[7] = HIBYTE(MAX_TOC_SIZE); // размер...
CDB[8] = LOBYTE(MAX_TOC_SIZE); // ...буфера
// читаем TOC
while(1)
{
// посылаем CDB-блок SCSI/ATAPI устройству
a = SEND_SCSI_CMD(argv[1], CDB, ATAPI_CDB_SIZE, NO_SENSE,
TOC, MAX_TOC_SIZE, SCSI_DATA_IN);
if (a == SCSI_OK) break; // TOC успешнопрочитан, рвемкогти
// произошла ошибка. что ли привод не готов?
Sleep(TRY_DELAY); // выдерживаем паузу
if (try++ == MAX_TRY) // макс. кол-во попыток уже вышло?
{
fprintf(stderr,"-ERR: can not read TOC\x7\n"); return -1;}
}
// TOC прочитан, приступаем к его анализу
//---------------------------------------
// проверка кол-ва сессий
if ((TOC[3] - TOC[2]) != (_N_SESSION-1))
{fprintf(stderr, "-ERR: not original CD\n");return -1;}
// проверка стартового LBA-адреса трека _TRACK
//--------------------------------------------
real_len = TOC[0]*0x100L+TOC[1]; // определение реальной длины TOC'a
for (a = 4; a < real_len; a+=11) // переборвсех entry
{
if (TOC[a+3] == _TRACK) // этонаштрек?
if ((((TOC[a+4]*60L)+TOC[a+5])*75L)+TOC[a+6] != _TRACK_LBA)
{fprintf(stderr, "-ERR: not original LBA\n");return -1;}
else
break;
}
// это оригинальный диск!
printf("Hello, original CD\n");
}
Листинг 8 Демонстрационный пример простейшей
защиты, привязывающейся к искаженному TOC'у и не позволяющей себя копировать
Предлагаемая
защита не копируется Clone CD
(т. к. он создает всего одну сессию вместо ожидаемых двух), но легко
обходится Алкоголем, которой хоть и помещает на место первой секции непотребный
мусор, зато вполне корректно воссоздает оригинальный TOC.
Для усиления
защиты мы можем попытаться не только проверять обе сессии на существование, но
и контролировать целостность их содержимого. Разумеется, не обязательно перелопачивать
каждую из секций целиком. Достаточно выбрать несколько ключевых секторов,
желательно имеющих по возможности уникальное содержимое. "Постойте! –
воскликнет внимательный читатель. ‑ Разве автор не предостерегал нас
о последствиях такой проверки?! Ведь никто не может гарантировать, что на
оборудовании пользователя эти сектора вообще прочтутся! " "Что
ж, – отвечу я. ‑ Закладываться на читабельность секторов, действительно категорически не
рекомендуется, но вот контролировать успешно
прочитавшиеся сектора можно и нужно! То есть: если ключевые сектора не
читаются, то все ОК, и нет никаких поводов считать диск нелицензионным –
это просто у конечного пользователя оборудование такое (в смысле ‑
кривое). Другое дело, если чтение секторов прошло без ошибок, но вместо
ключевых данных в них оказалось нечто совсем иное. Вот тогда, действительно,
проблема не в оборудовании, а в диске".
Усиленный
вариант защиты уже не копируется Алкоголем (т.к. вместо оригинального
содержимого первой сессии Алкоголь помещает на диск какой-то дикий мусор), но
может быть скопирован вручную по методике, описанной выше. К тому же привязка к
искаженному TOC'у
элементарно отламывается в отладчике/дизассемблере. Так что дальнейшее
совершенствование защиты практически полностью бессмысленно. От "простых
смертных" пользователей мы уже защитились, а от хакеров мы не сумеем
защититься все равно (во всяком случае, этим способом). В любом случае, более
продвинутые защиты – тема отдельного разговора.
Условные обозначения
Под приводом NEC понимается NEC CD-RW NR-9100A; firmware version 1.4;
Подприводом ASUSпонимается ASUS CD-S500/A; firmware version 1.4K;
Подприводом PHILIPSпонимается PHILIPS CDRW2412A firmware version P1.55;
Alcohol 120% – отличный копировщик защищенных дисков, условно-бесплатную
версию которого можно утянуть с сайта http://www.alcohol-soft.com/.
Автоматически ломает более половины всех существующих типов защит от
копирования и позволяет динамически монтировать образы защищенных дисков на
виртуальный привод CD-ROM, что очень удобно для
экспериментов. К сожалению, монтированию подлежат лишь "правильные"
образы, коими большинство образом защищенных дисков отнюдь не являются.
Clone CD – хороший копировщик защищенных
дисков, условно-бесплатную версию которого можно утянуть по следующему адресу:
http://www.elby.ch/. С копированием защищенных дисков в полностью
автоматическом режиме Clone CD справляется скорее плохо,
чем хорошо, однако, после ручного шаманства с настройками и непосредственно
самим образом защищенного диска он может скопировать добрую половину
существующих типов защит. Утверждение о том, что Clone CD "берет"
практически все существующие защиты от копирования – ложное и невероятно
далеко от действительности.
Глоссарий
Lead- In Area – (вводная область диска). Служебная область диска по сути своей
представляющая нулевой трек, всегда предшествующий первому треку PA. Каждая сессия
многосессионного диска имеет собственную вводную область. Размер вводной
области по стандарту составляет 9 мегабайт (60 секунд или 4500 секторов). Q-канал
подкода вводной сессии содержит TOC, среди прочей полезной информации указывающей либо на адрес выводной области
(закрытый диск), либо на адрес вводной области следующей сессии (открытый
диск). Содержимое вводной области недоступно для чтения на программном уровне.
Визуально вводная область выглядит равномерно освещенным блестящим кольцом.
Lead- Out Area – (выводная область диска). Служебная
область диска, условно обозначаемая треком номер AAh и замыкающая собой всякую закрытую
сессию. Выводная область служит своеобразным индикатором конца сессии и/или
диска и помогает оптической головке не вылететь за пределы диска. Пишущие
приводы должны корректно обрабатывать диски с незакрытыми сессиями, однако,
обыкновенные приводы CD-ROM и аудио проигрыватели это
делать не обязаны. Внимание! Отсутствие
выводной сессии (равно как и некорректное задание ее адреса) может повредить
некоторые модели приводов (один из них PHILIPS).
Емкость выводной области односессионного диска по стандарту составляет 13.5 MB (6750 секторов
или 1.5 минуты). Емкость выводных областей для второй и последующих сессий
многосессионных дисков уменьшена до 4 МБ (0.5 минуты или 2250 секторов). Содержимое выводной
области недоступно на программном уровне. Визуально выводная область выглядит
равномерно освещенным блестящим кольцом.
TOC – Table Of Content (Таблица Содержимого или, попросту,
оглавление диска). Служебная область диска, записанная в Q-канале подкода вводной области диска,
также называемой Lead-In областью (такое блестящее кольцо у внутреннего края диска). Многосессионный диск имеет несколько
независимых TOC – по одному TOC'у на каждую закрытую сессию.
TOC содержит информацию о стартовых адресах вводной/выводной областей диска и атрибуты всех его треков
(как-то тип трека: аудио или данные, а если данные то в каком режиме – Mode 1, Mode 2 и т. д.,
абсолютном стартовом адресе трека и номере соответствующей ему сессии). Также TOC содержит часть ATIP и указатели на
местоположения ее продолжения.
Непосредственно (т. е. на секторном уровне) для чтения TOC недоступен, но для извлечения его содержимого в
"сыром" виде можно воспользоваться следующей SCSI/ATAPI командной READ TOC/PMA/ATIP
(операционный код: 43h) с formatfield == 2h.
Однако не стоит путать TOC с файловой системой – между ними нет ничего общего! Файловые системы
лазерных дисков хранятся непосредственно в PM и свободно доступы для чтения на секторном уровне.
Program Area – (программная
область). Область диска, расположенная между Lead-In и Lead-Out областями и содержащая
информационные треки с музыкой или данными. Это основная область диска, целиком
доступная на секторном уровне с паузами между аудиотреками включительно.