SET 39 Call For Papers

¿Eres un hacker? Si deseas pasar a formar parte de la historia del hacking hispano, colabora con la próxima edición de SET 39 enviándonos un artículo. No esperes más, esta es tu oportunidad de demostrar lo que sabes. Ayúdanos a construir una revista de hackers para hackers. SET Staff

SET 16

60414 visitas

Cracking bajo Linux

      3312

Autor: SiuL+Hacky
-[ 0x0A ]--------------------------------------------------------------------
-[ CRACKING BAJO LINUX]------------------------------------------------------
-[ by SiuL+Hacky ]----------------------------------------------------SET-16-



Hola a todos, queria desde aqui agradecer a El Paseante (y en general a la
gente de SET) la invitacion para escribir en el ezine y cubrir un poco la
carencia de contenidos sobre cracking que tenia ultimamente.

Como hay mucho hacker por aqui suelto :-), aclaro que es cracking referido a
la modificacion de programas, bien porque tienen alguna funcionalidad (o
todas) deshabilitada o porque simplemente quieres que se ajuste a tus
preferencias. Dicho asi no suena tan mal, pero lo cierto es que los crackers
no suelen estar tan bien vistos como los hackers :-(.
Como siempre la informacion no es buena ni mala, tan solo depende del uso
que se haga de ella. Yo no tengo el menor interes economico en desproteger un
programa, es mas, la mayoria de ellos no son tan interesantes como para luego
usarlos :-).

INTRODUCCION ------------------------------------------------------------

He intentado que el nivel sea lo suficientemente asequible, como para que
cualquiera con interes puede engancharse facilmente (estaria bien que los
que ya saben no se duerman).
Aun asi es inevitable dar por supuestas determinadas cosas (aparte de un PC);
en este caso es imprescindible tener un cierto manejo con el ensamblador x86.
El que sea perezoso, que se mentalice ya que sin saber ensamblador no
crackeara ni el software de Micro$oft. En Internet hay cientos de
cursos/manuales sobre  ensamblador.
Conocimientos de programacion en C tampoco estaria mal :-) y un poco de
paciencia al principio, tambien.

Aunque las tecnicas basicas son mas o menos universales, este articulo (y los
que pudieran seguir) estan orientados a programas bajo Linux. Ademas de no
tener que salir de nuestro entorno favorito, hay otras razones:

1) Es el futuro. A pesar de que linux se sigue moviendo en torno a programas
basados en licencia GNU, cada vez hay mas empresas de software que empiezan a
ver linux como un mercado interesante, y por ello el numero de aplicaciones
comerciales va a crecer enormemente en los proximos a¤os. No se cuanto
durara lo de que las distribuciones quepan en un CD.

2) Carencia de informacion. Mientras que los tutoriales y las herramientas
disponibles para el entorno Windows son muy abundantes, para linux es
practicamente inexistente (en parte porque en programas GNU no tenia mucho
sentido). Me voy a basar para ello en una serie de articulos que empece hace
un a¤o en la pagina de +Fravia.

3) Para que cada vez tengais menos excusas los que no usais linux :-).

Si alguien quiere informacion mas avanzada (tanto para Win como para linux,
eso si, en ingles), consultad, por ejemplo, la pagina de +Fravia: 

http://www.fravia.org

FUNDAMENTOS -------------------------------------------------------------

El cracking se basa en analizar mediante Ingenieria Inversa las condiciones
que han llevado a un programa a tomar un camino en vez de otro, por ejemplo,
las condiciones que le han llevado a mostrar por pantalla el mensaje de
"Este codigo de registro no es valido". Aunque todo puede estar mas o menos
enmascarado, al final el analisis te lleva a puntos de bifurcacion, que en el
caso de codigos de registro viene a ser algo como:


              push offset(cadena_codigo)
              call check_code
              cmp eax, 0
              je buen_chico
              jmp chico_malo
chico_malo:   call salir
buen_chico:   call continuar_programa

        
que en C, equivaldria a una declaracion mas o menos asi

int check_code(char* cadena_codigo);

El parametro, para el que no lo sepa, se pasa por la pila, la funcion
check_code lo recibira y el valor de la funcion se devuelve siempre en el
registro eax. En un caso como este devolveria 0 si el codigo es bueno, y -1
si es malo (vereis que siempre es bueno conocer la forma en que los
compiladores generan el codigo). Variaciones sobre esto hay muchas, pero
valga como ejemplo sencillo. Fijaros que modificando el primero de los saltos
condicionales, de forma que se convierta en un salto incondicional, dara por
buenos todos los codigos; tan sencillo como eso. Otra posibilidad es analizar
el codigo de la funcion check_code, e ir viendo como se manipula la cadena de
texto, de tal forma que seamos capaces de comprender que caracteristicas debe
tener para ser considerado un "buen codigo". A pesar de su simplicidad,
protecciones de este tipo es la que utilizaban el 95% de las protecciones con
codigos de registro.
Actualmente, sigun habiendo protecciones tan simples, pero empiezan a
aparecer otras mas sofisticadas, que en principio se basan en cosas sencillas,
pero aplican metodos que dificultan su analisis (mas al ver herramientas
genericas).


HERRAMIENTAS BASICAS  ------------------------------------------------------

1. DEPURADOR:

Aunque luego hablaremos de las tecnicas, exiten dos tipos fundamentales de
abordar el analisis de un programa: el analisis "en vivo" y el analisis
basado en listados.
Para el analisis en vivo, es necesario utilizar un depurador, que supongo
todo el mundo sabra lo que es, pero recordemos que permite ejecutar un
programa bajo su control, modificar el flujo de ejecucion, acceder a su
espacio de datos, acceder a los registros del procesador, etc ...
Excepto el viejo debug del DOS, la mayoria de los depuradores permiten
depurar codigo fuente, pero dado que las aplicaciones comerciales no suelen
acompa¤ar el codigo fuente, no queda otra opcion que depurar a nivel de
ensamblador.

Debido a que cualquier programa ejecuta millones de instrucciones
(instrucciones maquina), si no quereis acabar ingresados en un sanatorio, es
necesario acceder al codigo significativo donde reside el esquema de
proteccion, y desechar el resto.
Para ello se utilizan puntos de ruptura que detienen la ejecucion de un
programa bajo determinadas circunstancias. Los puntos de ruptura tradicionales se
insertan en una direccion del codigo, deteniendolo y cediendo el control al
depurador. Afortunadamente a partir del 80386 se introdujeron facilidades de
depurado por el propio hardware que permiten detener un programa cuando se
lee/escribe en una determinada posicion de memoria. Aparte de esta facilidad
el propio depurador suele permitir que el programador a¤ada una serie de
condiciones adicionales para detener el codigo. Estas condiciones son del
tipo de las que se pueden expresar con una setencia "if" en C. Por ejemplo;

puntoruptura_memoria_escritura 30:8a362346 if (ebx==3)

de esta forma el programa se detiene al modificar la posicion de memoria
30:8a362346 y siempre que el registro ebx sea igual a 3. Parte del secreto del
analisis en vivo es saber seleccionar adecuadamente los puntos de ruptura.
Cuando analicemos tecnicas basicas veremos que puntos de ruptura son
interesantes en cada momento.

Algunos programas utilizan tecnicas que dificultan su analisis mediante un
depurador. Algunas de estas tecnicas serian:

1) Intentar detectar la presencia en memoria del depurador.

2) Utilizar su propio gestor de modo protegido. De esta forma la aplicacion se
convierte en due¤a de la maquina y no se puede depurar mas que en un emulador
software de CPU (olvidaos de esa posibilidad :-). Esto solo vale para MSDOS,
ya que bajo linux o bajo Windows, las aplicaciones no acceden directamente a
los recursos hardware ( o casi ) y dependen del SO para ello.

3) La interrupcion que posibilita los puntos de ruptura es la int 03. Un
programa que redirija esta interrupcion para su uso propio, interferiria con
el depurador. En los procesadores 386+ esto se supera ya que se puede detener
la ejecucion de un programa por hardware.

4) Al utilizar puntos de ruptura convencionales el depurador, modifica (de
forma transparente al usuario) el codigo del programa, insertando
instrucciones int 03 en sustitucion de instrucciones originales del programa
(que luego se recolocaran cuando llegue el momento). Dicho de otra forma,
contaminan el codigo del programa, siendo esto detectable por una rutina que
lea su propio codigo por ejemplo.


2. DESENSAMBLADOR

Una alternativa mucho mas elegante (y en mi opinion mas relajada) es el
analisis de listados de ensamblador. Analizar un listado en ensamblador de un
programa Windows ( o XWindows ) puede ser aparentemente monstruoso, dado que
se generan ficheros de texto de hasta 60 Mb, pero en determinados programas
(como los de Windows o los de Linux), es sencillo encontrar indicios que
ayuden a acotar donde reside la rutina de proteccion. Estos indicios suelen
venir en forma de cadenas de texto, como mensajes de error, mensajes de que
la version que ejecutamos no esta registrada, etc ...

La potencia de un desensamblador radica, aparte de su velocidad, en saber
establecer referencias cruzadas de codigo y datos.
Referencias cruzadas de codigo y datos? Bueno, eso quiere decir indicar en
cada instruccion QUE OTRAS instrucciones la referencian con instrucciones
call o jmp.
Y las referencias de datos consisten en que una vez localizadas las cadenas
de texto, se busquen las instrucciones que las referencian. Esto tanto en
linux como en Windows es relativamente sencillo de hacer.

Otra de las cosas que facilita el analisis de listados, es que tanto linux
como Windows utilizan gran cantidad de llamadas a librerias dinamicas. Estas
llamadas no pueden enmascararse (ya que el lincador dinamico debe
identificarlas) y estareis de acuerdo en que es mucho mas util ver
"call printf" que ver "call 383763".

Como opcion anti-desensamblado, no hay mas que encriptar/comprimir el codigo
de un programa, de forma que se desencripte/descomprima en tiempo de
ejecucion.


3. EDITOR HEXADECIMAL

Bueno una vez que se ha localizado la zona de interes, queda modificar el
ejecutable y para ello hace falta un editor hexadecimal donde buscar cadenas
binarias. Si ademas el editor es capaz de interpretar el codigo binario como
instrucciones en ensamblador, pues la leche, ya que se puede editar el fichero
introduciendo los nuevos mnemonicos directamente.


TECNICAS BASICAS -------------------------------------------------------------

Esta seccion pretende ser un peque¤o resumen de tecnicas que se utilizan y se
han utilizado desde los tiempos del MS-DOS. No pretende ser en ningun caso un
recetario de metodos para crackear, sino simplemente ideas para que la gente
que empieza, entienda un poco como va el juego y a partir de ahi desarrolle
sus propio metodos.

Yo empece crackeando juegos en MSDOS (de los que cabian en un diskette,
tiempos gloriosos aquellos), y se utilizaba fundamentalmente un depurador
(TurboDebugger). Entonces era muy util fijar puntos de ruptura de atencion a
la interrupcion de teclado (o del raton en su caso), y a partir de ahi
examinar que es lo que hacia el programa con los datos que se le iban
introduciendo.
Una vez localizado el punto "caliente" no habia mas que parchear el ejecutable.
Sin embargo cuando el programa se encontraba comprimido, era necesario
acceder al codigo una vez que este se habia autodescomprimido en memoria.
La opcion en ese caso era crear un parcheador residente que se activara en el
momento preciso.
Esta opcion con SS.OO. en modo protegido se complica, ya que las aplicaciones
tienen su espacio privado de direcciones, pero no es imposible.

Cuando los programas leian entradas de teclado mediante bucles de espera,
utilizar un depurador para detener el programa en el bucle de espera te
llevaba directamente a las rutinas que trataban la clave recien introducida, y
asi podian ver todas las perrerias que le iban haciendo a tu codigo hasta que
te acababan dicendo que lo volvieras a intentar. En cada sistemas operativo
hay un forma mas o menos estandar de leer las entradas de teclado. Este debe
ser otro punto de comienzo en el analisis en vivo. Si los programas estan
hechos en c++, el codigo que generan es mastodontico y desde que se lee una
entrada de usuario hasta que se procesa, pueden ejecutarse cientos de miles
de instrucciones. Es preciso entonces capturar donde se almacenan en primera
instancia los datos introducidos por el usuario, y utilizar un punto de
ruptura de lectura en memoria (sobre la direccion en memoria donde se ha
almacenado tu entrada) para identificar donde retoma el programa el
"tratamiento" de los datos recien introducidos.

Era la epoca de los buenos juegos y la escasez de aplicaciones comerciales.
Con la llegada de Windows95 se produce la explosion de aplicaciones shareware.
Los programas se presentan entoces con funcionalidades deshabilitadas
permanentemente, funcionalidades que se pueden "despertar" introduciendo un
codigo de registro, programas que caducan, pantallas de recuerdo, etc ...

La caracteristica fundamental de todas estas aplicaciones es que se
caracterizan por dar evidentes pistas para diferenciar un programa registrado
de uno no registrado. 

1) Las ventanas de recuerdo, cuyo texto puede ser luego localizado en el
fichero desensamblado, o bien la funcion que se utiliza para generar esas
ventanas (funcion MessageBox en el caso de Windows, por ejemplo, o printf en
el caso de linux).
2) Palabras que aparecen como: "Registered version", "Unregistered",
"Registered to:".
3) Pantallas de error cuando se introduce un codigo erroneo.
4) Textos de agradecimiento por haberse registrado

Todos estas circunstancias son pistas por donde empezar a buscar en un
analisis de listados, y ver que circunstancias llevan a un programa a seguir
esa linea y no otra. En algunas ocasiones, la parte del codigo que lleva la
proteccion no es encuentra en ejecutable principal, sino en una libreria
asociada.

En el caso de los programas que caducan, cuentan con un problema dificil de
ocultar, y que en mi opinion los hace muy vulnerables: de alguna forma
tienen que conocer la fecha actual. Su otra gran limitacion es tener que
almacenar de forma mas o menos discreta la fecha en que fueron instalados.
Igual que para las entradas de teclado, en cada SO hay funciones
preestablecidas que los programas suelen utilizar para leer la fecha del
sistema, siendo ese un punto a partir del cual se puede empezar.

Con la aparicion de nuevas herramientas de analisis las posibilidades se
multiplican, pero eso lo veremos en proximas entregas. Aparte de los
conocimientos de programacion, que ya he comentado son muy importantes, hay
que conocer algo del funcionamiento del sistema operativo en que se ejecutan,
por ejemplo:

1) En cracking de DOS, es necesario conocer los servicios que proporcionan
   las llamadas a la interrupcion 0x21, la interrupcion 0x10 y otras.
2) En Windows hay que conocer que es el API de Windows, funciones mas
   utilizadas, etc ...
3) En Linux saber lo que son las llamadas al sistema, lo que son la
   librerias dinamicas, como va lo de XWindows ...


HERRAMIENTAS EN LINUX -----------------------------------------------------

Hasta ahora hemos tratado temas genericos, pero a partir de ahora nos vamos a
dedicar en exclusiva a linux por las razones que ya he comentado anteriormente.
En este primer articulo para que no se alargue demasiado la cosa, solo voy a
presentar las herramientas basicas: depurador, desensamblador y editor
hexadecimal.

1. DEPURADOR: Gdb, Xgdb y DDD

Gdb es practicamente el unico depurador existente en linux. Tiene licencia GNU,
y ofrece unas facilidades similares a las que puedan ofrecer depuradores en
otros sistemas operativos. El handicap, como ocurre con muchos programas de
linux, es que su interfaz de usuario no es excesivamente amigable. Esto se
compensa con programas como Xgdb o DDD, que en si no son mas que un interfaz
grafico basado en gdb, con lo cual se a¤aden ventanas, botones y todas esas
cosas que tanto le gustan a algunos. La verdad es que estos depuradores estan
muy orientados a depuracion con codigo fuente, pero la cosa ha mejorado algo
ultimamente.

Para suavizar un poco la curva de aprendizaje, yo os aconsejaria que
utilizarais DDD, y luego fuerais aprendiendo los comandos que estan detras de
pulsar tal o cual boton. Os recomiendo la version 2.2.3, aunque la 3.0 ya esta
disponible, no he tenido ocasion de utilizarla. DDD cuenta con una ventana de
comandos, que es equivalente a la ventana original del gdb, con lo cual se
pueden introducir comandos gdb directamente. El gran avance, en mi opinion,
que se produce con el DDD es un ventana en la que muestra el codigo en
ensamblador que se esta ejecutando, y sobre esa ventana se pueden fijar
puntos de ruptura.
Tambien es util desplegar la ventana en la que se muestran los registros del
procesador. Lo unico que se echa en falta es una ventana en la que se vuelquen
datos en memoria.

Vamos a ver los comandos mas utiles y luego el que quiera jugar con los
botones y los menus, pues que juegue :-). Entre parentesis figura la
abreviatura de cada comando (que tambien funciona) Como era de esperar el
programa se detiene con la famosa Control-C. Entre corchetes figuran las
cosas que son opcionales:

run(r)
	Ejecuta el programa desde cero
cont
	Continua la ejecucion de un programa detenido por un punto de rupt.
stepi(si)
	Ejecuta la siguiente instruccion en ensamblador y se detiene
nexti(ni)
	idem a la anterior, pero no entra dentro de las rutinas call
finish
	Ejecuta el programa hasta que finaliza la funcion actual (hasta que
	encuentra una intruccion "ret")
breakpoint(br) *direccion_de_memoria [if condicion]
	Fija un punto de ruptura en direccion_de_memoria, con lo que el
	programa se detendra al ejecutar la instruccion en esa posicion
tbreakpoint(tbr) *direccion_de_memoria [if condicion]
	Fija un punto de ruptura que solo se usa una vez
commands numero_de_un_breakpoint
	Permite ejecutar cualquier comando gdb cuando un programa se
	detiene. El ultimo comando debe ser siempre "end"
del [numero_de_un_breakpoint]
        Borra un punto de ruptura, o todos si no se especifica ninguno.
awatch *direccion de memoria
	Detiene el programa cuando se lee o escribe en la direccion de
	memoria indicada
x [/s] [/x] [/10x] direccion_de_memoria
	Muestra el contenido de la direccion_de_memoria, y lo interpreta
	como un numero hexadecimal(/x), una cadena de texto(/s). Se pueden
	visualizar tambien las posiciones contiguas, por ejemplo, visualizar
        el contenido de direccion_de_memoria y los 10 bytes siguientes(/10x)
info [breakpoints] [regis]
	Da informacion de los puntos de ruptura existentes, de los registros
help [comando]
	Da informacion de un comando en concreto
	
Hay muchas mas opciones y subopciones siempre interesantes y que podeis
consultar en la pagina info del gdb. Gdb viene en cualquier distribucion de
linux, y DDD lo podeis encontrar en :

http://www.cs.tu-bs.de/softech/ddd/


2. DESENSAMBLADOR: objdump, dasm, IDA

Un buen desensamblador deberia no solamente convertir codigo binario a
mnemonicos de ensamblador, deberia analizar las referencias cruzadas.
objdump es una de las utilidades binarias que vienen con el compilador gcc.
Extrae informacion sobre ficheros ejecutables y una de las opciones crea un
listado en ensamblador, pero un listado sin ningun tipo de referencias
cruzadas.
Cualquiera que tenga una distribucion de linux, tiene acceso a objdump.

Dado que no existia ninguna alternativa seria a objdump, decidi programar un
script en perl que analizara las referencias a los saltos, las referencias a
las funciones que figuren en la tabla de simbolos y las referencias a las 
cadenas de texto. Esta informacion se a¤ade al listado original que genera
objdump. El resultado es un listado con toda la informacion util para analizar
un programa.

Recientemente un conocido desensamblador, IDA (Interactive Disassembler)
soporta ficheros ELF-32. Este es un desensamblador mucho mas complejo
(y lento) que objdump, ya que tiene una orientacion completamente distinta.
La idea es que la informacion generada por IDA pueda ser utilizada
directamente para ensamblarla, editarla si es preciso y obtener un ejecutable.
El problema es que, que yo sepa, IDA no esta disponible para linux. Esta la
opcion de ejecutarlo bajo el dosemu, pero en ficheros medianamente grandes
suele cascar.

Os ofrezco a continuacion el codigo de dasm, el script en perl que he
comentado antes, no teneis mas que "cortarlo" y salvarlo en un fichero
(dadle permisos de ejecucion !!!! :-) :

<++> set_016/articulos/dasm.pl
#!/usr/bin/perl
;############ MODIFICAD ESTA LINEA CON EL PATH ADECUADO ############
push(@INC,"/usr/lib/perl5");
require("flush.pl");


;##################################################################
;######## LINUX DISASSEMBLER 2.1
;######## (C) SiuL+Hacky Ago 1998
;######## Puedes copiar, modificar y distribuir este programa
;######## y es cosa tuya el mantener esta cabecera
;######## Uso: dasm exe_file dasm_file
;##################################################################


$f_input=$ARGV[0];
$f_output=$ARGV[1];
&printflush(STDOUT, "\nCreating disassembled file ...");
$return=system("objdump -d -T -x --prefix-addresses ".$f_input.">".$f_output."2");
if ($return!=0){
  print "\nERROR OPENING OBJDUMP $return";
  print "\nUsage: dasm exe_file dasm_file";
  print "\nBe sure to get objdump in your path. Check also file permissions\n";
  exit(1);
 }

open(INPUT, "<".$f_output."2");

&printflush(STDOUT, "\nReading strings ...");
$_=<INPUT>;
while (!/.rodata/){
  $_=<INPUT>;
}
($rubbish, $rest)=split(/.rodata/,$_,2);
($rubbish, $rest)=split(/0/,$rest,2);
@numbers=split(/  /,$rest,5);
$size=hex($numbers[0]);
$starting_address=hex($numbers[1]);
$end_address=$starting_address+$size;
$offset=hex($numbers[3]);
open(CODIGO, "<".$f_input);
seek(CODIGO,$offset,0);
read(CODIGO,$cadena,$size);
close(CODIGO);


$_=<INPUT>;
while (!/SYMBOL TABLE/){
  $_=<INPUT>;
}
&printflush(STDOUT, "\nProcessing symbol table ...");
$_=<INPUT>;
while (!/^\n/){
 @st_element=split(/ /, $_);
 $_=$st_element[$#st_element];
 chop;
 $symbol_table{$st_element[0]}=$_;
 $_=<INPUT>;
}


while (!/\.text/){
  $_=<INPUT>;
}
&printflush(STDOUT,  "\nProcessing jmps and calls ...");

######### la regex se desecha de la informacion de linea #############


while (<INPUT>){
  $_=~ s/<.*?>//g;
  $_=~s/  / /g;
  if (/j/){
    ($direccion,$inst,$destino)=split(/ /,$_,3);
    $destino=~s/ //g;
    chomp($destino);
    $salto{$destino}.=($direccion." \; ");
  }
  elsif (/call/){
    ($direccion,$inst,$destino)=split(/ /,$_,3);
    $destino=~s/ //g;
    chomp($destino);
    $call{$destino}.=($direccion." \; ");
  }
}

seek(INPUT,0,0);
&printflush(STDOUT, "\nWritting references ...\n");
open(OUTPUT, ">".$f_output) || die print "\nError opening write file\n";
print OUTPUT "FILE REFERENCED\n\n";

while (!/Disassembly of section .text:/){
 $_=<INPUT>;
 print OUTPUT;
}
$char=".";
$counter=0;
while(<INPUT>){
 $counter++;
 if ( ($counter % 400)==0){
   printflush(STDOUT,$char);
   if ( ($counter % 4000)==0){
     printflush(STDOUT,"\r");
     if ($char eq "."){ $char=" ";}
     else { $char=".";}
   }  
 }
 $copia=$_;
 $_=~s/<.*?>//ge;
 $_=~s/  / /g;
 ($direccion, $inst, $destino)=split(/ /,$_,3);
 if ( defined( $symbol_table{$direccion} )){
   print OUTPUT "\n";
   print OUTPUT "---- Function : ".$symbol_table{$direccion}." ----\n";
 }
 if (/call/){
   $destino=~s/ //g;
   chomp($destino);
   if ( defined( $symbol_table{$destino} )){
     print OUTPUT "\n";
     print OUTPUT "Reference to function : ".$symbol_table{$destino}."\n\n";
   }
 }  
 if ( defined( $salto{$direccion} )){
   print OUTPUT "\n";
   print OUTPUT "Referenced from jump at ".$salto{$direccion}."\n\n";
 }
 if ( defined( $call{$direccion} )){
   print OUTPUT "\n";
   print OUTPUT "Referenced from call at ".$call{$direccion}."\n\n";
 }
 if (/\$/){
        ($instruccion, $operand)=split(/\$/,$_,2);
        if (!/push/){
          ($operand, $rest)=split(/\,/,$operand,2);
        }
        chomp($operand);
        $offset=hex($operand);
        if ( ($offset <= $end_address) && ($offset >= $starting_address ) ){
          $auxiliar=substr($cadena, $offset-$starting_address);
          $length=index($auxiliar, pack("x") );
          $auxiliar=substr($auxiliar, 0, $length);       
          $auxiliar=~s/\n//g;
          print OUTPUT "\n";
          print OUTPUT "Possible reference to string:";
          print OUTPUT "\n\"$auxiliar\"\n\n"
        }       
  }
 print OUTPUT $copia;
}
close(INPUT);
close(OUTPUT);
print "\n";
system("rm ".$f_output."2");
<-->

3. EDITOR HEXADECIMAL: Hiew, hexedit

El unico editor hexadecimal decente que he encontrado bajo linux es hexedit,
podeis buscarlo por este nombre:

hexedit-0.9.3.src.tgz

De todas formas, esta todavia a a¤os luz de editores en MS-DOS, con lo cual
merece la pena ejecutarlos bajo dosemu. A mi me gusta especialmente uno
llamado Hiew, pero va segun gustos. Lo podeis encontrar, junto con un millon
de cosas mas, en la pagina de Lord Caligo:

http://cracking.home.ml.org/


PROXIMA ENTREGA ---------------------------------------------------------

Que hacer ahora con estas herramientas ? El que sepa usarlas ya sabra lo que
hacer con ellas, pero el que este empezando y tenga interes, deberia hacerse
un peque¤o programa en C ( o lo que mas le guste) que lea del usuario un
numero y saque algun mensaje por pantalla. Una vez compilado no estaria de
mas quitarle los simbolos mediante "strip nombre_ejecutable". Una vez hecho
esto, que lo desensamble y vea el aspecto que tiene su programa en
ensamblador, para luego utilizar el depurador y practicar con las opciones
que os he referenciado arriba.

La idea es en la proxima entrega analizar el resto de herramientas disponibles
para linux, y practicar ya con un programa (un ejemplo facil :-). De todas
formas podeis mandar sugerencias y el que quiera cosas mas avanzadas, ya he
dicho antes que en la pagina de +fravia puede encontrar lo que busca.

SiuL+Hacky  <s_h@nym.alias.net>



Referencias
-----------

* SOBRE TODOS LOS TEMAS.--------------
   Internet, ahi estan casi todos los documentos que querais, solo falta
poder encontrarlos :-).

* SOBRE CRACKING.---------------------
  1. Tutoriales de +orc (Old Red Cracker). En ingles, muy amenos y
divertidos, cubre una gama muy amplia de temas: DOS, Win 3.1, Windows 95.
+Gthorne mantiene unos "packs" con los programas utilizados en dichos
tutoriales.
  2. Pagina de fravia (+hcu): http://www.fravia.org. En ella encontrareis
(entre otras cosas) los tutoriales de +orc, muy buenos links sobre
cracking y un archivo de mas de 300 tutoriales centrados en DOS & Win.
TODOS los niveles, y TODOS en ingles. Referencias sobre ensamblador
tambien.

* SOBRE INTERRUPCIONES DOS.------------
  1. Una coleccion sensacional de interrupciones del PC ha sido recopilada
por Ralf Brown. Gary Chanson en 1994 hizo una aplicacion llamada InterHlp
que permitia un mejor manejo de la inmensa lista.
  2. Otra buena recopilacion de informacion sobre el IBM Pc, se llamaba
HelpPC, con un monton de informacion sobre hardware, software,
ensamblador y por supuesto interrupciones. El autor es David Jurgens.
  Estos programas yo no los he conseguido en internet, pero SEGURO que
estan si buscais por el nombre de las aplicaciones o de los autores.

* SOBRE ENSAMBLADOR.-------------------------
  1. La mejor opcion, en mi opinion, es que consulteis uno de los muchos
libros existentes sobre el procesador 8086, o sobre la familia x86 en
general. En cualquier biblioteca de Informatica, Teleco, Fisicas, etc ...
encontrareis libros en castellano (por ejemplo de Anaya multimedia o de
Paraninfo). Una vez conocidos los fundamentos, tan solo necesitareis un
manual de referencia para consultar instrucciones que no sepais o algun
otro detalle.

* SOBRE API DE WINDOWS.----------------------
  1. Para conocer su funcionamiento, vale lo mismo de antes. En cualquier
libro sobre Borland c++, Visual c++, etc ... se trata el tema del API de
Windows.
  2. Si buscais solo una referencia de consulta, los compiladores de C++
de Borland o Microsoft ( o el que sea ) traen las especificaciones del
API. Si no, lo podeis encontrar, por ejemplo, aqui
http://cracking.home.ml.org

* SOBRE LINUX.-------------------------------
  1. Para aprender como usuario, teneis dos opciones. Una, por vuestra
cuenta, dandoos de leches contra todo; la curva de aprendizaje sera
inmensa. Segunda, leed libros y aprended. 
  2. Una guia sobre el funcionamiento del kernel y el sistema se llama
tlk-0.8-2 (the linux kernel), se puede encontrar en sunsite, o sea,
ftp://sunsite.unc.edu/pub/Linux/docs. Eso si es un poco tocho ...
  3. Como alternativa a esto ultimo, hay un libro en castellano bastante
aceptable llamado "Programacion linux 2.0. API del sistema y
funcionamiento del nucleo". Edita Gestion 2000.

* SOBRE GDB.----------------------------------
  1. La magnifica pagina info del GDB :-).