Cita

enero 15, 2011 at 3:03 am (Uncategorized)

“Somos como las pelis porno, nadie verá nuestro final”.

Los Chikos del Maíz – “Sultanes del Funk (con Ina)”

Permalink Dejar un comentario

Creando “vacunas” con C/C++

diciembre 2, 2010 at 1:02 am (Cpp, Programación)

Últimamente cada vez abundan más los gusanos que se propagan por MSN, por lo que me he decidido a escribir este manual sobre como programar vacunas específicas para este tipo de malware (aunque se puede extrapolar a otros). Mi objetivo es que haya más gente con capacidad de lanzar vacunas para estos gusanos cutres pero que se propagan como la espuma.

El lenguaje de programación que usaremos será C/C++ con el compilador Dev-C++, utilizando APIs. Si no sabéis que son preguntad a Google o a Wikipedia. Empezaré desde cero y ya adelanto que no voy a hacer un tutorial demasiado avanzado, puesto que quiero que lo entienda todo el mundo. Las APIs que use las explicaré por encima, para una mayor explicación podéis consultar en MSDN:
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/winprog/winprog/functions_in_alphabetical_order.asp

Análisis del código maligno
Bien, explicaré el método más sencillo. Este consiste en utilizar una máquina virtual y con un programa llamado Regshot mirar que cambios ha realizado en el sistema tras su ejecución. No es el mejor método porque un programa bien hecho puede evitar ser registrado por programas así, pero es mucho más sencillo que el otro método (desensamblarlo) y como este manual pretende ser básico, será el método que usaremos.

Lo primero de todo será instalar un programa para crear máquinas virtuales, yo personalmente uso para eso VMWare. No voy a explicar como se crea una máquina virtual.

Una vez tenemos nuestra máquina virtual con el sistema operativo instalado (Windows) ya tan sólo hay que deshabilitar las conexiones (no queremos que se propague el malware ni que ataque a otros sitios mientras lo analizamos) y cerrar todo programa no imprescindible. Hacemos una primera foto con Regshot y luego otra después de haber ejecutado el malware. Entonces hacemos que compare y tendremos nuestra lista de cambios

Comencemos a programar
Antes que nada tenéis que tener instalado Dev-C++ o vuestro compilador si usáis otro, una vez hecho, vayamos al grano. Todo programa en C/C++ se divide en funciones, que son trozos de código a los que se puede llamar. Pueden devolver una salida o no (void). En C/C++ hay una función imprescindible que es main, aquella por la que empieza el programa cuando lo ejecutamos. Tiene la siguiente estructura:

int main()
{
...
}

La función main es la que menos utilizaremos, puesto que borraremos el gusano con funciones aparte, que llamaremos desde el main. Será necesario utilizar APIs, por lo que habrá que incluir el header (archivo de cabecera) que permite usarlas, que es windows.h. También queremos comunicarnos con el usuario, por lo que hace falta stdio.h (Standard Input/Output). También nos hará falta Tlhelp32.h y ctype.h (por la función toupper). Para incluir headers hay que poner las siguientes líneas al principio del código, antes que ninguna función:

#include <stdio.h>

#include <windows.h>

#include <Tlhelp32.h>

#include <ctype.h>

Matando procesos y eliminando archivos concretos
Para poder eliminar un archivo que se está ejecutando, es necesario matar antes su proceso. Para ello haremos una función que llamaremos KillProcess, que recibirá como entrada una cadena con el nombre del archivo al que hay que matar el proceso. Las funciones (excepto main) se declaran antes de poner el código de otra función y después de los headers incluidos.

Como salida nuestra función devolvera un entero (un número) indicando si ha tenido éxito o no. Para declarar la función habría que usar la sentencia siguiente:

int KillProcess(LPCTSTR lpfilename);
Luego también tendríamos que poner la función en sí, por lo que hasta ahora tendríamos que tener el código así:

Código
#include
#include
#include
#include

int KillProcess(LPCTSTR lpfilename);

int KillProcess(LPCTSTR lpfilename)
{
...
}

int main()
{
...
}

Ahora veamos como matar el proceso de un archivo. Hay que declarar una serie de variables que usaremos:


WIN32_FIND_DATA Win32FindData;
HANDLE handle;
DWORD exitcode;
PROCESSENTRY32 pe32;

Estas son las que necesitaremos para poder matar el proceso. No hace falta que los nombres de variable (la segunda palabra) sea la misma, estos son los que usaré yo aquí. Los tipos de variable no los podéis cambiar y tened en cuenta que C/C++ distingue mayúsculas de minúsculas.

Ahora tenemos que hacer como si fuera una foto de todos los procesos que se ejecutan, para ello usaremos la API CreateToolhelp32Snapshot, que tiene la siguiente forma:

HANDLE WINAPI CreateToolhelp32Snapshot(
__in DWORD dwFlags,
__in DWORD th32ProcessID
);

Luego recorremos los procesos con las APIs Process32First (para el primero) y Process32Next (para los siguientes). Tienen la siguiente forma:

BOOL WINAPI Process32First(
__in HANDLE hSnapshot,
__inout LPPROCESSENTRY32 lppe
);

BOOL WINAPI Process32Next(
__in HANDLE hSnapshot,
__out LPPROCESSENTRY32 lppe
);

Harán falta otras APIs:

//Cierra un handle abierto
BOOL WINAPI CloseHandle(
__in HANDLE hObject
);

//Abre un proceso
HANDLE WINAPI OpenProcess(
__in DWORD dwDesiredAccess,
__in BOOL bInheritHandle,
__in DWORD dwProcessId
);

//Devuelve el estado de finalización del proceso
BOOL WINAPI GetExitCodeProcess(
__in HANDLE hProcess,
__out LPDWORD lpExitCode
);

//Termina un proceso y sus threads
BOOL WINAPI TerminateProcess(
__in HANDLE hProcess,
__in UINT uExitCode
);

Para hacer todo esto, traducido a código hay que hacer lo siguiente:


handle = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); //Guardamos en nuestra variable de tipo HANDLE la "foto"
if(handle == INVALID_HANDLE_VALUE) return ERROR_LISTAR; //Si no es correcta la "foto" se acaba la funcion y se devuelve un error
pe32.dwSize = sizeof(PROCESSENTRY32); //Definimos la medida de nuestra estructura PROCESSENTRY32
if(!Process32First(handle, &pe32)) //Si hay un error al mirar el primer proceso
{
CloseHandle(handle); //Cierra el HANDLE que usamos
return ERROR_PROCESO; //Acaba la funcion devolviendo un error
}
int i; //Declaramos un par de variables más que hacen falta para pasar a mayusculas dos cadenas
char lpfilename2[strlen(lpfilename) + 1];
strcpy(lpfilename2, lpfilename);
for(i = 0; pe32.szExeFile[i] != ''; i++) pe32.szExeFile[i] = toupper(pe32.szExeFile[i]); //Pasamos a mayúsculas las dos cadenas a comparar para que si no son exactamente iguales en cuanto a mayusculas o minusculas, también mate el proceso
for(i = 0; lpfilename2[i] != ''; i++) lpfilename2[i] = toupper(lpfilename2[i]);
while(strcmp(pe32.szExeFile,lpfilename2)) /Mientras el proceso no coincida con el que buscamos...
{
if(!Process32Next(handle, &pe32)) //Va mirando el siguiente, acabando la funcion si hay errores
{
CloseHandle(handle);
return ERROR_PROCESO;
}
for(i = 0; pe32.szExeFile[i] != ''; i++) pe32.szExeFile[i] = toupper(pe32.szExeFile[i]); //Pasa a mayusculas por lo que he dicho antes
}
/**Una vez hemos encontrado el proceso**//
handle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pe32.th32ProcessID); //Abrimos el proceso
if(handle == NULL) //Si sale mal, damos error y salimos de la funcion
{
CloseHandle(handle);
return ERROR_PROCESO;
}
else //Si no sale mal...
{
GetExitCodeProcess(handle, &exitcode); //Cogemos el exitcode del proceso y lo guardamos en nuestra variable destinada a ese cometido
TerminateProcess(handle, exitcode); //Matamos el proceso
CloseHandle(handle); //Cerramos el HANDLE que habiamos usado
return 0; //Devolvemos el valor 0, que es el que indicara que todo va bien y acaba la funcion
}

Como ya supongo que habréis supuesto, return se utiliza para terminar la función y devolver un valor. La doble barra sirve para introducir comentarios de una línea y también son comentario todo aquello entre /* y */. Además, también podéis ver que excepto el cero del final, los return devuelven cosas como ERROR_PROCESO. Esto sirve para llamar de una forma más recordable a una salida, en vez de usar un número. Para usar estos nombres, hay que definirlos antes, en la zona de los headers. Veamos todo lo que llevamos de código, incluyendo estas definiciones:


#define ERROR_LISTAR 1
#define ERROR_PROCESO 2

#include
#include
#include
#include

int KillProcess(LPCTSTR lpfilename);

int KillProcess(LPCTSTR lpfilename)
{
WIN32_FIND_DATA Win32FindData;
HANDLE handle;
DWORD exitcode;
PROCESSENTRY32 pe32;
handle = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if(handle == INVALID_HANDLE_VALUE) return ERROR_LISTAR;
pe32.dwSize = sizeof(PROCESSENTRY32);
if(!Process32First(handle, &pe32))
{
CloseHandle(handle);
return ERROR_PROCESO;
}
int i;
char lpfilename2[strlen(lpfilename) + 1];
strcpy(lpfilename2, lpfilename);
for(i = 0; pe32.szExeFile[i] != ''; i++) pe32.szExeFile[i] = toupper(pe32.szExeFile[i]);
for(i = 0; lpfilename2[i] != ''; i++) lpfilename2[i] = toupper(lpfilename2[i]);
while(strcmp(pe32.szExeFile,lpfilename2))
{
if(!Process32Next(handle, &pe32))
{
CloseHandle(handle);
return ERROR_PROCESO;
}
for(i = 0; pe32.szExeFile[i] != ''; i++) pe32.szExeFile[i] = toupper(pe32.szExeFile[i]);
}
handle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pe32.th32ProcessID);
if(handle == NULL)
{
CloseHandle(handle);
return ERROR_PROCESO;
}
else
{
GetExitCodeProcess(handle, &exitcode);
TerminateProcess(handle, exitcode);
CloseHandle(handle);
return 0;
}
}

int main()
{
...
}

Bueno, ahora que ya está hecha la función de matar el proceso, vayamos con la de borrar el archivo. Usaremos una función con la misma estructura, recibe como parámetro un archivo y de salida devuelve un entero. Para seguir poniendo de manifiesto mi gran originalidad, la llamaremos FileDelete. La declaración que habría que poner junto con la de la otra función, quedaría así:

int FileDelete(LPCTSTR lpfilename);
Para la función es muy sencillo, tan sólo hay que ver una API, que es DeleteFile:

BOOL WINAPI DeleteFile(
__in LPCTSTR lpFileName
);

El código de la función quedaría así:

int FileDelete(LPCTSTR lpfilename)
{
return DeleteFile(lpfilename);
}

Y el código total por ahora:

#define ERROR_LISTAR 1
#define ERROR_PROCESO 2

#include
#include
#include
#include

int KillProcess(LPCTSTR lpfilename);
int FileDelete(LPCTSTR lpfilename);

int KillProcess(LPCTSTR lpfilename)
{
WIN32_FIND_DATA Win32FindData;
HANDLE handle;
DWORD exitcode;
PROCESSENTRY32 pe32;
handle = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if(handle == INVALID_HANDLE_VALUE) return ERROR_LISTAR;
pe32.dwSize = sizeof(PROCESSENTRY32);
if(!Process32First(handle, &pe32))
{
CloseHandle(handle);
return ERROR_PROCESO;
}
int i;
char lpfilename2[strlen(lpfilename) + 1];
strcpy(lpfilename2, lpfilename);
for(i = 0; pe32.szExeFile[i] != ''; i++) pe32.szExeFile[i] = toupper(pe32.szExeFile[i]);
for(i = 0; lpfilename2[i] != ''; i++) lpfilename2[i] = toupper(lpfilename2[i]);
while(strcmp(pe32.szExeFile,lpfilename2))
{
if(!Process32Next(handle, &pe32))
{
CloseHandle(handle);
return ERROR_PROCESO;
}
for(i = 0; pe32.szExeFile[i] != ''; i++) pe32.szExeFile[i] = toupper(pe32.szExeFile[i]);
}
handle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pe32.th32ProcessID);
if(handle == NULL)
{
CloseHandle(handle);
return ERROR_PROCESO;
}
else
{
GetExitCodeProcess(handle, &exitcode);
TerminateProcess(handle, exitcode);
CloseHandle(handle);
return 0;
}
}

int FileDelete(LPCTSTR lpfilename)
{
return DeleteFile(lpfilename);
}

int main()
{
...
}

Realmente la función FileDelete es inútil, podríamos llamar directamente a la API, que es lo único que hace la función. Si no hago esto es porque más adelante (en próximos capítulos xD) ampliaremos esta función.

Borrando valores del registro
Este será el último apartado de este capítulo, el borrado de valores del registro, para por ejemplo borrar una entrada que pueda usar un gusano para autoejecutarse al inicio. Llamaremos a nuestra función RegKill, que será así:

long RegKill(HKEY hkey, LPCTSTR lpSubKey, LPCTSTR lpValueName);
Devolverá un entero largo y como parámetros recibe un HKEY, que será en este caso HKEY_CLASSES_ROOT, HKEY_CURRENT_USER, HKEY_LOCAL_MACHINE o HKEY_USERS, que son valores predefinidos; como segundo parámetro una cadena que indica la ruta de la clave donde está el valor a borrar y como tercer parámetro otra cadena que indica el nombre del valor a borrar.

Usaremos tres APIs para esta función. La primera es RegOpenKeyEx, que abre una clave del registro y tiene la siguiente forma:

LONG WINAPI RegOpenKeyEx(
__in HKEY hKey,
__in_opt LPCTSTR lpSubKey,
__reserved DWORD ulOptions,
__in REGSAM samDesired,
__out PHKEY phkResult
);

La segunda API es RegDeleteValue, que elimina un valor de una clave del registro y tiene la siguiente forma:

LONG WINAPI RegDeleteValue(
__in HKEY hKey,
__in_opt LPCTSTR lpValueName
);

La última es RegCloseKey, que cierra el handle abierto y tiene esta forma:

LONG WINAPI RegCloseKey(
__in HKEY hKey
);

El código de la función quedaría así:

long RegKill(HKEY hkey, LPCTSTR lpSubKey, LPCTSTR lpValueName)
{
HKEY hregkey; //Definimos la variable donde guardaremos la ruta entera de la clave
long vuelta; //Definimos la variable donde guardaremos el valor a devolver
if(RegOpenKeyEx(hkey, lpSubKey, 0, KEY_ALL_ACCESS, &hregkey) == ERROR_SUCCESS) //Si consigue abrir la clave...
{
vuelta = RegDeleteValue(hregkey, lpValueName); //Borra el valor de la clave y guarda el resultado en "vuelta"
RegCloseKey(hregkey); //Cierra el handle que hemos usado
return vuelta; //Devuelve "vuelta"
}
else return ERROR_OPEN_REG; //Si no consigue abrir la clave, devuelve este error
}

Hace falta definir al inicio ERROR_OPEN_REG. Definiendo eso e incorporando el código, queda así:

#define ERROR_LISTAR 1
#define ERROR_PROCESO 2
#define ERROR_OPEN_REG 3

#include
#include
#include
#include

int KillProcess(LPCTSTR lpfilename);
int FileDelete(LPCTSTR lpfilename);
long RegKill(HKEY hkey, LPCTSTR lpSubKey, LPCTSTR lpValueName);

int KillProcess(LPCTSTR lpfilename)
{
WIN32_FIND_DATA Win32FindData;
HANDLE handle;
DWORD exitcode;
PROCESSENTRY32 pe32;
handle = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if(handle == INVALID_HANDLE_VALUE) return ERROR_LISTAR;
pe32.dwSize = sizeof(PROCESSENTRY32);
if(!Process32First(handle, &pe32))
{
CloseHandle(handle);
return ERROR_PROCESO;
}
int i;
char lpfilename2[strlen(lpfilename) + 1];
strcpy(lpfilename2, lpfilename);
for(i = 0; pe32.szExeFile[i] != ''; i++) pe32.szExeFile[i] = toupper(pe32.szExeFile[i]);
for(i = 0; lpfilename2[i] != ''; i++) lpfilename2[i] = toupper(lpfilename2[i]);
while(strcmp(pe32.szExeFile,lpfilename2))
{
if(!Process32Next(handle, &pe32))
{
CloseHandle(handle);
return ERROR_PROCESO;
}
for(i = 0; pe32.szExeFile[i] != ''; i++) pe32.szExeFile[i] = toupper(pe32.szExeFile[i]);
}
handle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pe32.th32ProcessID);
if(handle == NULL)
{
CloseHandle(handle);
return ERROR_PROCESO;
}
else
{
GetExitCodeProcess(handle, &exitcode);
TerminateProcess(handle, exitcode);
CloseHandle(handle);
return 0;
}
}

int FileDelete(LPCTSTR lpfilename)
{
return DeleteFile(lpfilename);
}

long RegKill(HKEY hkey, LPCTSTR lpSubKey, LPCTSTR lpValueName)
{
HKEY hregkey;
long vuelta;
if(RegOpenKeyEx(hkey, lpSubKey, 0, KEY_ALL_ACCESS, &hregkey) == ERROR_SUCCESS)
{
vuelta = RegDeleteValue(hregkey, lpValueName);
RegCloseKey(hregkey);
return vuelta;
}
else return ERROR_OPEN_REG;
}

int main()
{
...
}

Ahora que ya tenemos las funciones, falta ver que poner en el main. Esto variará según qué malware queramos eliminar. Imaginemos que tenemos un malware que crea el archivo siguiente:

C:\gusano.exe
Y se autoejecuta a cada inicio con la siguiente clave:

HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Run\Soy un gusano malo y propagador
La función main deberá llamar a las tres funciones que hemos hecho: primero tendrá que matar el proceso, luego eliminar el archivo y después borrar el valor del registro. Quedaría así nuestro main de forma cutre:

int main()
{
KillProcess("gusano");
FileDelete("C:\\gusano");
RegKill(HKEY_CURRENT_USER, "Software\\Microsoft\\Windows\\CurrentVersion\\Run", "Soy un gusano malo y propagador");
return 0;
}

Pero si nos hemos molestado en poner diferentes valores a las salidas es para tenerlos en cuenta, no para pasar de ellos. Hagamos un main que mire también como les va a nuestras funciones xDD:

int main()
{
long salida;

salida = KillProcess("gusano.exe");
if(salida == ERROR_LISTAR) printf("Error al listar los procesos\n");
else if((salida == ERROR_PROCESO) && (GetLastError() == ERROR_NO_MORE_FILES)) printf("El proceso no existe\n");
else if(salida == ERROR_PROCESO) printf("Error al manejar los procesos\n");
else printf("Proceso finalizado correctamente\n");

salida = FileDelete("C:\\gusano.exe");
if(salida == ERROR_FILE_NOT_FOUND) printf("Archivo no encontrado\n");
else if(salida == ERROR_ACCESS_DENIED) printf("Acceso denegado\n");
else if(salida) printf("Archivo eliminado correctamente\n");
else printf("Error al eliminar el archivo\n");

salida = RegKill(HKEY_CURRENT_USER, "Software\\Microsoft\\Windows\\CurrentVersion\\Run", "Soy un gusano malo y propagador");
if(salida == ERROR_OPEN_REG) printf("Error al abrir el registro\n");
else if(salida == ERROR_SUCCESS) printf("Valor borrado del registro\n");
else printf("Error al borrar valor del registro\n");

return 0;
}

El hecho de que las contrabarras aparezcan duplicadas es porque la contrabarra se usa en C/C++ para las secuencias de escape (\n simboliza un salto de línea). Para poner una contrabarra, se ponen dos. Y el código entero sería así:

#define ERROR_LISTAR 1
#define ERROR_PROCESO 2
#define ERROR_OPEN_REG 3

#include
#include
#include
#include

int KillProcess(LPCTSTR lpfilename);
int FileDelete(LPCTSTR lpfilename);
long RegKill(HKEY hkey, LPCTSTR lpSubKey, LPCTSTR lpValueName);

int KillProcess(LPCTSTR lpfilename)
{
WIN32_FIND_DATA Win32FindData;
HANDLE handle;
DWORD exitcode;
PROCESSENTRY32 pe32;
handle = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if(handle == INVALID_HANDLE_VALUE) return ERROR_LISTAR;
pe32.dwSize = sizeof(PROCESSENTRY32);
if(!Process32First(handle, &pe32))
{
CloseHandle(handle);
return ERROR_PROCESO;
}
int i;
char lpfilename2[strlen(lpfilename) + 1];
strcpy(lpfilename2, lpfilename);
for(i = 0; pe32.szExeFile[i] != ''; i++) pe32.szExeFile[i] = toupper(pe32.szExeFile[i]);
for(i = 0; lpfilename2[i] != ''; i++) lpfilename2[i] = toupper(lpfilename2[i]);
while(strcmp(pe32.szExeFile,lpfilename2))
{
if(!Process32Next(handle, &pe32))
{
CloseHandle(handle);
return ERROR_PROCESO;
}
for(i = 0; pe32.szExeFile[i] != ''; i++) pe32.szExeFile[i] = toupper(pe32.szExeFile[i]);
}
handle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pe32.th32ProcessID);
if(handle == NULL)
{
CloseHandle(handle);
return ERROR_PROCESO;
}
else
{
GetExitCodeProcess(handle, &exitcode);
TerminateProcess(handle, exitcode);
CloseHandle(handle);
return 0;
}
}

int FileDelete(LPCTSTR lpfilename)
{
return DeleteFile(lpfilename);
}

long RegKill(HKEY hkey, LPCTSTR lpSubKey, LPCTSTR lpValueName)
{
HKEY hregkey;
long vuelta;
if(RegOpenKeyEx(hkey, lpSubKey, 0, KEY_ALL_ACCESS, &hregkey) == ERROR_SUCCESS)
{
vuelta = RegDeleteValue(hregkey, lpValueName);
RegCloseKey(hregkey);
return vuelta;
}
else return ERROR_OPEN_REG;
}

int main()
{
long salida;

salida = KillProcess("gusano.exe");
if(salida == ERROR_LISTAR) printf("Error al listar los procesos\n");
else if((salida == ERROR_PROCESO) && (GetLastError() == ERROR_NO_MORE_FILES)) printf("El proceso no existe\n");
else if(salida == ERROR_PROCESO) printf("Error al manejar los procesos\n");
else printf("Proceso finalizado correctamente\n");

salida = FileDelete("C:\\gusano.exe");
if(salida == ERROR_FILE_NOT_FOUND) printf("Archivo no encontrado\n");
else if(salida == ERROR_ACCESS_DENIED) printf("Acceso denegado\n");
else if(salida) printf("Archivo eliminado correctamente\n");
else printf("Error al eliminar el archivo\n");

salida = RegKill(HKEY_CURRENT_USER, "Software\\Microsoft\\Windows\\CurrentVersion\\Run", "Soy un gusano malo y propagador");
if(salida == ERROR_OPEN_REG) printf("Error al abrir el registro\n");
else if(salida == ERROR_SUCCESS) printf("Valor borrado del registro\n");
else printf("Error al borrar valor del registro\n");

return 0;
}

Con esto doy por acabado este primer capítulo, escribiré el siguiente cuando el tiempo lo permita, en el que explicaré como hacer más cosas. Mañana si tengo tiempo pongo un ejercicio para que podáis practicar lo aprendido.

Como deberes os digo que en la función de matar procesos hay un fallo, que no es explotable ni nada, simplemente que algunos procesos según la entrada que demos no los matará. Esto para los que sepan más de C/C++.

Este texto puede ser publicado en cualquier sitio siempre que no se modifique y se cite al autor y la fuente.

Un saludo de Alex

Permalink Dejar un comentario

Cita

octubre 28, 2010 at 9:17 pm (Uncategorized)

—Y ellos, naturalmente, responden a sus nombres, ¿no? —observó al desgaire el Mosquito.

—Nunca oí decir tal cosa.

—¿Pues de qué les sirve tenerlos —preguntó el Mosquito— si no responden a sus nombres?

Lewis Carroll, Alicia a través del espejo.

 

Permalink Dejar un comentario

El manifiesto del Hacker

julio 14, 2010 at 10:35 am (Uncategorized)

Hoy han cogido a otro, aparece en todos los periódicos. “Joven arrestado por delito informático”, “hacker arrestado por irrumpir en un sistema bancario”.

“Malditos críos. Son todos iguales”.

¿Pero pueden, con su psicología barata y su cerebro de los años cincuenta, siquiera echar un vistazo a lo que hay detrás de los ojos de un hacker? ¿Se han parado alguna vez a pensar qué es lo que les hace comportarse así, qué les ha convertido en lo que son? Yo soy un hacker, entre en mi mundo. Mi mundo comienza en el colegio. Soy más listo que el resto de mis compañeros, lo que enseñan me parece muy aburrido.

“Malditos profesores. Son todos iguales”. Puedo estar en el colegio o un instituto. Les he oído explicar cientos de veces cómo se reducen las fracciones. Todo eso ya lo entiendo. “No, Sr. Smith, no he escrito mi trabajo. Lo tengo guardado en la cabeza”.

“Malditos críos. Seguro que lo ha copiado. Son todos iguales”.

Hoy he descubierto algo. Un ordenador. Un momento, esto mola. Hace lo que quiero que haga. Si comete errores, es porque yo le he dicho que lo haga.

No porque yo no le guste, me tenga miedo, piense que soy un listillo o no le guste ni enseñar ni estar aquí.

Malditos críos. A todo lo que se dedican es a jugar. Son todos iguales. Entonces ocurre algo… se abre una puerta a un nuevo mundo… todo a través de la línea telefónica, como la heroína a través de las venas, se emana un pulso electrónico, buscaba un refugio ante las incompetencias de todos los días… y me encuentro con un teclado.

“Es esto… aquí pertenezco… “. Conozco a todo mundo… aunque nunca me haya cruzado con ellos, les dirigiese la palabra o escuchase su voz… los conozco a todos… malditos críos. Ya está enganchado otra vez al teléfono.

Son todos iguales… puedes apostar lo quieras a que son todos iguales… les das la mano y se toman el brazo… y se quejan de que se lo damos todo tan masticado que cuando lo reciben ya ni siquiera tiene sabor. O nos gobiernan los sádicos o nos ignoran los apáticos. Aquellos que tienen algo que enseñar buscan desesperadamente alumnos que quieran aprender, pero es como encontrar una aguja en un pajar.

Este mundo es nuestro… el mundo de los electrones y los interruptores, la belleza del baudio. Utilizamos un servicio ya existente, sin pagar por eso que podrían haber sido más barato si no fuese por esos especuladores. Y nos llamáis delincuentes. Exploramos… y nos llamáis delincuentes. Buscamos ampliar nuestros conocimientos… y nos llamáis delincuentes. No diferenciamos el color de la piel, ni la nacionalidad, ni la religión… y vosotros nos llamáis delincuentes. Construís bombas atómicas, hacéis la guerra, asesináis, estafáis al país y nos mentís tratando de hacernos creer que sois buenos, y aún nos tratáis de delincuentes.

Sí, soy un delincuente. Mi delito es la curiosidad. Mi delito es juzgar a la gente por lo que dice y por lo que piensa, no por lo que parece. Mi delito es ser más inteligente que vosotros, algo que nunca me perdonaréis. Soy un hacker, y éste es mi manifiesto. Podéis eliminar a algunos de nosotros, pero no a todos… después de todo, somos todos iguales.

The Mentor >> El manifiesto del Hacker

Permalink 3 comentarios

Oracle

mayo 28, 2010 at 6:16 pm (Bases de Datos, Programación)

Bueno, pues ahora me ha dado por bajarme oracle y aprender a manejarlo, a primera vista es mucho más complejo y completo que MySQL, claro, pesa mucho más del doble (la gracia me ha pesado 2GB), si bien aun no lo he instalado lo he estado ojeando, procedo a instalarlo y probarlo este finde. Me gustaría emprenderme en un nuevo proyecto y disponer de Oracle como base de datos puede que sea un alivio (mysql suele ser muy problemático), el proyecto empezará siendo PHP, pero mi objetivo es terminar pasándolo a plataforma Linux, Windows y, si es posible, MAC.. Para ello utilizaré Python o C++, dependiendo de lo que necesite. Empezaré a programarlo dentro de unas 3 semanas, así habré terminado el curso, a ver si para finales del verano tuviera una versión sostenible sobre la que ir probando =).

Permalink Dejar un comentario

Cuanto tiempo..

mayo 22, 2010 at 1:33 pm (Uncategorized)

Buenas, llevo ya bastante sin escribir, y es que no sé que contar.. Podría contar mucho sobre mis avances con Python, ya que no me falta mucho para terminar el libro y voy bastante rápido, también podría contar muchas cosas sobre el instituto y mis estudios, o sobre los proyectos XNova que me reclaman, pero no sé cuál es el tema más adecuado para escribir aquí.. Siempre que he escrito he orientado el blog hacia el mundo de la informática y la programación en general, pero ahora me planteo si tiene algún sentido hacer ésto.. Nunca he pensado en escribir refiriéndome a un lector, aunque siempre que escribo lo hago hablando a un “tú” imaginario, ya que es obvio que nadie me lee. Y tampoco sé si quiero que lo hagan, aquí puedo contar lo que quiera y como quiera, de momento – como dije antes – solo he escrito a cerca de la programación y los programas que he ido desarrollando, y tampoco he realizado grandes proyectos, porque no me vienen grandes ideas, solo simples programillas, aunque los he ido haciendo con éxito. Esta entrada es más bien un monólogo interior, ya que no voy a obtener respuesta, pero me sirve para aclararme, o intentarlo, me gustaría escribir a cerca de lo que me gusta, que sobre todo es la programación y el mundo del hacking, también me gustan muchas otras cosas, pero no veo si tienen cabida aquí, podría hablaros de cómo me va con mi novia, por ejemplo. Aunque si bien es cierto siempre me ha gustado leer blogs de otras personas, y siempre está bien la idea de que lean tu blog, ayuda a seguir y te anima. Quizá sea esa la causa de que no escriba con frecuencia, de hecho casi no entro al blog.. Me da pena, porque sé que es una experiencia tener un blog, y me gusta escribir, la verdad, pero no sé que contar. Creo que escribiré más a menudo en el blog, lo que se me ocurra, lo usaré como “diario”. Intentaré contar todo lo que me pase, desde mis avances en programación, en los diversos lenguajes que me gustaría estudiar, lo que estudio.. etc. Espero que al menos me entretenga.

Permalink Dejar un comentario

Videojuego Python

abril 29, 2010 at 3:59 pm (Programación, Python)

Pues como bien dice el título hoy os voy a presentar un par de videojuegos creados por mí, uno de ellos basado en los modelos de un texto. El primero es un juego bien sencillo en el que una nave cae por la acción de la gravedad y nosotros debemos conducirla hasta una plataforma móvil, podemos contrarrestar el efecto de la gravedad pulsado la flecha de arriba (activa un propulsor) y ocurrirá lo mismo con las flechas de los lados. =). Además el juego muestra una amplia gama de información, muestra el combustible, velocidad de caída.. Espero que os guste, es una gilipollez, pero me ayuda mucho hacer este tipo de aplicaciones.

from math import pi, cos, sin

#Escogemos dificultad
print 'Escoge dificultad:'
print 'a) Facil'
print 'b) Medio'
print 'c) Dificil'
dif = raw_input('Introduce la letra de tu opcion: ')

#Definimos el paisaje

altura_paisaje = 400
anchura_paisaje = 400

window_coordinates(0, 0, anchura_paisaje, altura_paisaje)
create_filled_rectangle(0, 0, 400, 400, 'black')

#Gravedad
if dif == 'a':
g = 0.001
elif dif == 'b':
g = 0.01
elif dif == 'c':
g = 0.1

#Definimos la nave

tamanyo_nave = 10
x = anchura_paisaje/2
y = altura_paisaje - 100
vy = 0
impulso_y = 2*g
impuslo_x = 0.001
vx = 0
nave = create_filled_rectangle(x, y, x+tamanyo_nave, y+tamanyo_nave, 'blue')

#Plataforma
px = anchura_paisaje / 2
py = 75
if dif == 'a':
vpx = 0.05
anchura_plataforma = 40
altura_plataforma = 3
elif dif == 'b':
vpx = 0.1
anchura_plataforma = 30
altura_plataforma = 3
elif dif == 'c':
vpx = 1.15
anchura_plataforma = 25
altura_plataforma = 3

plataforma = create_filled_rectangle(px, py, px+anchura_plataforma, py+altura_plataforma, 'red')

#Tanque de combustible
fuel = 1000
consumo = 0.1
create_rectangle(0,altura_paisaje, 10, altura_paisaje-100, 'black')
if fuel >= 250:
lleno = create_filled_rectangle(1,altura_paisaje, 9, altura_paisaje-fuel/10, 'green')
else:
lleno = create_filled_rectangle(1,altura_paisaje, 9, altura_paisaje-fuel/10, 'red')

create_text(25, altura_paisaje-8, '0%', 10, 'W')
create_text(30, altura_paisaje-95, '100%', 10, 'W')

#Dial de velocidad
create_circle(anchura_paisaje-50, altura_paisaje-50, 50, 'black')
for i in range(0, 360, 10):
create_line(anchura_paisaje-50 + 40 * sin(i*pi/180), \
altura_paisaje-50 + 40 * cos(i*pi/180), \
anchura_paisaje-50 + 50 * sin(i*pi/180), \
altura_paisaje-50 + 50 * cos(i*pi/180))
if i % 30 == 0:
create_text(anchura_paisaje-50 + 30 * sin(i*pi/180), \
altura_paisaje-50 + 30 * cos(i*pi/180), str(i), 5, 'CENTER')

aguja = create_line(anchura_paisaje-50, altura_paisaje-50, \
anchura_paisaje-50 + 50 * sin(0*pi/180), \
altura_paisaje-50 + 50 * cos(0*pi/180), 'blue')

# Simulacion
while y > 0 and y 0 and x 0:
vy += impulso_y
fuel -= consumo
create_line(anchura_paisaje-x+tamanyo_nave/2, altura_paisaje-y, x+tamanyo_nave/2, y)
elif keypressed(1) == 'Left' and fuel > 0:
vx -= impulso_x
fuel -= consumo
create_line(anchura_paisaje-x, altura_paisaje-y-tamanyo_nave/2, x, y-tamanyo_nave/2)
elif keypressed(1) == 'Right' and fuel > 0:
vx += impulso_x
fuel -= consumo
create_line(x, y-tamanyo_nave/2, anchura_paisaje-x, altura_paisaje-y-tamanyo_nave/2)
y += vy
px += vpx
if px = anchura_paisaje - anchura_plataforma:
vpx = -vpx

move(nave, vx, vy)
move(plataforma, vpx, 0)
viejo_lleno = lleno
lleno = create_filled_rectangle(1, altura_paisaje, 9, altura_paisaje-fuel/10, 'green')
erase(viejo_lleno)
vieja_aguja = aguja
aguja = create_line(anchura_paisaje-50, altura_paisaje-50, \
anchura_paisaje-50 + 50 * sin(1000*vy*pi/180), \
altura_paisaje-50 + 50 * cos(1000*vy*pi/180), 'blue')
erase(vieja_aguja)

msg_x = anchura_paisaje / 2
msg_y1 = altura_paisaje / 2
msg_y2 = altura_paisaje / 3
if y >= altura_paisaje:
create_text(msg_x, msg_y1, 'Perdiste', 24, 'CENTER')
create_text(msg_x, msg_y2, 'Rumbo a las estrellas?', 12, 'CENTER')
elif y <= 0 and vy = anchura_paisaje - tamanyo_anve or x <= 0:
create_text(msg_x, msg_y1, 'Perdiste', 24, 'CENTER')
create_text(msg_x, msg_y2, 'Te has estrellado contra la pared', 12, 'CENTER')
elif x == plataforma_x and y == plataforma_y:
create_text(msg_x, msg_y1, 'Perdiste', 24, 'CENTER')
create_text(msg_x, msg_y2, 'Te has estrellado contra la plataforma por debajo', 12, 'CENTER')
else:
create_text(msg_x, msg_y1, 'Ganaste', 24, 'CENTER')
create_text(msg_x, msg_y2, 'Enhorabuena piloto!', 12, 'CENTER')

Para obtener el juego es tan simple como copiar esto en un bloc de notas, guardarlo con la extensión ".py" y tener python instalado, luego lo ejecutas y debería salir, si no sólo os servirá para leer el código xD. El otro juego lo posteo esta noche.

Ahora el segundo juego, es una especie de Frontón electrónico, el jugador dispone de una pala en el inferior del plano y una pelota azul en la parte superior de la pantalla, la pelota baja con un movimiento diagonal, y cuando choca con las paredes la velocidad cambia de dirección, el objetivo es darle con la pala a la pelota el tiempo que seas capaz de aguantar.


#Fronton electrico

altura = 400
anchura = 400
window_coordinates(0, 0, altura, anchura)

#Definimos la pala
pala_x = 175
pala_y = 0
pala_altura = 3
pala_anchura = 50
vx = 0.1
impulso_px = 0.3
pala = create_filled_rectangle(pala_x, pala_y, pala_x+pala_anchura, pala_y+pala_altura, 'red')

#Definimos la pelota
pelota_x = 200
pelota_y = 350
vpx = -0.07
vpy = -0.09
impulso_y = 0.006
impulso_x = 0.006

pelota = create_filled_circle(pelota_x, pelota_y, 8, 'blue')

#Simulacion
while pelota_y > 0 and pelota_y = 0 and pelota_x <= 400:
pelota_y += vpy
pelota_x -= vpx
vieja_pelota = pelota
pelota = create_filled_circle(pelota_x, pelota_y, 8, 'blue')
erase(vieja_pelota)

if keypressed(1) == 'Left':
vx = -vx-impulso_px
elif keypressed(1) == 'Right':
vx += impulso_px

pala_x += vx
vieja_pala = pala
pala = create_filled_rectangle(pala_x, pala_y, pala_x+pala_anchura, pala_y+pala_altura, 'red')
erase(pala)

if pala_x == 400 or pala_x == 0:
vpx = -vpx
if pelota_x == 400 or pelota_x == 0:
vpx = -vpx
if pelota_y == 400:
vpy = -vpy
elif pelota_y == pala_y and pelota_x == pala_x:
vpy = -vpy+impulso_y
vpx += impulso_x

if pelota_y == 0:
create_text(350, 350, 'Perdiste', 24, 'CENTER')
create_text(300, 300, 'Tu pelota se colo por debajo', 12, 'CENTER')

Permalink 2 comentarios

Python

abril 25, 2010 at 10:53 am (Programación)

Bueno, ya era hora de escribir.. Comentaros que he empezado a estudiar python (hará una semana), y bueno, que espero terminarlo en 1 mes – mes y medio.. Os iré comunicando programillas y tal, y cuando termine pondré manuales de C++ y de Python. Buena suerte :D.

Permalink Dejar un comentario

Porfin, programa desarrollado =D

octubre 18, 2009 at 10:47 am (Cpp, Programación)

Bueno, tras 15 días sin haber publicado nada y habiéndome dedicado al programa conseguí sacarlo, aquí la primera versión, solo falla en el “caso 5”, al imprimir el resultado, pero bueno, quitamos los últimos carácteres dejando solo el binario y nos sale exitosamente, aquí tenemos el código, el próximo paso será meterle interfaz gráfica =), estoy aprendiendo a manejarlo ya =D:


V1

#include <
stdlib.h>
#include <math.h>
#include <iostream>
#include <string.h>
using namespace std;

void ConvertirDecimalABinario();
void ConvertirDecimalAHexadecimal();
void ConvertirBinarioADecimal();
void ConvertirBinarioAHexadecimal();
void ConvertirHexadecimalABinario();
void ConvertirHexadecimalADecimal();
int ConvertirBinADecSimple(char binario[3]);
char ConvertirDecAHexSimple(int decimal);
char* ConvertirHexABinSimple(char hexa, char* bin);

int main()
{
int sistema;
system("clear");
cout << "Bienvenido al programa, indique que operacion desea realizar: " << endl;
cout << "1.- Pasar numero de binario a decimal" << endl;
cout << "2.- Pasar numero de binario a hexadecimal" << endl;
cout << "3.- Pasar numero de decimal a binario" << endl;
cout << "4.- Pasar numero de decimal a hexadecimal" << endl;
cout << "5.- Pasar numero de hexadecimal a binario" << endl;
cout << "6.- Pasar numero de hexadecimal a decimal" << endl; cin >> sistema;
switch(sistema)
{
case 1:
ConvertirBinarioADecimal();
break;
case 2:
ConvertirBinarioAHexadecimal();
break;
case 3:
ConvertirDecimalABinario();
break;
case 4:
ConvertirDecimalAHexadecimal();
break;
case 5:
ConvertirHexadecimalABinario();
break;
case 6:
ConvertirHexadecimalADecimal();
break;
default:
cout << "No introdujo un valor válido, retornando a menu principal" << main();
break;
}
}

void ConvertirBinarioADecimal() // CORRECTO
{
char *binario;
binario = new char[32];
int decimal = 0;
int cifras;

cout << "Indique el numero binario: "; cin >> binario;

// Conocer el nº de dígitos de la cifra tecleada

if(strchr(binario, '23456789ABCDEFGHIJKLMNÑOPQRSTUVWXYZ'))
{
for(int j = 0; binario[j]; j++)
{
cifras = j+1;
}

// ----------------------------------------------
// Pasamos el binario al decimal correspondiente

int i = 0;
int k = cifras-1;

while(i <= cifras-1)
{
decimal += (binario[k]-'0')*pow(2,i);
k--;
i++;
}

cout << "\nEl numero binario: " << binario << " es " << decimal << " en decimal" << endl;
cout << "Volver a menu principal" << endl;
system("read a");
main();

delete[] binario;
} else {
cout << "Valor incorrecto, introduzcalo de nuevo";
system("read a");
ConvertirBinarioADecimal();
}
}

char ConvertirDecAHexSimple(int decimal) // CORRECTO
{
char hexsimpl;

if(decimal == 0)
{
hexsimpl = '0';
} else if(decimal == 1)
{
hexsimpl = '1';
} else if(decimal == 2)
{
hexsimpl = '2';
} else if(decimal == 3)
{
hexsimpl = '3';
} else if(decimal == 4)
{
hexsimpl = '4';
} else if(decimal == 5)
{
hexsimpl = '5';
} else if(decimal == 6)
{
hexsimpl = '6';
} else if(decimal == 7)
{
hexsimpl = '7';
} else if(decimal == 8 )
{
hexsimpl = '8';
} else if(decimal == 9)
{
hexsimpl = '9';
} else if(decimal == 10)
{
hexsimpl = 'A';
} else if(decimal == 11)
{
hexsimpl = 'B';
} else if(decimal == 12)
{
hexsimpl = 'C';
} else if(decimal == 13)
{
hexsimpl = 'D';
} else if(decimal == 14)
{
hexsimpl = 'E';
} else if(decimal == 15)
{
hexsimpl = 'F';
}

return hexsimpl;
}

int ConvertirBinADecSimple(char binario[3]) // CORRECTO
{
int decimal = 0;
int cifras = 3+1;

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

int i = 0;
int k = cifras-1;

while(i <= cifras-1)
{
decimal += (binario[k]-'0')*pow(2,i);
k--;
i++;
}

return decimal;
}

void ConvertirBinarioAHexadecimal() // CORRECTO
{
char *binario;
binario = new char[32];
char *hexadecimal;
hexadecimal = new char[32];
int cifras;
int restante;

cout << "Indique el numero binario: "; cin >> binario;

if(strchr(binario, '23456789ABCDEFGHIJKLMNÑOPQRSTUVWXYZ'))
{
for(int j = 0; binario[j]; j++)
{
cifras = j+1;
}

if(cifras%4 != 0)
{
char *copia;
copia = new char[cifras+(4-cifras%4)];
restante = 4-cifras%4;

for(int i = 0; i < restante ; i++)
{
copia[i] = '0';
}

for(int i = restante; i < (cifras + restante); i++)
{
copia[i] = binario[i-restante];
}

int pos = 0;
int dec = 0;
for(int i = 4; i <= cifras + restante; i+= 4)
{
char cpy[4] = {copia[i-4], copia[i-3], copia[i-2], copia[i-1]};
dec = ConvertirBinADecSimple(cpy);
hexadecimal[pos] = ConvertirDecAHexSimple(dec);
pos++;
}
delete[] copia;

} else {
int pos = 0;
int dec = 0;
for(int i = 4; i <= cifras; i+= 4)
{
char cpy[4] = {binario[i-4], binario[i-3], binario[i-2], binario[i-1]};
dec = ConvertirBinADecSimple(cpy);
hexadecimal[pos] = ConvertirDecAHexSimple(dec);
pos++;
}
}


cout << "El numero binario " << binario << " es " << hexadecimal << " en hexadecimal" << endl;
delete[] binario;
delete[] hexadecimal;
cout << "Volver a menu principal" << endl;
system("read a");
main();
} else {
cout << "Valor incorrecto, introduzcalo de nuevo";
system("read a");
ConvertirBinarioAHexadecimal();
}
}

void ConvertirDecimalABinario() // CORRECTO
{
int decimal, dec;
char binario[64];
char *copia;
copia = new char[32];

cout << "Indique el numero decimal: "; cin >> dec;
cout << endl;

decimal = dec;

int j = 0;

while(decimal/2 >= 1)
{
if(decimal%2 == 0)
{
binario[j] = '0';
} else
{
binario[j] = '1';
}
decimal /= 2;
j++;
}

binario[j] = '1';

int i = 0;
for(int d = j; d >= 0; d--)
{
copia[i] = binario[d];
i++;
}

cout << "El numero decimal " << dec << " es " << copia << " en binario" << endl;
delete[] copia;

cout << "Volver a menu principal" << endl;
system("read a");
main();

}

void ConvertirDecimalAHexadecimal() // CORRECTO
{
int decimal, dec, cifras, restante;
char binario[64], *copia, *hexadecimal;
copia = new char[32];
hexadecimal = new char[32];

cout << "Indique el numero decimal: "; cin >> dec;

decimal = dec;

int j = 0;

// Convertimos decimal a binario
while(decimal/2 >= 1)
{
if(decimal%2 == 0)
{
binario[j] = '0';
} else
{
binario[j] = '1';
}
decimal /= 2;
j++;
}

binario[j] = '1';

int i = 0;
for(int d = j; d >= 0; d--)
{
copia[i] = binario[d];
i++;
}

// Convertimos binario a hexadecimal

for(int j = 0; copia[j]; j++)
{
cifras = j+1;
}

if(cifras%4 != 0)
{
char *ncopia;
ncopia = new char[cifras+(4-cifras%4)];
restante = 4-cifras%4;

for(int i = 0; i < restante ; i++)
{
ncopia[i] = '0';
}

for(int i = restante; i < (cifras + restante); i++)
{
ncopia[i] = copia[i-restante];
}

int pos = 0;
int dec = 0;
for(int i = 4; i <= cifras + restante; i+= 4)
{
char cpy[4] = {ncopia[i-4], ncopia[i-3], ncopia[i-2], ncopia[i-1]};
dec = ConvertirBinADecSimple(cpy);
hexadecimal[pos] = ConvertirDecAHexSimple(dec);
pos++;
}
delete[] ncopia;

} else {
int pos = 0;
int dec = 0;
for(int i = 4; i <= cifras; i+= 4)
{
char cpy[4] = {copia[i-4], copia[i-3], copia[i-2], copia[i-1]};
dec = ConvertirBinADecSimple(cpy);
hexadecimal[pos] = ConvertirDecAHexSimple(dec);
pos++;
}
}

cout << "El numero decimal " << dec << " es " << hexadecimal << " en hexadecimal" << endl;
delete[] copia;
delete[] hexadecimal;
cout << "Volver a menu principal" << endl;
system("read a");
main();
}

void ConvertirHexadecimalABinario() // CORRECTO SALVO AL IMPRIMIR
{
char *hexadecimal;
hexadecimal = new char[32];
int cifras = 0;

cout << "Indique el numero hexadecimal: "; cin >> hexadecimal;
cout << endl;

for(int i = 0; hexadecimal[i]; i++)
{
cifras = i+1;
}
char binario[cifras][4], **binsimpl;
binsimpl = new char*[cifras-1];
binsimpl[cifras] = new char[5];

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

for(int j = 0; j < cifras; j++)
{
binsimpl[j] = ConvertirHexABinSimple(hexadecimal[j], binario[j]);
}

cout << "El numero hexadecimal: " << hexadecimal << " es " << binsimpl[0] << " en binario" << endl;
cout << "Volver a menu principal" << endl;
system("read a");
main();
delete[] binsimpl;
delete[] hexadecimal;
}

char* ConvertirHexABinSimple(char hexa, char* bin) // CORRECTO
{

if(hexa == '0')
{
bin[0] = '0';
bin[1] = '0';
bin[2] = '0';
bin[3] = '0';
} else if(hexa == '1')
{
bin[0] = '0';
bin[1] = '0';
bin[2] = '0';
bin[3] = '1';
} else if(hexa == '2')
{
bin[0] = '0';
bin[1] = '0';
bin[2] = '1';
bin[3] = '0';
} else if(hexa == '3')
{
bin[0] = '0';
bin[1] = '0';
bin[2] = '1';
bin[3] = '1';
} else if(hexa == '4')
{
bin[0] = '0';
bin[1] = '1';
bin[2] = '0';
bin[3] = '0';
} else if(hexa == '5')
{
bin[0] = '0';
bin[1] = '1';
bin[2] = '0';
bin[3] = '1';
} else if(hexa == '6')
{
bin[0] = '0';
bin[1] = '0';
bin[2] = '1';
bin[3] = '1';
} else if(hexa == '7')
{
bin[0] = '0';
bin[1] = '1';
bin[2] = '1';
bin[3] = '1';
} else if(hexa == '8')
{
bin[0] = '1';
bin[1] = '0';
bin[2] = '0';
bin[3] = '0';
} else if(hexa == '9')
{
bin[0] = '1';
bin[1] = '0';
bin[2] = '0';
bin[3] = '1';
} else if(hexa == 'A')
{
bin[0] = '1';
bin[1] = '0';
bin[2] = '1';
bin[3] = '0';
} else if(hexa == 'B')
{
bin[0] = '1';
bin[1] = '0';
bin[2] = '1';
bin[3] = '1';
} else if(hexa == 'C')
{
bin[0] = '1';
bin[1] = '1';
bin[2] = '0';
bin[3] = '0';
} else if(hexa == 'D')
{
bin[0] = '1';
bin[1] = '1';
bin[2] = '0';
bin[3] = '1';
} else if(hexa == 'E')
{
bin[0] = '1';
bin[1] = '1';
bin[2] = '1';
bin[3] = '0';
} else if(hexa == 'F')
{
bin[0] = '1';
bin[1] = '1';
bin[2] = '1';
bin[3] = '1';
}


return bin;
delete[] bin;

}

void ConvertirHexadecimalADecimal() // CORRECTO
{
char *hexadecimal;
hexadecimal = new char[32];
int decimal = 0, cifras = 0;

cout << "Indique el numero hexadecimal: "; cin >> hexadecimal;
cout << endl;

if(strchr(hexadecimal, 'GHIJKLMNÑOPQRSTUVWXYZ'))
{
for(int j = 0; hexadecimal[j]; j++)
{
cifras = j+1;
}

int k = 0;
int i = cifras-1;

while(i >= 0)
{
if(hexadecimal[i] >= 0 && hexadecimal[i] != 'A' && hexadecimal[i] != 'B' && hexadecimal[i] != 'C' && hexadecimal[i] != 'D' && hexadecimal[i] != 'E' && hexadecimal[i] != 'F')
{
decimal += (hexadecimal[i]-'0')*pow(16,k);
} else {
decimal += (hexadecimal[i]-'7')*pow(16,k);
}
k++;
i--;
}

cout << "El hexadecimal " << hexadecimal << " es " << decimal << " en decimal" << endl;
cout << "Volver a menu principal" << endl;
system("read a");
main();
delete[] hexadecimal;
} else {
cout << "Valor incorrecto, introduzcalo de nuevo";
system("read a");
ConvertirHexadecimalADecimal();
}

}

Permalink Dejar un comentario

Desarrollando un nuevo programa

septiembre 30, 2009 at 11:13 pm (Cpp, Programación)

Buenas!, El otro día tuve informática y empezamos a “dar” las notaciones decimal, hexadecimal y binaria, y el profesor me dio la idea de desarrollar un programa que convierta numeros de una notación a otra, estoy trabajando en ello, porque hay partes del algoritmo que no me resultan bien, pero bueno, la verdad es que va muy bien, con pequeños fallos, es obvio que yo ya conocia las notaciones, si no no me habría aventurado a desarrollar el programa en C++ .. Lo colgaré en cuanto lo termine y compruebe que funciona, por cierto, tambien tengo que contaros otras novedades, atentos al blog!.

Saludoos!.

Permalink Dejar un comentario

Next page »