PE头读写(C语言实现)

/*本程序对https://blog.csdn.net/yan_star/article/details/79605860.做了以下修改:
1.文件路径可键盘输入;2.原博主程序在释放内存前没有将指针返回到起始位置(for循环中pmySectionHeader 不断++),因此添加了 pmySectionHeader=pmySectionHeader-SectionCount语句
(我运行原作者程序时会中断)。另外,补充一点,IMAGE_OPTIONAL_HEADER64 structure没有 DWORD  BaseOfData;,只有IMAGE_OPTIONAL_HEADER32有
*/


#include<stdio.h>
#include<windows.h>

//IMAGE_OPTIONAL_HEADER64 structure没有 DWORD  BaseOfData;
 
IMAGE_DOS_HEADER myDosHeader;
IMAGE_NT_HEADERS myNtHeader;
IMAGE_FILE_HEADER myFileHeader;
IMAGE_OPTIONAL_HEADER myOptionHeader;
IMAGE_SECTION_HEADER* pmySectionHeader;
 
LONG e_lfanew;
int SectionCount;
int Signature;
 
int main()
{
	FILE* pfile;
	errno_t err;
	int i;
	char filepath[MAX_PATH]={0};
	printf("欢迎使用PEViewTool\r\n");
	printf("请输入一个文件路径:\n");
    scanf("%s",&filepath);
    fflush(stdin);
	if ((err = fopen_s(&pfile, filepath, "r")) != 0)
	{
		printf("打开文件错误");
		return -1;
	}
	//DOS头部分
	printf("================IMAGE_DOS_HEADER================\n");
	fread(&myDosHeader, sizeof(IMAGE_DOS_HEADER), 1, pfile);
	printf("WORD  e_magic:				%04X\n", myDosHeader.e_magic);
	printf("DWORD e_lfanew:				%08X\n\n", myDosHeader.e_lfanew);
	e_lfanew = myDosHeader.e_lfanew;
	
	//NT头部分
	printf("================IMAGE_NT_HEADER================\n");
	fseek(pfile, e_lfanew, SEEK_SET);
	fread(&myNtHeader, sizeof(IMAGE_NT_HEADERS), 1, pfile);
	printf("DWORD Signature:			%08x\n\n", myNtHeader.Signature);
	Signature = myNtHeader.Signature;
	if (Signature != 0x4550)
	{	
		exit(0);
	}
	
	//FILE头部分
	printf("================IMAGE_FILE_HEADER================\n");
	fseek(pfile, (e_lfanew+sizeof(DWORD)), SEEK_SET);
	fread(&myFileHeader, sizeof(IMAGE_FILE_HEADER), 1, pfile);
	printf("WORD Machine:				%04X\n", myFileHeader.Machine);
	printf("WORD NumberOfSections:			%04X\n", myFileHeader.NumberOfSections);
	printf("DWORD TimeDateStamp:			%08X\n", myFileHeader.TimeDateStamp);
	printf("DWORD PointerToSymbolTable:		%08X\n", myFileHeader.PointerToSymbolTable);
	printf("DWORD NumberOfSymbols:			%08X\n", myFileHeader.NumberOfSymbols);
	printf("WORD SizeOfOptionalHeader:		%04X\n", myFileHeader.SizeOfOptionalHeader);
	printf("WORD Characteristics:			%04X\n\n", myFileHeader.Characteristics);
	SectionCount = myFileHeader.NumberOfSections;
 
	//OPTIONAL头部分
	printf("================IMAGE_OPTIONAL_HEADER================\n");
	fseek(pfile, (e_lfanew + sizeof(DWORD)+sizeof(IMAGE_FILE_HEADER)), SEEK_SET);
	fread(&myOptionHeader, sizeof(IMAGE_OPTIONAL_HEADER), 1, pfile);
	printf("WORD Magic:				%04X\n", myOptionHeader.Magic);
	printf("BYTE MajorLinkerVersion:		%02X\n", myOptionHeader.MajorLinkerVersion);
	printf("BYTE MinorLinkerVersion:		%02X\n", myOptionHeader.MinorLinkerVersion);
	printf("DWORD SizeOfCode:			%08X\n", myOptionHeader.SizeOfCode);
	printf("DWORD SizeOfInitializedData:		%08X\n", myOptionHeader.SizeOfInitializedData);
	printf("DWORD SizeOfUninitializedData:		%08X\n", myOptionHeader.SizeOfUninitializedData);
	printf("DWORD AddressOfEntryPoint:		%08X\n", myOptionHeader.AddressOfEntryPoint);
	printf("DWORD BaseOfCode:			%08X\n", myOptionHeader.BaseOfCode);
//	printf("DWORD BaseOfData:			%08X\n", myOptionHeader.BaseOfData);
	printf("DWORD ImageBase:			%08X\n", myOptionHeader.ImageBase);
	printf("DWORD SectionAlignment:			%08X\n", myOptionHeader.SectionAlignment);
	printf("DWORD FileAlignment:			%08X\n", myOptionHeader.FileAlignment);
	printf("WORD MajorOperatingSystemVersion:	%04X\n", myOptionHeader.MajorOperatingSystemVersion);
	printf("WORD MinorOperatingSystemVersion:	%04X\n", myOptionHeader.MinorOperatingSystemVersion);
	printf("WORD MajorImageVersion:			%04X\n", myOptionHeader.MajorImageVersion);
	printf("WORD MinorImageVersion:			%04X\n", myOptionHeader.MinorImageVersion);
	printf("WORD MajorSubsystemVersion:		%04X\n", myOptionHeader.MajorSubsystemVersion);
	printf("WORD MinorSubsystemVersion:		%04X\n", myOptionHeader.MinorSubsystemVersion);
	printf("DWORD Win32VersionValue:		%08X\n", myOptionHeader.Win32VersionValue);
	printf("DWORD SizeOfImage:			%08X\n", myOptionHeader.SizeOfImage);
	printf("DWORD SizeOfHeaders:			%08X\n", myOptionHeader.SizeOfHeaders);
	printf("DWORD CheckSum:				%08X\n", myOptionHeader.CheckSum);
	printf("WORD Subsystem:				%04X\n", myOptionHeader.Subsystem);
	printf("WORD DllCharacteristics:		%04X\n", myOptionHeader.DllCharacteristics);
	printf("DWORD SizeOfStackReserve:		%08X\n", myOptionHeader.SizeOfStackReserve);
	printf("DWORD SizeOfStackCommit:		%08X\n", myOptionHeader.SizeOfStackCommit);
	printf("DWORD SizeOfHeapReserve:		%08X\n", myOptionHeader.SizeOfHeapReserve);
	printf("DWORD SizeOfHeapCommit:			%08X\n", myOptionHeader.SizeOfHeapCommit);
	printf("DWORD LoaderFlags:			%08X\n", myOptionHeader.LoaderFlags);
	printf("DWORD NumberOfRvaAndSizes:		%08X\n\n", myOptionHeader.NumberOfRvaAndSizes);
 
	//节表目录
	printf("================IMAGE_OPTIONAL_HEADER================\n");
	pmySectionHeader = (IMAGE_SECTION_HEADER*)calloc(SectionCount, sizeof(IMAGE_SECTION_HEADER));
    printf("%p\n",pmySectionHeader);

	fseek(pfile, (e_lfanew + sizeof(IMAGE_NT_HEADERS)),SEEK_SET);
	fread(pmySectionHeader, sizeof(IMAGE_SECTION_HEADER), SectionCount, pfile);
	for (i = 0; i < SectionCount; i++, pmySectionHeader++)
	{	
		printf("BYTE Name:				%s\n", pmySectionHeader->Name);
		printf(":DWORD PhysicalAddress			%08X\n", pmySectionHeader->Misc.PhysicalAddress);
		printf(":DWORD VirtualSize			%08X\n", pmySectionHeader->Misc.VirtualSize);
		printf(":DWORD VirtualAddress			%08X\n", pmySectionHeader->VirtualAddress);
		printf(":DWORD SizeOfRawData			%08X\n", pmySectionHeader->SizeOfRawData);
		printf(":DWORD PointerToRawData			%08X\n", pmySectionHeader->PointerToRawData);
		printf(":DWORD PointerToRelocations		%08X\n", pmySectionHeader->PointerToRelocations);
		printf(":DWORD PointerToLinenumbers		%08X\n", pmySectionHeader->PointerToLinenumbers);
		printf(":WORD NumberOfRelocations		%04X\n", pmySectionHeader->NumberOfRelocations);
		printf(":WORD NumberOfLinenumbers		%04X\n", pmySectionHeader->NumberOfLinenumbers);
		printf(":DWORD Characteristics			%08X\n\n", pmySectionHeader->Characteristics);
	
	}
	 

    pmySectionHeader=pmySectionHeader-SectionCount;//指针回到头部
	printf("%p\n",pmySectionHeader);
	
	if (pmySectionHeader!=NULL){
	    free(pmySectionHeader);
	    pmySectionHeader=NULL;
	}
    //清空内存 

	
	fclose(pfile);
	return 0;
}

 

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
### 回答1: SPI EEPROM 是一种使用 SPI 接口进行通信的电可擦可编程只读存储器(Electrically Erasable Programmable Read-Only Memory),常用于嵌入式系统和电子设备中。在 C 语言中,可以通过调用 SPI 接口的函数来读写 SPI EEPROM。通常,需要先通过 SPI 接口发送写入地址和数据,然后再通过 SPI 接口读取相应的数据。 以下是一个示例代码,用于从 SPI EEPROM 中读取数据: ```c #include <stdio.h> #include <stdlib.h> #include <wiringPiSPI.h> #define CS_PIN 0 void read_eeprom(unsigned int address, unsigned char *data, unsigned int len) { unsigned char txbuf[4] = {0x03, address >> 8, address & 0xFF, 0}; wiringPiSPIDataRW(CS_PIN, txbuf, sizeof(txbuf)); wiringPiSPIDataRW(CS_PIN, NULL, len); memcpy(data, &txbuf[1], len); } int main() { unsigned char data[8]; read_eeprom(0x1234, data, sizeof(data)); printf("Read data: "); for (int i = 0; i < sizeof(data); i++) { printf("%02X ", data[i]); } printf("\n"); return 0; } ``` 在上述代码中,使用了 WiringPi 库提供的 `wiringPiSPIDataRW()` 函数进行 SPI 通信,其中 `CS_PIN` 定义了片选信号的引脚号。`read_eeprom()` 函数接受 EEPROM 的地址、要读取的数据存储缓冲区和数据长度作为参数,使用 SPI 接口读取 EEPROM 中的数据并存储到缓冲区中。在 `main()` 函数中调用 `read_eeprom()` 函数读取指定地址的数据,并使用 `printf()` 函数输出读取到的数据。 ### 回答2: SPI EEPROM是一种串行外部存储器,采用串行外设接口(Serial Peripheral Interface, SPI)进行读写操作。下面是使用C语言实现SPI EEPROM读写的步骤: 1. 设置SPI总线:首先需要初始化SPI总线,设置SPI的时钟、数据传输模式和其他参数。可以使用SPI控制寄存器进行配置。 2. 选择EEPROM芯片:通过SPI总线给EEPROM芯片发送特定的命令字,来选择要进行读写操作的芯片。在SPI总线上,每个设备都有一个特定的片选引脚,使得我们可以选择和通信特定的EEPROM芯片。 3. 发送读写指令:根据需求,发送读取或写入指令给EEPROM芯片,以便进行相应的操作。对于读取操作,我们可以发送读取命令,指定要读取的内存地址。对于写入操作,我们可以发送写入命令,并将要写入的数据和内存地址发送给EEPROM芯片。 4. 读取数据:在执行读取操作后,通过SPI总线接收EEPROM芯片返回的数据。可以通过读取数据寄存器来获取所需的数据。根据具体的EEPROM芯片,可能需要等待一段时间来确保数据传输的完成。 5. 写入数据:在执行写入操作后,将要写入的数据发送给EEPROM芯片。可以通过写入数据寄存器来发送数据。同样,根据具体的EEPROM芯片,可能需要等待一段时间来确保数据传输的完成。 6. 解除片选:最后,通过SPI总线关闭对EEPROM芯片的选择,以便进行其他操作。 7. 处理错误:在进行SPI EEPROM读写操作时,对可能出现的错误进行处理。例如,可以检查传输过程中的错误位,以确保数据的正确传输。 以上是使用C语言实现SPI EEPROM读写的基本步骤。具体实现可能因为硬件平台和EEPROM芯片的不同而有所差异,可以根据具体情况进行调整和优化。 ### 回答3: SPI EEPROM是一种通过SPI接口进行读写操作的存储器,下面是一个使用C语言实现SPI EEPROM读写的简单例程。 首先,需要定义一些必要的宏和变量: ```c #include <stdio.h> #include <wiringPiSPI.h> #define CHANNEL 0 // SPI通道号 #define SPEED 100000 // SPI速度 // 初始化SPI int spi_init() { int ret = wiringPiSPISetup(CHANNEL, SPEED); if (ret == -1) { printf("SPI初始化失败!\n"); return -1; } return 0; } ``` 接下来,编写读取函数: ```c // 从SPI EEPROM中读取数据 int eeprom_read(unsigned int addr, unsigned char *data, unsigned int len) { unsigned char buffer[3] = {0}; buffer[0] = 0x03; // 读指令 buffer[1] = addr >> 8; // 地址高字节 buffer[2] = addr & 0xFF; // 地址低字节 wiringPiSPIDataRW(CHANNEL, buffer, 3); // 发送读指令和地址 wiringPiSPIDataRW(CHANNEL, data, len); // 读取数据 return 0; } ``` 然后,编写写入函数: ```c // 向SPI EEPROM中写入数据 int eeprom_write(unsigned int addr, unsigned char *data, unsigned int len) { unsigned char buffer[3] = {0}; buffer[0] = 0x02; // 写指令 buffer[1] = addr >> 8; // 地址高字节 buffer[2] = addr & 0xFF; // 地址低字节 wiringPiSPIDataRW(CHANNEL, buffer, 3); // 发送写指令和地址 wiringPiSPIDataRW(CHANNEL, data, len); // 写入数据 delay(10); // 等待写入完成 return 0; } ``` 最后,使用时可以调用上述函数来读写SPI EEPROM: ```c int main() { unsigned char data[10] = {0}; spi_init(); // 初始化SPI eeprom_write(0x0000, "Hello", 5); // 向地址0x0000写入字符串"Hello" eeprom_read(0x0000, data, 5); // 从地址0x0000读取5个字节的数据 printf("Read data: %s\n", data); // 打印读取的数据 return 0; } ``` 以上是一个简单的SPI EEPROM读写C语言实现,通过调用相应的读写函数即可进行操作。不同的SPI EEPROM芯片可能有不同的指令和地址格式,具体实现可能需要根据芯片的规格手册进行调整。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值