Por favor, tengan paciencia conmigo. Todavía soy nuevo en la programación en C, mi objetivo es obtener un número de serie que esté guardado en un archivo llamado mtd0 y validar ese número de serie. En bash, el comando es:

dd if=/dev/mtd0 bs=1 skip=$((0x1fc30)) count=16 2>/dev/null

Y la salida debería ser:

1866203214226041

Pero quiero hacerlo en lenguaje C puro, lo que he intentado hasta ahora es así:

#include <stdio.h>
#include <string.h>

int main ()
{
    FILE *fp;
    FILE *s;

    fp = fopen("/tmp/mtd0","rb");
    if(NULL == fp) {
        printf("\n Cannot open file!!!\n");
        return 1;
    }
    typedef unsigned char byte; 
    byte s_no[16];
    fseek(fp, 0x1fc30, SEEK_SET);
    fread(s_no, 1, 16, fp);
    printf ("Serial number: %s\n", s_no);
    fclose(fp);

    char mtd0[16];
    char defser[16];
    int ret;

    memcpy(mtd0, s_no, 16);
    memcpy(defser, "1866203214226041", 16);

    ret = memcmp(mtd0, defser, 16);

    if(ret == 0)
    {
        printf("Serial number is correct!\n");
    }
    else 
    {
        printf("Serial number is not correct\n");
    }

    return(0);
}

Pero cuando ejecuto eso, no imprime nada. mtd0 no es un archivo de texto normal, no sé cómo se llama, pero el archivo se parece a esto descargue ese archivo si necesita más información. Entonces, ¿cómo puedo arreglar mi código anterior?

c
0
hillz 16 ene. 2017 a las 20:56
Eso se llama archivo binario .
 – 
Alex K.
16 ene. 2017 a las 20:59
Oh, sí, gracias, pero ¿sabes cómo arreglar mi código anterior?
 – 
hillz
16 ene. 2017 a las 20:59
En C necesitará usar strcmp no == para comparar cadenas y fread para leer los datos del archivo.
 – 
Alden
16 ene. 2017 a las 21:00
sn = fread( fp, 0x1fc30, 16 ); printf ("Serial number: %s\n", sn ); -> fread() devuelve size_t, algún tipo de entero. Eso no es algo para imprimir con printf ("%s", sn ); Ciertamente, su compilador debería proporcionar una advertencia. Habilite todas las advertencias para ahorrar tiempo.
 – 
chux - Reinstate Monica
16 ene. 2017 a las 21:34
Tenga en cuenta que la cadena 1866203214226041 se insertará literalmente en el binario resultante, lo que hará que romper la protección sea trivial.
 – 
Daniel Kamil Kozar
16 ene. 2017 a las 21:46

3 respuestas

Hay algunas cosas mal en lo que estás haciendo.

  1. fseek simplemente ajusta el puntero del archivo para la siguiente lectura o escritura del archivo; en realidad, no recupera nada del archivo. Además, los valores válidos para el tercer argumento de fseek son:

    • SEEK_SET: establece la posición del puntero del archivo al principio del archivo más el valor en el segundo argumento

    • SEEK_CUR: establece la posición del puntero del archivo en la posición actual del puntero del archivo, más el valor del segundo argumento

    • SEEK_END: establece la posición del puntero del archivo al final del archivo.

  2. Suponiendo que quería hacer "leer 16 bytes del archivo en la posición 0x1fc30", querría guardar esos datos como una matriz de bytes, no como una cadena:

    typedef unsigned char byte; 
    byte s_no[16];
    fseek(fp, 0x1fc30, SEEK_SET);
    fread(s_no, 1, 16, fp);
    
  3. Si bien strcmp es la forma correcta de comparar cadenas en C, si el número de serie se almacena como bytes , lo que supongo que es, porque /dev/mtd0 parece un binario archivo, tendría que comparar la memoria usando memcmp con otra matriz de bytes establecida en el valor válido para la serie.

1
Govind Parmar 16 ene. 2017 a las 21:12
Hola, gracias. Me las arreglé para comparar el número de serie pero hay un pequeño problema con mi código, a veces el número de serie muestra caracteres adicionales al final como este s27.postimg.org/dkumqgmcj/screenshot_2017_01_17_01_34_16.png He actualizado mi código en mi publicación, por favor échale un vistazo nuevamente
 – 
hillz
16 ene. 2017 a las 21:38
Si lo está imprimiendo como una cadena, haga que la matriz de bytes tenga 17 elementos de longitud y configure manualmente el último elemento (s_no[16]) en 0 antes de llamar a printf pero después de llamar a fread
 – 
Govind Parmar
16 ene. 2017 a las 23:56

Fseek no lee del archivo, simplemente mueve el puntero del archivo para su próxima lectura. Necesita usar fread para leer desde el archivo. La documentación sobre fread se puede encontrar aquí: https://linux.die.net/man/3/ fread.

Además, es una buena práctica abrir un archivo binario en modo binario:

fopen("mtd0","rb");

Según el comentario de Alden, la comparación de cadenas en C se realiza mediante una función llamada strcmp, cuya documentación se puede encontrar aquí: https://linux.die.net/man/3/strcmp.

Finalmente, probablemente debería calificar completamente la ruta a mtd0, es decir:

fopen("/dev/mtd0","rb");
0
Irisshpunk 16 ene. 2017 a las 21:01
Todavía no imprime nada, ¿puede descargar el archivo mtd0 que he proporcionado arriba y ver qué pasa con mi código? También he actualizado mi código anterior con su sugerencia.
 – 
hillz
16 ene. 2017 a las 21:14
Fread no devuelve su salida, devuelve el número de elementos que ha leído. Eche otro vistazo a la documentación sobre fread.
 – 
Irisshpunk
16 ene. 2017 a las 21:16

Utilice strcmp:

if (strcmp (sn, "1866203214226041") != 0) {
    printf("Serial number is correct\n");
}
0
Saurav Sahu 16 ene. 2017 a las 21:04