# 03 - E um byte inteiro não é suficiente ... | 2B ou não 2B

Então, amigos, em 1º de abril, é hora de revelar as cartas, o que exatamente é “ 2B ou não 2B ”. Este é um texto conjunto do autor do trabalho.jin_x e já familiar para o seu avô incrédulo

imagem

Certifique-se de baixar o arquivo com o trabalho em Pouet e leia o artigo introdutório (April Fools '), bem como comentários sobre ele. Assista ao primeiro vídeo com uma demonstração prática de como o código de dois bytes funciona no x86. E só então tente dominar o texto inteiro abaixo.


Sim, 2B ou não, 2B é realmente um ambiente para iniciar vários trabalhos de codificação de tamanho, muito simples e, talvez, o menor. No entanto, ele tem seus próprios requisitos e limitações.

Se alguém não o pegou, a ferramenta 2b.com é iniciada no DOS (DOSBox, FreeDOS, MS-DOS) e salta para a área de linha de comando (no deslocamento $ 82 * do segmento PSP), iniciando o código que foi transferido para execução linha de comando em binário. Na verdade, esse código pode muito bem ter a forma de uma string que pode ser digitada no teclado (ou seja, consistir em caracteres ASCII com códigos de 33 a 126), mas mais sobre isso posteriormente.

* Números hexadecimais que escreveremos na notação Pascal $ XX, isso é conveniente e fasm permite que você faça isso.

O que é importante saber?


Nulo, recomendamos o uso do fasm como compilador , todas as nossas ferramentas foram escritas especificamente para ele.

Em primeiro lugar, o código principal pode ter um tamanho máximo de 125 bytes (essas são as restrições no comprimento da linha de comando) e será iniciado como um programa COM comum, apenas com um deslocamento de $ 82, e não $ 100, como de costume. Imediatamente após o código principal, um símbolo de retorno de carro (CR) com o código 13 ($ 0D) será adicionado automaticamente e o comando jmp short $82($ EB, $ 80) será localizado em $ 100 .

Em segundo lugar, como o lançamento deve ser de um arquivo BAT (bem, ou do interpretador da linha de comando), o código não deve conter alguns caracteres. Primeiro, esses são caracteres de redirecionamento de E / S ("<", ">" e "|"), bem como o caractere de substituição de parâmetro e variáveis ​​de ambiente ("%"). Em alguns sistemas (incluindo Windows, que suportam o lançamento de programas DOS sob a V86), os caracteres "&", "^" também têm um significado especial. Caracteres especiais com códigos de até 32 não são suportados por todos os DOS, e alguns não são suportados por nenhum ou quase nenhum (o DOSBox tem um conjunto particularmente escasso), portanto, também excluímos todos esses caracteres.

Em terceiro lugar, os valores iniciais de todos os registros e sinalizadores são os mesmos que ao iniciar o programa COM. Na grande maioria do DOS, no início será: ax = bx = 0 (quase sempre é), cx = $ FF, dx = cs = ds = es = ss, si = $ 100, di = sp = $ FFFE (com capacidade operacional suficiente) memória), bp = $ 9XX (o byte baixo é diferente em todos os lugares, mas seu tetrad alto, ou seja, uma mordidela, geralmente = 1), sinaliza cf = df = 0. Você pode usá-lo ou não.

Acima de tudo, o "segundo" ponto é confuso aqui, não é?
Suponha que precisamos escrever:

   mov ah,0
   int $16
   cmp al,27
   je x

E então, imediatamente, existem 5 caracteres proibidos de uma só vez: 0 pol mov ah,0, 16 pol int $16, US $ 3C (caractere "<") e 27 (US $ 1B) cmp al,27e um número com o código <32 pol je xse xestiver localizado em algum lugar próximo ao código.

O que fazer? O que pode ser substituído por outros comandos é substituído por:

  • em vez disso mov ah,0, escrevemos xor ah,ahou mesmo cbw(quando possível);
  • em vez disso cmp al,27, escrevemos not al+ sub al,not 27ou xor al,not 27+ inc al, e ainda melhor (porque aqui precisamos aguardar a tecla ser pressionada e comparar o código recebido com o código da tecla ESC) - dec ah.

C é int $16mais complicado, mas se você pensar sobre isso, a construção xor ah,ah+ int $16pode ser substituída, por exemplo, por mov ah,$83+ ror ah,1+ int $21.

Permanece je $+10. Há pelo menos duas maneiras: ou dê um pulo para trás (a uma distância suficiente) e, a partir daí, vá em frente. Ou substitua o byte no código. Por exemplo, você pode escrever z: je ($*2+3)-x, mas em algum lugar acima: not byte [si-($100-(z+1))].

Como resultado, obtemos:

   not byte [si-($100-(z+1))]  ;  2-  ( ) je  si=$100
   mov ah,$83
   rol ah,1  ; ah=7
   int $21  ;   ,    al
   not al
   sub al,not 27  ; cmp al,27
z: je ($*2+3)-x  ;    x (   )

Soluções alternativas


É claro que, na introdução final para mais de 100 bytes de caracteres proibidos, pode haver bastante (por exemplo, 15-20 e mais), e cada vez que fazer essas manipulações é uma ocupação bastante sombria, além disso, eles geralmente levam a um aumento no tamanho do código.

Portanto, você pode recorrer à criptografia. O código inteiro ou os locais individuais. No exemplo 2b_life.asm, criptografamos todo o código adicionando $ AC a cada byte. Após a primeira criptografia, temos cerca de 4 caracteres proibidos restantes, que poderíamos resolver substituindo por outros comandos. Obviamente, a escolha do método de criptografia (add, sub, xor, não etc.), assim como a chave, também leva tempo, mas esse é o menor de todos os males. O código do decodificador é de apenas 8 bytes - isso é bastante aceitável nessa situação. A criptografia acontece automaticamente usando diretivas.repeat, loade store(ou seja, já obtemos o código criptografado).


Locais individuais são criptografados no exemplo 2b_note.asm . Aqui, novamente, com a ajuda de repeat, loade storeo valor $ 3D é adicionado a alguns bytes, e a lista de endereços desses bytes é armazenada separadamente (1 byte do endereço para cada byte). No total, criptografamos 20 bytes + 13 bytes são ocupados pelo decodificador. Sim, o primeiro método foi mais econômico :)

No início do artigo, prometemos falar sobre o código, que pode assumir a forma de uma string composta por caracteres ASCII com códigos de 33 a 126 (para que possa ser digitada, por exemplo, sem dificuldades especiais no teclado). Isso é possível, por exemplo, se o código for criptografado usando caracteres hexadecimais ou similares. Sim, isso é um desperdício, mas se criptografado usando o método BASE64, a despesa pode se tornar ainda maior, porque o decodificador deve consistir apenas desses caracteres.


Ferramentas


Para a conveniência de escrever código em " 2B ou não 2B ", foram criados 4 arquivos:

  • 2b.draft.asm – 128- BAT-, 2b ( , - , ). , .
  • 2b.draft44.asm – 44- , ASCII- 33 126. - : + «A» ( «A»...«P»), + «K» ( «K» «Z»). – 37 (+ 2 pusha + popa, ). : (125 — 37) / 2 = 44 ( 43, pusha + popa). :). , – 2b_snow.asm 2b_hello.asm
  • 2b.check.inc – include- . , , ( BAT-).
  • 2b.debug.inc – include- ( COM- BIN- ).

?


O conjunto de plataformas existentes para as quais as intras são gravadas permaneceu praticamente inalterado por muitos anos, se você não levar em consideração a categoria Wild (AON, ferros de solda, cotonetes). Oferecemos a você ... não apenas uma nova plataforma, mas pelo menos alguma variedade, com suas limitações. São as limitações e sua superação que são a essência da demoscena como um processo. Seria divertido ver todo o concurso no quadro deste conceito, no mais próximo demopati, onde diferentes autores poderão experimentar o “2B or not 2B compo” :)

--- EOF ---

#FF - E um byte inteiro não é suficiente ... | Piloto)
# 00 - ICBM ... | Convite para Revisão Online 2020
# 01 - IBMP ... | O que são introduções?
# 02 - O MBM ... | A cruz das mudanças
# 03 - IBMP ... | 2B ou não 2B
# 04 - O MBM ... | Tomamos BC pelos chifres
# 05 - ICBM ... | Anime
# 06 - IBMP ... | Canal

de entretenimento do avô em meteorologia no telegrama:teleg.run/bornded

Há um bate-papo ao lado do canal. Nele, você pode tentar levantar questões para o demosceno, montador, pixel art, música do rastreador e outros aspectos dos processos. Você pode ser respondido ou enviado para outros chats mais temáticos.

Então eles venceram - então nós vencemos!

All Articles