
Una CPU minimale in-memory per la creazione agnostica di protocolli al volo
Harald è una piccola CPU ad alto livello in memoria, in grado di elaborare un insieme di istruzioni per generare protocolli a livello applicativo da utilizzare su un dato protocollo di rete (TCP/UDP).
Harald consumerà un flusso di OPCODE e applicherà diverse trasformazioni al payload affinché sia adatto al protocollo a livello applicativo definito.
[!TIP] Perché Harald? Potresti conoscere Harald Gormsson, re di Danimarca, per il suo soprannome: Blátǫnn, o come lo pronunciamo oggi, Bluetooth. La tecnologia prese il nome dal soprannome di Harald poiché egli collegò i regni danese e vichingo all'epoca. Quindi sto chiamando questo progetto con il suo nome di battesimo.
Harald si comporta come una CPU. Segue un insieme di OPCODE che definiscono azioni. Un PROTOCOLLO. Harald elaborerà le operazioni necessarie per creare il protocollo richiesto al volo.
Una volta fornito il PROTOCOLLO, Harald itererà sul PAYLOAD da inviare attraversando l'intero PROTOCOLLO una volta per ogni frammento. Ovvero: se il payload dovesse essere suddiviso in più frammenti, Harald utilizzerà lo stesso protocollo per ogni frammento, eseguendo ogni azione definita nel protocollo sul frammento di payload corrente.
Harald mantiene una serie di registri da utilizzare dal protocollo per memorizzare valori. Questi registri possono essere usati per eseguire molteplici operazioni, come addizione, sottrazione, codifica e decodifica... ecc.
Harald alloca dinamicamente un array di risultati dove il protocollo può memorizzare le risposte a ogni richiesta effettuata durante l'invio di un frammento di payload.

Harald supporta una varietà di Opcode da fornire come protocollo. Harald eseguirà un insieme di operazioni ad alto livello al ricevimento di un dato Opcode. Ogni Opcode si aspetta un insieme predefinito di argomenti con una lunghezza predefinita.
| OPCODE::Nº | Descrizione | ARGS::Size |
|---|---|---|
| H_F_APPEND::0x01 | Aggiunge i successivi N Byte alla fine del payload | Size::4, NBytes::N |
| H_F_PREPEND::0x02 | Antepone i successivi N Byte alla fine del payload | Size::4, NBytes::N |
| H_F_SPLIT::0x03 | Suddivide il Payload in frammenti della dimensione data | Size::4 |
| H_F_PAYLOAD_INJECT::0x04 | Inietta il frammento di Payload nel Payload Finale | - |
| H_F_SOCK_INIT::0x05 | Inizializza la connessione socket | IsIPAddress:1, SSL_Enabled::1, TCP/UDP::1, [(HostLen::4,HostName:N)/IPAddress::4], Port::2 |
| H_F_SEND::0x06 | Invia il Payload Finale costruito | - |
| H_F_RECV::0x07 | Riceve fino a N Byte | Size::4 |
| H_F_CLOSE::0x08 | Chiude il socket e pulisce | - |
| H_F_INJECT::0x09 | Inietta il registro richiesto nel Payload Finale | Reg::1 |
| H_F_ENCODE_STR::0x0A | Codifica un campo del Payload nella sua rappresentazione stringa | IsReg::1, [(Payload::1, Field::1)/Reg::1], Format::1 |
| H_F_DECODE_STR::0xA0 | Decodifica il contenuto di un registro nella sua rappresentazione numerica | Reg::1 |
| H_F_ENCODE_STRB64::0x0B | Codifica un campo del Payload nella sua rappresentazione B64string | Payload::1, Field::1 |
| H_F_COMPUTE_FRAG_LENGTH::0x0D | Calcola la lunghezza del prossimo frammento da inviare | - |
| H_F_SEARCH::0x0E | Cerca un dato pattern di byte di una data dimensione N in un dato registro | Reg::1, Size::4, NBytes::N |
| H_F_SEEK::0x0F | Sposta il cursore in un dato payload di un dato numero di byte | Payload::1, Offset::4 |
| H_F_PUSH::0x10 | Inserisce un numero di byte o il contenuto di un registro in un altro registro | IsReg::1, [Size::4, NBytes::N]/SrcReg::1, DstReg::2 |
| H_F_ADD::0x12 | Somma due registri o un numero a un registro | IsReg::1, [Size::4, NBytes::N]/SrcReg::1, DstReg::2 |
| H_F_SUBSTRACT::0x13 | Sottrae due registri o un numero a un registro | IsReg::1, [Size::4, NBytes::N]/SrcReg::1, DstReg::2 |
| H_F_READ::0x14 | Legge da un dato registro fino alla lunghezza memorizzata in un altro registro | FromReg::1, SizeReg::1 |
| H_F_STORE::0x15 | Memorizza un valore di registro nello Storage di Harald | Reg::1 |
Il seguente flusso di Opcode genererà i dati richiesti da inviare affinché una comunicazione sia interpretata come HTTP. Inizierà, modificherà il payload per farlo sembrare traffico HTTP, lo invierà su una connessione SSL/TLS e chiuderà la connessione alla fine.
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