提交 ed474be6 创建 作者: 赵鹏翀's avatar 赵鹏翀

init template

上级
/Debug
/Release
\ No newline at end of file
<?xml version="1.0" encoding="gb2312"?>
<ASMProject Version="1.00" Name="Demo035" TemplatePath="Lab012\Project" ProjectID="339c6bfd-886d-4300-a482-e146fd00ab15" IsSubmitWork="0">
<Configurations>
<Configuration Name="Debug" DebuggerFlavor="0">
<Tool Name="PreBuildEventTool"/>
<Tool Name="CustomBuildTool"/>
<Tool Name="GCCCompilerTool" PreprocessorDefinitions="_DEBUG" GenerateDebugInformation="-1" LanguageStandard="c99"/>
<Tool Name="PreLinkEventTool"/>
<Tool Name="GCCLinkerTool"/>
<Tool Name="PostBuildEventTool"/>
</Configuration>
<Configuration Name="Release" DebuggerFlavor="0">
<Tool Name="PreBuildEventTool"/>
<Tool Name="CustomBuildTool"/>
<Tool Name="GCCCompilerTool" PreprocessorDefinitions="NDEBUG" LanguageStandard="c99"/>
<Tool Name="PreLinkEventTool"/>
<Tool Name="GCCLinkerTool" StripDebugInfo="-1"/>
<Tool Name="PostBuildEventTool"/>
</Configuration>
</Configurations>
<Files>
<Filter Name="ͷļ" Filter="h;hpp;hxx">
<File RelativePath=".\console.h">
</File>
</Filter>
<Filter Name="Դļ" Filter="cpp;c;cc;cxx">
<File RelativePath=".\console.c">
</File>
<File RelativePath=".\PEdump.c">
</File>
</Filter>
</Files>
</ASMProject>
添加文件
// PEDUMP.cpp : 定义控制台应用程序的入口点。
//
/*
PE 文件的大致布局
+------------------------------+ File offset 0
| DOS Header |
| PE_IMAGE_DOS_HEADER |
+------------------------------+
| DOS Stub |
---------+------------------------------+
/ | PE Signature (PE\0\0) |
| +------------------------------+
| | PE_IMAGE_FILE_HEADER |
PE_IMAGE_NT_HEADERS +------------------------------+--------\
| | | |
| | | PE_IMAGE_OPTIONAL_HEADER
| +------------------------------+ |
\ | Data Directory | |
---------+------------------------------+--------/
| Section Table |
| PE_IMAGE_SECTION_HEADER array|
+------------------------------+
---------+------------------------------+ File align
/ | .text |
| +------------------------------+
| +------------------------------+
| | .data |
| +------------------------------+
| +------------------------------+
Sections | .edata |
| +------------------------------+
| +------------------------------+
| | .idata |
| +------------------------------+
| +------------------------------+
\ | .reloc |
---------+------------------------------+
......
+------------------------------+
| COFF Line Numbers (Optional) |
+------------------------------+
| COFF Symbols (Optional) |
+------------------------------+
| CodeView Debug Information |
| (Optional) |
+------------------------------+
*/
#include "console.h"
// 全局变量
FILE* g_pFile; // PE 文件
PE_IMAGE_DOS_HEADER g_DosHeader;
PE_IMAGE_NT_HEADERS g_NTHeaders;
PE_IMAGE_SECTION_HEADER* g_pSectionTable = NULL;
PE_IMAGE_EXPORT_DIRECTORY* g_ExportDir = NULL;
PE_IMAGE_IMPORT_DESCRIPTOR* g_ImportDsr = NULL;
// 主函数
int main(int argc, char* argv[])
{
// 打开 PE 文件
g_pFile = fopen("library.dll", "rb");
if(NULL == g_pFile)
{
printf("Open file failed!\n");
return 1;
}
// 读取 DOS 头
ReadDosHeader();
// 读取 NT 头
ReadNTHeader();
// 读取 section table
ReadSectionTable();
// 读取 Export Table
ReadExportTable();
// 关闭 PE 文件
fclose(g_pFile);
return 0;
}
#include "console.h"
int SectionCnt; // 保存节的数量
DWORD dwExportVA, dwExPointerToRawData; // 保存导出表,导入表的地址信息
DWORD dwImportVA, dwImPointerToRawData;
// 虚拟地址到文件中的位置转换程序
DWORD OnConvertVAToRawA(DWORD dwTransVA, DWORD dwSectionVA, DWORD dwPointerToRawData)
{
// 将两个虚拟地址做差,求出偏移量,再加上所在节的PointerToRawData即可将虚拟地址转换成文件中的位置
// 将转换好的地址返回
return dwTransVA - dwSectionVA + dwPointerToRawData;
}
void ReadDosHeader()
{
// DOS Header 在文件开始处
fseek(g_pFile, 0, SEEK_SET);
fread(&g_DosHeader, sizeof(g_DosHeader), 1, g_pFile);
// 判断DOS头是否合法
if(g_DosHeader.e_magic != 0x5A4D)
{
printf("DOS头不合法!\n");
exit(1);
}
// 打印
printf("****** DOS Header ******\n");
printf("magic: %.4s\n", (CHAR*)&g_DosHeader.e_magic);
printf("e_lfanew: 0x%X\n\n",g_DosHeader.e_lfanew);
}
void ReadNTHeader()
{
// DOS Header 中的 e_lfanew 存储了 NT Header 相对文件起始的偏移值
fseek(g_pFile, g_DosHeader.e_lfanew, SEEK_SET);
fread(&g_NTHeaders, sizeof(g_NTHeaders), 1, g_pFile);
// 判断是否为有效PE文件
if(g_NTHeaders.Signature != 0x4550)
{
printf("不是有效的PE文件!\n");
exit(1);
}
// 保存节的数量
SectionCnt = g_NTHeaders.FileHeader.NumberOfSections;
// 打印
printf("****** NT Header ******\n");
printf("Signature: %.4s\n", (CHAR*)&g_NTHeaders.Signature);
printf("NumberOfSections: %d\n", g_NTHeaders.FileHeader.NumberOfSections);
printf("SizeOfOptionalHeader: 0x%X\n", g_NTHeaders.FileHeader.SizeOfOptionalHeader);
printf("AddressOfEntryPoint: 0x%X\n", g_NTHeaders.OptionalHeader.AddressOfEntryPoint);
printf("BaseOfCode: 0x%X\n", g_NTHeaders.OptionalHeader.BaseOfCode);
printf("BaseOfData: 0x%X\n", g_NTHeaders.OptionalHeader.BaseOfData);
printf("ImageBase: 0x%X\n", g_NTHeaders.OptionalHeader.ImageBase);
printf("SectionAlignment: 0x%X\n", g_NTHeaders.OptionalHeader.SectionAlignment);
printf("FileAlignment: 0x%X\n\n", g_NTHeaders.OptionalHeader.FileAlignment);
}
void ReadSectionTable()
{
// Section Table 在 NT Header 之后。但是不应该使用 NT Header 的大小
// 直接计算位置,应该使用 File Header 中的 SizeOfOptionalHeader 计算。
// 这样才能在 Optional Header 发生变化的情况下继续使用。
ULONG FileOffset;
ULONG SectionTableSize;
FileOffset = g_DosHeader.e_lfanew + sizeof(g_NTHeaders.Signature)
+ sizeof(g_NTHeaders.FileHeader) + g_NTHeaders.FileHeader.SizeOfOptionalHeader;
SectionTableSize = g_NTHeaders.FileHeader.NumberOfSections * sizeof(PE_IMAGE_SECTION_HEADER);
g_pSectionTable = (PE_IMAGE_SECTION_HEADER*)malloc(SectionTableSize);
// 设置文件指针的位置,从文件头开始,sectiontable的偏移是FileOffset
fseek(g_pFile, FileOffset, SEEK_SET);
// 从文件中读取一个SectionTableSize大小的数据存放到g_pSectionTable指向的缓存地址中。
fread(g_pSectionTable, SectionTableSize, 1, g_pFile);
// 打印
printf("****** Section Table ******\n");
for(int i = 0; i < SectionCnt; i++, g_pSectionTable++)
{
// 取得导出表的地址信息
if(strcmp(g_pSectionTable->Name, ".edata") == 0)
{
dwExportVA = g_pSectionTable->VirtualAddress;
dwExPointerToRawData = g_pSectionTable->PointerToRawData;
}
// 取得导入表的地址信息
if(strcmp(g_pSectionTable->Name, ".idata") == 0)
{
dwImportVA = g_pSectionTable->VirtualAddress;
dwImPointerToRawData = g_pSectionTable->PointerToRawData;
}
printf("Number:%d\n", i+1);
printf("Name:%.8s\n", g_pSectionTable->Name);
printf("VirtualSize:%08x\n", g_pSectionTable->Misc.VirtualSize);
printf("VirtualAddress:0x%08x\n", g_pSectionTable->VirtualAddress);
printf("SizeOfRawData:0x%08x\n", g_pSectionTable->SizeOfRawData);
printf("PointerToRawData:0x%08x\n", g_pSectionTable->PointerToRawData);
printf("PointerToRelocations:0x%08x\n", g_pSectionTable->PointerToRelocations);
printf("PointerToLinenumbers:0x%08x\n", g_pSectionTable->PointerToLinenumbers);
printf("NumberOfRelocations:0x%04x\n", g_pSectionTable->NumberOfRelocations);
printf("NumberOfLinenumbers:0x%04x\n", g_pSectionTable->NumberOfLinenumbers);
printf("Characteristics:0x%08x\n\n", g_pSectionTable->Characteristics);
}
}
// 读取并输出导出表的内容
void ReadExportTable()
{
// 打印
printf("****** Export Table ******\n");
// 数据目录表的第一个元素为导出表
printf("导出表的偏移地址:%04x\n", g_NTHeaders.OptionalHeader.DataDirectory[0].VirtualAddress);
printf("导出表的大小:%04x\n\n", g_NTHeaders.OptionalHeader.DataDirectory[0].Size);
DWORD dwFileOffset;
// 导出表内容非空
if (g_NTHeaders.OptionalHeader.DataDirectory[0].VirtualAddress != 0)
{
// 求导出表在PE文件中的偏移
dwFileOffset = OnConvertVAToRawA(g_NTHeaders.OptionalHeader.DataDirectory[0].VirtualAddress, dwExportVA, dwExPointerToRawData);
// 导出表在文件中的偏移
printf("导出表的偏移:%04x\n\n", dwFileOffset);
int nNumberOfFunctions = 0;
int nNumberOfNames = 0;
g_ExportDir = (PE_IMAGE_EXPORT_DIRECTORY *)malloc(sizeof(PE_IMAGE_EXPORT_DIRECTORY));
fseek(g_pFile, dwFileOffset, SEEK_SET);
fread(g_ExportDir, sizeof(PE_IMAGE_EXPORT_DIRECTORY), 1, g_pFile);
printf("IMAGE_EXPORT_DIRECTORY结构如下: \n");
printf("Characteristics:%08x(没有用途,总是为0)\n", g_ExportDir->Characteristics);
printf("TimeDateStamp:%08x(文件被产生时刻)\n", g_ExportDir->TimeDateStamp);
printf("MajorVersion:%08x(没有用途,总是为0)\n", g_ExportDir->MajorVersion);
printf("MinorVersion:%08x(没有用途,总是为0)\n", g_ExportDir->MinorVersion);
printf("Name:%08x(RVA,指向一个DLL文件名称)\n\n", g_ExportDir->Name);
// 读取DLL名称
char chDllName[64] = {0}; // 这里多留点空间给函数名字,防止出错
// 将指向DLL文件名称的VA转化为文件偏移
DWORD dwTemp = OnConvertVAToRawA(g_ExportDir->Name, dwExportVA, dwExPointerToRawData);
// 读取DLL文件名称
fseek(g_pFile, dwTemp, SEEK_SET);
fread(chDllName, 64, 1, g_pFile);
printf("DLL文件名称为:%s\n\n", chDllName);
printf("Base:%08x(起始序号)\n", g_ExportDir->Base);
// 被此模块导出的函数的起始序号
WORD wBase = (WORD)g_ExportDir->Base;
// AddressOfFunctions 数组中的元素个数。此值同时也是导出函数的个数。
// 通常这个值和 NumberOfNames 字段相同,但也可以不同。
printf("NumberOfFunctions:%d(导出函数个数)\n", g_ExportDir->NumberOfFunctions);
nNumberOfFunctions = g_ExportDir->NumberOfFunctions;
// AddressOfNames 数组中的元素个数。此值表示以名称导出的函数个数。
// 通常(但不总是)和导出函数的总数相同。
printf("NumberOfNames:%d(以名称导出的函数个数)\n", g_ExportDir->NumberOfNames);
nNumberOfNames = g_ExportDir->NumberOfNames;
printf("AddressOfFunctions:%08x(RVA, 指向一个由函数地址构成的数组)\n", g_ExportDir->AddressOfFunctions);
DWORD dwAddressOfFunctions = OnConvertVAToRawA(g_ExportDir->AddressOfFunctions, dwExportVA, dwExPointerToRawData);
// 这是一个 RVA 值,指向一个由字符串指针所构成的数组。
// 字符串的内容是此一模块中的每一个"以名称导出的导出函数"的名称
printf("AddressOfNames:%08x(RVA, 指向一个由字符串指针所构成的数组)\n", g_ExportDir->AddressOfNames);
// 转化为文件偏移地址
DWORD dwNameAddressOfFunctions = OnConvertVAToRawA(g_ExportDir->AddressOfNames, dwExportVA, dwExPointerToRawData);
// 这是一个 RVA 值,指向一个 WORD 数组。
// WORD 的内容是此一模块中的每一个"以名称导出的导出函数"的序号。别忘了要加上 Base 字段中的起始序号。
printf("AddressOfNameOrdinals:%08x(RVA, 指向一个DWORD数组)\n", g_ExportDir->AddressOfNameOrdinals);
// 转化为文件偏移地址
DWORD dwAddressOfNameOrdinals = OnConvertVAToRawA(g_ExportDir->AddressOfNameOrdinals, dwExportVA, dwExPointerToRawData);
// 动态开辟内存用来存储函数的VirtualAddress
DWORD *pdwAddressOfFunctions = (DWORD *)calloc(nNumberOfFunctions, sizeof(DWORD));
fseek(g_pFile, dwAddressOfFunctions, SEEK_SET);
fread(pdwAddressOfFunctions, sizeof(DWORD), nNumberOfFunctions, g_pFile);
// 动态开辟内存用来存储函数的RawAddress
DWORD *pRowAddressOfFunctions = (DWORD *)calloc(nNumberOfFunctions, sizeof(DWORD));
*pRowAddressOfFunctions = OnConvertVAToRawA(*pdwAddressOfFunctions, dwExportVA, dwExPointerToRawData);
// 动态开辟内存用来存储函数名称地址
DWORD *pdwNameAddressOfFunctions = (DWORD *)calloc(nNumberOfNames, sizeof(DWORD));
fseek(g_pFile, dwNameAddressOfFunctions, SEEK_SET);
fread(pdwNameAddressOfFunctions, sizeof(DWORD), nNumberOfNames, g_pFile);
*pdwNameAddressOfFunctions = OnConvertVAToRawA(*pdwNameAddressOfFunctions, dwExportVA, dwExPointerToRawData);
// 二重指针,用来存储函数名称指针,因为函数个数不固定
DWORD **pFunctionsName = (DWORD **)calloc(nNumberOfNames, sizeof(char *));
// 这块内存是用来存放函数名称的
char *pchFunctionName = (char *)malloc(sizeof(char) * 64);
*pFunctionsName = (DWORD *)pchFunctionName;
// 读出函数名称
fseek(g_pFile, *pdwNameAddressOfFunctions, SEEK_SET);
fread(*pFunctionsName, 64, 1, g_pFile);
// 读出函数的序号
WORD *pwFunctionsOrdinals = (WORD *)calloc(nNumberOfNames, sizeof(WORD));
fseek(g_pFile, dwAddressOfNameOrdinals, SEEK_SET);
fread(pwFunctionsOrdinals, sizeof(WORD), 1, g_pFile);
// 打印调用函数的信息
printf("\nOrdinals: %04x\n", *pwFunctionsOrdinals + wBase);
printf("函数: %s\n", *pFunctionsName);
printf("RowAddress: %08x\n", *pRowAddressOfFunctions);
printf("VirtulAddress: %08x\n", *pdwAddressOfFunctions);
}
else
{
printf("此文件无导出表\n");
}
}
#ifndef _PEDUMP_H_
#define _PEDUMP_H_
#include <stdio.h>
/* TODO: 在此处引用程序需要的其他头文件 */
#include <windows.h>
//////////////////////////////////////////////////////////////////////////
typedef struct { // DOS头
WORD e_magic; // 魔术数字
WORD e_cblp; // 文件最后页的字节数
WORD e_cp; // 文件页数
WORD e_crlc; // 重定向元素个数
WORD e_cparhdr; // 头部尺寸,以段落为单位
WORD e_minalloc; // 所需的最小附加段
WORD e_maxalloc; // 所需的最大附加段
WORD e_ss; // 初始的SS值(相对偏移量)
WORD e_sp; // 初始的SP值
WORD e_csum; // 校验和
WORD e_ip; // 初始的IP值
WORD e_cs; // 初始的CS值(相对偏移量)
WORD e_lfarlc; // 重分配表文件地址
WORD e_ovno; // 覆盖号
WORD e_res[4]; // 保留字
WORD e_oemid; // OEM标识符(相对e_oeminfo)
WORD e_oeminfo; // OEM信息
WORD e_res2[10]; // 保留字
LONG e_lfanew; // 新EXE文件的头部地址
} PE_IMAGE_DOS_HEADER;
typedef struct {
WORD Machine; // 能够运行 PE 文件的 CPU 类型
WORD NumberOfSections; // Section 个数
DWORD TimeDateStamp; // 链接器产生此 PE 文件的时间戳
DWORD PointerToSymbolTable; // COFF 符号表偏移位置。调试器使用
DWORD NumberOfSymbols; // COFF 符号表中的符号个数。调试器使用
WORD SizeOfOptionalHeader; // 可选头的大小。EXE 中是 PE_IMAGE_OPTIONAL_HEADER 的大小。OBJ 中是 0
WORD Characteristics; // 描述此 PE 文件的属性。属性信息见后面的宏定义
} PE_IMAGE_FILE_HEADER;
#define PE_IMAGE_FILE_RELOCS_STRIPPED 0x0001 // Relocation info stripped from file.
#define PE_IMAGE_FILE_EXECUTABLE_IMAGE 0x0002 // File is executable (i.e. no unresolved externel references).
#define PE_IMAGE_FILE_LINE_NUMS_STRIPPED 0x0004 // Line nunbers stripped from file.
#define PE_IMAGE_FILE_LOCAL_SYMS_STRIPPED 0x0008 // Local symbols stripped from file.
#define PE_IMAGE_FILE_AGGRESIVE_WS_TRIM 0x0010 // Agressively trim working set
#define PE_IMAGE_FILE_LARGE_ADDRESS_AWARE 0x0020 // App can handle >2gb addresses
#define PE_IMAGE_FILE_BYTES_REVERSED_LO 0x0080 // Bytes of machine word are reversed.
#define PE_IMAGE_FILE_32BIT_MACHINE 0x0100 // 32 bit word machine.
#define PE_IMAGE_FILE_DEBUG_STRIPPED 0x0200 // Debugging info stripped from file in .DBG file
#define PE_IMAGE_FILE_REMOVABLE_RUN_FROM_SWAP 0x0400 // If Image is on removable media, copy and run from the swap file.
#define PE_IMAGE_FILE_NET_RUN_FROM_SWAP 0x0800 // If Image is on Net, copy and run from the swap file.
#define PE_IMAGE_FILE_SYSTEM 0x1000 // System File.
#define PE_IMAGE_FILE_DLL 0x2000 // File is a DLL.
#define PE_IMAGE_FILE_UP_SYSTEM_ONLY 0x4000 // File should only be run on a UP machine
#define PE_IMAGE_FILE_BYTES_REVERSED_HI 0x8000 // Bytes of machine word are reversed.
typedef struct {
DWORD VirtualAddress;
DWORD Size;
} PE_IMAGE_DATA_DIRECTORY;
#define PE_IMAGE_NUMBEROF_DIRECTORY_ENTRIES 16
typedef struct {
//
// Standard fields.
//
WORD Magic; // 标识可执行映像的状态。0x0107 表示一个 ROM 映像,0x010B 表示一个 EXE 映像。
BYTE MajorLinkerVersion;
BYTE MinorLinkerVersion;
DWORD SizeOfCode; // 所有 code section 合计大小
DWORD SizeOfInitializedData; // 所有已初始化数据 section 合计大小
DWORD SizeOfUninitializedData; // 所有未初始化数据 section 合计大小
DWORD AddressOfEntryPoint; // 入口点的 RVA
DWORD BaseOfCode; // code section 的 RVA。通常为 0x1000
DWORD BaseOfData; // data section 的 RVA。
//
// NT additional fields.
//
DWORD ImageBase; // 将 PE 文件载入内存的基地址
DWORD SectionAlignment; // 将 PE 文件载入内存后,各个 section 起始虚拟地址是此值的整数倍,内存中节对齐的粒度
DWORD FileAlignment; // 在 PE 文件中,各个 section 相对于文件开始的地址是此值的整数倍,文件中节对齐的粒度
WORD MajorOperatingSystemVersion;
WORD MinorOperatingSystemVersion;
WORD MajorImageVersion;
WORD MinorImageVersion;
WORD MajorSubsystemVersion;
WORD MinorSubsystemVersion;
DWORD Win32VersionValue;
DWORD SizeOfImage; // 将 PE 文件载入内存后可执行映像的大小。从 image base 开始,到最后一个 section 结束。最后一个 section 的尾端必须是 SectionAlignment 的整数倍。
DWORD SizeOfHeaders; // PE 表头及 section table 的合计大小。各个 section 就从此后展开。
DWORD CheckSum; // 校验和
WORD Subsystem; // 子系统
WORD DllCharacteristics; // 总是 0
DWORD SizeOfStackReserve;
DWORD SizeOfStackCommit;
DWORD SizeOfHeapReserve;
DWORD SizeOfHeapCommit;
DWORD LoaderFlags; // 被放弃
DWORD NumberOfRvaAndSizes; // 在 DataDirectory 数组中的项目数量。总是 16。
/*
使用这个数组能够迅速在可执行映像中找到特定的 section,而不需要按照顺序遍历 section。
例如使用数组中的第一个项目可以找到所有 exported function 的 RVA 及大小。
*/
PE_IMAGE_DATA_DIRECTORY DataDirectory[PE_IMAGE_NUMBEROF_DIRECTORY_ENTRIES];
} PE_IMAGE_OPTIONAL_HEADER;
typedef struct {
DWORD Signature; // 文件类型标志
PE_IMAGE_FILE_HEADER FileHeader; // 文件头
PE_IMAGE_OPTIONAL_HEADER OptionalHeader; // 可选头
} PE_IMAGE_NT_HEADERS;
#define PE_IMAGE_SIZEOF_SHORT_NAME 8
typedef struct {
BYTE Name[PE_IMAGE_SIZEOF_SHORT_NAME]; // section 名称
union {
DWORD PhysicalAddress; // 在 OBJ 中表示 section 的实际位置,第一个 section 为 0。
DWORD VirtualSize; // 在 EXE 中表示 section 的虚拟大小,就是没有进行任何对齐的大小。
} Misc;
DWORD VirtualAddress; // 在 EXE 中表示将 section 映射到内存中的 RVA。
DWORD SizeOfRawData; // 在 EXE 中表示 file align 后的大小。
DWORD PointerToRawData; // 以文件起始为基准的偏移值。
DWORD PointerToRelocations; // 在 EXE 中为 0
DWORD PointerToLinenumbers; // 在 EXE 中为 0
WORD NumberOfRelocations; // 在 EXE 中为 0
WORD NumberOfLinenumbers; // 在 EXE 中为 0
DWORD Characteristics; // section 的属性标志。参见后面的宏定义。
} PE_IMAGE_SECTION_HEADER;
typedef struct {
DWORD Characteristics; // 保留
DWORD TimeDateStamp; // 时间日期记录
WORD MajorVersion; // dll的首版本号
WORD MinorVersion; // dll的次版本号
DWORD Name; // dll的模块名
DWORD Base; // 基数
DWORD NumberOfFunctions; // 函数的总数
DWORD NumberOfNames; // 有名函数的总数
DWORD AddressOfFunctions; // FAT表RVA值
DWORD AddressOfNames; // FNT表RVA值
WORD AddressOfNameOrdinals; // FOT表RVA值
} PE_IMAGE_EXPORT_DIRECTORY;
typedef struct {
union {
ULONG Characteristics; // 0 for terminating null import descriptor
ULONG OriginalFirstThunk; // RVA to original unbound IAT (PIMAGE_THUNK_DATA)
} u;
DWORD TimeDateStamp; // 时间日期记录
DWORD ForwarderChain; // 正向链接索引
DWORD Name; // DLL名字符串的RVA值
DWORD FirstThunk; // Import ThunkData数组RVA值(IAT)
}PE_IMAGE_IMPORT_DESCRIPTOR;
typedef struct {
WORD Hint;
BYTE Name[1];
}PE_IMAGE_IMPORT_BY_NAME;
typedef struct {
union {
PBYTE ForwarderString;
PDWORD Function;
DWORD Ordinal;
PE_IMAGE_IMPORT_BY_NAME AddressOfData;
}u1;
}PE_IMAGE_THUNK_DATA;
//
// 常用的 section 属性标志。
//
//#define IMAGE_SCN_CNT_CODE 0x00000020 // Section contains code.
//#define IMAGE_SCN_CNT_INITIALIZED_DATA 0x00000040 // Section contains initialized data.
//#define IMAGE_SCN_CNT_UNINITIALIZED_DATA 0x00000080 // Section contains uninitialized data.
//#define IMAGE_SCN_LNK_INFO 0x00000200 // Section contains comments or some other type of information.
//#define IMAGE_SCN_LNK_REMOVE 0x00000800 // Section contents will not become part of image.
//#define IMAGE_SCN_MEM_DISCARDABLE 0x02000000 // Section can be discarded.
//#define IMAGE_SCN_MEM_SHARED 0x10000000 // Section is shareable.
//#define IMAGE_SCN_MEM_EXECUTE 0x20000000 // Section is executable.
//#define IMAGE_SCN_MEM_READ 0x40000000 // Section is readable.
//#define IMAGE_SCN_MEM_WRITE 0x80000000 // Section is writeable.
//////////////////////////////////////////////////////////////////////////
// 全局变量声明
extern FILE* g_pFile;
extern PE_IMAGE_DOS_HEADER g_DosHeader;
extern PE_IMAGE_NT_HEADERS g_NTHeaders;
extern PE_IMAGE_SECTION_HEADER* g_pSectionTable;
extern PE_IMAGE_EXPORT_DIRECTORY* g_ExportDir;
extern PE_IMAGE_IMPORT_DESCRIPTOR* g_ImportDsr;
//////////////////////////////////////////////////////////////////////////
// 函数声明
void ReadDosHeader();
void ReadNTHeader();
void ReadSectionTable();
void ReadExportTable();
#endif /* _PEDUMP_H_ */
添加文件
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论