lunes, 21 de diciembre de 2009

pyCrawler 0.1 (Crawler en Python)

Esto es un ejemplo de como hacer un crawler (un script que va siguiendo los enlaces de las paginas web) escrito en python.

El proposito original del script era hacer mas sencillo el trabajo de moderacion de un sitio web, filtrando las imagenes (por url), textos, enlaces y titulos, a traves de una blacklist (nota: estas no traen por defecto ningun elemento, asi que hay que añadirlos a mano, en las lineas 170 y 171,implementadas como listas).

Lo que se hace al encontrar algo en la lista negra se define en la funcion Aviso (linea 16).

Como el proposito original era la moderacion, el script esta programado para no seguir ningun enlace fuera de ese sitio web (pero esto se puede cambiar facilmente).

Link: pyCrawler

Suerte y hasta otra.

jueves, 10 de diciembre de 2009

Jugando a Core Wars [2° Parte/2]

Sigamos con el Core Wars...
Resumiendo, lo que vimos hasta ahora fue:

    ;Comentarios
    ;name nombre del programa
    ;author autor
    MOV A,B ;Copia A en B
    ADD A,B  ;Añade A a B
    JMP A     ;Se salta la instruccion A
    DAT A,B ;Un espacio para datos

Formas de indicar una direccion:

-Inmediata, por de la posicion donde esta el valor, se indica con un '#'
-Directa, por la posicion actual, se representa con '$' (o sin nada)
-Indirecta, por el valor de la posicion indicada, se indica con un '*' si es el primer campo (A), o con '@' si es el segundo campo (B)

Pero hay mas formas de indicar una direccion de forma indirecta:

- La del campo A, restandole 1 antes, '{'
- La del campo B, restandole 1 antes, '<'
- La del campo A, sumandole 1 despues, '}'
- La del campo B, sumandole 1 despues, '>'

Por ejemplo, se podria modificar el programa "dwarf"

            ;name Dwarf
            ;author A. K. Dewdney
dwarf  ADD #4, bomb
           MOV   bomb, @bomb
           JMP    dwarf

bomb  DAT #0


Haciendo que llene todos los espacios de memoria 1 a 1, en vez de cuatro en cuatro, y de paso eliminamos una instruccion (con lo que el programa es mas rapido)


dwarf  MOV   bomb, >bomb
          JMP    dwarf

bomb  DAT #1


Veamos las diferencias, la primera es que ya no esta la instruccion ADD por que lo que hacia (cambiar el valor de "bomb" para evitar estar siempre "golpeando la misma zona")ahora lo hace el MOV.
La segunda es el campo B de la instruccion MOV incrementa el valor del campo B de "bomb" uno de cada vez (por el '>').
La ultima es que el valor al que apunta "bomb" al principio es el siguiente ('#1'), ya que al no haber ADD y a que el incremento es posterior, si fuera el mismo ('#0'), se sobreescribiria, algo totalmente inutil.

Ahora algo mas complejo... aunque no por ello util:

      SUB #7,inst ;Para reajustar el puntero de instruccion
      SUB #6,pos ; Esto tambien
      MOV >inst,>pos
      SEQ inst,inst+1 ;Aqui esta el problema XD
      JMP -2
      JMP -14 ;Al proximo paso
pos  DAT #-9
inst  DAT #0 ;Los valores que quedaran despues de copiarse a si mismos
       DAT #2

Como se puede ver aqui hay instrucciones nuevas:
-La primera es SUB (de substract, restar ), funciona igual que el ADD, pero en vez de sumar, resta (logicamente es igual que hacer ADD de un numero negativo)
-La otra es SEQ (skip if equal, saltar si es igual), compara las dos instucciones y si son iguales se salta la siguiente instruccion

Veamos que hace el codigo entonces :
El DAT con la etiqueta pos, indica la posicion a donde se va a copiar, y el de la etiqueta inst, la instruccion que se va a copiar.
El DAT siguiente al de inst tiene siempre el valor #2, esto servira para comprobar si se acabo de copiar todo el codigo.

-Resta 7 al DAT que indica la instruccion a copiar (para que apunte al principio del codigo)    [ SUB #7,inst ]
-Resta 6 al DAT que indica donde se copiara la instruccion (para que apunte a la proxima seccion donde se copiara) [ SUB #6,pos ]
-Copia la instruccion a la que apunta inst a la posicion que indica pos, y incrementa en 1 los dos (para que apunten al siguiente) [ MOV >inst,>pos ]
-Si inst es igual a lo que hay en la siguiente posicions, se salta la siguiente posicion [ SEQ inst,inst+1 ]
-Vuelve atras 2 instrucciones [ JMP -2 ]
-Vuelve atras 14 instrucciones (pasa al bucle siguiente) [ JMP -14 ]

Es decir, que se copia todo hacia atras, hasta que acaba y salta hacia atras, para continuar copiandose.La utilidad que tiene esto es poca, con un minimo cambio en cualquier parte del codigo que se este ejecutando, el programa falla.

Las opciones para cambiar el flujo del programa son:

-SEQ (explicado anteriormente)
-SNE (funciona al reves que SEQ) (Skip if Not Equal, saltar si no es igual)
-SLT (se salta la siguiente instruccion si el campo A es menor que el campo B) (Skip if Less Than, saltar si es menos de)

-JNZ, si el valor del campo A es distinto de 0, se salta a la posicion que indica el campo B (Jump if Not Zero, saltar si no es cero)
-JZ, como JZN, pero si el valor de A es 0 (Jump if Zero, saltar si es cero)
-DJN, como JNZ, pero decrementa previamente el valor de A (Decrement & Jump if Not zero, decrementar y saltar si no es cero)

-SPL, se crea un segundo proceso que empieza en la posicion indicada (Split, separar)

La unica que introduce algo nuevo es SPL, veamos un ejemplo:

    SPL 0
    MOV 0,1

- SPL 0, crea un proceso mas, que seguira en la misma instruccion (si, asi continuamente)- MOV 0,1 ... un clasico imp (como el primero de todo)

Lo que hace es generar muchos procesos, ejecutando todos el codigo del imp
Si lo ejecutamos veremos que aunque al principio el conjunto de imps avanzan relativamente rapido, poco a poco van mas lentos, esto es por la forma que hay de repartir el tiempo entre los procesos:

Durante el turno de cada programa se ejecuta un proceso suyo y este no se volvera a ejecutar hasta que lo hayan hecho el resto

Esto significa que cuantos mas procesos haya para el programa, mas habra que esperar para que se repita el mismo proceso (por esto y por otras cosas suele haber un limite de procesos por programa)

Ya no se me ocurre nada mas que pueda hacer falta para escribir un programa de Core Wars, asi que eso es todo por ahora.

Quien no tenga problemas con el ingles tiene un buen tutorial en [ http://vyznev.net/corewar/guide.html ]

Actualizacion: Uno mas ( este no lo explicare :)}, es bastante sencillo )

    ;name Code Runner
    ;author Kenkeiras

    ADD #4,3
    SPL >2
    JMP -2
    DAT #1,#1

Suerte

domingo, 6 de diciembre de 2009

Jugando a Core Wars [1° Parte/2]

Aqui veremos como funciona el juego Core wars, en el que hay que escribir un programa que intente eliminar a sus oponentes (para esto hay varios metodos... hacer que dividan por cero, que intenten ejecutar algo que no sea codigo,etc )

No voy a explicar como instalarlo, ya que hay muchos programas que sirven para jugar, puedes encontrar muchos aqui: http://homepages.paradise.net.nz/~anton/cw/corewar-faq.html#CoreWarSystems
En los repositorios de Ubuntu/Debian hay un paquete llamado corewars [ sudo apt-get install corewars ] que sirve perfectamente, pero es posible que despues no este en el menu, si es asi tendras que abrir un terminal y lanzar corewars

El lenguaje que se usa (llamado Redcode) es bastante parecido al Ensamblador, asi que aunque quien maneje este tendra mucho trabajo adelantado (se usan ADD's, MOV's, JMP's...), para est@s ultim@s hay que destacar que la sintaxis es mas parecida a la de AT&T que a la de Intel (por ejemplo en el ADD el primer argumento es la cantidad a añadir y la segunda donde se añadira), se explicara todo como si no se tuviera ninguna nocion de ensamblador.

Nota: desde ya mismo perdon por algunas licencias que me tomare para intentar hacer mas sencillo todo (como llamar "bytes" a las posiciones de memoria)

Como primer ejemplo utilizaremos el programa mas sencillo, llamado imp (de impulso):

    ;name Imp
    ;author Walter Hofmann

    mov 0,1

Si lo ejecutamos veremos que va llenando la memoria byte a byte (si se le puede llamar asi), uno de cada vez.

Veamos como es el codigo... lo que va despues de un ';' es un comentario (no tiene relevancia en el juego), algunos MARS (las maquinas virtuales donde suceden los "combates") buscan cierta informacion en los comentarios, por ejemplo los que despues de el ';' llevan la palabra "name", especifican el nombre del programa, y los que despues del ';' llevan "author", muestran el nombre del autor del programa.

Hasta ahora no paso nada que afectase a la "maquina" que ejecuta el programa, ahora viene lo divertido,el codigo MOV 0,1 copia la instruccion (MOV) que esta en la posicion 0 desde el codigo (el propio codigo) hasta la posicion 1 desde el codigo, la posicion de memoria siguiente, con lo que la instruccion se copia a la siguiente posicion y despues se ejecuta lo que haya en la siguiente posicion ( si, el mismo codigo otra vez ).

Para entenderlo mejor veamos rapidamente como funciona la maquina:

La memoria de la maquina es circular (no hay punto inicial ni final), es lineal (solo se puede ir hacia adelante o hacia atras) y es relativa (solo se puede especificar una posicion a partir de la actual, no se puede decir por ejemplo, la posicion 74).

El procesador de la maquina ejecuta una instruccion ( que siempre ocupan 1 "byte" ) y a menos que la instruccion implique un cambio en el flujo del programa (JMP, JNZ... ya se explicaran despues) a continuacion se ejecuta la siguiente, si no hay ninguna o la operacion no esta permitida (como una division por 0), el proceso "muere".

Entonces nustro ejemplo pasaria algo asi:

t=0

 ...
 ---------------
 | ???          |
 ---------------
 | MOV 0,1  | <- (Se va a ejecutar esto)
 ---------------
 | ???          |
 ---------------
 | ???          |
 ---------------

...


t=1 (despues de ejecutar la primera instruccion)


 ...

 --------------
 | ???         |
 --------------
 | MOV 0,1 |
 --------------
 | MOV 0,1 | <- (Se va a ejecutar esto)
 --------------
 | ???         |
 --------------
...


t=2 (despues de la segunda instruccion)


 ...

 --------------
 | ???         |
 --------------
 | MOV 0,1 |
 --------------
 | MOV 0,1 |
 --------------
 | MOV 0,1 | <- (Se va a ejecutar esto)
 --------------
 | ???         |
 --------------
 ...


Asi el programa va "haciendo el camino" y sigue hasta que algo lo detenga.

Ahora veamos algo un poco mas complejo.

            ;name Dwarf
            ;author A. K. Dewdney
dwarf  ADD #4, bomb
           MOV   bomb, @bomb
           JMP    dwarf

bomb  DAT #0

Aqui se introducen muchas mas posibilidades, empezando por esta:

bomb   DAT #0

Esto significa, hay un "byte" que no contiene ninguna instruccion, sino datos, y a esta posicion tiene la etiqueta "bomb" (para no tener que ver donde seria su direccion con cada nueva instruccion), su uso es bastante simple, si alguien intenta ejecutarlo el proceso falla, y se puede utilizar para almacenar datos (de ahi su nombre, DAT).

La segunda es:

dwarf  ADD #4, bomb

Un "byte" con la etiqueta "dwarf" y con la instruccion ADD, que añade el valor del primer argumento (en este caso 4), a lo que este en la segunda posicion (en este caso a lo que tiene la etiqueta "bomb" ).

Despues tenemos:

    MOV   bomb, @bomb

Como ya vimos en el primer ejemplo, la instruccion MOV copia lo que haya en el primer valor, en el segundo,pero en este caso el segundo valor se utiliza para indicar donde se va a copiar...me explico:

Hay tres grupos de formas de indicar una direccion, inmediata, directa e indirecta.

La inmediata es la que se toma partiendo de la posicion de donde se toma el valor, se indica con un '#' antes del valor (por ejemplo, el DAT o el primer valor del ADD).

La directa es la que se calcula partiendo de la posicion actual, se indica con un '$' o no añadiendo nada (por ejemplo, en el primer valor del MOV o en el JMP).

La indirecta, es la que se calcula partiendo de la posicion que indique el "byte" que se indique, dependiendo de si es el que indica el primero (campo A) o el segundo argumento (campo B) del "byte" se indican con un '*' o '@' respectivamente (se pueden hacer mas cosas, pero ya me estoy extendiendo demasiado por ahora)

Entonces     MOV   bomb, @bomb     copia lo que haya en la posicion "bomb" a donde apunte el campo B de "bomb".
Por ultimo...

          JMP  dwarf

La instruccion JMP salta a la posicion que se indique, en este caso la posicion con la etiqueta dwarf (el principio del codigo).
En resumen, lo que hace el codigo es:

- Añade 4 a la posicion que apunta "bomb"  (MOV #4,bomb)
- Copia "bomb" a la posicion que apunta (MOV bomb,@bomb)
- Vuelve al principio (JMP dwarf)

Asi que va llenando la memoria de DAT's, (si algun programa los intenta ejecutar falla), por ejemplo, contra un imp, podria ocurrir esto.

t=0
...
 ---------------
 | MOV 0,1  |
 ---------------
 | MOV 0,1  | <- (Se va a ejecutar esto)
 ---------------
 | ???          |
 ---------------
 | ???          |
 ---------------
...

t=1 (cuando el imp se copia a la siguiente posicion, y en el mismo "turno" el "bomb" del programa anterior se copia a la misma posicion)

...                                                          ...
 ---------------                                       ----------------
 | MOV 0,1  |                                        | MOV 0,1  |
 ---------------                                       ----------------
 | MOV 0,1  |                                        | MOV 0,1  |
 ---------------                          =>         -----------------
 | MOV 0,1  | <-  (Se va a ejecutar)    | DAT         | <-
 ---------------                                       ------------------ 
 | ???          |                                        | ???          |
 ---------------                                       -----------------
...                                                        ...

Esto es todo por ahora... hay una guia bastante completa en [http://vyznev.net/corewar/guide.html]

Suerte

jueves, 3 de diciembre de 2009

Manifiesto en defensa de los derechos fundamentales en internet

Ante la inclusión en el Anteproyecto de Ley de Economía sostenible de modificaciones legislativas que afectan al libre ejercicio de las libertades de expresión, información y el derecho de acceso a la cultura a través de Internet, los periodistas, bloggers, usuarios, profesionales y creadores de internet manifestamos nuestra firme oposición al proyecto, y declaramos que...
1.- Los derechos de autor no pueden situarse por encima de los derechos fundamentales de los ciudadanos, como el derecho a la privacidad, a la seguridad, a la presunción de inocencia, a la tutela judicial efectiva y a la libertad de expresión. 2.- La suspensión de derechos fundamentales es y debe seguir siendo competencia exclusiva del poder judicial. Ni un cierre sin sentencia. Este anteproyecto, en contra de lo establecido en el artículo 20.5 de la Constitución, pone en manos de un órgano no judicial -un organismo dependiente del ministerio de Cultura-, la potestad de impedir a los ciudadanos españoles el acceso a cualquier página web.
3.- La nueva legislación creará inseguridad jurídica en todo el sector tecnológico español, perjudicando uno de los pocos campos de desarrollo y futuro de nuestra economía, entorpeciendo la creación de empresas, introduciendo trabas a la libre competencia y ralentizando su proyección internacional.
4.- La nueva legislación propuesta amenaza a los nuevos creadores y entorpece la creación cultural. Con Internet y los sucesivos avances tecnológicos se ha democratizado extraordinariamente la creación y emisión de contenidos de todo tipo, que ya no provienen prevalentemente de las industrias culturales tradicionales, sino de multitud de fuentes diferentes.
5.- Los autores, como todos los trabajadores, tienen derecho a vivir de su trabajo con nuevas ideas creativas, modelos de negocio y actividades asociadas a sus creaciones. Intentar sostener con cambios legislativos a una industria obsoleta que no sabe adaptarse a este nuevo entorno no es ni justo ni realista. Si su modelo de negocio se basaba en el control de las copias de las obras y en Internet no es posible sin vulnerar derechos fundamentales, deberían buscar otro modelo.
6.- Consideramos que las industrias culturales necesitan para sobrevivir alternativas modernas, eficaces, creíbles y asequibles y que se adecuen a los nuevos usos sociales, en lugar de limitaciones tan desproporcionadas como ineficaces para el fin que dicen perseguir.
7.- Internet debe funcionar de forma libre y sin interferencias políticas auspiciadas por sectores que pretenden perpetuar obsoletos modelos de negocio e imposibilitar que el saber humano siga siendo libre.
8.- Exigimos que el Gobierno garantice por ley la neutralidad de la Red en España, ante cualquier presión que pueda producirse, como marco para el desarrollo de una economía sostenible y realista de cara al futuro.
9.- Proponemos una verdadera reforma del derecho de propiedad intelectual orientada a su fin: devolver a la sociedad el conocimiento, promover el dominio público y limitar los abusos de las entidades gestoras.
10.- En democracia las leyes y sus modificaciones deben aprobarse tras el oportuno debate público y habiendo consultado previamente a todas las partes implicadas. No es de recibo que se realicen cambios legislativos que afectan a derechos fundamentales en una ley no orgánica y que versa sobre otra materia.

Este manifiesto es obra de muchas manos, y propiedad de todos. Si te gusta, cópialo, pásalo, publícalo en tu weblog o haz lo que quieras con él.

viernes, 27 de noviembre de 2009

Como hacer las imagenes que ponen ip, navegador...

Para esto necesitaremos un servidor HTTP ( como apache ) y PHP, las dos cosas es lo tipico que se encuentra en un hosting gratuito ( aqui hay una lista )

Si lo vamos a alojar nosotros mismos necesitaremos habilitar el paquete php-gd para esto edita el php.ini, descomenta la linea de ";extension=php_gd2.dll" (quitale el ';'... en algunos casos es un '#')
En debian/ubuntu se hace con "sudo apt-get install php5-gd"

Vamos alla...

Buscamos una imagen, la imagen sera la base, conviene que sea lo mas uniforme posible para que quede bien, yo escogi esta, aun que no sea la mas apropiada



Preparamos el codigo en PHP

El siguiente codigo es el que escribira en la imagen


<?php
 // Escrito por Kenkeiras

function navegador($ua){ // Devuelve el navegador ...bastante simple ;)
 $nav="";
 if (strstr($ua,"Firefox"))
  $nav="Firefox";
 elseif (strstr($ua,"MSIE 6"))
  $nav="IExplorer 6";
 elseif (strstr($ua,"MSIE 7"))
  $nav="IExplorer 7";
 elseif (strstr($ua,"MSIE 8"))
  $nav="IExplorer 8";
 elseif (strstr($ua,"Opera"))
  $nav="Opera";
 elseif (strstr($ua,"Safari"))
  $nav="Safari";
 return $nav;
}
function os($ua){ // lo mismo, pero para el SO
 $os="";
 if (strstr($ua,"Linux"))
  $os="Linux";
 elseif (strstr($ua,"Windows"))
  $os="Windows";
 elseif (strstr($ua,"Mac"))
  $os="Mac";
 return $os;
}

$back="esfera.png";     //Imagen de fondo

$img=imagecreatefrompng($back);   //Se crea la imagen (desde un png)

$fcolor=ImageColorAllocate($img,255,120,0); // El color de las letras ($img,r,g,b)

// Ejemplo: ImageString($img,Tamaño de letra,Longitud,Altura,"Texto",$fcolor);

$ip=$_SERVER['REMOTE_ADDR'];    //La ip esta en la variable $_SERVER['REMOTE_ADDR']

ImageString($img,5,65,75,"IP: $ip",$fcolor); // Escribimos la IP en la imagen
$lang=$_SERVER['HTTP_ACCEPT_LANGUAGE'];
$i=stripos($lang,";");
if ($i)
 $lang=substr($lang,0,$i);
if ($lang!="")
 ImageString($img,5,50,100,"Lenguaje: $lang",$fcolor); 
$ua=$_SERVER['HTTP_USER_AGENT'];
$os=os($ua);
$nav=navegador($ua);
if ($nav!="")
 ImageString($img,5,40,125,"Navegador: $nav",$fcolor);
if ($os!="")
 ImageString($img,5,35,150,"Sistema Operativo: $os",$fcolor);
// ----------------
Header("Content-Type: image/png");  // Avisamos que es una imagen png
ImagePNG($img);             // Convertimos a png

//Si prefieres un JPEG cambia las dos ultimas lineas por

//Header("Content-Type: image/jpeg");

//ImageJPEG($img);

// ----------------

ImageDestroy($img);    // Liberamos el espacio

?> 

Como funciona? (Para l@s que no les guste leer los comentarios del codigo)

Se usan dos funciones (navegador y os), que buscan en la cadena del "User-Agent", alguna parte conocida (Firefox, MSIE, etc...), y que devuelven el navegador y el sistema operativo del usuario

El resto es PHP,

$back="esfera.png"; //Imagen de fondo
$img=imagecreatefrompng($back); //Se crea la imagen (desde un png)

Como indican los comentarios, la primera linea es saber donde esta la imagen base, la segunda es para importarla como PNG, tambien se puede hacer para jpg

imagecreatefromjpeg

o con gif

imagecreatefromgif

(aqui hay mas funciones parecidas: http://us3.php.net/manual-lookup.php?pattern=imageCreateFrom&lang=es)

$fcolor=ImageColorAllocate($img,255,120,0); // El color de las letras ($img,r,g,b)

Prepara el color de las letras en la imagen (recuerda que la imagen esta en $img), el color se asigna en rgb, de 0 a 255 (esta combinacion, "255,120,0", seria naranja)

$ip=$_SERVER['REMOTE_ADDR']; //La ip esta en la variable

Guarda la ip (que esta en la variable $_SERVER['REMOTE_ADDR'])

ImageString($img,5,65,75,"IP: $ip",$fcolor);

Escribe en la imagen, con tamaño de letra 5, desde el pixel 65 (horizontal) y el 75 (vertical), la cadena "IP: $ip",en el color $fcolor

El resto es hacer lo mismo con lo que nos interesa (lenguaje, navegador,etc...)

Y despues

Header("Content-Type: image/png"); // Avisamos que es una imagen png

Avisamos al navegador para que reconozca lo que viene ahora como una imagen png (si es jpg, habria que poner "image/png")

Y los dos ultimos pasos

ImagePNG($img); // Convertimos a png
ImageDestroy($img); // Liberamos el espacio

Resultado:



Suerte y hasta otra

lunes, 23 de noviembre de 2009

Un par de scripts perl

Uno para lanzar comandos de consola/programas como daemon (se usa como el comando time ):
./daemonize.pl [comando]
Por ejemplo, si queremos hacer un ./configure;make;make install...
./daemonize.pl "./configure;make;make install"
Daemonize

Y otro para extraer los elinks de una pagina web y pasarlos al aMule ( via comando ed2k ), con cambiar la funcion link_mngr , se puede adaptar para links http, o para usar otro comando: 
getMule

Suerte

jueves, 19 de noviembre de 2009

Y... empezamos fuerte

Con un programa para distribuir el aircrack... no esta acabado del todo, no distribuye los archivos .cap (hay que hacerlo a mano) ni soporta el uso de diccionarios, pero por lo demas funciona perfectamente.

Solo hay que hacer make;make install

Descargar

Suerte y hasta otra.

Hola Mundo!

Pues aqui empieza este blog dedicado a algunos experimentos de programacion y demas cosas que puedan parecer utiles.

Suerte y hasta otra