
Una CPU mínima en memoria para la creación agnóstica de protocolos sobre la marcha
Harald es una pequeña CPU de alto nivel en memoria, capaz de procesar un conjunto de instrucciones para generar protocolos de capa de aplicación que se utilizarán sobre un protocolo de red determinado (TCP/UDP).
Harald consumirá un flujo de OPCODES y aplicará diferentes transformaciones a la carga útil para que sea adecuada para el protocolo de capa de aplicación definido.
[!TIP] ¿Por qué Harald? Puede que conozcas a Harald Gormsson, rey de Dinamarca, por su apodo: Blátǫnn, o como lo pronunciamos hoy en día, Bluetooth. La tecnología recibió el nombre del apodo de Harald, ya que él conectó los reinos danés y vikingo en aquella época. Así que le pongo este nombre por su nombre de pila.
Harald se comporta como una CPU. Sigue un conjunto de OPCODES que definen acciones. Un PROTOCOLO. Harald procesará las operaciones necesarias para crear el protocolo requerido sobre la marcha.
Una vez proporcionado el PROTOCOLO, Harald iterará sobre el PAYLOAD que se enviará recorriendo todo el PROTOCOLO una vez por cada fragmento. Es decir: si la carga útil tuviera que dividirse en varios fragmentos, Harald utilizará el mismo protocolo para cada fragmento, ejecutando cada acción definida en el protocolo contra el fragmento de carga útil actual.
Harald mantiene una serie de registros que el protocolo puede utilizar para almacenar valores. Estos registros pueden usarse para realizar múltiples operaciones, como suma, resta, codificación y decodificación... etc.
Harald asigna dinámicamente un array de resultados donde el protocolo puede almacenar las respuestas a cada petición realizada al enviar un fragmento de carga útil.

Harald admite una variedad de Opcodes que se pueden proporcionar como protocolo. Harald realizará un conjunto de operaciones de alto nivel al recibir un Opcode determinado. Cada Opcode espera un conjunto predefinido de argumentos con una longitud predefinida.
| OPCODE::Nº | Descripción | ARGS::Size |
|---|---|---|
| H_F_APPEND::0x01 | Añade los siguientes N Bytes al final de la carga útil | Size::4, NBytes::N |
| H_F_PREPEND::0x02 | Antepone los siguientes N Bytes al final de la carga útil | Size::4, NBytes::N |
| H_F_SPLIT::0x03 | Divide la carga útil en fragmentos del tamaño indicado | Size::4 |
| H_F_PAYLOAD_INJECT::0x04 | Inyecta el fragmento de carga útil en la carga útil final | - |
| H_F_SOCK_INIT::0x05 | Inicializa la conexión de socket | IsIPAddress:1, SSL_Enabled::1, TCP/UDP::1, [(HostLen::4,HostName:N)/IPAddress::4], Port::2 |
| H_F_SEND::0x06 | Envía la carga útil final construida | - |
| H_F_RECV::0x07 | Recibe hasta N Bytes | Size::4 |
| H_F_CLOSE::0x08 | Cierra el socket y limpia | - |
| H_F_INJECT::0x09 | Inyecta el registro solicitado en la carga útil final | Reg::1 |
| H_F_ENCODE_STR::0x0A | Codifica un campo de la carga útil a su representación como cadena | IsReg::1, [(Payload::1, Field::1)/Reg::1], Format::1 |
| H_F_DECODE_STR::0xA0 | Decodifica el contenido de un registro a su representación numérica | Reg::1 |
| H_F_ENCODE_STRB64::0x0B | Codifica un campo de la carga útil a su representación como cadena B64 | Payload::1, Field::1 |
| H_F_COMPUTE_FRAG_LENGTH::0x0D | Calcula la longitud del siguiente fragmento a enviar | - |
| H_F_SEARCH::0x0E | Busca un patrón de bytes dado de un tamaño N dado en un registro dado | Reg::1, Size::4, NBytes::N |
| H_F_SEEK::0x0F | Mueve el cursor en una carga útil dada un número de bytes dado | Payload::1, Offset::4 |
| H_F_PUSH::0x10 | Inserta un número de bytes o el contenido de un registro en otro registro | IsReg::1, [Size::4, NBytes::N]/SrcReg::1, DstReg::2 |
| H_F_ADD::0x12 | Suma dos registros o un número a un registro | IsReg::1, [Size::4, NBytes::N]/SrcReg::1, DstReg::2 |
| H_F_SUBSTRACT::0x13 | Resta dos registros o un número a un registro | IsReg::1, [Size::4, NBytes::N]/SrcReg::1, DstReg::2 |
| H_F_READ::0x14 | Lee de un registro dado hasta la longitud almacenada en otro registro | FromReg::1, SizeReg::1 |
| H_F_STORE::0x15 | Almacena un valor de registro en el Storage de Harald | Reg::1 |
El siguiente flujo de Opcodes generará los datos necesarios para enviar en una comunicación que sea entendida como HTTP. Iniciará, modificará la carga útil para que parezca tráfico HTTP, la enviará a través de una conexión SSL/TLS y cerrará la conexión al final.
H_F_SPLIT, 0x00, 0x00, 0x00, 0xFF, // Splits the Payload
H_F_APPEND, 0x00, 0x00, 0x00, 0x46, // Appends...
'P', 'O', 'S', 'T', ' ', '/', ' ', // POST /
'H', 'T', 'T', 'P', '/', '1', '.', '1', '\r', '\n', // HTTP/1.1
'H', 'o', 's', 't', ':', ' ', // Host:
'd', 'o', 'm', 'a', 'i', 'n', '.', 'c', 'o', 'm', '\r', '\n', // domain.com
'C', 'o', 'n', 'n', 'e', 'c', 't', 'i', 'o', 'n', ':', ' ', // Connection:
'c', 'l', 'o', 's', 'e', '\r', '\n', // close
'C', 'o', 'n', 't', 'e', 'n', 't', '-', // Content-
'L', 'e', 'n', 'g', 't', 'h', ':', ' ', // Length:
H_F_COMPUTE_FRAG_LENGTH, // Next Fragment's size
H_F_ENCODE_STR, H_PAY_END_PAYLOAD, H_PAY_FRAGMENT_SIZE, 'u', // FragSize encode
H_F_INJECT, H_REG_RET, // Inject the Fragment Size encoded str
H_F_APPEND, 0x00, 0x00, 0x00, 0x04, '\r', '\n', '\r', '\n', // Append Body begin
H_F_PAYLOAD_INJECT, // Inject the Payload
H_F_SOCK_INIT, 0x01, 0x01, 0x7F, 0x00, 0x00, 0x01, 0x04, 0xD2, // Init Socket
H_F_SEND, // Send the Payload over the socket
H_F_CLOSE // Close the socket and cleanup