Mais um blog inútil.

Arvorezinha

Agosto 4, 2009

Arvorezinha - OpenGL

Arquivado em: arvorezinha, coding, java, windows — falso @ 22:17

Ora viva. Trago-vos uma nova uma submissão para a saga da arvorezinha, desta meu amigo João Saramago. Aqui vai:

Como prometi aqui vai.
Não consegui foi por em applet. Precisa de dll’s :S.

Só funciona em Windows. Mas se quiseres posso fazer binários para Linux e para Mac.

Estão ai os binários e o source.

arvorezinha.zip

E claro como toda a gente gosta de screenshots, aqui vão, até porque merece, porque é uma árvore completa em vez de ser só meia.

arvorezinha1arvorezinha2

Maio 14, 2009

Arvorezinha - ML (versão alternativa)

Arquivado em: arvorezinha, coding — falso @ 00:22

Ora viva de novo!
Mais uma vez venho blogar por causa de novas submissões de arvorezinhas, desta vez do ardoRic da PTnet! Ele diz o seguinte:

nao gostei da outra versão (está nos comentários) … estava pouco ML like.
Espero que gostes desta :)

let rec branch n = 
   match n with 
     0 -> [] 
   | n -> "*":: branch (n-1)

let rec nat n = 
  match n with
     0 -> []
   | n -> n::(nat (n-1))
;;

List.iter (fun x -> 
  List.iter print_string x ;
  print_string "\n"
) (List.rev_map branch (nat 5))

Maio 13, 2009

Arvorezinha - COBOL

Arquivado em: arvorezinha, coding, useless — falso @ 16:07

Outra submissão para a saga da arvorezinha, pelo meu colega João Saramago, desta vez em COBOL. Aqui vai:

IDENTIFICATION DIVISION.
PROGRAM-ID.  Arvorezinha.
AUTHOR.  João Saramago.

DATA DIVISION.

WORKING-STORAGE SECTION.
01  Linhas                                PIC 99  VALUE 5.
01  AUX                                   PIC 99 VALUE ZEROS.
01  AUX2                                  PIC 99 VALUE ZEROS.

PROCEDURE DIVISION.
Main.
    DISPLAY "Número de Linhas: " WITH NO ADVANCING
    ACCEPT Linhas.
    PERFORM VARYING AUX FROM 1 BY 1 UNTIL AUX GREATER THAN Linhas
       PERFORM VARYING AUX2  FROM 0 BY 1 UNTIL AUX2 EQUAL TO AUX 
          DISPLAY "*" WITH NO ADVANCING
       END-PERFORM
       DISPLAY ""
    END-PERFORM
    STOP RUN.

Para compilar usei o OpenCobol e para compilar é este comando:

cobc -free -x arvorezinha.cbl 

Maio 10, 2009

Arvorezinha - ARM Assembly

Arquivado em: arvorezinha, assembly, coding, useless — falso @ 23:18

Boas noites!

Venho de novo dar continuação à saga da arvorezinha, desta vez em ARM assembly para Linux. Esta foi relativamente simples, mas também depois de se ter feito em tantos tipos de arches já não há muito a diferir :-P

Aqui segue o código:

.equ SYSCALL_BASE,	0x900000
.equ SYSCALL_EXIT,	1
.equ SYSCALL_WRITE,	4

.text
.align 2
.globl _start

_start:
	mov r0,#5				@ total = 5
	mov r1,#0				@ counter1 = 0

_ciclo1:
	cmp r0,r1				@ compara c1 e tot
	beq _exit				@ se for igual sai
	mov r2,#0				@ counter2 = 0

_ciclo2:
	cmp r2,r1				@ compara c1 e c2 	
	beq _estrela			@ se for igual _estrela
	blt _estrela			@ se for menor _estrela

	stmfd sp!, {r0-r2}		@ guarda r0 a r2 na stack
	adr r1,newline			@ le \n
	bl _print				@ imprime
	ldmfd sp!, {r0-r2}		@ le da stack r0 a r2
	
	add r1,r1,#1			@ incrementa c1
	b _ciclo1				@ salta _ciclo1

_estrela:
	stmfd sp!, {r0-r2}		@ guarda r0 a r2 na stack
	adr r1,estrela			@ le *
	bl _print				@ imprime
	ldmfd sp!, {r0-r2}		@ le da stack r0 a r2

	add r2,r2,#1			@ incrementa c2
	b _ciclo2				@ salta _ciclo2

_exit:
	mov	r0,#0				@ resultado e' 0
	swi	SYSCALL_BASE+SYSCALL_EXIT	@ sai

_print:
	mov	r0,#1				@ 1 == stadout
	mov	r2,#1				@ tamanho da string
	swi	SYSCALL_BASE+SYSCALL_WRITE	@ imprime
	bx	r14					@ return

estrela:.string "*"
newline:.string "\n"

E aqui a prova-dos-nove:

:~/arvorezinha-arm$ cat /proc/cpuinfo
Processor       : XScale-IXP42x Family rev 1 (v5b)
BogoMIPS        : 266.24
Features        : swp half thumb fastmult edsp
CPU implementer : 0x69
CPU architecture: 5TE
CPU variant     : 0x0
CPU part        : 0x41f
CPU revision    : 1
Cache type      : undefined 5
Cache clean     : undefined 5
Cache lockdown  : undefined 5
Cache format    : Harvard
I size          : 32768
I assoc         : 32
I line length   : 32
I sets          : 32
D size          : 32768
D assoc         : 32
D line length   : 32
D sets          : 32

Hardware        : Linksys NSLU2
Revision        : 0000
Serial          : 0000000000000000
:~/arvorezinha-arm$ make
rm -f arvorezinha.o arvorezinha *~
Using fallback suid method
as -o arvorezinha.o arvorezinha.arm.s
ld -o arvorezinha arvorezinha.o
:~/arvorezinha-arm$ ./arvorezinha
*
**
***
****
*****
:~/arvorezinha-arm$

Download do projecto: arvorezinha-arm.tar.

Arvorezinha de Letras

Arquivado em: arvorezinha — drune @ 19:55

Olá a todos,

Todos os que visitam o blol conhecem de certeza o sucesso da árvorezinha, publicada imensas vezes de inúmeras formas sempre com o mesmo grau de inutilidade.

Quando passava os olhos no blol deparei-me com um post do spico que fazia uma arvorezinha com letras de forma manual. Ora não seria isto engraçado ser feito com o mesmo entusiasmo que a v1.0 da arvorezinha nas mais inúmeras formas cada uma mais inútil que a anterior?
Decidi assim ser o primeiro a fazê-lo em python, pois é simples de entender para todos os que quiserem pegar nisto.

As regras do RFC são simples:

\* Toda a árvorezinha é desenhada com base numa palavra
\* A árvorezinha tem uma dimensão de copa, ou seja é o número de linhas representado pela copa
\* A base da árvorezinha de letras deve ter a palavra repetida o número de vezes o número de letras que contem.
\* A base da árvorezinha deve ter um espaço em após cada letra (opcional)
Assim convido-vos a todos a escrever as vossas versões da árvorezinha de letras.

Aqui está um exemplo em python:

import sys

# Funcao que desenha a copa da arvore
def copaArvorezinha(a,n):
 i=0
 ic=0
 x=''
 while (i<=n):
 x=x+a[i]
 i+=1
 ic+=1
 print x #imprime as letras concactenadas
 if (len(a) == i):
 if (ic < n):
 i=0
 else:
 break

def baseArvorezinha(a):
 # desenhar a base
 for char in a:
 s = ' '.join(a)
 print s

## MAIN ##

if len(sys.argv) <= 2 or len(sys.argv) >=4:
 print '''Uso: python arvorezinha_de_letras.py
<palavra> <tamanho_copa>
 Opcoes:
<palavra> : Palavra com que a arvore de letras sera desenhada [string]
 <tamanho_copa> : Numero de linhas da copa [int]'''
else:
 try:
 #dividir letra a letra
 letters = [k for k in sys.argv[1]]
 # desenhar agora ;)
 copaArvorezinha(letters,int(sys.argv[2]))
 baseArvorezinha(letters)
 except:
 print '''Uso: arvorezinha_de_letras.py
<palavra> <tamanho_copa>
 Opcoes:
<palavra> : Palavra com que a arvore de letras sera desenhada [string]
 <tamanho_copa> : Numero de linhas da copa [int]'''

Download
O resultado é algo do género:
arvorezinha_letras

Um abraço,

Maio 9, 2009

arvorezinha em LUA

Arquivado em: arvorezinha, useless — gatuno @ 01:22

Olá a todos,

Depois de ter xatiado o falso um bocado, lá consegui que ele me abrisse uma conta… Ora bem.. primeiro post, vamos a ver se não fico mal…

A saga da arvorezinha continua a nos assombrar… desta vez em Lua (pelo menos ainda não vi por cá…) a correr na PSP, só para ser diferente =).

Aqui têm a “sores”, como vocês chamam:

verde = Color.new(0, 255, 0)
screen:clear()
arv="*"
for i=100,140,10 do
screen:print(200,i, arv, verde)
arv=arv .. "*"
endscreen.flip()
while true do
screen.waitVblankStart()
end

Parabéns aos gurus do malbolge e do assembly! Já agora, aproveito para lançar um desafio:

Que tal fazer em assembly para o MIPS da PSP? Alguém se atreve? ;)
http://jacksonm88.googlepages.com/linuxonpsp.htm

Maio 7, 2009

Arvorezinha - LISP

Arquivado em: arvorezinha — falso @ 19:38

Submetido pelo _Lone_Wolf_ da ptnet:

(defun arvorezinha (count) (loop for i from 1 to count do (print (make-string i :initial-element #\*))))

Maio 6, 2009

Arvorezinha - C Preprocessor

Arquivado em: arvorezinha — dcoder @ 20:34

Aqui vai uma submissão ligeiramente lame da arvorezinha em C preprocessor. Infelizmente não descobri como concatenar os ‘*’ (concatenar uma vez funciona com ##, mas a segunda vez não, dado que o preprocessor não avalia as expressões até o fim). Se alguém tiver sugestões, tomem a liberdade de as colocar nos comentários.

print.h:

#if i <= total
#if i > 0
#pragma message( STR )
#endif
#include "inc_i.h"
#include __FILE__
#endif

inc_i.h:

#if i == 0
#undef i
#define i 1
#undef STR
#define STR "*"
#elif i == 1
#undef i
#define i 2
#undef STR
#define STR "**"
#elif i == 2
#undef i
#define i 3
#undef STR
#define STR "***"
#elif i == 3
#undef i
#define i 4
#undef STR
#define STR "****"
#elif i == 4
#undef i
#define i 5
#undef STR
#define STR "*****"
#elif i == 5
#undef i
#define i 6
#undef STR
#define STR "******"
#endif

#undef j
#define j 0

test.cpp:

#define total 5
#define i 0
#define STR ""

#include "print.h"

O resultado é apresentado durante a compilação do test.cpp:

C:\>cl /c test.cpp
Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 15.00.21022.08 for 80x86
Copyright (C) Microsoft Corporation.  All rights reserved.

test.cpp
*
**
***
****
*****

Maio 5, 2009

Arvorezinha - Pascal

Arquivado em: arvorezinha — devnull @ 13:49

Directly from South Africa we have a submission from Desmond that works for Cartrack, here it is his submission:

for i := 1 to 5 do
begin
for j := 1 to i do write(´*´);
writeln;
end;

Maio 4, 2009

Malbolge desmistificado

Arquivado em: arvorezinha, coding, lulz, useless — mirage @ 21:42

Bem-vindos. Espicaçado pelas inutilidades que o falso e o Dcoder fizeram em malbolge, e ainda mais depois de o falso ter afirmado peremptoriamente que era impossível fazer uma arvorezinha à mão nesta linguagem diabólica, decidi, fatalmente, jogar mãos à obra.

O segredo do falso em relação ao malbolge é que todo o código dele é gerado por bruteforce. As optimizações do Dcoder limitaram-se a correr o bruteforce durante mais tempo para procurar soluções mais curtas. Neste post proponho um método real, analítico e bastante simples para criar um programa de malbolge que imprima qualquer sequência de caracteres, com a limitação de ser curta. E sim, a arvorezinha é suficientemente curta. ;-) Para facilitar a programação, criei vários utilitários, baseados no malbolge.c original, que constituem o malbolge SDK disponível aqui. Eis uma curta explicação de cada programa:

  • malbolgec: Compila uma source não obfuscada de malbolge (extensão .mbs), transformando-a na versão obfuscada executável (extensão .mb). São admitidos comentários na source, começando com “;”.
  • malbolged: Uma variação do malbolge.c standard que imprime o estado da VM à medida que executa o código. Muito útil para debugging.
  • malbolgedis: O inverso do malbolgec. Dado um programa executável de malbolge, mostra o seu código desobfuscado.
  • malbolgeconstant: Descobre a sequência mais curta para calcular o valor desejado. Mais abaixo será mostrado como o utilizar, já que é uma peça fulcral no método apresentado.
  • malbolgevalid: Mostra os valores válidos num programa de malbolge no intervalo de memória especificado. Útil para procurar valores directos para usar em jumps.
  • malbolgestring: Um proof-of-concept que gera um programa de malbolge que imprima a string especificada. Apenas aceita strings muito curtas (uma arvorezinha completa não cabe, por exemplo, mas “lol jews” sim).

Um dos problemas da programação em malbolge é que que o code pointer e o data pointer começam ambos a 0 no início do programa, ou seja, estão sobrepostos. Por isso, o meu plano começa por separar claramente a zona de código da zona de dados. Assim sendo, a primeira coisa que faço é avançar o D para qualquer sítio mais à frente, com a instrução “j”. Devido à obfuscação que a o malbolge obriga no input, esta instrução na posição 0 de memória corresponde a um salto do D para o valor 41. Temos agora 40 bytes de código disponíveis pela frente, sem mais complicações, antes de voltar a tropeçar nos dados.

Outro dos problemas é a alteração sofrida nas instruções depois de serem executadas, e também dos dados depois de serem usados pelos operadores. Para minimizar estes problemas optei por uma abordagem naïve mas suficientemente eficaz para o problema em questão, que consiste em ter todo o código e dados a correr linearmente, excepto a configuração inicial da área de dados descrita anteriormente.

Talvez a limitação mais severa seja a dos caracteres que podemos usar como input inicial no malbolge, o que dificulta tremendamente o uso de valores pré-definidos, como sejam os caracteres da nossa string. Isto obriga-nos a calcular praticamente todos os valores desejados e imprimi-los, um por um. O malbolge apenas oferece duas instruções de cálculo, o trinary rotate e a trinary op a.k.a. crazy operation. Felizmente para nós, qualquer valor ASCII é calculável usando estas operações com um máximo 3 operações seguidas com valores específicos nos dados (por vezes antecedidas de nops, é certo, para aceder aos dados necessários que, como é sabido, variam consoante a sua posição em memória). Para ajudar, não precisamos de ter o valor exacto no A, basta um A tal que A & 0xFF seja o caracter que queremos (os registos são unsigned short e o print só usa os primeiros 8 bits). Para descobrir a menor sequência de operações necessárias e respectivos valores nos dados fiz o malbolgeconstant (tal como referi acima, pertence ao SDK).

Para exemplificar, vamos criar um programa que imprima “Oi”. Usaremos os símbolos reais para as instruções e não a versão executável, que depois compilaremos com o malbolgec. Primeiro avançamos o D para a posição 41:

jv

Agora calculamos o caracter “O” (ASCII 79) com o malbolgeconstant (tem como input o valor do D, o valor que procuramos e o valor actual do A, que no início do programa é zero):

./malbolgeconstant 41 79 0
EUREKA! code=p pos=42 data=p (r)
EUREKA! code=* pos=41 data=p (s)

OK, esta efusão de felicidade conta-nos que devemos usar as operações “*” e “p”, com o input “p” e “p” respectivamente (que correspondem a “r” e “s” em código obfuscado, mas vamos aqui trabalhar com código normal). De notar que o pos (a posição de memória onde devem estar os dados) começa a 41, que foi a posição inicial que especificámos. Poderia ser 42 ou mais, o que significaria que precisávamos de inserir nops no código (e nos dados, mas aqui não é obrigatório serem nops) antes de executar as instruções especificadas. Por vezes os valores necessários às operações só estão disponíveis mais à frente na memória, devido à forma como o malbolge obriga a codificar as sores. Adiante, o nosso programa tem agora este aspecto:

j*p<voooooooooooooooooooooooooooooooooooopp

Recapitulando: avançamos o D, calculamos “O” (o seu valor fica no registo A) e imprimimo-lo com “< “, terminando o programa com o “v”. A sequência de “o” (nops) no meio é apenas para encher choriços, já que não chegam a ser executados. Estão cá apenas para chegar à posição 41 e 42, onde temos o input necessário às nossas instruções. Vamos compilar este programa e corre-lo no malbolged para ver a evolução dos registos:

./malbolgec example.mbs example.mb && ./malbolged example.mb
	CODE: j	MEM: 040 (() 	A: 00000	C: 00000	D: 00000
	CODE: *	MEM: 115 (s) 	A: 00000	C: 00001	D: 00041
	CODE: p	MEM: 114 (r) 	A: 19721	C: 00002	D: 00042
	CODE: < MEM: 29416 (è) 	A: 09807	C: 00003	D: 00043
O	CODE: v	MEM: 114 (r) 	A: 09807	C: 00004	D: 00044

Como podem ver, quando o programa termina, o registo A tem o valor 9807 e o D tem 44. Vamos usar estes valores como base para calcular a próxima constante de que necessitamos, que é a letra “i” (ASCII 105):

./malbolgeconstant 44 105 9807
EUREKA! code=p pos=45 data=j (Y)
EUREKA! code=* pos=44 data=/ (I)

Mais uma vez só precisamos de duas operações. Temos assim o seguinte:

j*p<*p<voooooooooooooooooooooooooooooooooppo/j

Notem o “o” entre os dois grupos de dados: é para compensar o avanço do D gerado pela instrução que imprime o caracter. Poderia ser qualquer outro símbolo, já que não está a ser usado.

Vamos terminar com um \n, para ficar com um output decente:

./malbolgec example.mbs example.mb && ./malbolged example.mb
	CODE: j	MEM: 040 (() 	A: 00000	C: 00000	D: 00000
	CODE: *	MEM: 115 (s) 	A: 00000	C: 00001	D: 00041
	CODE: p	MEM: 114 (r) 	A: 19721	C: 00002	D: 00042
	CODE: < MEM: 119 (w) 	A: 09807	C: 00003	D: 00043
O	CODE: *	MEM: 073 (I) 	A: 09807	C: 00004	D: 00044
	CODE: p	MEM: 089 (Y) 	A: 19707	C: 00005	D: 00045
	CODE: <	MEM: 29477 (%) 	A: 09833	C: 00006	D: 00046
i	CODE: v	MEM: 088 (X) 	A: 09833	C: 00007	D: 00047

./malbolgeconstant 47 10 9833
EUREKA! code=p pos=49 data=* (T)
EUREKA! code=p pos=48 data=v (!)
EUREKA! code=* pos=47 data=i (3)

Chegamos por fim ao programa desejado:

mirage@arda ~/malbolge-sdk-1.0 $ cat example.mbs
j*p<*p<*pp<voooooooooooooooooooooooooooooppo/joiv*
mirage@arda ~/malbolge-sdk-1.0 $ ./malbolgec example.mbs example.mb
mirage@arda ~/malbolge-sdk-1.0 $ cat example.mb
(&<`#9]~65YF876543210/.-,+*)('&%$#"!~}|{zsrwIYt3!T
mirage@arda ~/malbolge-sdk-1.0 $ ./malbolge example.mb
Oi

Vamos agora à prova dos nove: a arvorezinha! Note-se que esta arvorezinha tem \n na última linha, como manda o RFC. Tal como as arvorezinhas anteriores em malbolge, não usa ciclos. Ocupa 99 caracteres (incluí no SDK uma versão sem a última newline com apenas 95 caracteres). Como verão, usei dois incrementos ao D, porque a arvorezinha não coube em 40 caracteres de código. Ainda assim, foi necessário usar o próprio valor em 44, que é um < , para imprimir um caracter da árvore, e simultaneamente servir de input para o segundo “j”. Reparem:

./malbolgevalid 44 44
44:	037 (v)	054 (i)	055 (<)	073 (/)	089 (*)	090 (j)	112 (p)	118 (o)

O “< “, por coincidência a instrução de print, resulta no valor 55, bastante simpático para o novo início dos dados. Atenção que, na listagem que se segue, o nº de linha N corresponde à posição de memória N-1. Sem mais paleio, aqui vai:

j ; avançar dados para o 41
o ; estes nops são para diminuir o resultado do próximo j
o
o
j ; avançar ainda mais, para o 56
p ; calcular "*" com "pp" com os dados 56 e 57
p
< ; imprime-o
* ; agora calcula o "\n" com dados do 59 ao 61
p
p
< ; imprime-o
* ; calcula novamente "*"
p
p
< ; desta vez imprime dois
<
p ; calcula "\n" de novo e assim sucessivamente até completar a arvorezinha
p
<
p
p
<
<
<
p
p
<
*
p
p
<
<
<
<
p
p
<
p
p
< ; print dos últimos 5 asteriscos
< ; posição de dados usado no D=56, e simultaneamente faz um print ;-)
<
<
<
*
p
p
< ; printa "\n" no fim, como manda o RFC, seus batoteiros
v ; fim do código
o ; nops a encher choriço até começarem os dados úteis
o
o
o
o
o
j ; dados do cálculo do primeiro "*"
*
o ; nop para compensar o "<" desse "*"
i ; dados do cálculo do primeiro "\n"
p
i
o ; nop idem
i ; etc, dados dos cálculos até ao final
<
*
o
o
o
p
o
*
<
o
o
o
o
i
o
/
p
j
o
o
o
o
*
o
o
p
j
o
o
o
o
o
p
/
j

Rapidamente, a versão prêt-à-porter:

(CBA$98}54Xy10TS-,P*)MLK%$Hi!~DCBAyx>vu;:987Xnm3~ponmlkNLh'`%d##D`_^W>yYXWVsT&L5PONM/KJC,GFEDC<r$

E assim chegamos ao fim do post. Espero que tenham perdido tanto tempo a lê-lo como eu perdi a escrevê-lo. ;-) Feliz programação em malbolge!

Este post é dedicado à memória do fravia, o Deus do cracking, e do Vasco Granja, o Rei do lulz importado da antiga checoslováquia.