|
Форум - нестандартная загрузка.
|
Нестандартная загрузка.
Комиссаров Павел из пос. Видово Мурманской обл. пишет о том, что он занимается взломом программ, в которых используется нестандартная загрузка или есть что-то необычное. У него уже набралась небольшая коллекция таких загрузчиков. Павел прислал распечатку одного из них. Он загружает блоки кодов с изменением цвета бордюрных полос. Павел пишет, что он взял этот загрузчик из программы "BARBARIAN-3" (BY BILL GILBERT). Он начинается с адреса 65000 и используется точно так же, как и процедура "LOAD BYTES" из ПЗУ, расположенная по адресу 1366 (0556H). Вот этот загрузчик:
FDE8 |
14 |
INC |
D |
FDE9 |
08 |
EX |
AF,AF' |
FDEA |
15 |
DEC |
D |
FDEB |
F3 |
DI |
|
FDEC |
3E00 |
LD |
A,#00 |
FDEE |
D3FE |
OUT |
(#FE),A |
FDFO |
213F05 |
LD |
HL, #053F |
FDF3 |
E5 |
PUSH |
HL |
FDF4 |
DBFE |
IN |
A,(#FE) |
FDF6 |
1F |
RRA |
|
FDF7 |
E620 |
AND |
#20 |
FDF9 |
CD6F3C |
CALL |
#3C6F |
FDFC |
BF |
CP |
A |
FDFD |
00 |
NOP |
|
FDFE |
CD79FE |
CALL |
#FE79 |
FE01 |
30FA |
JR |
NC,#FDFD |
FE03 |
216900 |
LD |
HL,#0069 |
FE06 |
10FE |
DJNZ |
#FE06 |
FE08 |
2B |
DEC |
HL |
FE09 |
7C |
LD |
A,H |
FEOA |
B5 |
OR |
L |
FEOB |
20F9 |
JR |
NZ,#FE06 |
FEOD |
CD75FE |
CALL |
#FE75 |
FE10 |
30EB |
JR |
NC,#FDFD |
FE12 |
069C |
LD |
A,#9C |
FE14 |
CD75FE |
CALL |
#FE75 |
FE1T |
30E4 |
JR |
NC,#FDFD |
FE19 |
3EC6 |
LD |
A,#C6 |
FE1B |
B0 |
CP |
B |
FE1C |
30E0 |
JR |
NC,#FDFE |
FEIE |
24 |
INC |
H |
FE1F |
20F1 |
JR |
NZ,#FE12 |
FE21 |
06C9 |
LD |
B,#C9 |
FEE3 |
CD79FE |
CALL |
#FE79 |
FE26 |
3OD5 |
JR |
NC,#FDFD |
FE28 |
78 |
LD |
A,B |
FE29 |
FED4 |
CP |
#D4 |
FE2B |
30F4 |
JR |
NC,#FE21 |
FE2D |
CD79FE |
CALL |
#FE79 |
FE30 |
D0 |
RET |
NC |
FE31 |
79 |
LD |
A, C |
FE32 |
EE03 |
XOR |
#03 |
FE34 |
4F |
LD |
C, A |
FE35 |
2600 |
LD |
H,#O0 |
FE37 |
06B0 |
LD |
B,#B0 |
FE39 |
181F |
JR |
#FE5A |
FE3B |
08 |
EX |
AF,AF' |
FE3C |
2007 |
JR |
NZ,#FE45 |
FE3E |
300F |
JR |
NC,#FE4F |
FE40 |
DD7500 |
LD |
(IX+0),L |
FE43 |
160F |
JR |
#FE54 |
FE45 |
CB11 |
RL |
C |
FE47 |
AD |
XOR |
L |
FE48 |
CO |
RET |
NZ |
FE49 |
79 |
LD |
A,C |
FE4A |
1F |
RRA |
|
FE4B |
4F |
LD |
C,A |
FE4C |
13 |
INC |
DE |
FE4D |
1807 |
JR |
#FE56 |
FE4F |
DD7E00 |
LD |
A,(IX+0) |
FE52 |
AD |
XOR |
L |
FE53 |
C0 |
RET |
NZ |
FE54 |
DD23 |
INC |
IX |
FE56 |
1B |
DEC |
DE |
FE57 |
08 |
EX |
AF,AF' |
FE58 |
06B2 |
LD |
B,#B2 |
FE5A |
2E01 |
LD |
L,#01 |
FE5C |
CB75FE |
CALL |
#FE75 |
FE5F |
D0 |
RET |
NC |
FE60 |
3ECB |
LD |
A,#CB |
FE62 |
B8 |
CP |
B |
FE53 |
CB15 |
RL |
L |
FE65 |
0680 |
LD |
B,#B0 |
FE67 |
D25CFE |
JP |
NC,#FE5C |
FE6A |
7C |
LD |
A,H |
FE6B |
AD |
XOR |
L |
FE6C |
67 |
LD |
H,A |
FE6D |
7A |
LD |
A,D |
FE6E |
B3 |
OR |
E |
FE6F |
20CA |
JR |
NZ,#FE3B |
FE71 |
7C |
LD |
A,H |
FE72 |
FEO1 |
CP |
#01 |
FE74 |
C9 |
RET |
|
FE75 |
CD79FE |
CALL |
#FE79 |
FE76 |
D0 |
RET |
NC |
FE79 |
3E16 |
LD |
A,#16 |
FE7B |
3D |
DEC |
A |
FE7C |
20FD |
JR |
NZ,#FE7B |
FE7E |
A7 |
AND |
A |
FE7F |
04 |
INC |
B |
FE80 |
C8 |
RET |
Z |
FE81 |
3E7F |
LD |
A,#7F |
FE83 |
DBFE |
IN |
A,(#FE) |
FE85 |
1F |
RRA |
|
FE86 |
00 |
NOP |
|
FE87 |
A9 |
XOR |
C |
FE88 |
E6E0 |
AND |
#20 |
FE8A |
28F3 |
JR |
Z,#FE7F |
FE8C |
79 |
LD |
A,C |
FE8D |
2F |
CPL |
|
FE8E |
4F |
LD |
C,A |
FE6F |
82 |
ADD |
A,D |
FE90 |
A9 |
XOR |
C |
FE91 |
E607 |
AND |
#07 |
FE93 |
F608 |
OR |
#08 |
FE95 |
D3FE |
OUT |
(#FE),A |
FE97 |
37 |
SCF |
|
FE98 |
C9 |
RET |
|
Перед вызовом загрузчика надо в регистре IX задать адрес загрузки, а в регистре DE -длину загружаемого блока кодов. Процедура вызова загрузчика, например для загрузки экрана-заставки может иметь следующий вид:
DD210040 LD IX,#4000 11001B LD DE,#1B00 3EFF LD A,#FF
37 SCF
CDE8FD CALL #FDE8 C9 RET
При этом блок кодов, подлежащий загрузке, может быть записан на ленте обычным способом, надо лишь удалить заголовок, оставив только коды.
Цвет полос бордюра во время загрузки будет периодически меняться, временами полосы вообще будут исчезать, затем появляться вновь с новыми цветами. Клавиша BREAK при загрузке не действует.
По окончании загрузки значение флага переноса содержит информацию об ошибке при загрузке: 1 - не было, 0 - была. Здесь надо сказать, что и как в случае использования процедуры 1366 (0556Н) ПЗУ, об ошибке свидетельствует только значение флага переноса, никакие дальнейшие действия, связанные с наличием ошибки не выполняются. Но если Вы хотите, чтобы при ошибке программа останавливалась с выдачей сообщения: "R Tape loading error", то надо поступить аналогично тому, как это делается в ПЗУ. Там для вызова процедуры 1366 используется процедура 2050. Применяя аналогичный прием, вызов приведенного загрузчика может выглядеть следующим образом: ...... подготовка пара...... метров (см. выше)
CDE8FD CALL #FDE8 D8 RET C
CF RST 8
1A DEFB #1A
На этом можно было бы и закончить, но вот что случилось спустя некоторое время, после того, как мы успешно оттестировали этот загрузчик. Неожиданно выяснилось, что загрузчик упорно не хочет работать на другом компьютере. Мы решили выяснить, почему это происходит. К счастью, программа "BARBARIAN-3" оказалась в нашей "фонотеке". Мы опробовали ее и выяснили, что на обоих компьютерах программа нормально загружается. В чем же дело? Стали исследовать коды загрузчика, который приводит Павел. Как и следовало ожидать, загрузчик похож на процедуру "LOAD BYTES", расположенную в ПЗУ по адресу 1366. Но стоп! Что это такое? По адресу FDF9H видим команду: CALL 3C6FH. Это вызов подпрограммы из ПЗУ. Но ведь мы знаем, что в ПЗУ на этом месте ничего нет. Или есть? Так вот, оказывается, где кроется разгадка. Дело в том, что на том компьютере, где этот загрузчик не работал, стоит стандартное ПЗУ, а на том, где работал нормально, стоит ПЗУ "ТУРБО-90", а котором на свободном месте, перед символьным набором расположены программы, расширяющие функциональные возможности компьютера, в частности, загрузка с удвоенной скоростью. Для этого процедура 0556H (1366) этого ПЗУ содержит в точности то, что видим в листинге загрузчика, который приводит Павел, по адресу FDF9H: выполнение подпрограммы 3C6FH. Это связано с загрузкой на удвоенной скорости. В обычном ПЗУ подпрограмма 5С6FH отсутствует, поэтому этот загрузчик и не может работать с другим ПЗУ, кроме "ТУРБО-90". Кстати, у Комиссарова Павла, наверняка, тоже ПЗУ "ТУРБО-90" (необходимый инструмент любого "взломщика").
Вроде бы разобрались, но опять непонятно, почему же программа "BARBARIAN-3" работает с любым ПЗУ: и с обычным, и с "ТУРБО-90". Полезли в программу. А выяснилась очень интересная вещь. В программе "BARBARIAN-3" отсутствует загрузчик кодов в том виде, в каком его приводит Павел. Загрузчик в кодах формируется в программе из подпрограммы 1366 ПЗУ. Мы немного поискали и нашли ту процедуру, которая выполняет эту работу. Она в процессе загрузки "BARBARIAN-3" располагается с адреса C3D5H (50133). Вот что там находится (фрагмент кодов приводим с некоторыми изменениями, в виде завершенной подпрограммы, готовой к употреблению):
C3D5 |
215605 |
LD |
HL,#0556 |
C3D8 |
11E8FD |
LD |
DE,#FDE8 |
C3DB |
O1AF00 |
LD |
BC,#00AF |
C3DE |
EDB0 |
LDIR |
|
C3E0 |
2119C4 |
LD |
HL,#C419 |
C3E3 |
118FFE |
LD |
DE,#FE8F |
C3E6 |
010A00 |
LD |
BC,#000A |
C3E9 |
EDB0 |
LDIR |
|
C3EB |
2175FE |
LD |
HL,#FE75 |
C3EE |
220EFE |
LD |
(#FE0E),HL |
C3F1 |
22I5FE |
LD |
(#FE15),HL |
C3F4 |
225DFE |
LD |
(#FE5D),HL |
C3F7 |
21T9FE |
LD |
HL,#FE79 |
C3FA |
22FFFD |
LD |
(#FDFF),HL |
C3FD |
2224FE |
LD |
(#FE24),HL |
C400 |
222EFE |
LD |
(#FE2E),HL |
C403 |
2276FE |
LD |
(#FE76),HL |
C406 |
215CFE |
LD |
HL,#FE5C |
C409 |
2268FE |
LD |
(#FE66),HL |
C40C |
AF |
XOR |
A |
C40D |
32EDFD |
LD |
(#FDED),A |
C410 |
32FDFD |
LD |
(#FDFD),A |
C413 |
3286FE |
LD |
(#FE86),A |
C416 |
C9 |
RET |
|
C417 |
00 |
NOP |
|
C418 |
00 |
NOP |
|
C519 |
82 |
ADD |
A,D |
C41A |
A9 |
XOR |
C |
C41B |
E607 |
AND |
#07 |
C41D |
F608 |
OR |
#08 |
C41F |
D3FE |
OUT |
(#FE),A |
C421 |
37 |
SCF |
|
C422 |
C9 |
RET |
|
Эта подпрограмма формирует загрузчик кодов, расположенный с адреса 65000, а далее Вы можете использовать его так, как рассказывалось выше.
Если сформировать загрузчик кодов, пользуясь приведенной подпрограммой C3D5H, при использовании ПЗУ "ТУРБО-90", получим тот загрузчик, который приводит Комиссаров Павел. А если сформировать загрузчик при использовании стандартного ПЗУ, то получим следующие отличия no-сравнению с вариантом для "ТУРБО-90": FDF9 F602 OR #02
FDFB 4F LD C,A
FE03 211504 LD HL,#0415
Кстати, если внести эти изменения в вариант Павла, то загрузчик будет работать с обоими ПЗУ. Почему же в "BARBARIAN-3" используется казалось бы более головоломный прием, когда загрузчик формируется при помощи другой подпрограммы (C3D5H) из процедуры 0556Н ПЗУ? Ответ прост. Если у Вас стандартное ПЗУ, то Вы работаете как обычно. А если у Вас "ТУРБО-90", то сохранится возможность загружать всю игру в режиме с удвоенной скоростью (как это предусмотрено, введя "-" перед командой LOAD "". Несмотря на то, что загрузчик кодов в общем-то нестандартный, в нем поддерживается турбо-режим. Это происходит как раз из-за вызова подпрограммы 3C6FH, который мы видим по адресу FDF9H. Те читатели, у которых есть "ТУРБО 90", могут убедиться в том, что загрузчик, приведенный Павлом, работает и на удвоенной скорости (правда при этом пропадает эффект переключения цвета бордюрных полос). Кроме того, процедура, которая создает загрузчик, гораздо короче самого загрузчика, поэтому такой путь еще и экономит память и время загрузки исходной программы.
Эта история показывает, насколько осторожным и предусмотрительным надо быть, проектируя автономные загрузчики для загрузки кодов. Иначе за Вашей замечательной программой, в которой Вы примените такой загрузчик, может закрепиться репутация "капризной" или "неработоспособной". Надеемся все же, что приведенный пример не отпугнет программистов, а вооружит сведениями, позволяющими выполнить эту работу более квалифицированно.
|
|