
Um CPU mínimo em memória para criação de protocolos agnósticos em tempo real
Harald é uma CPU minúscula de alto nível em memória, capaz de processar um conjunto de instruções para gerar protocolos de camada de aplicação a serem usados sobre um determinado protocolo de rede (TCP/UDP).
Harald consumirá um fluxo de OPCODES e aplicará diferentes transformações ao payload para que ele seja adequado ao protocolo de camada de aplicação definido.
[!TIP] Por que Harald? Você pode conhecer Harald Gormsson, rei da Dinamarca, por seu apelido: Blátǫnn, ou como pronunciamos hoje em dia, Bluetooth. A tecnologia foi nomeada em homenagem ao apelido de Harald, pois ele conectou os reinos dinamarquês e viking naquela época. Então estou nomeando isto em homenagem ao seu primeiro nome.
Harald se comporta como uma CPU. Ele segue um conjunto de OPCODES que definem ações. Um PROTOCOLO. Harald processará as operações necessárias para criar o protocolo necessário em tempo real.
Uma vez que o PROTOCOLO é fornecido, Harald irá iterar sobre o PAYLOAD a ser enviado percorrendo todo o PROTOCOLO uma vez para cada fragmento. Ou seja: se o payload tiver que ser dividido em múltiplos fragmentos, Harald usará o mesmo protocolo para cada fragmento, executando cada ação definida no protocolo contra o fragmento de payload atual.
Harald mantém uma série de registradores para serem usados pelo protocolo para armazenar valores. Esses registradores podem ser usados para realizar múltiplas operações, como adição, subtração, codificação e decodificação... etc.
Harald aloca dinamicamente um array de resultados onde o protocolo pode armazenar as respostas para cada requisição realizada ao enviar um fragmento de payload.

Harald suporta uma variedade de Opcodes a serem fornecidos como um protocolo. Harald realizará um conjunto de operações de alto nível ao receber um determinado Opcode. Cada Opcode espera um conjunto predefinido de argumentos com um comprimento predefinido.
| OPCODE::Nº | Descrição | ARGS::Size |
|---|---|---|
| H_F_APPEND::0x01 | Anexa os seguintes N Bytes ao payload final | Size::4, NBytes::N |
| H_F_PREPEND::0x02 | Prefixa os seguintes N Bytes ao payload final | Size::4, NBytes::N |
| H_F_SPLIT::0x03 | Divide o Payload em fragmentos do tamanho fornecido | Size::4 |
| H_F_PAYLOAD_INJECT::0x04 | Injeta o fragmento do Payload no Payload Final | - |
| H_F_SOCK_INIT::0x05 | Inicializa a conexão do socket | IsIPAddress:1, SSL_Enabled::1, TCP/UDP::1, [(HostLen::4,HostName:N)/IPAddress::4], Port::2 |
| H_F_SEND::0x06 | Envia o Payload Final construído | - |
| H_F_RECV::0x07 | Recebe até N Bytes | Size::4 |
| H_F_CLOSE::0x08 | Fecha o socket e limpa | - |
| H_F_INJECT::0x09 | Injeta o registrador solicitado no Payload Final | Reg::1 |
| H_F_ENCODE_STR::0x0A | Codifica um campo do Payload para sua representação em string | IsReg::1, [(Payload::1, Field::1)/Reg::1], Format::1 |
| H_F_DECODE_STR::0xA0 | Decodifica o conteúdo de um registrador para sua representação numérica | Reg::1 |
| H_F_ENCODE_STRB64::0x0B | Codifica um campo do Payload para sua representação em string B64 | Payload::1, Field::1 |
| H_F_COMPUTE_FRAG_LENGTH::0x0D | Calcula o comprimento do próximo fragmento a ser enviado | - |
| H_F_SEARCH::0x0E | Procura por um determinado padrão de bytes de um determinado tamanho N em um determinado registrador | Reg::1, Size::4, NBytes::N |
| H_F_SEEK::0x0F | Move o cursor em um determinado payload por um determinado número de bytes | Payload::1, Offset::4 |
| H_F_PUSH::0x10 | Insere um número de bytes ou o conteúdo de um registrador em outro registrador | IsReg::1, [Size::4, NBytes::N]/SrcReg::1, DstReg::2 |
| H_F_ADD::0x12 | Soma dois registradores ou um número a um registrador | IsReg::1, [Size::4, NBytes::N]/SrcReg::1, DstReg::2 |
| H_F_SUBSTRACT::0x13 | Subtrai dois registradores ou um número de um registrador | IsReg::1, [Size::4, NBytes::N]/SrcReg::1, DstReg::2 |
| H_F_READ::0x14 | Lê de um determinado registrador até o comprimento armazenado em outro registrador | FromReg::1, SizeReg::1 |
| H_F_STORE::0x15 | Armazena um valor de registrador no Storage do Harald | Reg::1 |
O seguinte fluxo de Opcodes irá gerar os dados necessários a serem enviados para que uma comunicação seja entendida como HTTP. Ele irá iniciar, modificar o payload para parecer tráfego HTTP, enviá-lo por uma conexão SSL/TLS e fechar a conexão no 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