c语言 oem信息,自己打造一个 PeView 工具 C语言实现(基本上可以了)

[C] 纯文本查看 复制代码#include

#include

#include

#include

#include

// 计算数组长度

#define GET_ARRAY_LEN(array) (sizeof(array) / sizeof(array[0]))

/*

打印 IMAGE_DOS_HEADER 信息

PIMAGE_DOS_HEADER pDosHeader: IMAGE_DOS_HEADER 结构体指针

*/

void printImageDosHeader (IN PIMAGE_DOS_HEADER pDosHeader) {

printf ("IMAGE_DOS_HEADER:\n");

char *DOS_HEADER_Name[] = {"e_magic", "e_cblp", "e_cp", "e_crlc", "e_cparhdr",

"e_minalloc", "e_maxalloc", "e_ss", "e_sp",

"e_csum", "e_ip", "e_cs", "e_lfarlc", "e_ovno",

"e_res[4]", "e_oemid", "e_oeminfo",

"e_res2[10]",

"e_lfanew", //指向IMAGE_NT_HEADERS的所在

};

int temp = 0;

for (int i = 0; i < 31; i++) {

if (i == 14) { // 打印 e_res[4] 的内容

for (int j = 0; j < 4; j++) {

printf ("\t%-20s:%04X\n", DOS_HEADER_Name[temp],

*(&(pDosHeader->e_magic) + i++));

}

temp++;

}

else if (i == 20) { // 打印 e_res2[10] 的内容

for (int j = 0; j < 10; j++) {

printf ("\t%-20s:%04X\n", DOS_HEADER_Name[temp],

*(&(pDosHeader->e_magic) + i++));

}

temp++;

}

printf ("\t%-20s:%04X\n", DOS_HEADER_Name[temp++], *(&(pDosHeader->e_magic) + i));

}

}

/*

打印 IMAGE_OPTIONAL_HEADER32 结构体信息

IMAGE_NT_HEADERS* pPeHeader: IMAGE_NT_HEADERS 结构体指针

*/

void printOptionalHead32 (IN IMAGE_NT_HEADERS* pPeHeader) {

char *OptionalHeadName[] = {

// Standard fields.

"Magic", "MajorLinkerVersion", "MinorLinkerVersion", "SizeOfCode",

"SizeOfInitializedData", "SizeOfUninitializedData", "AddressOfEntryPoint", "BaseOfCode", "BaseOfData",

// NT additional fields.

"ImageBase", "SectionAlignment", "FileAlignment", "MajorOperatingSystemVersion",

"MinorOperatingSystemVersion", "MajorImageVersion", "MinorImageVersion", "MajorSubsystemVersion",

"MinorSubsystemVersion", "Win32VersionValue", "SizeOfImage", "SizeOfHeaders", "CheckSum",

"Subsystem", "DllCharacteristics", "SizeOfStackReserve", "SizeOfStackCommit", "SizeOfHeapReserve",

"SizeOfHeapCommit", "LoaderFlags", "NumberOfRvaAndSizes", "IMAGE_DATA_DIRECTORY"};

char *DataDirectory[] = {"VirtualAddress", "Size"};

char *VirtualAddressp[] = {"IMAGE_DIRECTORY_ENTRY_EXPORT", "IMAGE_DIRECTORY_ENTRY_IMPORT",

"IMAGE_DIRECTORY_ENTRY_RESOURCE", "IMAGE_DIRECTORY_ENTRY_EXCEPTION", "IMAGE_DIRECTORY_ENTRY_SECURITY",

"IMAGE_DIRECTORY_ENTRY_DEBUG", "IMAGE_DIRECTORY_ENTRY_COPYRIGHT", "IMAGE_DIRECTORY_ENTRY_GLOBALPTR",

"IMAGE_DIRECTORY_ENTRY_TLS", "IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG", "IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT",

"IMAGE_DIRECTORY_ENTRY_IAT", "IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT", "IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR",

"IMAGE_NUMBEROF_DIRECTORY_ENTRIES"

};

size_t structOffset = 0;

DWORD* addr;

printf ("IMAGE_OPTIONAL_HEADER32\n");

for (size_t i = 0; i < GET_ARRAY_LEN (OptionalHeadName); i++) {

if (i == 1) {

structOffset++;;

printf ("\t%-40s:%02X\n", OptionalHeadName[i++], pPeHeader->OptionalHeader.MajorLinkerVersion);

printf ("\t%-40s:%02X\n", OptionalHeadName[i++], pPeHeader->OptionalHeader.MinorLinkerVersion);

}

if (i == 3) {

for (size_t j = 0; j < 9; j++) {

addr = &(pPeHeader->OptionalHeader.Magic) + structOffset;

structOffset += 2;

printf ("\t%-40s:%08X\n", OptionalHeadName[i++], *addr);

}

}

if (i == 18) {

for (size_t j = 0; j < 4; j++) {

addr = &(pPeHeader->OptionalHeader.Magic) + structOffset;

structOffset += 2;

printf ("\t%-40s:%08X\n", OptionalHeadName[i++], *addr);

}

}

if (i == 24) {

for (size_t j = 0; j < 6; j++) {

addr = &(pPeHeader->OptionalHeader.Magic) + structOffset;

structOffset += 2;

printf ("\t%-40s:%08X\n", OptionalHeadName[i++], *addr);

}

}

printf ("\t%-40s:%04X\n", OptionalHeadName[i], *(&(pPeHeader->OptionalHeader.Magic) + structOffset));

structOffset++;

}

}

/*

打印 IMAGE_NT_HEADERS 结构体信息

IMAGE_NT_HEADERS *pPeHeader: IMAGE_NT_HEADERS 结构体指针

*/

void printImageNtHeaders (IN IMAGE_NT_HEADERS* pPeHeader) {

char *PeHeaderName[] = {"Signature", "IMAGE_FILE_HEADER", "IMAGE_OPTIONAL_HEADER32"};

char *FileHeaderName[] = {"Machine", "NumberOfSections", "TimeDateStamp", "PointerToSymbolTable",

"NumberOfSymbols", "SizeOfOptionalHeader", "Characteristics"};

printf ("IMAGE_NT_HEADERS:\n");

printf ("\t%-20s:%08X\n", PeHeaderName[0], pPeHeader->Signature);

printf ("IMAGE_FILE_HEADER:\n");

int temp = 0;

size_t structOffset = 0;

DWORD *addr;

for (int i = 0; i < 7; i++) {

if (i == 2) {

for (int j = 0; j < 3; j++) {

/*

printf ("\t%-20s:%04X%04X\n", FileHeaderName[temp++],

// 这里实在是想不到什么好方法来处理了 求指导下

*(&(pPeHeader->FileHeader.Machine) + structOffset++),

*(&(pPeHeader->FileHeader.Machine) + structOffset++));

这里完全被自己带沟里去了......

果然对指针还是不了解啊

addr = (DOWRD *)&(pPeHeader->FileHeader.Machine) + structOffset; // 这个就偏移飞了.

*/

addr = &(pPeHeader->FileHeader.Machine) + structOffset;

structOffset += 2;

printf ("\t%-40s:%08X\n", FileHeaderName[temp++], *addr);

i++;

}

}

printf ("\t%-40s:%04X\n", FileHeaderName[temp++], *(&(pPeHeader->FileHeader.Machine) + structOffset++));

}

}

int main (int argc, char *argv[])

{

if (argc < 2) {

printf ("Help: %s FileName\n", argv[0]);

exit (EXIT_FAILURE);

}

IMAGE_DOS_HEADER DosHeader; // Dos 头 结构体

IMAGE_NT_HEADERS PeHeader; // PE 头 结构体

FILE *fpPeFile = fopen (argv[1], "rb"); // 以二进制方式打开文件

if (!fpPeFile) {

fprintf (stderr, "打开文件失败\n");

exit (EXIT_FAILURE);

}

fread (&DosHeader.e_magic, 1, sizeof(DosHeader), fpPeFile);

if (DosHeader.e_magic != IMAGE_DOS_SIGNATURE) { // e_magic --> DOS可执行文件标记

fprintf (stderr, "请确定该文件是PE文件\n");

exit (EXIT_FAILURE);

}

/*

这里我想多了 其实可以一次性读取出来的

fseek (fpPeFile, 0, SEEK_SET);

for (int i = 0; i < 30; i++) {

// 取 DosHeader.e_magic 首地址

// 根据这个地址来计算 结构体偏移

fread (&DosHeader.e_magic + i, 1, sizeof(WORD), fpPeFile);

}

fread (&DosHeader.e_lfanew, 1, sizeof(LONG), fpPeFile); // 获取 指向PE文件头的文件偏移

*/

printImageDosHeader (&DosHeader);

// 直接跳过了 Dos Stub

fseek (fpPeFile, DosHeader.e_lfanew, 0); // 移动文件偏移到PE头

// 获取PeHeader 信息

fread (&PeHeader, 1, sizeof(PeHeader), fpPeFile);

printImageNtHeaders (&PeHeader);

printOptionalHead32 (&PeHeader);

return 0;

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值