ZX Format
#04
14 июня 1996 |
|
Программистам - Адаптация программ под TR-DOS #2.
Адаптация #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!
Другие статьи номера:
Похожие статьи:
В этот день... 21 ноября