代码分析windows下PE文件格式结构,并附带PE文件格式详细图解
2012-10-09 22:08
801 查看
#include <stdio.h>
#include <windows.h>
#include <time.h>
// Data Directory Description
char szDataDirectory[ 16] [ 64] =
{
"Export Directory" ,
"Import Directory" ,
"Resource Directory" ,
"Exception Directory" ,
"Security Directory" ,
"Base Relocation Table" ,
"Debug Directory" ,
"Architecture Specific Data" ,
"RVA of GP" ,
"TLS Directory" ,
"Load Configuration Directory" ,
"Bound Import Directory in headers" ,
"Import Address Table" ,
"Delay Load Import Descriptors" ,
"COM Runtime descriptor" ,
"UnKnow Flag"
} ;
HANDLE hFile = NULL ;
HANDLE hFileMapping = NULL ;
void * pFileBase = NULL ;
IMAGE_DOS_HEADER * pDosHeader= NULL ;
IMAGE_NT_HEADERS * pNTHeader= NULL ;
IMAGE_SECTION_HEADER *pSectionHeader = NULL ;
DWORD RVA2FileOffset( DWORD dwRVA) ;
int main( int argc,char **argv)
{
struct tm * ptm;
DWORD dwIndex;
IMAGE_IMPORT_DESCRIPTOR * pImportDescriptor= NULL ;
IMAGE_THUNK_DATA * pThunkData= NULL ;
IMAGE_IMPORT_BY_NAME * pImportByName= NULL ;
IMAGE_EXPORT_DIRECTORY * pExportDirectory= NULL ;
DWORD * pdw;
WORD * pw;
if ( argc !=2 )
{
printf ( "Usage:\n\t%s PEFile\n" ,argv[0] ) ;
return -1;
}
/*********************** Map the file to memory *************************/
hFile = CreateFile( argv[ 1] , GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL , OPEN_EXISTING, FILE_ATTRIBUTE_ARCHIVE, NULL ) ;
if ( hFile==INVALID_HANDLE_VALUE )
{
printf ("Open File Error.\n" ) ;
return -1;
}
hFileMapping = CreateFileMapping( hFile, NULL , PAGE_READONLY, 0, 0, NULL ) ;
if ( ! hFileMapping )
{
CloseHandle( hFile) ;
printf ( "Create File Mapping Error.\n" ) ;
return -1;
}
pFileBase = MapViewOfFile( hFileMapping, FILE_MAP_READ, 0, 0, 0) ;
if ( ! pFileBase )
{
CloseHandle( hFileMapping) ;
CloseHandle( hFile) ;
printf ("Map View Of File Error.\n" ) ;
return -1;
}
/*********************** Map end *****************************************/
// get the dos heaader pointer
pDosHeader = (IMAGE_DOS_HEADER* ) pFileBase;
if ( pDosHeader->e_magic!=IMAGE_DOS_SIGNATURE )
{
printf ("Unknow File Format.\n") ;
goto End;
}
printf("*****************IMAGE_DOS_HEADER****************\n");
printf ("%-35s%s\n" , "FileName:" , argv[1]) ;
printf ("%-35s%#010x\n" , "Dos Stub Size:" , pDosHeader->e_lfanew - sizeof(IMAGE_DOS_HEADER)) ;
printf ("%-35s%#010x\n" , "NT File RVA:" , pDosHeader->e_lfanew) ;
// get the nt header pointer
pNTHeader=(IMAGE_NT_HEADERS*)((char*)pFileBase+pDosHeader->e_lfanew) ;
if ( pNTHeader->Signature!=IMAGE_NT_SIGNATURE )
{
printf ("Not NT File.\n") ;
goto End;
}
// get the section header pointer
pSectionHeader=(IMAGE_SECTION_HEADER*)((char* ) pNTHeader+sizeof(IMAGE_NT_HEADERS) ) ;
printf("*****************IMAGE_FILE_HEADER***************\n");
printf ("%-35s%s\n" , "nRun Platform:" ,(pNTHeader->FileHeader. Machine==IMAGE_FILE_MACHINE_I386) ? "Intel 386" : "Other" ) ;
printf ( "%-35s%d\n" , "NumOfSections:" , pNTHeader->FileHeader. NumberOfSections) ;
ptm=localtime((const long*)&(pNTHeader->FileHeader.TimeDateStamp)) ;
printf ("%-35s%02d/%02d/%04d %02d:%02d:%02d\n" , "FileCreateTime:",ptm-> tm_mon + 1, ptm-> tm_mday, ptm-> tm_year+1900,
ptm->tm_hour, ptm->tm_min, ptm->tm_sec) ;
//printf("%.19s\n", asctime(ptm));
printf ("%-35s%#010x\n" , "SizeofOptionHdr:" , pNTHeader-> FileHeader. SizeOfOptionalHeader) ;
printf ( "%-35s%s\n" , "File Type:" , ( pNTHeader-> FileHeader. Characteristics & IMAGE_FILE_DLL) ? "DLL" : "EXE" ) ;
printf("*****************IMAGE_OPTIONAL_HEADER***********\n");
printf ("%-35s%s\n" , "Image Type:" , ( pNTHeader->OptionalHeader. Magic == 0x10B) ? "Exe Image" : "Other" ) ;
printf ("%-35s%d.%d\n" , "Linker Version:" , pNTHeader-> OptionalHeader. MajorLinkerVersion, pNTHeader-> OptionalHeader. MinorLinkerVersion) ;
printf ("%-35s%#010x\n" , "SizeofCode:" , pNTHeader->OptionalHeader. SizeOfCode) ;
printf ( "%-35s%#010x\n" , "AddressOfEntryPoint:" , pNTHeader->OptionalHeader. AddressOfEntryPoint) ;
printf ( "%-35s%#010x\n" , "DefaultLoadAddress:" , pNTHeader->OptionalHeader. ImageBase) ;
printf ( "%-35s%#010x\n" , "SectionAlignment:" , pNTHeader-> OptionalHeader. SectionAlignment) ;
printf ( "%-35s%#010x\n" , "FileAlignment:" , pNTHeader-> OptionalHeader. FileAlignment) ;
printf ( "%-35s%d.%d\n" , "OS SystemVersion:" , pNTHeader-> OptionalHeader. MajorOperatingSystemVersion,
pNTHeader-> OptionalHeader. MinorOperatingSystemVersion) ;
printf ( "%-35s%d.%d\n" , "ImageVersion:" , pNTHeader-> OptionalHeader. MajorImageVersion,
pNTHeader-> OptionalHeader. MinorImageVersion) ;
printf ( "%-35s%d.%d\n" , "SubSystemVersion:" , pNTHeader-> OptionalHeader. MajorSubsystemVersion,
pNTHeader-> OptionalHeader. MinorSubsystemVersion) ;
printf ( "%-35s%#010d\n" , "SizeOfIamge:" , pNTHeader-> OptionalHeader. SizeOfImage) ;
printf ( "%-35s%#010d\n" , "SizeOfHeaders:" , pNTHeader-> OptionalHeader. SizeOfHeaders) ;
if ( pNTHeader-> OptionalHeader. Subsystem== IMAGE_SUBSYSTEM_WINDOWS_GUI )
printf ( "%-35s%s\n" , "GUI System:" , "Windows GUI" ) ;
else if ( pNTHeader-> OptionalHeader. Subsystem==IMAGE_SUBSYSTEM_WINDOWS_CUI)
printf ( "%-35s%s\n" , "GUI System:" , "Windows Console" ) ;
else
printf ( "%-35s%s\n" , "GUI System:" , "Other" ) ;
printf("-----------------IMAGE_DATA_DIRECTY---------------\n");
printf ("#Index\t#VirAddress\t#Size\t\t#%-32s\n" , "Directory Name" ) ;
for (dwIndex=0; dwIndex<IMAGE_NUMBEROF_DIRECTORY_ENTRIES; dwIndex++)
{
printf ("0x%02x\t0x%08x\t0x%08x\t%-50s\n" , dwIndex,
pNTHeader-> OptionalHeader.DataDirectory[ dwIndex].VirtualAddress,
pNTHeader-> OptionalHeader.DataDirectory[ dwIndex].Size, szDataDirectory[ dwIndex]) ;
}
printf("*****************IMAGE_SECTION_HEADER****************\n");
printf ("#VirtualAddress\t#VirtualSize\t#PointerToRawData\t#SizeOfRawData\t#Name\n") ;
for ( dwIndex = 0; dwIndex < pNTHeader-> FileHeader. NumberOfSections; dwIndex++)
{
printf ("0x%08x\t0x%08x\t0x%08x\t\t0x%08x\t%-10s\n" , pSectionHeader[dwIndex].VirtualAddress,
pSectionHeader[ dwIndex].Misc. VirtualSize, pSectionHeader[dwIndex].PointerToRawData,
pSectionHeader[ dwIndex].SizeOfRawData, pSectionHeader[dwIndex].Name) ;
}
// Import Table
printf ("\n---------------Import Table----------------------\n") ;
pImportDescriptor=(IMAGE_IMPORT_DESCRIPTOR*)((char*) pFileBase+RVA2FileOffset( pNTHeader->OptionalHeader.DataDirectory[1].VirtualAddress)) ;
for (; *(char*)pImportDescriptor ; pImportDescriptor++)
{
printf ("Import Lib: %s\n" , (char *)( RVA2FileOffset( pImportDescriptor->Name)+(char *) pFileBase)) ;
pThunkData = ( IMAGE_THUNK_DATA* ) ( RVA2FileOffset( pImportDescriptor->OriginalFirstThunk)+(char*) pFileBase) ;
for (;pThunkData->u1.AddressOfData; pThunkData++)
{
if ( pThunkData->u1.Ordinal & IMAGE_ORDINAL_FLAG32 ) // import by index
{
printf ( "\t0x%04x\n" , pThunkData-> u1. Ordinal & 0xffff) ;
}
else // import by name
{
pImportByName = ( IMAGE_IMPORT_BY_NAME* ) ( RVA2FileOffset( pThunkData->u1.Ordinal) + ( char * ) pFileBase) ;
printf ( "\t0x%04x\t%s\n" , pImportByName->Hint, pImportByName->Name) ;
}
}
printf ( "\n" ) ;
}
if ( pNTHeader->OptionalHeader.DataDirectory[0].Size== 0 ) // Export Table Not Exist
goto End;
// Export Table
printf ( "\n---------------Export Table----------------------\n") ;
pExportDirectory = ( IMAGE_EXPORT_DIRECTORY* ) ( RVA2FileOffset( pNTHeader->OptionalHeader.DataDirectory[ 0].VirtualAddress) + ( char * ) pFileBase) ;
printf ("Export Lib: \t%s\n" , ( char * ) ( RVA2FileOffset( pExportDirectory->Name) + ( char * ) pFileBase) ) ;
printf ("\tIndex\tName\t\t\n" ) ;
printf ("\t---------------------------------------------------\n") ;
for (dwIndex = 0;dwIndex< pExportDirectory->NumberOfNames;dwIndex++)
{
pdw=(DWORD*)(RVA2FileOffset( pExportDirectory->AddressOfNames) + (char*) pFileBase) ;
pw=(WORD*)(RVA2FileOffset(pExportDirectory->AddressOfFunctions)+( char * ) pFileBase) ;
printf ( "\t0x%04x\t%-20s\n" , dwIndex, ( char * )(RVA2FileOffset( pdw[dwIndex])+(char*)pFileBase) , pw[ dwIndex] ) ;
}
End:
UnmapViewOfFile( pFileBase) ;
CloseHandle( hFileMapping) ;
CloseHandle( hFile) ;
getchar();
return 0;
}
/*
Convert RVA To File Offset
*/
DWORD RVA2FileOffset( DWORD dwRVA)
{
DWORD dwNum, dwIndex;
if ( pNTHeader== NULL)
return 0;
if (pSectionHeader== NULL )
return 0;
dwNum=pNTHeader->FileHeader.NumberOfSections;
for (dwIndex = 0; dwIndex<dwNum; dwIndex++)
{
if ( dwRVA>= pSectionHeader[ dwIndex] .VirtualAddress &&
dwRVA<= pSectionHeader[ dwIndex] .VirtualAddress+pSectionHeader[dwIndex].SizeOfRawData)
{
return dwRVA-pSectionHeader[dwIndex].VirtualAddress + pSectionHeader[ dwIndex].PointerToRawData;
}
}
return 0;
}
#include <windows.h>
#include <time.h>
// Data Directory Description
char szDataDirectory[ 16] [ 64] =
{
"Export Directory" ,
"Import Directory" ,
"Resource Directory" ,
"Exception Directory" ,
"Security Directory" ,
"Base Relocation Table" ,
"Debug Directory" ,
"Architecture Specific Data" ,
"RVA of GP" ,
"TLS Directory" ,
"Load Configuration Directory" ,
"Bound Import Directory in headers" ,
"Import Address Table" ,
"Delay Load Import Descriptors" ,
"COM Runtime descriptor" ,
"UnKnow Flag"
} ;
HANDLE hFile = NULL ;
HANDLE hFileMapping = NULL ;
void * pFileBase = NULL ;
IMAGE_DOS_HEADER * pDosHeader= NULL ;
IMAGE_NT_HEADERS * pNTHeader= NULL ;
IMAGE_SECTION_HEADER *pSectionHeader = NULL ;
DWORD RVA2FileOffset( DWORD dwRVA) ;
int main( int argc,char **argv)
{
struct tm * ptm;
DWORD dwIndex;
IMAGE_IMPORT_DESCRIPTOR * pImportDescriptor= NULL ;
IMAGE_THUNK_DATA * pThunkData= NULL ;
IMAGE_IMPORT_BY_NAME * pImportByName= NULL ;
IMAGE_EXPORT_DIRECTORY * pExportDirectory= NULL ;
DWORD * pdw;
WORD * pw;
if ( argc !=2 )
{
printf ( "Usage:\n\t%s PEFile\n" ,argv[0] ) ;
return -1;
}
/*********************** Map the file to memory *************************/
hFile = CreateFile( argv[ 1] , GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL , OPEN_EXISTING, FILE_ATTRIBUTE_ARCHIVE, NULL ) ;
if ( hFile==INVALID_HANDLE_VALUE )
{
printf ("Open File Error.\n" ) ;
return -1;
}
hFileMapping = CreateFileMapping( hFile, NULL , PAGE_READONLY, 0, 0, NULL ) ;
if ( ! hFileMapping )
{
CloseHandle( hFile) ;
printf ( "Create File Mapping Error.\n" ) ;
return -1;
}
pFileBase = MapViewOfFile( hFileMapping, FILE_MAP_READ, 0, 0, 0) ;
if ( ! pFileBase )
{
CloseHandle( hFileMapping) ;
CloseHandle( hFile) ;
printf ("Map View Of File Error.\n" ) ;
return -1;
}
/*********************** Map end *****************************************/
// get the dos heaader pointer
pDosHeader = (IMAGE_DOS_HEADER* ) pFileBase;
if ( pDosHeader->e_magic!=IMAGE_DOS_SIGNATURE )
{
printf ("Unknow File Format.\n") ;
goto End;
}
printf("*****************IMAGE_DOS_HEADER****************\n");
printf ("%-35s%s\n" , "FileName:" , argv[1]) ;
printf ("%-35s%#010x\n" , "Dos Stub Size:" , pDosHeader->e_lfanew - sizeof(IMAGE_DOS_HEADER)) ;
printf ("%-35s%#010x\n" , "NT File RVA:" , pDosHeader->e_lfanew) ;
// get the nt header pointer
pNTHeader=(IMAGE_NT_HEADERS*)((char*)pFileBase+pDosHeader->e_lfanew) ;
if ( pNTHeader->Signature!=IMAGE_NT_SIGNATURE )
{
printf ("Not NT File.\n") ;
goto End;
}
// get the section header pointer
pSectionHeader=(IMAGE_SECTION_HEADER*)((char* ) pNTHeader+sizeof(IMAGE_NT_HEADERS) ) ;
printf("*****************IMAGE_FILE_HEADER***************\n");
printf ("%-35s%s\n" , "nRun Platform:" ,(pNTHeader->FileHeader. Machine==IMAGE_FILE_MACHINE_I386) ? "Intel 386" : "Other" ) ;
printf ( "%-35s%d\n" , "NumOfSections:" , pNTHeader->FileHeader. NumberOfSections) ;
ptm=localtime((const long*)&(pNTHeader->FileHeader.TimeDateStamp)) ;
printf ("%-35s%02d/%02d/%04d %02d:%02d:%02d\n" , "FileCreateTime:",ptm-> tm_mon + 1, ptm-> tm_mday, ptm-> tm_year+1900,
ptm->tm_hour, ptm->tm_min, ptm->tm_sec) ;
//printf("%.19s\n", asctime(ptm));
printf ("%-35s%#010x\n" , "SizeofOptionHdr:" , pNTHeader-> FileHeader. SizeOfOptionalHeader) ;
printf ( "%-35s%s\n" , "File Type:" , ( pNTHeader-> FileHeader. Characteristics & IMAGE_FILE_DLL) ? "DLL" : "EXE" ) ;
printf("*****************IMAGE_OPTIONAL_HEADER***********\n");
printf ("%-35s%s\n" , "Image Type:" , ( pNTHeader->OptionalHeader. Magic == 0x10B) ? "Exe Image" : "Other" ) ;
printf ("%-35s%d.%d\n" , "Linker Version:" , pNTHeader-> OptionalHeader. MajorLinkerVersion, pNTHeader-> OptionalHeader. MinorLinkerVersion) ;
printf ("%-35s%#010x\n" , "SizeofCode:" , pNTHeader->OptionalHeader. SizeOfCode) ;
printf ( "%-35s%#010x\n" , "AddressOfEntryPoint:" , pNTHeader->OptionalHeader. AddressOfEntryPoint) ;
printf ( "%-35s%#010x\n" , "DefaultLoadAddress:" , pNTHeader->OptionalHeader. ImageBase) ;
printf ( "%-35s%#010x\n" , "SectionAlignment:" , pNTHeader-> OptionalHeader. SectionAlignment) ;
printf ( "%-35s%#010x\n" , "FileAlignment:" , pNTHeader-> OptionalHeader. FileAlignment) ;
printf ( "%-35s%d.%d\n" , "OS SystemVersion:" , pNTHeader-> OptionalHeader. MajorOperatingSystemVersion,
pNTHeader-> OptionalHeader. MinorOperatingSystemVersion) ;
printf ( "%-35s%d.%d\n" , "ImageVersion:" , pNTHeader-> OptionalHeader. MajorImageVersion,
pNTHeader-> OptionalHeader. MinorImageVersion) ;
printf ( "%-35s%d.%d\n" , "SubSystemVersion:" , pNTHeader-> OptionalHeader. MajorSubsystemVersion,
pNTHeader-> OptionalHeader. MinorSubsystemVersion) ;
printf ( "%-35s%#010d\n" , "SizeOfIamge:" , pNTHeader-> OptionalHeader. SizeOfImage) ;
printf ( "%-35s%#010d\n" , "SizeOfHeaders:" , pNTHeader-> OptionalHeader. SizeOfHeaders) ;
if ( pNTHeader-> OptionalHeader. Subsystem== IMAGE_SUBSYSTEM_WINDOWS_GUI )
printf ( "%-35s%s\n" , "GUI System:" , "Windows GUI" ) ;
else if ( pNTHeader-> OptionalHeader. Subsystem==IMAGE_SUBSYSTEM_WINDOWS_CUI)
printf ( "%-35s%s\n" , "GUI System:" , "Windows Console" ) ;
else
printf ( "%-35s%s\n" , "GUI System:" , "Other" ) ;
printf("-----------------IMAGE_DATA_DIRECTY---------------\n");
printf ("#Index\t#VirAddress\t#Size\t\t#%-32s\n" , "Directory Name" ) ;
for (dwIndex=0; dwIndex<IMAGE_NUMBEROF_DIRECTORY_ENTRIES; dwIndex++)
{
printf ("0x%02x\t0x%08x\t0x%08x\t%-50s\n" , dwIndex,
pNTHeader-> OptionalHeader.DataDirectory[ dwIndex].VirtualAddress,
pNTHeader-> OptionalHeader.DataDirectory[ dwIndex].Size, szDataDirectory[ dwIndex]) ;
}
printf("*****************IMAGE_SECTION_HEADER****************\n");
printf ("#VirtualAddress\t#VirtualSize\t#PointerToRawData\t#SizeOfRawData\t#Name\n") ;
for ( dwIndex = 0; dwIndex < pNTHeader-> FileHeader. NumberOfSections; dwIndex++)
{
printf ("0x%08x\t0x%08x\t0x%08x\t\t0x%08x\t%-10s\n" , pSectionHeader[dwIndex].VirtualAddress,
pSectionHeader[ dwIndex].Misc. VirtualSize, pSectionHeader[dwIndex].PointerToRawData,
pSectionHeader[ dwIndex].SizeOfRawData, pSectionHeader[dwIndex].Name) ;
}
// Import Table
printf ("\n---------------Import Table----------------------\n") ;
pImportDescriptor=(IMAGE_IMPORT_DESCRIPTOR*)((char*) pFileBase+RVA2FileOffset( pNTHeader->OptionalHeader.DataDirectory[1].VirtualAddress)) ;
for (; *(char*)pImportDescriptor ; pImportDescriptor++)
{
printf ("Import Lib: %s\n" , (char *)( RVA2FileOffset( pImportDescriptor->Name)+(char *) pFileBase)) ;
pThunkData = ( IMAGE_THUNK_DATA* ) ( RVA2FileOffset( pImportDescriptor->OriginalFirstThunk)+(char*) pFileBase) ;
for (;pThunkData->u1.AddressOfData; pThunkData++)
{
if ( pThunkData->u1.Ordinal & IMAGE_ORDINAL_FLAG32 ) // import by index
{
printf ( "\t0x%04x\n" , pThunkData-> u1. Ordinal & 0xffff) ;
}
else // import by name
{
pImportByName = ( IMAGE_IMPORT_BY_NAME* ) ( RVA2FileOffset( pThunkData->u1.Ordinal) + ( char * ) pFileBase) ;
printf ( "\t0x%04x\t%s\n" , pImportByName->Hint, pImportByName->Name) ;
}
}
printf ( "\n" ) ;
}
if ( pNTHeader->OptionalHeader.DataDirectory[0].Size== 0 ) // Export Table Not Exist
goto End;
// Export Table
printf ( "\n---------------Export Table----------------------\n") ;
pExportDirectory = ( IMAGE_EXPORT_DIRECTORY* ) ( RVA2FileOffset( pNTHeader->OptionalHeader.DataDirectory[ 0].VirtualAddress) + ( char * ) pFileBase) ;
printf ("Export Lib: \t%s\n" , ( char * ) ( RVA2FileOffset( pExportDirectory->Name) + ( char * ) pFileBase) ) ;
printf ("\tIndex\tName\t\t\n" ) ;
printf ("\t---------------------------------------------------\n") ;
for (dwIndex = 0;dwIndex< pExportDirectory->NumberOfNames;dwIndex++)
{
pdw=(DWORD*)(RVA2FileOffset( pExportDirectory->AddressOfNames) + (char*) pFileBase) ;
pw=(WORD*)(RVA2FileOffset(pExportDirectory->AddressOfFunctions)+( char * ) pFileBase) ;
printf ( "\t0x%04x\t%-20s\n" , dwIndex, ( char * )(RVA2FileOffset( pdw[dwIndex])+(char*)pFileBase) , pw[ dwIndex] ) ;
}
End:
UnmapViewOfFile( pFileBase) ;
CloseHandle( hFileMapping) ;
CloseHandle( hFile) ;
getchar();
return 0;
}
/*
Convert RVA To File Offset
*/
DWORD RVA2FileOffset( DWORD dwRVA)
{
DWORD dwNum, dwIndex;
if ( pNTHeader== NULL)
return 0;
if (pSectionHeader== NULL )
return 0;
dwNum=pNTHeader->FileHeader.NumberOfSections;
for (dwIndex = 0; dwIndex<dwNum; dwIndex++)
{
if ( dwRVA>= pSectionHeader[ dwIndex] .VirtualAddress &&
dwRVA<= pSectionHeader[ dwIndex] .VirtualAddress+pSectionHeader[dwIndex].SizeOfRawData)
{
return dwRVA-pSectionHeader[dwIndex].VirtualAddress + pSectionHeader[ dwIndex].PointerToRawData;
}
}
return 0;
}
相关文章推荐
- windows系统平台下的PE文件格式和数据定义详解(附带详细高清大图)
- BMP图像文件格式分析附带图解
- PE文件结构分析(代码)
- WAV文件格式分析解析,代码已附
- PE文件分析图详细2
- 转——kmeans特征提取原理,详细代码图解分析
- PE文件格式分析及修改
- PNG文件结构分析(上:了解PNG文件存储格式)
- PE文件格式分析及修改
- wav文件格式分析详解和解析代码
- PE文件结构分析
- 转:Nutch Crawler工作流程及文件格式详细分析
- PE文件和COFF文件格式分析——签名、COFF文件头和可选文件头1
- Windows图标-Icon文件格式分析
- wav文件格式分析(代码 C++ )
- 从monodis源码分析pe文件结构与msil反汇编
- [转]整理一份我对Windows文件系统过滤驱动的sFilter工程代码的详细说明
- 图解 bmp 文件(BITMAP,windows位图文件)格式
- mp4(H264容器)的详细文件格式分析
- Nutch Crawler工作流程及文件格式详细分析