Адаптация #2.
(C) Ржавельщик.
________________________________
Публикуем продолжение саги об
адаптации (см. ZX-Format #3).
________________
Итак, продолжим. Использовав
материалы первой серии, Вы имели
возможность научиться адаптиро-
вать на диск беззащитные и защи-
щенные программы, имеющие тради-
ционную организацию (т.е. заг-
рузчик, работающий до победного
конца и тело, с которым он рабо-
тает). Последний комментарий:
упоминание того, что TR-DOS не-
долюбливает INT MODE 2, имело
своей целью прозрачно намекнуть
Вам, что во избежание трагичес-
кого непонимания между Вашим мо-
нолоадером и DOS'ом стоит до
окончания загрузки сделать IM1
(конечно если Вы используете для
загрузки процедуры самой DOS).
Теперь мы покидаем мир здоро-
вых и полноценных программ,чтобы
заглянуть в Tomb of mutilated,
где покоятся неудачливые прог-
раммы, изнасилованные всеми
"мултифейсами" и искалеченные
хакерами тех мест,что лежат меж-
ду нашей страной и производите-
лями этих программ. Наиболее
распостраненная клиническая кар-
тина выглядит так: у клиента
имеется один маленький такой
LOAD'ер и одно монолитное тело
(малость побольше), которое гру-
зится непрерывно и от начала
RAM. Т.е. начиная с заставки и
почти до конца памяти. Я пола-
гаю, что многие, следуя моему
инструктажу, жестоко изорвали
сие тело на две - три части и
смели останки на диск (кстати,
поздравляю тех, кто догадался
переписать DISMEMBER '& ->MACTER
на свой рабочий диск, обнаружив,
что из журнала они не запускают-
ся).
После проведения этой опера-
ции требуется сшить куски файла
в один целый, оставив заставку
отдельно. Сделать это можно, до-
пустим, так: записать подряд все
части в их исходном порядке
(так, как они шли в файле на
ленте), затем войти в доктор и,
выискав заголовок первого куска,
торжественно присвоить ему длину
в секторах, равную длине всех
кусков. Полезно также скорректи-
ровать его размер в байтах. Дабы
не утруждаться сложением, длину
в секторах можно узнать, пометив
все сшиваемые файлы в каталоге
(CONVER и другие commander'ы по-
казывают количество отмеченных
секторов). Произведя сие неслож-
ное действо, лучше переписать
новый файл на рабочий диск (на
тот же) и стереть то, из чего он
был получен (чтобы не путалось
под руками); перезапись можно
осушествлять boot'ом,который по-
нимает длину в секторах (CONVER
нужно переключать, а свой режим
он не показывает). Полученному
таким образом файлу следует при-
своить адрес загрузки #5b00 (ес-
ли игра имела означенную клини-
ку). Подготовительная фаза за-
кончена.
После проделаной опции Вы
сравнялись с владельцами ZS-256,
которые скинули программу на
диск из своего монитора. А вот
теперь начинается самое интерес-
ное - создание LOAD'ера. Напоми-
наю, что должен делать загруз-
чик:
1. Поместить программу в па-
мять на нужные адреса.
2. Выполнить запуск.
Начнем с запуска. Что нужно
для запуска программы? Как мини-
мум нужно знать стартовый адрес.
Для проведения дознания обратим-
ся к ленточному LOAD'еру.
1. Работающие коды.
Здесь имеется нормальный ко-
довый загрузчик, который при за-
пуске переносится в самые стар-
шие адреса, которые не накрыва-
ются программой при загрузке. В
ту же область помещается и стек.
О подобном уже было сказано в
первой серии. Возможен вариант,
когда только стек переносится в
ненакрываемую зону, а коды оста-
ются там, где стояли. В таком
случае запуск программы происхо-
дит через стек (делается PUSH
стартового адреса и JP в проце-
дуру загрузки ПЗУ). В обоих слу-
чаях загрузчик содержит искомый
адрес в явном виде.
2. Запуск через измененный
стек.
Кодовый загрузчик вызывает
любым способом процедуру загруз-
ки из ПЗУ, но стек при этом име-
ет такой адрес, что по ходу заг-
рузки файл игры на него наедет и
переедет. При этом в стеке ока-
жется требуемый адрес, по кото-
рому произойдет возврат из ПЗУ.
Для того, чтобы найти стартовый
адрес Вам нужно узнать адрес
стека. Если он не устанавливает-
ся лоадером, то это значит, что
он имеет стандартное значение,
которое Вы можете узнать из сис-
темной переменной по адресу
23730. Узнав адрес стека, кото-
рый имеет место во время загруз-
ки программы, запишите его в
протокол. Далее владельцы скор-
пов загружают файл через мони-
тор, владельцы 128-х и более -
грузят сшитый файл в STS и, пока
счастливые юзеры 48к едут поку-
пать ADM_2.7, смотрят содержимое
файла по вышеупомянутому адресу
стека.(Те, кто уже имеет ADM,
могут сделать то же самое, отмо-
тав курсор к этому адресу вруч-
ную. Физический адрес отобража-
ется в левой нижней части экра-
на).
Данный адрес содержит то, что
мы и искали - адрес точки входа
в программу. Последний раз напо-
минаю, что хакеру голова дана не
для того, чтобы ей есть, а для
того, чтобы думать. Так что если
в означенном месте Вы нашли 0
(итп) то это значит, что искали
не там (намек: посмотрите в ок-
рестности SP). В любом случае
адрес следует проверить на дос-
товерность, т.е. посмотреть по
нему содержимое файла. Если ад-
рес указывает на таблицу преры-
вания или на спрайт, то стоит
подвергнуть сомнению его истин-
ность.
3. Бейсик.
Иногда встречаются BASIC -
лоадеры, аналогично использующие
запуск по измененному SP. Они
выглядят примерно так:
0 CLEAR 30000:LOAD""CODE
В таком случае адрес входа
ищется как и в пункте 2.
Второй распостраненный вари-
ант: грузящийся файл содержит
новый бейсик (естественно он со-
держит и системные переменные,
нужные для работы BASIC'а). В
таком случае Вам следует найти
адрес команды LOAD в исходном
загрузчике (ADM'ом либо STS'ом,
помня, что с ленты бейсик гру-
зится по адресу 23755 (#5CCB)).
Записав адрес LOAD, грузим файл
и смотрим, что находится за ним.
Скорее всего там будет команда
RANDOMIZE USR ... (#F9 #C0 ...).
Как просматривать бейсик по ко-
дам, я уже где-то объяснял и по-
лагаю, что Вам не составит труда
узнать стартовый адрес из
BASIC'a.
Последний вариант (из области
дурной фантастики): лоадер пере-
устанавливает переменную ERR_SP
(23613) так, что по окончании
загрузки машина, наткнувшись на
кодовый мусор, не печатает "Non-
sense in basic ", а производит
запуск игры (честно говоря, я
такого изврата никогда не встре-
чал).
Итак, стартовый адрес найден.
Осталась сущая мелочь - загру-
зить файл игры из TR-DOS. Тут-то
и возникнет проблема: файл ма-
лость длинноват. Прежде чем сно-
ва рвать его на части, стоит
внимательно рассмотреть ВЕСЬ
файл на предмет сокращения объе-
ма. Начинаем с области загрузчи-
ка. Если клиент грузился накры-
ваемым бейсиком, то его коды на-
чинаются не с конца экрана, а,
как минимум, с конца бейсика.
Следовательно всю часть от #5b00
и до начала кодов самой програм-
мы можно опустить. Далее стоит
посмотреть на старшие адреса,
начиная примерно от #E000. Если
с некотрого адреса там пойдут
нули, то, проверив - не является
ли сие место спрайтом, его можно
отбрасывать. Проверку на кхм..
спрайтовость можно произвести
при помощи программы FDE либо
SCE (по-моему FDE намного удоб-
нее). Оканчивается файл, как
правило, следами использования
стека, на которые можно не обра-
щать внимание, т.к. при старте
программа сама ставит SP куда ей
нужно. Даже если очевидного кон-
ца кодов не найдется, вниматель-
но разберите все процедуры, ко-
торые Вы найдете на этих адре-
сах. Если программа имеет упомя-
нутую клинику, то там может най-
тись программка, при помощи ко-
торой игра была приведена к та-
кому виду. При нахождении подоб-
ной подпрограммки можете отбро-
сить все, начиная с нее, однако
тщательно проверьте стартовый
адрес - он может оказаться ма-
лость лажовым.
Из практики: Игра TLL, в слу-
чае урезания этой самой проце-
дурки, выходила в начальное ме-
ню, но при выборе "START" сбра-
сывалась. При внимательном рас-
смотрении оказалось, что обра-
ботка IM2 начиналась у нее с ад-
реса #FFFF, где в исходном файле
стояло #18 (JR). При старте игры
по адресу, выкопанному из бейси-
ка, она не устанавливала преры-
вания. Настоящая процедура стар-
та делала настройку на прерыва-
ния, и после переходила (JP) по
этому адресу.
# Кстати, "урезание" файла сво-
дится просто к опции "SAVE" с
нужного адреса, если у Вас прод-
винутый SPECCY, а если Вы имеете
48-й, то придется прибегать к
долгим манипуляциям на ленте.
После всех манипуляций Вы за-
имели сильно сократившийся файл,
который можно грузить и запус-
кать. Для наведения блеска стоит
этот файл скомпрессовать. Очень
удобен и эффективен для этого
дела LPC. Самый тяжелый случай:
все данные, от #5B00 до #FFFF,
являют собой полезную информа-
цию, которая не подлежит сокра-
щению (либо Вам ну очень лениво
разбираться). Тогда можно посту-
пить так: отрезаем от начала
файла кусок длиной 1704 (#6A8);
остаток со страшной силой комп-
рессуем; грузим заставку; грузим
упакованную часть, развертываем
ее; гасим экран; грузим кусочек
1704 в экранную область; перено-
сим остаток лоадера туда же, (на
свободное место, естественно)
делаем переход в него, ставим
нужный SP и переносим отрезанные
байты на их родное место, после
чего выполняем запуск программы.
Длинная часть файла будет начи-
наться с 25000,что позволит сде-
лать всю загрузку из BASIC'а,
написав коды только для переноса
и запуска. Не забудьте перенести
эту процедурку в экран, так как
при помещении отрезанных байтов
загрузчик будет накрыт и не смо-
жет запустить программу.
Теперь рассмотрим какую-ни-
будь гадость, например такую:
Игра имеет файлы приличного
размера, но подозрительно похожа
на кинутую MAGIC'ом (пачкает эк-
ран и после загрузки делает POP
всех регистров из "грязи"). Фай-
лы такой игры содержат массу
"излишеств", выкинув которые
можно сильно выиграть в объеме.
Также сие явление имеет левый
адрес запуска. По поводу лишних
байтов ничего конкретного ска-
зать нельзя, так как они будут
заполнены не нулями. Стоит поис-
кать рабочую область (буферную),
теневой экран (/окно) и систем-
ные переменные BASIC'а. Со стар-
товым адресом немного попроще:
прежде всего нужно смотреть
настройку IM2. Найдя процедуры
настройки, нужно искать ссылки
на них, а так же куда идет прог-
рамма после их выполнения. Можно
с уверенностью утверждать, что
если Вы нашли подпрограммку
настройки прерываний, кончающую-
ся на JP, на которую никто не
ссылается, то это и есть точка
входа. Точка старта может выгля-
деть и как серия CALL, среди ко-
торых есть и настройка прерыва-
ний. Если игра не использует IM2
(>;->), то найдите процедуру пе-
чати начального меню и проследи-
те путь к ней. Т.е. в любом слу-
чае нужно найти первое звено в
цепочке CALL'ов. Найдя точку
входа, можно сразу отбросить
"мусор" с данными о состоянии
регистров, которым портится зас-
тавка. Выбросив все лишнее, мож-
но писать лоадер по Вашему при-
вычному образцу, на чем адапта-
ция вообщем-то и заканчивается.
________________
Ну вот, пожалуй по части соб-
ственно адаптации программ на
диск сказать больше и нечего.
Подводя общий итог, скажу только
одно: ассемблер, ассемблер и еще
раз ассемблер.
P.S. Не могу не добавить пару
слов о software - хотя я и имею
ZS-256, я все равно пользуюсь
STS'ом, который во многих отно-
шениях удобней scorp'ового тене-
вика. Ну и раз уж начал, то и о
железе замечу: Владельцы 48-х!
Если Вы умеете работать паяльни-
ком, то довесить памяти до 128
обойдется Вам максимум в 15 тонн
и часа два простенькой работы,
зато Вы получите в свое распоря-
жение такую мощную систему как
STS и TASM!