Na postagem anterior mostrei uma técnica de proteção de programa BASIC, que consiste em camuflar os valores reais de constantes numéricas. O jogo Quazatron é um que faz uso desta artimanha. Ao carregar o programa e interrompendo sua execução, obtém-se a listagem:
Obviamente os valores numéricos são falsos, pois estão todos zerados.
A solução é usar o programa Basic Lister que apresentei na postagem passada. Entretanto alguma coisa está errada:
A parte inicial da linha não faz sentido. Examinando o conteúdo dos endereços 23757-23758 (com
Para contornar esta proteção, deve-se executar
Os valores reais são os impressos em fundo (PAPER) preto. A listagem real é portanto:
PEEK 23757+256*PEEK 23758
), obtém-se valor 0, o que quer dizer que o comprimento da linha BASIC é 0. Uma linha não pode ter comprimento nulo, portanto foi feito um POKE para confundir.Para contornar esta proteção, deve-se executar
POKE 23757,64
que define linha de 64 bytes (isto porque este carregador BASIC tem este comprimento). Rodando novamente o Basic Lister, obtém se a listagem correta:Os valores reais são os impressos em fundo (PAPER) preto. A listagem real é portanto:
0 CLEAR 25000: POKE 23659,0: LOAD ""CODE: RANDOMIZE USR EXP 10.435528
O POKE 23659,0 altera a variável de sistema SIZE (ou DF_SZ) que faz com que o computador trave, se o programa BASIC for interrompido.
O resultado de EXP 10.435528 é 34048.049, então o endereço do USR é 34048. Carregando o código de máquina e começando um disassembly a partir de 38048, resulta em:
34048 JR 34058
34058 DI
LD HL,22528 ; Coloca valor 96 (INK 0, PAPER 4 e
LD (HL),96 ;BRIGHT 1) na área de atributos de
LD DE,22529 ;cores da tela.
LD BC,767
LDIR
CALL 34166 ; Exibe primeira tela de instruções.
LD HL,(23613) ; Um erro resulta em reset.
LD SP,HL
POP HL
LD HL,0
PUSH HL
34084 LD IX,38403 ; Carrega no endereço 38403
LD DE,8192 ;8192 bytes.
LD A,255
SCF
CALL 1366
34097 DI
LD HL,34058 ; Coloca valor 199 nos endereços
LD DE,34059 ;34058 a 34104.
LD BC,46
LD (HL),199
LDIR
CALL 34166 ; Exibe segunda tela de instruções.
LD HL,(23613) ; Um erro resulta em reset.
LD SP,HL
POP HL
LD HL,0
PUSH HL
34123 LD IX,46595 ; Carrega no endereço 46595
LD DE,8192 ;8192 bytes.
LD A,255
SCF
CALL 1366
34136 DI
CALL 34166 ; Exibe terceira tela de instruções.
LD HL,(23613) ; Um erro resulta em reset.
LD SP,HL
POP HL
LD HL,0
PUSH HL
LD HL,(34054) ; Coloca na pilha endereço de execução
PUSH HL ;do jogo que estava em (34054).
34153 LD IX,54787 ; Carrega no endereço 54787
LD DE,6397 ;6397 bytes.
LD A,255
SCF
34163 JP 1366
Esta rotina faz carregamento de 3 blocos de bytes headerless, que pode ser tranquilamente adaptado para Beta 48 usando brekpoint em emuladores como foi explicado anteriormente.
Na listagem nota-se o uso da variável de sistema em 23613 (P_ERR ou ERR_SP), que aponta para o endereço a saltar em caso de algum erro. Como este endereço é alterado para 0, qualquer erro de leitura ou acionamento da tecla BREAK irá causar reset do TK90X. Como se pode ver, se faz de tudo para evitar interromper o carregamento.
Por fim, pode-se ver que por 3 vezes invoca-se uma sub-rotina com CALL 34166. Esta sub-rotina é a responsável por exibir telas com instruções do jogo durante o carregamento:
Todas estas operações podem ser facilmente feitas através do BASIC. Para obter o Quazatron já adaptado para o Beta 48, acesse este link do Google Drive ou do
Atualização em 08/11/2012: nova versão disponível.
Nenhum comentário:
Postar um comentário
Seu comentário é bem vindo, mas peço que use este espaço adequadamente.