cat /dev/null

Uma linguagem para parseamento de buffers...

Eu sei "regex", "awk", mas é mal de cientista da computação... Queria meu próprio "Bufferstein".

Há 3 anos atrás pude proferir "It's alive, it's alive" com minha própria linguagem para parsing de buffers.

Não regulo muito e resolvi criar algo orientado à instruções, imagine um ASSEMBLY só que para buffers... Mas esse pseudo-ASSEMBLY é realmente alienígena!

É a BPL (Buffer Parsing Language), confesso que já fui mais criativo em acrônimos, e realmente é uma sigla bem genérica, hehe.

As instruções BPL (bem atômicas até certo ponto) são:

INSTRUÇÃOAÇÃO
auxCria um registrador auxiliar
setSeta todo conteúdo de um buffer
wlkIncrementa/decrementa ponteiro de deslocamento do buffer
ldbPõe um byte no offset atual de um buffer
bobCheca por início de buffer
eobCheca pelo final do buffer
jmpSalto condicional
lblAdiciona marcação de label no código, usado nos jumps
addIncrementa valor contido na posição de memória atual do buffer
subSimilar a add mas em termos de decremento
mulSimilar a sub mas em termos de multiplicação
divSimilar a mul mas em termos de divisão
aluResolve uma expressão lógica
varCria uma variável, ok, me chame de Herege ASSEMBLY people


Cada instrução informada tem suas particularidades quanto à passagem de parâmetros, caso queira saber mais, encontre os detalhes na documentação informada no final desse post.

Que tal exemplos:


  1. # Rot13 em C-Strings

  2. var byte %byte 0x0

  3. lbl ___DO_ROT13

  4. ldb %byte BUF

  5. jmp eq BUF 0x00 ___WALK_ON ___CONTINUE

  6. lbl ___CONTINUE

  7. sub %byte 13

  8. ldb BUF %byte

  9. lbl ___WALK_ON

  10. wlk > BUF

  11. eob %byte BUF

  12. jmp ne %byte 1 ___DO_ROT13 ___END_ROT13

  13. lbl ___END_ROT13

Um maior, que atesta minha loucura :P


  1. #

  2. # ``urldecoding.bpl'' ( Thu 08 May 2008 10:10:42 AM UTC )

  3. #

  4. # URL decoding sem suporte para Utf-8

  5. #

  6. var byte %result_flag 0

  7. aux %nibble_l 1

  8. aux %nibble_h 1

  9. aux %buf 8192

  10. lbl ___NEXT_HEX_BYTE

  11. eob %result_flag BUF

  12. jmp eq %result_flag 1 ___DECODING_END ___DO_NEXT_HEX_BYTE

  13. lbl ___DO_NEXT_HEX_BYTE

  14. jmp eq BUF "%" ___HEX_2_CHAR_BYTE ___NEXT_HEX_BYTE_CONTINUE

  15. lbl ___NEXT_HEX_BYTE_CONTINUE

  16. jmp eq BUF "+" ___PLUS_2_SPACE ___SIMPLE_ASSIGMENT

  17. lbl ___PLUS_2_SPACE

  18. ldb %buf " "

  19. jmp eq %buf " " ___POINTER_AHEAD ___POINTER_AHEAD # goto ;)

  20. lbl ___SIMPLE_ASSIGMENT

  21. ldb %buf BUF

  22. lbl ___POINTER_AHEAD

  23. wlk > %buf

  24. wlk > BUF

  25. jmp eq 1 1 ___NEXT_HEX_BYTE ___NEXT_HEX_BYTE

  26. lbl ___HEX_2_CHAR_BYTE

  27. wlk > BUF #[%]XX -> %[X]X

  28. ldb %nibble_h BUF

  29. jmp ge %nibble_h "0" ___IS_NUMBER_H ___NOT_NUMBER_H

  30. lbl ___IS_NUMBER_H

  31. jmp le %nibble_h "9" ___NUMBER_2_DEC_H ___NOT_NUMBER_H

  32. lbl ___NOT_NUMBER_H

  33. jmp ge %nibble_h "a" ___IS_LWR_ALPHA_H ___NOT_LWR_ALPHA_H

  34. lbl ___IS_LWR_ALPHA_H

  35. jmp le %nibble_h "f" ___LWR_ALPHA_2_DEC_H ___NOT_LWR_ALPHA_H

  36. lbl ___NOT_LWR_ALPHA_H

  37. jmp ge %nibble_h "A" ___IS_UPR_ALPHA_H ___NOT_UPR_ALPHA_H

  38. lbl ___IS_UPR_ALPHA_H

  39. jmp le %nibble_h "F" ___UPR_ALPHA_2_DEC_H ___NOT_UPR_ALPHA_H

  40. lbl ___NOT_UPR_ALPHA_H

  41. ldb %buf BUF

  42. wlk > BUF

  43. wlk > %buf

  44. jmp eq 1 1 ___NEXT_HEX_BYTE ___NEXT_HEX_BYTE

  45. lbl ___NUMBER_2_DEC_H

  46. sub %nibble_h 48

  47. jmp eq 1 1 ___NEXT_NIBBLE ___NEXT_NIBBLE

  48. lbl ___LWR_ALPHA_2_DEC_H

  49. sub %nibble_h 87

  50. jmp eq 1 1 ___NEXT_NIBBLE ___NEXT_NIBBLE

  51. lbl ___UPR_ALPHA_2_DEC_H

  52. sub %nibble_h 55

  53. lbl ___NEXT_NIBBLE

  54. mul %nibble_h 16

  55. wlk > BUF #%[X]X -> %X[X]

  56. ldb %nibble_l BUF

  57. jmp ge %nibble_l "0" ___IS_NUMBER_L ___NOT_NUMBER_L

  58. lbl ___IS_NUMBER_L

  59. jmp le %nibble_l "9" ___NUMBER_2_DEC_L ___NOT_NUMBER_L

  60. lbl ___NOT_NUMBER_L

  61. jmp ge %nibble_l "a" ___IS_LWR_ALPHA_L ___NOT_LWR_ALPHA_L

  62. lbl ___IS_LWR_ALPHA_L

  63. jmp le %nibble_l "f" ___LWR_ALPHA_2_DEC_L ___NOT_LWR_ALPHA_L

  64. lbl ___NOT_LWR_ALPHA_L

  65. jmp ge %nibble_l "A" ___IS_UPR_ALPHA_L ___NOT_UPR_ALPHA_L

  66. lbl ___IS_UPR_ALPHA_L

  67. jmp le %nibble_l "F" ___UPR_ALPHA_2_DEC_L ___NOT_UPR_ALPHA_L

  68. lbl ___NOT_UPR_ALPHA_L

  69. ldb %buf BUF

  70. wlk > BUF

  71. wlk > %buf

  72. jmp eq 1 1 ___NEXT_HEX_BYTE ___NEXT_HEX_BYTE

  73. lbl ___NUMBER_2_DEC_L

  74. sub %nibble_l 48

  75. jmp eq 1 1 ___ADJUST_L ___ADJUST_L

  76. lbl ___LWR_ALPHA_2_DEC_L

  77. sub %nibble_l 87

  78. jmp eq 1 1 ___ADJUST_L ___ADJUST_L

  79. lbl ___UPR_ALPHA_2_DEC_L

  80. sub %nibble_l 55

  81. jmp eq 1 1 ___ADJUST_L ___ADJUST_L

  82. lbl ___ADJUST_L

  83. add %nibble_h %nibble_l

  84. ldb %buf %nibble_h

  85. wlk > %buf

  86. wlk > BUF

  87. jmp eq 1 1 ___NEXT_HEX_BYTE ___NEXT_HEX_BYTE

  88. lbl ___DECODING_END

  89. set BUF "\0x00"

  90. lbl ___GET_BUF_REG_BEGIN

  91. wlk < %buf

  92. bob %result_flag %buf

  93. jmp ne %result_flag 1 ___GET_BUF_REG_BEGIN ___OVERWRITE_INPUT

  94. lbl ___OVERWRITE_INPUT

  95. ldb BUF %buf

  96. wlk > %buf

  97. wlk > BUF

  98. eob %result_flag %buf

  99. jmp eq %result_flag 1 ___DONE ___OVERWRITE_INPUT

  100. lbl ___DONE

É, criei um monstro.


"Inquirrível funquiciona. Está vivo, está vivo! MuAhhauahuahauh."
-- Dr. Bufferstein.


Pensei em criar a BPL enquanto desenvolvia um sniffer e esbarrei no problema de filtrar de forma geral dados vindos de protocolos layer7.

Meu sniffer no caso trabalha com uma linguagem bem específica que permite acesso aos campos dos protocolos de camada de rede e transporte, mas é impossível criar todos os campos para protocolos layer7 visto que à cada hora surge um novo (eita exagero)...

Nisso a BPL resolvia meu problema, entregando ao usuário a responsabilidade de criar seus próprios filtros para extração da informação layer7 desejada.

Fora que os usuários do sniffer podem criar seus próprios parsers e distribuir isso como funções de biblioteca.

Documentação e compilador/interpretador em: BPL_pack.

Igor para Dr. Bufferstein:


"- Qual é o próximo plano mestre??"
"- Parsearemos o Mundo..."
"- Bom!"


Python impressions

Na linha do "me dê uma alavanca e um ponto de apoio que moverei o mundo"... "me dê um interpretador e um editor de textos que resolverei tudo" é o que um programador python deve sentir.

Não tinha tido muito contato com essa linguagem ainda, mas no trabalho tenho sido forçado usá-la e confesso que tinha uma idéia errada dela...

Certas coisas são muito fáceis, intuitivas e claras, contudo, a endentação é uma coisa que não ajuda muito. Não pelo fato de se endentar errado, mas a visualização do código principalmente se você não largar umas linhas em branco, contribui produzir uma maçaroca de código que franzirá tua testa ao ler de primeira algo escrito na linguagem.

Mandracarias bem escrotinhas diga-se de passagem. Falo principalmente de __init__.py... "Whatta fuck porra is that?!", tem tanta coisa que é assumida, será que não dá para se esforçar um pouco e deduzir/assumir isso também?

A interface de sockets é mais ou menos. Mexeram em certas coisas. Mexer na API clássica de sockets é a mesma coisa que mudar o formato de uma Strato, de uma Les Paul.... Enfim, eu sei lá.

O módulo de threads segue a "filosofia" Java de se lidar com a coisa: você não pode pausar, resumir ou cancelar um thread. Tisss... E aí?

Unicode blues.

Vantagens: coisas bem na cara... Se você já conhece C, as funções da libc que você encontra até em caixas de sapato... POSIX te diz algo? (bom, mas isso é outra história...) Se conhecer isso a introdução básica no site do python já vai ser bem informativa.

Outra fonte que indico é "dive into python", se trata de um livro com alguns extratos on-line e free.

Taí dois bons pontos de partida que me são bem úteis.

Minha impressão até o momento: Python é bom para resolver coisas que não posso ou não quero gastar tempo em cima. Em resumo bem prática, uma boa linguagem de apoio.