Mostrando las entradas con la etiqueta C. Mostrar todas las entradas
Mostrando las entradas con la etiqueta C. Mostrar todas las entradas

miércoles, 11 de febrero de 2015

Como leer Numeros Magicos con C (file signatures)

En esta ocasión aprenderemos a leer los números mágicos de un archivo,esto funciona para saber el tipo de archivo de un archivo,si así como suena ya que algunas ocasiones podemos deducir el tipo de archivo solo por su extension,por ejemplo podemos tener una imagen con este nombre:

imagen.png

Pero que tal si es formato .jpg o incluso un vídeo o audio,esto no es muy importante,para el usuario,pero a la hora de programar algo de bajo nivel o incluso de nivel usuario,por ejemplo una GUI si no seleccionamos el archivo correcto tendríamos un error,por ejemplo un reproductor de música o vídeo que le mandemos una imagen como ruta,esto causaría el cierre de la aplicación o en sistemas débiles el congelamiento de todo el sistema.

Bueno también en ocasiones tenemos archivos sin extensión,con el nombre por ejemplo:

archivo

En Unix si tiene permisos de ejecución lo mas seguro es que sea un programa,pero en ocasiones son archivos multimedia,como dije el usuario no se debe preocupar por esto ya que si tienen un explorador potente como por ejemplo Dolphin de KDE el lee los Magic Numbers y si tenemos una imagen sin extensión la detecta:



Como vemos detecta los archivos,pero si quisiéramos crear un explorador necesitaríamos usar números mágicos y no filtro por extensión.

En esta ocasión vamos a hacer este trabajo usando C,ya que lo vamos a usar en el sistema,si lo quisiéramos usar por ejemplo en Android lo podemos hacer en Java o usando el NDK.

Bien vamos a leer el archivo en modo binario y vamos a leer los primeros 8 bytes que serian 8 char,los primeros 8 char del archivo,luego los vamos a imprimir en pantalla,hay caracteres Hex que no se pueden imprimir asi que solo imprimiremos los que se puedan.


1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
#include <stdio.h>
#include <ctype.h>

#define BYTES 8 // Numero de bytes

void readFile(char *file); // Funcion que leera el archivo,le pasamos el nombre

int main(int argv,char *argc[])
{
    if (argv>1)
        readFile(argc[1]); // Le pasamos el nombre del archivo que indiquemos en el argumento
    return 0;
}

void readFile(char *file)
{
    char nums[BYTES]; // Definimos un array de n bytes
    int i;
    FILE *fp = fopen(file,"rb"); // Abrimos el archivo en modo binario y lectura
    fread(nums,1,BYTES,fp); // Lemos los primeros n bytes
    for (i=0;i<BYTES;i++) // Recorremos el array
    {
        if (isgraph(nums[i]))  // Si se puede imprimir
            printf("Nums %c\n",nums[i]); // Lo imprimimos
    }

    fclose(fp);
    return;
}


Ahora vamos a usarlo:


Como vemos en el primer archivo use una imagen png con extensión jpg y no hubo problema al detectar el tipo de archivo,en el segundo use un .pdf y efectivamente es .pdf.

Algunos archivos no simplemente van a decir PNG o PDF,por ejemplo el numero magico de un mp3 es ID3:


Algunos números mágicos los podemos encontrar aquí:

https://en.wikipedia.org/wiki/List_of_file_signatures

Y eso nos sirve para definir un array de comprobacion,por ejemplo para el mp3,seria en HEX:

49 44 33

Que solo serian 3 bytes,3 char:

Veamos:


1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
#include <stdio.h>
#include <ctype.h>

#define BYTES 8 // Numero de bytes

typedef enum _boolean {FALSE,TRUE} boolean; // Tipo boolean

void readFile(char *file); // Funcion que leera el archivo,le pasamos el nombre

boolean isMp3(char *file); // Funcion para saber si es mp3

int main(int argv,char *argc[])
{
    if (argv>1){

        readFile(argc[1]); // Le pasamos el nombre del archivo que indiquemos en el argumento
        if(isMp3(argc[1])) // Vemos si es mp3
            printf("%s es mp3\n",argc[1]);
        else
            printf("%s no es mp3\n",argc[1]);
    }
    
    return 0;
}

boolean isMp3(char *file)
{
    const int lenNum = 3; // Numero de Bytes
    char nums[lenNum]; // array que contendra los numero magicos
    char id[] = {0x49,0x44,0x33}; // Numeros magicos del mp3
    int i;
    boolean flag = TRUE; // Este sera el valor de retorno
    FILE *fp = fopen(file,"rb"); // Abrimos el archivo
    fread(nums,1,lenNum,fp); // Lemos los primeros 3 bytes
    for (i=0;i<lenNum;i++) // Recorremos el array
    {
        if(nums[i] != id[i]) // Si no son iguales 
        {
             flag = FALSE; // Cambiamos el valor de retorno
             break; // rompemos el bucle
        }
    }
    fclose(fp); // Cerramos el archivo
    return flag; // Regresamos el valor
}

void readFile(char *file)
{
    char nums[BYTES]; // Definimos un array de n bytes
    int i;
    FILE *fp = fopen(file,"rb"); // Abrimos el archivo en modo binario y lectura
    fread(nums,1,BYTES,fp); // Lemos los primeros n bytes
    for (i=0;i<BYTES;i++) // Recorremos el array
    {
        if (isgraph(nums[i]))  // Si se puede imprimir
            printf("Nums %c\n",nums[i]); // Lo imprimimos
    }

    fclose(fp);
    return;
}

Con esa funcion que definimos logramos saber si un archivo es mp3,igual lo podemos hacer con un mp4 solo que wikipedia nos dice que hay dos posibilidades,veamos:


1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
#include <stdio.h>
#include <ctype.h>

#define BYTES 8 // Numero de bytes

typedef enum _boolean {FALSE,TRUE} boolean; // Tipo boolean

void readFile(char *file); // Funcion que leera el archivo,le pasamos el nombre

boolean isMp3(char *file); // Funcion para saber si es mp3

boolean isMp4(char *file);

int main(int argv,char *argc[])
{
    if (argv>1){

        readFile(argc[1]); // Le pasamos el nombre del archivo que indiquemos en el argumento
        if(isMp4(argc[1])) // Vemos si es mp3
            printf("%s es mp4\n",argc[1]);
        else
            printf("%s no es mp4\n",argc[1]);
    }
    
    return 0;
}

boolean isMp4(char *file)
{
    const int lenNum = 4; // Numero de Bytes
    char nums[lenNum]; // array que contendra los numero magicos
    char id1[] = {0x22,0x67,0x70,0x35}; // Numeros magicos del mp4
    char id2[] = {0x66,0x74,0x79,0x70}; // Numeros magicos del mp4(otra posibilidad)
    int i;
    boolean flag = TRUE; // Este sera el valor de retorno
    FILE *fp = fopen(file,"rb"); // Abrimos el archivo
    fread(nums,1,lenNum,fp); // Lemos los primeros 4 bytes para probar el primer id
    for (i=0;i<lenNum;i++) // Recorremos el array
    {
        if(nums[i] != id1[i]) // Si no son iguales 
        {
             flag = FALSE; // Cambiamos el valor de retorno
             break; // rompemos el bucle
        }
    }
    if (flag == FALSE) // Si la bandera es FALSE probamos el siguiente id
    {
        flag = TRUE; // Cambiamos el flag a TRUE
        fseek( fp, 4, SEEK_SET ); // Nos movemos 4 bytes a la derecha ya que no nos sirven estos : 00 00 00 nn
        fread(nums,1,lenNum,fp); // Lemos los segundos 4 bytes
        for (i=0;i<lenNum;i++) // Recorremos el array
        {
            if(nums[i] != id2[i]) // Si no son iguales 
            {
                flag = FALSE; // Cambiamos el valor de retorno
                break; // rompemos el bucle
            }
        }
    }
    fclose(fp); // Cerramos el archivo
    return flag; // Regresamos el valor
}

boolean isMp3(char *file)
{
    const int lenNum = 3; // Numero de Bytes
    char nums[lenNum]; // array que contendra los numero magicos
    char id[] = {0x49,0x44,0x33}; // Numeros magicos del mp3
    int i;
    boolean flag = TRUE; // Este sera el valor de retorno
    FILE *fp = fopen(file,"rb"); // Abrimos el archivo
    fread(nums,1,lenNum,fp); // Lemos los primeros 3 bytes
    for (i=0;i<lenNum;i++) // Recorremos el array
    {
        if(nums[i] != id[i]) // Si no son iguales 
        {
             flag = FALSE; // Cambiamos el valor de retorno
             break; // rompemos el bucle
        }
    }
    fclose(fp); // Cerramos el archivo
    return flag; // Regresamos el valor
}

void readFile(char *file)
{
    char nums[BYTES]; // Definimos un array de n bytes
    int i;
    FILE *fp = fopen(file,"rb"); // Abrimos el archivo en modo binario y lectura
    fread(nums,1,BYTES,fp); // Lemos los primeros n bytes
    for (i=0;i<BYTES;i++) // Recorremos el array
    {
        if (isgraph(nums[i]))  // Si se puede imprimir
            printf("Nums %c\n",nums[i]); // Lo imprimimos
    }

    fclose(fp);
    return;
}

Así podemos crear un biblioteca con todas las extensiones para usarlas en un programa.

Eso es todo :D
Leer más...

viernes, 16 de enero de 2015

Como convertir un string a binario con C

Esto es especificamente con C o C++,pero especificamente con C,en este caso hacemos uso del poderoso Union y de punteros:


1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
#include <stdio.h>

typedef struct _byte { /* Estructuramos 8 bits para un Byte */
    unsigned a: 1;
    unsigned b: 1;
    unsigned c: 1;
    unsigned d: 1;
    unsigned e: 1;
    unsigned f: 1;
    unsigned g: 1;
    unsigned h: 1;
} byte;

typedef union _charbits { /* Unimos un char(caracter) con un Byte */
    char ch;
    byte bits;
} charbits;

void decode(byte b)/* Esta funcion decodifica el char en 8 bits */
{
    printf("%2u%2u%2u%2u%2u%2u%2u%2u  ",b.h,b.g,b.f,b.e,b.d,b.c,b.b,b.a);
}

void readString(const char *str)/* Esta funcion simplemente lee la string como un array de punteros a char y los decodifica char a char con la funcion de arriba*/
{
    charbits word;
    while(*str) 
    {
        word.ch = *str;
        decode(word.bits);
        *str++;
    }
    printf("\n");
}

int main(int argv,char **argc) /* Iniciamos el main */
{
    if (argv > 1)
        readString(argc[1]);
    else
        printf( "Uso : %s <Palabra>",argc[0]);
    return 0;
}

Para compilar metemos el codigo en un archivo por ejemplo:

decode.c


Y compilamos:

gcc -o decode decode.c

./decode "Tiempo de Tux"

 0 1 0 1 0 1 0 0   0 1 1 0 1 0 0 1   0 1 1 0 0 1 0 1   0 1 1 0 1 1 0 1   0 1 1 1 0 0 0 0   0 1 1 0 1 1 1 1   0 0 1 0 0 0 0 0   0 1 1 0 0 1 0 0   0 1 1 0 0 1 0 1   0 0 1 0 0 0 0 0   0 1 0 1 0 1 0 0   0 1 1 1 0 1 0 1   0 1 1 1 1 0 0 0  


Eso es todo.
Leer más...

viernes, 17 de octubre de 2014

[Shell] Reloj binario en C

Esta ocasión crearemos un reloj binario en C,en el entorno de escritorio KDE,contamos con un reloj binario como applet,me imagine como programar uno y mas adelante colocare el código.

En primer lugar debemos saber como leerlo,en esta ocasión el reloj se basa en cuatro bits,representados por 1 y 0 como realmente se hace,para el bit activo usamos 1 y para el bit apagado usamos 0,el reloj esta representado en formato de 24 horas y cada hora es un Byte de 4 bits un nibble.

Veamos la notación,por ejemplo las 5 de la tarde es 17 en formato de 24 horas,ahora vamos a dividir los números de uno en uno y nos queda 1 y 7,representados en binario son:

1 = 0001
7 = 0111

Bien la lectura binaria la podemos traducir asi de la forma mas fácil,imaginemos que los numero de arriba corresponden a una potencia de 2,comensando por el 1 y luego el 2 mismo,en nuestro caso cuatro bits:

8 4 2 1

Ahora abajo de esos numero colocamos el 0 o 1 que estén activados para que la suma de el numero en notación decimal,por ejemplo 1 y 7:

bits : 8   4   2   1

1  =   0   0   0   1
7  =   0   1   1   1

Bien ahora sumamos los bits que están activos:

1 = 0+0+0+1 = 1 en decimal

7 = 0+4+2+1 = 7 en decimal

Bien eso es todo ahora si el código,el código cuenta con 6 numero en notación binaria,2 para la hora 2 para los minutos y dos para los segundos:

El código se basa en programación funcional  y llamamos las funciones una a una en el main.



1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
#include <stdio.h>
#include <time.h>
#include <string.h>
#include <stdlib.h>

/*
 * Archivo : relojbinario.c
 * Compila : gcc -o relojbinario relojbinario.c
 */


#define BUF_TIME 60
#define BITS 4

typedef enum {
    ZERO = 0x30,
    UNO,
    DOS,
    TRES,
    CUATRO,
    CINCO,
    SEIS,
    SIETE,
    OCHO,
    NUEVE
} Hora;

typedef struct _f_hora {
    int hora_decena[BITS];
    int hora_unidad[BITS];
    int minuto_decena[BITS];
    int minuto_unidad[BITS];
    int segundo_decena[BITS];
    int segundo_unidad[BITS];
} f_hora;

char formato[] = "%k%M%S";
char fecha[BUF_TIME];
void create_clock();
void create_num(char num,f_hora *hora,int i);
void destroy_Binary(f_hora *hora);
void create_binary(f_hora *hora);
void show_clock(f_hora hora);

int main()
{
    f_hora hora;
    create_clock();
    create_binary(&hora);
    show_clock(hora);
    return 0;
}

void create_clock()
{
    struct tm *tiempo;
    time_t ahora = time(0);
    tiempo = localtime(&ahora);
    strftime(fecha,BUF_TIME,formato,tiempo);
}

void create_binary(f_hora *hora)
{
    int len = strlen(fecha),i;
    if (len == 0)
        exit(1);
    for (i = 0;i< len;i++)
        create_num(fecha[i],hora,i);
}

void create_num(char num,f_hora *hora,int iter)
{
    int aux[BITS],i;
    switch((int)num)
    {
        case ZERO:
            aux[0] = 0;
            aux[1] = 0;
            aux[2] = 0;
            aux[3] = 0;
            break;
        case UNO:
            aux[0] = 0;
            aux[1] = 0;
            aux[2] = 0;
            aux[3] = 1;
            break;
        case DOS:
            aux[0] = 0;
            aux[1] = 0;
            aux[2] = 1;
            aux[3] = 0;
            break;
        case TRES:
            aux[0] = 0;
            aux[1] = 0;
            aux[2] = 1;
            aux[3] = 1;
            break;
        case CUATRO:
            aux[0] = 0;
            aux[1] = 1;
            aux[2] = 0;
            aux[3] = 0;
            break;
        case CINCO:
            aux[0] = 0;
            aux[1] = 1;
            aux[2] = 0;
            aux[3] = 1;
            break;
        case SEIS:
            aux[0] = 0;
            aux[1] = 1;
            aux[2] = 1;
            aux[3] = 0;
            break;
        case SIETE:
            aux[0] = 0;
            aux[1] = 1;
            aux[2] = 1;
            aux[3] = 1;
            break;
        case OCHO:
            aux[0] = 1;
            aux[1] = 0;
            aux[2] = 0;
            aux[3] = 0;
            break;
        case NUEVE:
            aux[0] = 1;
            aux[1] = 0;
            aux[2] = 0;
            aux[3] = 1;
            break;
        default:
            break;
    }
    for (i=0;i<BITS;i++)
    {
        if (iter == 0)
        {
            hora->hora_decena[i] = aux[i];
        }
        else if (iter == 1)
        {
            hora->hora_unidad[i] = aux[i];
        }
        else if (iter == 2)
        {
            hora->minuto_decena[i] = aux[i];
        }
        else if (iter == 3)
        {
            hora->minuto_unidad[i] = aux[i];
        }
        else if (iter == 4)
        {
            hora->segundo_decena[i] = aux[i];
        }
        else
        {
            hora->segundo_unidad[i] = aux[i];
        }
    }
}

void show_clock(f_hora hora)
{
    int i;
    for (i=0;i<BITS;i++)
    {
        printf("\t%d\t",hora.hora_decena[i]);
        printf("\t%d\t",hora.hora_unidad[i]);
        printf("\t%d\t",hora.minuto_decena[i]);
        printf("\t%d\t",hora.minuto_unidad[i]);
        printf("\t%d\t",hora.segundo_decena[i]);
        printf("\t%d\t",hora.segundo_unidad[i]);
        puts("");
    }
}


Para compilar usamos:

gcc -o relojbinario relojbinario.c

Y si lo ejecutamos en linux podemos llamarlo así,para ver como se ejecuta cada segundo:




while [ 1 ];do sleep 1; clear; ./relojbinario; done


-->
Leer más...

martes, 4 de diciembre de 2012

Compilar C con gcc desde iOS

Últimamente he estado aprendiendo un poco de C gracias a hitmontop , también hay algo que he estado pensando, y es si se podrán ejecutar programas C desde el iphone,ipod touch, y si si se puede :D

Solo que en varios sitios hablan de un riesgo,de que se puede trabar el nuestro dispositivo a la hora de arrancar.

Pero encontré un muy buen tutorial donde muestran como hacerlo y yo no he tenido problemas con mi ipod touch 3g iOS 5.1.1 ni con mi iphone 4g iOS
5.1.1.

Enlace

Pero de todas formas:Esto es avanzado y lo hace bajo su propio riesgo.  

Bien como somos arriesgados,necesitamos ya tener el jailbreak

También necesitamos instalar de cydia,openssh,APT 0.7 HTTPS Method,wget,tar, también sbsettings y el toogle de ssh,para activarlo


Ahora en nuestro sistema operativo necesitamos un cliente ssh,en mi caso Archlinux instale openssh

sudo pacman -S openssh
Para su sistema,o distribución googlen openssh

Ahora conectamos la pc y el iphone/ipod a la misma red

Abrimos la terminal de Linux y escribimos

ssh root@ip_de_tu_iphone
La ip de tu iphone la obtienes con mismo sbsettings,(esta hasta abajo).



Cuando nos conectemos nos pedirá el password de root

Normalmente es:

alpine

Pero puede que lo haya cambiado

Ya conectados por ssh,hacemos lo siguiente:

1.Descarga libgcc con wget

wget http://www.syshalt.net/pub/iphone/gcc-iphone/fake-libgcc_1.0_iphoneos-arm.deb
2,Instala con dpkg

 dpkg –i fake-libgcc_1.0_iphoneos-arm.deb 

3.Ahora instala iphone-gcc con apt-get

apt-get install iphone-gcc 
Descargamos gcc usando wget:

wget http://www.syshalt.net/iphone/gcc-iphone/sdk-2.0-headers.tar.gz 
Descomprimes con tar:

tar -xvzf sdk-2.0-headers.tar.gz 
Entramos a la carpeta que se genero:

cd include-2.0-sdk-ready-for-iphone 

Copiamos todos los archivos a /usr/include

cp –r * /usr/include
Regresamos al directorio anterior

cd ..

Y descargamos gcc files:

wget http://www.syshalt.net/iphone/gcc-iphone/gcc_files.tar.gz
Descomprimimos y entramos a la carpeta que se genero:

tar -xvzf gcc_files.tar.gz

cd gcc_files
 Y copiamos su contenido a /usr/lib

cp –r * /usr/lib
Por ultimos instalamos ldid con apt-get:

apt-get install ldid
Ahora creamos Hola Mundo

Con nano

nano holamundo.c

Y metemos lo siguiente:


#include <stdio.h>
int main()
{
printf("Hola Mundo!!!\n");
return 0;
}


Y compilamos así:


gcc holamundo.c -o hola

y


ldid –S hola
Ahora ejecutamos así 


./hola




Eso es todo :D

Visto en : blog.syshalt.net

Leer más...