如何制作一个空指针来读取二进制文件的给定部分
How to make a void pointer to read a given part of a binary file
我有一个二进制文件,其中包含 3 个不同的结构和一个圣诞节文本。在二进制文件的第一行,他们为我提供了一个代表文件内包大小的整数。一个包包含 3 个结构,chistmastext 和大小。
这些结构位于一个名为 framehdr.h 的文件中,我正在阅读的二进制文件名为 TCPdump。
现在我正在尝试创建一个程序,att 将一次读取每个包,然后撤回文本。
我从这样的事情开始:
#pragma warning(disable: 4996)
#include <stdio.h>
#include <stdlib.h>
#include "framehdr.h"
#include <crtdbg.h>
int main()
{
_CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);
FILE *fileOpen;
char *buffer;
size_t dataInFile;
long filesize;
// The three structs
struct ethernet_hdr ethHdr;
struct ip_hdr ipHdr;
struct tcp_hdr tcpHDr;
fileOpen = fopen("C:\Users\Viktor\source\repos\Laboration_3\Laboration_3\TCPdump", "rb");
if (fileOpen == NULL)
{
printf("Error\n");
}
else
{
printf("Success\n");
}
char lenOf[10];
size_t nr;
// Reads until \n comes
fgets(lenOf, sizeof(lenOf), fileOpen);
sscanf(lenOf, "%d", &nr);
// Withdraw the size of a package and check if it's correct
printf("Value: %d\n", nr);
printf("Adress: %d\n", &nr);
void *ptr;
fread(&ptr, nr, 1, fileOpen);
int resEth = 14;
printf("resEth: %d\n", resEth);
int resIP = IP_HL((struct ip_hdr*)ptr);
printf("ResIP: %d\n", resIP);
int resTcp = TH_OFF((struct tcp_hdr*)ptr);
printf("tcpIP: %d\n", resTcp);
int res = resEth + resIP + resTcp;
printf("Total: %d", res);
fclose(fileOpen);
//free(buffer);
system("pause");
return 0;
}
我知道第一个 struct ethernet 的大小始终为 14,但我需要获取其他 2 个的大小,我想为此使用 IP_HL 和 TH_OFF .
但我的问题在于我似乎无法将整个包读成一个
void * 与恐惧。我在我的 *ptr 中注意到了。
当我尝试将 void * 转换为其中一个结构时,这又会导致代码中断。
void * 我做错了什么?
两个问题:
首先你不应该在读取二进制文件时真正使用文本函数。二进制文件实际上并没有 "lines",因为文本文件有它。
其次,与
void *ptr;
fread(&ptr, nr, 1, fileOpen);
您正在将指针 传递给指针变量 ,您实际上并没有将任何内容读入内存,然后使 ptr
指向该内存。现在发生的是fread
函数会从文件中读取nr
字节,然后写入到&ptr
指向的内存中,这会导致undefined behavior if nr > sizeof ptr
(因为那时数据将被写出边界)。
您必须分配 nr
字节的内存,然后将指针传递给该内存的第一个元素:
char data[nr];
fread(data, nr, 1, fileOpen);
您还应该养成检查错误的习惯。如果 fread
函数失败怎么办?或者文件被截断,没有 nr
个字节可供读取?
您可以通过检查 fread
returns.
来检查这些条件
并且不仅检查 fread
,还有比 fopen
更多的功能可能会失败。
我有一个二进制文件,其中包含 3 个不同的结构和一个圣诞节文本。在二进制文件的第一行,他们为我提供了一个代表文件内包大小的整数。一个包包含 3 个结构,chistmastext 和大小。 这些结构位于一个名为 framehdr.h 的文件中,我正在阅读的二进制文件名为 TCPdump。
现在我正在尝试创建一个程序,att 将一次读取每个包,然后撤回文本。 我从这样的事情开始:
#pragma warning(disable: 4996)
#include <stdio.h>
#include <stdlib.h>
#include "framehdr.h"
#include <crtdbg.h>
int main()
{
_CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);
FILE *fileOpen;
char *buffer;
size_t dataInFile;
long filesize;
// The three structs
struct ethernet_hdr ethHdr;
struct ip_hdr ipHdr;
struct tcp_hdr tcpHDr;
fileOpen = fopen("C:\Users\Viktor\source\repos\Laboration_3\Laboration_3\TCPdump", "rb");
if (fileOpen == NULL)
{
printf("Error\n");
}
else
{
printf("Success\n");
}
char lenOf[10];
size_t nr;
// Reads until \n comes
fgets(lenOf, sizeof(lenOf), fileOpen);
sscanf(lenOf, "%d", &nr);
// Withdraw the size of a package and check if it's correct
printf("Value: %d\n", nr);
printf("Adress: %d\n", &nr);
void *ptr;
fread(&ptr, nr, 1, fileOpen);
int resEth = 14;
printf("resEth: %d\n", resEth);
int resIP = IP_HL((struct ip_hdr*)ptr);
printf("ResIP: %d\n", resIP);
int resTcp = TH_OFF((struct tcp_hdr*)ptr);
printf("tcpIP: %d\n", resTcp);
int res = resEth + resIP + resTcp;
printf("Total: %d", res);
fclose(fileOpen);
//free(buffer);
system("pause");
return 0;
}
我知道第一个 struct ethernet 的大小始终为 14,但我需要获取其他 2 个的大小,我想为此使用 IP_HL 和 TH_OFF .
但我的问题在于我似乎无法将整个包读成一个 void * 与恐惧。我在我的 *ptr 中注意到了。 当我尝试将 void * 转换为其中一个结构时,这又会导致代码中断。
void * 我做错了什么?
两个问题:
首先你不应该在读取二进制文件时真正使用文本函数。二进制文件实际上并没有 "lines",因为文本文件有它。
其次,与
void *ptr;
fread(&ptr, nr, 1, fileOpen);
您正在将指针 传递给指针变量 ,您实际上并没有将任何内容读入内存,然后使 ptr
指向该内存。现在发生的是fread
函数会从文件中读取nr
字节,然后写入到&ptr
指向的内存中,这会导致undefined behavior if nr > sizeof ptr
(因为那时数据将被写出边界)。
您必须分配 nr
字节的内存,然后将指针传递给该内存的第一个元素:
char data[nr];
fread(data, nr, 1, fileOpen);
您还应该养成检查错误的习惯。如果 fread
函数失败怎么办?或者文件被截断,没有 nr
个字节可供读取?
您可以通过检查 fread
returns.
并且不仅检查 fread
,还有比 fopen
更多的功能可能会失败。