# 03 - Y un byte completo no es suficiente ... | 2B o no 2B

Entonces, amigos, el 1 de abril, es hora de revelar las cartas, qué es exactamente " 2B o no 2B ". Este es un texto conjunto del autor del trabajo.gafe y ya te es familiar tu abuelo no creyente

imagen

Asegúrese de descargar el archivo con el trabajo en Pouet y leer el artículo introductorio (April Fools '), así como los comentarios al respecto. Mire el primer video con una demostración práctica de cómo funciona el código de dos bytes en x86. Y solo entonces trate de dominar todo el texto a continuación.


Sí, 2B o no 2B es realmente un entorno para lanzar varios trabajos de codificación por tamaño, muy simple y, quizás, el más pequeño de los existentes. Sin embargo, tiene sus propios requisitos y limitaciones.

Si alguien más no lo ha atrapado, la herramienta 2b.com se inicia desde DOS (DOSBox, FreeDOS, MS-DOS) y salta al área de la línea de comando (en el desplazamiento $ 82 * del segmento PSP), iniciando el código que se transfirió a la ejecución línea de comando en binario. En realidad, este código puede tener la forma de una cadena que se puede escribir en el teclado (es decir, consta de caracteres ASCII con códigos del 33 al 126), pero más sobre eso más adelante.

* Números hexadecimales que escribiremos en notación Pascal $ XX, esto es conveniente, y fasm le permite hacer esto.

¿Qué es importante saber?


Nulo, recomendamos usar fasm como compilador , todas nuestras herramientas están escritas específicamente para ello.

En primer lugar, el código principal puede tener un tamaño máximo de 125 bytes (estas son las restricciones en la longitud de la línea de comando) y comenzará como un programa COM normal, solo con un desplazamiento de $ 82, no $ 100, como de costumbre. Inmediatamente después del código principal, se agregará automáticamente un símbolo de retorno de carro (CR) con el código 13 ($ 0D), y el comando jmp short $82($ EB, $ 80) se ubicará en $ 100 .

En segundo lugar, dado que se supone que el lanzamiento proviene de un archivo BAT (bueno, o del intérprete de línea de comandos), el código no debe contener algunos caracteres. En primer lugar, estos son caracteres de redirección de E / S ("<", ">" y "|"), así como el carácter de sustitución de parámetros y variables de entorno ("%"). En algunos sistemas (incluido Windows, que admite el lanzamiento de programas DOS desde V86), los caracteres "&", "^" también tienen un significado especial. Todos los DOS no admiten caracteres especiales con códigos de hasta 32, y algunos no son compatibles con ninguno o casi ninguno (DOSBox tiene un conjunto particularmente exiguo), por lo que también excluimos todos estos caracteres.

En tercer lugar, los valores iniciales de todos los registros e indicadores son los mismos que cuando se inicia el programa COM. En la gran mayoría de DOS, al principio será: ax = bx = 0 (casi siempre lo es), cx = $ FF, dx = cs = ds = es = ss, si = $ 100, di = sp = $ FFFE (con suficiente operación memoria), bp = $ 9XX (el byte bajo es diferente en todas partes, pero su tétrada alta, es decir, un mordisco, generalmente = 1), indica cf = df = 0. Usarlo o no depende de usted.

Sobre todo, el "segundo" punto es confuso aquí, ¿no?
Supongamos que necesitamos escribir:

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

Y luego, de inmediato, hay 5 caracteres prohibidos a la vez: 0 in mov ah,0, $ 16 in int $16, $ 3C (carácter "<") y 27 ($ 1B) cmp al,27y algún número con código <32 je xsi xestá ubicado en algún lugar cercano en el código.

¿Qué hacer? Lo que se puede reemplazar con otros comandos se reemplaza por:

  • en su lugar mov ah,0escribimos xor ah,aho incluso cbw(cuando es posible);
  • en su lugar cmp al,27, escribimos not al+ sub al,not 27o xor al,not 27+ inc al, y aún mejor (porque aquí tenemos que esperar a que se presione la tecla y comparar el código recibido con el código de la tecla ESC) - dec ah.

C es int $16más complicado, pero si lo piensa, entonces la construcción xor ah,ah+ int $16se puede reemplazar, por ejemplo, con mov ah,$83+ ror ah,1+ int $21.

Se queda je $+10. Hay al menos 2 formas: hacer un salto hacia atrás (a una distancia suficiente) y desde allí avanzar. O reemplace el byte en el código. Por ejemplo, puede escribir z: je ($*2+3)-x, pero en algún lugar por encima de: not byte [si-($100-(z+1))].

Como resultado, obtenemos:

   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 (   )

Soluciones alternativas


Por supuesto, en la introducción final de más de 100 bytes de caracteres prohibidos puede haber bastante (por ejemplo, 15-20 e incluso más), y cada vez que realizar tales manipulaciones es una ocupación bastante triste, además, a menudo conducen a un aumento en la longitud del código.

Por lo tanto, puede recurrir al cifrado. O todo el código o lugares individuales. En el ejemplo 2b_life.asm, ciframos todo el código agregando $ AC a cada byte. Después del primer cifrado, nos quedan unos 4 caracteres prohibidos, que podríamos resolver reemplazando con otros comandos. Por supuesto, la elección del método de cifrado (add, sub, xor, not, etc.), así como la clave, también lleva tiempo, pero este es el menor de todos los males. El código del decodificador es de solo 8 bytes; esto es bastante aceptable en esta situación. El cifrado ocurre automáticamente usando directivas.repeat, loady store(es decir, obtenemos el código ya cifrado).


Las ubicaciones individuales se cifran en el ejemplo 2b_note.asm . Aquí, nuevamente, con la ayuda de repeat, loady storeel valor $ 3D se agrega a algunos bytes, y la lista de direcciones de estos bytes se almacena por separado (1 byte de la dirección para cada byte). En total, ciframos 20 bytes + 13 bytes están ocupados por el descifrador. Sí, el primer método fue más económico :)

Al comienzo del artículo, prometimos hablar sobre el código, que puede tomar la forma de una cadena que consiste en caracteres ASCII con códigos del 33 al 126 (para que pueda escribirse, por ejemplo, sin dificultades especiales en el teclado). Esto es posible, por ejemplo, si el código se cifra con caracteres hexadecimales o similares. Sí, esto es un desperdicio, pero si se encripta utilizando el método BASE64, el gasto puede llegar a ser aún mayor, porque el decodificador solo debe consistir en dichos caracteres.


Herramientas


Para la conveniencia de escribir código bajo " 2B o no 2B " se crearon 4 archivos:

  • 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- ).

?


El conjunto de plataformas existentes para las que se escriben intras se ha mantenido prácticamente sin cambios durante muchos años, si no se tiene en cuenta la categoría Wild (AON, soldadores, bastoncillos de algodón). Le ofrecemos ... no solo una nueva plataforma, sino al menos una variedad, con sus limitaciones. Las limitaciones y su superación son la esencia del demoscene como proceso. Sería divertido ver todo el concurso en el marco de este concepto en la demopati más cercana, donde diferentes autores podrán probar suerte en el "2B o no 2B compo" :)

--- EOF ---

#FF - Y un byte completo no es suficiente ... El | Piloto)
# 00 - ICBM ... | Invitación a revisión en línea 2020
# 01 - IBMP ... | ¿Qué son las intro?
# 02 - El MBM ... | La Cruz de los Cambios
# 03 - IBMP ... | 2B o no 2B
# 04 - El MBM ... | Tomamos BC por los cuernos
# 05 - ICBM ... | Anime
# 06 - IBMP ... | Meteorismos

Canal de entretenimiento del abuelo en Telegram:teleg.run/bornded

Hay un chat al lado del canal. En él, puede intentar plantear preguntas para el demoscene, ensamblador, pixel art, música de seguimiento y otros aspectos de los procesos. Puede ser respondido o enviado a otros chats más temáticos.

Entonces ganaron, ¡así ganamos nosotros!

All Articles