Stack Overflow Asked on December 25, 2021
I want to read a binary file image.dd
into struct teststruct *test;
. Basically there are two problems:
1. Wrong order because of little / big endian.
printf("%02x", test->magic);
just gives me 534b554c
instead of 4c55b453
(maybe this has something to do with the "main problem" in the next part). Its just "one value". As an example, printf("%c", test->magic);
gives L
instead of LUKS
.
2. No output with test->version
.
uint16_t version;
in struct teststruct
gives no output. Which means, i call printf("%x ", test->version);
and there is no result.
This is exampleh.h
which contains struct
:
#ifndef _EXAMPLEH_H
#define _EXAMPLEH_H
#define MAGIC_L 6
struct teststruct {
char magic [MAGIC_L];
uint16_t version;
};
#endif
This is the main
code:
using namespace std;
#include <stdint.h>
#include <string.h>
#include <iostream>
#include <fstream>
#include "exampleh.h"
struct teststruct *test;
int main() {
FILE *fp = fopen("C:\image.dd", "rb"); // open file in binary mode
if (fp == NULL) {
fprintf(stderr, "Can't read file");
return 0;
}
fread(&test,sizeof(test),1,fp);
//printf("%x ", test->magic); //this works, but in the wrong order because of little/big endian
printf("%x ", test->version); //no output at all
fclose(fp);
return 0;
}
And this here are the first 114 Bytes of image.dd
:
4C 55 4B 53 BA BE 00 01 61 65 73 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 78 74 73 2D 70 6C 61 69
6E 36 34 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 73 68 61 32 35 36 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 10 00 00 00 00 40
printf("%x ", test->magic);
invokes undefined behavior because pointer (automatically converted from the array) is passed to where unsigned int
is required.In this case, the observed behavior is because:
Firstly, fread(&test,sizeof(test),1,fp);
read the first few bytes from the file as pointer value.
Then, printf("%02x", test->magic);
printed the first 4-byte integer from the file because test->magic
is (converted to) the pointer to the array placed at the top of the structure, and the address of the array is same as the address of the structure itself, so the address read from the file is printed. One more lucky is that where to read 4-byte integer and address (pointer) from as function arguments are the same.
Finally, you didn't get any output from printf("%x ", test->version);
because the address read from the file is unfortunately in region that is not readable and trying to read there caused Segmentation Fault.
Fixed code:
using namespace std;
#include <stdint.h>
#include <string.h>
#include <iostream>
#include <fstream>
#include "exampleh.h"
struct teststruct test; // allocate structure directly instead of pointer
int main() {
FILE *fp = fopen("C:\image.dd", "rb"); // open file in binary mode
if (fp == NULL) {
fprintf(stderr, "Can't read file");
return 0;
}
fread(&test,sizeof(test),1,fp); // now structure is read instead of pointer
for (int i = 0; i < 6; i++) {
printf("%02x", (unsigned char)test.magic[i]); // print using proper combination of format and data
}
printf(" ");
printf("%x ", test.version); // also use . instead of ->
fclose(fp);
return 0;
}
Answered by MikeCAT on December 25, 2021
struct teststruct *test;
points to NULL
, as it is defined in the global namespace. You do not allocate memory for this pointer, so test->version
is UB.
fread(&test,sizeof(test),1,fp);
is also wrong, this will read a pointer, not the content of the struct.
An easy fix is to change test
to be a struct teststruct
and not a pointer to it.
using namespace std;
#include <stdint.h>
#include <string.h>
#include <iostream>
#include <fstream>
#include "exampleh.h"
struct teststruct test; //not a pointer anymore
int main() {
FILE *fp = fopen("C:\image.dd", "rb"); // open file in binary mode
if (fp == NULL) {
fprintf(stderr, "Can't read file");
return 0;
}
fread(&test,sizeof(test),1,fp);
//printf("%x ", test.magic); //this works, but in the wrong order because of little/big endian
printf("%x ", test.version); //no output at all
fclose(fp);
return 0;
}
Answered by mch on December 25, 2021
Get help from others!
Recent Answers
Recent Questions
© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP