Sim, eu faço gambiarras em shellscript
Isso não é um conteúdo educativo, só quero compartilhar uma das coisas que eu sempre gostei de fazer: gambiarras em shellscript.
Essa paixão começou no Batch - shellscript do Windows, aquele arcaico que veio antes do Powershell. Batch era bastante limitado e até coisas simples, como printar um texto colorido, exigia fazer gambiarras. Hoje em dia eu uso Linux e faço gambiarras em Bash.
Vou falar abaixo de algumas das gambiarras que eu mais gostei de fazer (o que não significa que sejam bem feitas).
Superset de Batch
Obs.: Eu excluí esse projeto há muitos anos atrás.
Em 2016 eu desenvolvi um superset de Batch, cujo o crime está eternamente registrado no batch-satti: https://batch-satti.forumeiros.com/t3382-projeto-batch-construct-compilador-batch
O superset permitia escrever códigos como este:
#include "io.bat"
:start
printc 0A "Ola " 09 "mundo!" \n
#quit
E o resultado era um texto colorido impresso na tela:

Ou esse outro troço feio aqui:
#declare sqr
:start
echo Resultado: {sqr 9} >tst.txt
echo O conteudo do arquivo tst.txt^> $(type tst.txt)
#quit
:sqr
#return {(%~1)*(%~1)}
Que resultava nisso:

O objetivo do projeto era simples: converter arquivos .bat em arquivos executáveis, só que com recursos extras (daí o motivo de ter virado um superset).
Era um projeto mal feito, mas a parte mais interessante é que o executável de saída tinha apenas 3 KB. Pois eu não criava um auto extrator como outros projetos semelhantes faziam, eu montava o executável do zero em assembly usando o FASM.
Outra coisa interessante é que o superset permitia executar Powershell entre as diretivas #ps e #endps. O que não deveria ser possível, pois por motivos de segurança o Windows bloqueia a execução de scripts Powershell. Mas na época eu bolei um jeito de fazer bypass nisso e conseguia rodar o script sem precisar ter a execução de scripts Powershell liberada no sistema do usuário.
Tudo na base da mais pura gambiarra. O texto colorido era impresso com uma gambiarra usando findstr, o Powershell era executado usando uma gambiarra para dar bypass na restrição de segurança, o próprio código do projeto compilava o superset para Batch usando a mais pura gambiarra (eu não tinha muita experiência escrevendo compiladores na época). E depois gerava um executável pequeno gambiarrado em assembly.
Não vou mentir, foi legal fazer esse projeto e brincar de escrever executáveis em um Batch tunado. :D
DSL em Bash
Ferramentas para templates de arquivos de texto é bem comum... Mas e que tal uma ferramenta para templates de arquivos binário? Para suprir essa ideia nonsense que eu fiz uma DSL (Domain-Specific Language) implementada em Bash. O script pode ser lido aqui: https://github.com/Silva97/cli-tools/blob/master/new
Como já deu para notar, eu gosto de inventar linguagens. Por mais esquisito e sem utilidade que seja, meu script Bash consegue interpretar um código como o abaixo e gerar um binário ELF a partir dele:
if .out == "/dev/stdout"
error "Please specifie 'out' file. This is a binary file not text."
help
endif
set max = "2048"
set max = .max # Maximum size of the file
## ELF header ##
x 7f 45 4c 46 # Magic number
x 02 # Class
x 01 # Data
x 01 # Version
x 01 # OS ABI
x 00 # ABI Version
dump 7 # Reserved
b16 2 # Type
b16 0x3e # Machine
b32 1 # Version
b64 0x401078 # Entry point
b64 64 # Program header offset
b64 0xffffffff # Section header offset
b32 0 # Flags
b16 64 # ELF header size
b16 56 # Program header entry size
b16 1 # Program header count
b16 64 # Section header entry size
b16 2 # Section header count
b16 1 # Section header strtab section index
## Program header ##
# Entry 0
b32 1 # Type (load)
b32 7 # Flags (0b111 = RWX)
b64 0 # Offset
b64 0x401000 # Virtual address
b64 0x401000 # Physical address
b64 $max # In file size
b64 $max # In memory size
b64 0 # Alignment
## Code ##
align 120
if .file
file .file
elif .code
str .code
x 90 # NOP
x b8 3c 00 00 00 # mov eax, 60
x 31 ff # xor edi, edi
x 0f 05 # syscall
else
error "Please specifie a 'file' or 'code' option."
help
endif
if $size > $max
error "Maximum size exceeded."
help
endif
O binário resultante é propositalmente capado para ficar bem pequeno. Um hello world como este:
org 0x401078
bits 64
mov rax, 1
mov rdi, 1
mov rsi, txt
mov rdx, TSIZE
syscall
mov rax, 60
xor rdi, rdi
syscall
txt: db `Hello World!\n\0`
TSIZE equ $-txt
Pode ser inserido em um binário ELF assim:
$ nasm hello.asm -o hello
$ new bin-elf64 file=hello out=test
E o arquivo binário test de saída seria um ELF de apenas 171 bytes de tamanho.
Também já fiz outras gambiarras interessantes, mas que prefiro não mostrar. Como o valva, que era um projeto de gerenciador de pacotes para Bash... Feito em Bash. Incluindo ferramentas de build e execução de testes.
Vocês já fizeram projetos malucos assim em shellscript? Estou curioso para saber das gambiarras da galera. Compartilha aí nos comentários. :D