从sys文件中提取资源

如何提取资源的sys文件? 我相信,exe文件,dll和sys文件具有相同的标题。 那是对的吗?

我不明白我该如何处理资源表中的VirtualAddress和Size。

#include <stdio.h> #include <windows.h> #include <string.h> void main() { FILE *file = fopen( "example.sys", "r" ); IMAGE_DOS_HEADER dos_header; IMAGE_NT_HEADERS nt_header; IMAGE_DATA_DIRECTORY data_directory; char *data; if( file != NULL ) { fseek( file, 0, SEEK_SET ); fread( &dos_header, sizeof( dos_header ), 1, file ); if( dos_header.e_magic != IMAGE_DOS_SIGNATURE ) return; fseek( file, dos_header.e_lfanew, SEEK_SET ); fread( &nt_header, sizeof( nt_header ), 1, file ); if( nt_header.Signature != IMAGE_NT_SIGNATURE ) return; data_directory = nt_header.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE]; data = malloc( data_directory.Size + 1 ); memset( data, 0, data_directory.Size + 1 ); fseek( file, data_directory.VirtualAddress, SEEK_SET ); // <- ???? fread( data, data_directory.Size, 1, file ); free( data ); fclose( file ); } } 

VirtualAddress实际上是数据结构的相对虚拟地址(RVA)。 例如,如果此结构用于导入符号,则此字段包含IMAGE_IMPORT_DESCRIPTOR数组的RVA。

isize包含VirtualAddress引用的数据结构的大小(以字节为单位)。

看看这个链接。 这是如何深入到win32程序集的一个很好的解释。

我终于找到了解决我的问题的代码示例 – PEDump 。

使用它我做了这个示例:

 #include <stdio.h> #include <windows.h> #include <string.h> #define MakePtr( cast, ptr, addValue ) (cast)( (DWORD)(ptr) + (DWORD)(addValue)) #define RESOURCE_ADDRESS( pdr, o ) ((PUCHAR) (pdr + 1) + (o)) typedef struct tag_VS_VERSIONINFO { USHORT wLength; // 00 length of entire version resource USHORT wValueLength; // 02 length of fixed file info, if any USHORT wType; // 04 type of resource (1 = text, 0 = binary) WCHAR szKey[17]; // 06 key -- VS_VERSION_INFO + padding byte VS_FIXEDFILEINFO Value; // 28 fixed information about this file (13 dwords) } VS_VERSIONINFO, *PVS_VERSIONINFO; // 5C PIMAGE_SECTION_HEADER GetEnclosingSectionHeader(DWORD rva, PIMAGE_NT_HEADERS pNTHeader) { PIMAGE_SECTION_HEADER section = IMAGE_FIRST_SECTION(pNTHeader); unsigned i; for ( i=0; i < pNTHeader->FileHeader.NumberOfSections; i++, section++ ) { // Is the RVA within this section? if ( (rva >= section->VirtualAddress) && (rva < (section->VirtualAddress + section->Misc.VirtualSize))) return section; } return 0; } LPVOID GetPtrFromRVA( DWORD rva, PIMAGE_NT_HEADERS pNTHeader, DWORD imageBase ) { PIMAGE_SECTION_HEADER pSectionHdr; INT delta; pSectionHdr = GetEnclosingSectionHeader( rva, pNTHeader ); if ( !pSectionHdr ) return 0; delta = (INT)(pSectionHdr->VirtualAddress-pSectionHdr->PointerToRawData); return (PVOID) ( imageBase + rva - delta ); } void main() { unsigned int index; PIMAGE_DOS_HEADER dos_header; PIMAGE_NT_HEADERS nt_header; PIMAGE_DATA_DIRECTORY data_directory; PIMAGE_RESOURCE_DIRECTORY resources; PIMAGE_RESOURCE_DIRECTORY_ENTRY listItem; PIMAGE_RESOURCE_DIRECTORY child; PIMAGE_RESOURCE_DIRECTORY_ENTRY version; PIMAGE_RESOURCE_DATA_ENTRY data_entry; PVS_VERSIONINFO version_info; HANDLE hFile; HANDLE hFileMapping; LPVOID lpFileBase; hFile = CreateFile( L"samples.sys", GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0 ); if ( hFile == INVALID_HANDLE_VALUE ) return; hFileMapping = CreateFileMapping( hFile, NULL, PAGE_READONLY, 0, 0, NULL ); if ( hFileMapping == 0 ) { CloseHandle(hFile); return; } lpFileBase = MapViewOfFile( hFileMapping, FILE_MAP_READ, 0, 0, 0 ); if ( lpFileBase == 0 ) { CloseHandle(hFileMapping); CloseHandle(hFile); return; } dos_header = MakePtr( PIMAGE_DOS_HEADER, lpFileBase, 0 ); if( dos_header->e_magic != IMAGE_DOS_SIGNATURE ) return; nt_header = MakePtr( PIMAGE_NT_HEADERS, lpFileBase, dos_header->e_lfanew ); if( nt_header->Signature != IMAGE_NT_SIGNATURE ) return; data_directory = &nt_header->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE]; resources = ( PIMAGE_RESOURCE_DIRECTORY )GetPtrFromRVA( data_directory->VirtualAddress, nt_header, ( DWORD )lpFileBase ); listItem = ( PIMAGE_RESOURCE_DIRECTORY_ENTRY )( resources + 1 ); for( index = 0; index < resources->NumberOfIdEntries; index++ ) { if( listItem->Id == ( WORD )RT_VERSION ) { if( listItem->DataIsDirectory ) { child = ( PIMAGE_RESOURCE_DIRECTORY )( ( listItem->OffsetToData & 0x7FFFFFFF ) + (DWORD)resources ); version = ( PIMAGE_RESOURCE_DIRECTORY_ENTRY )( child + 1 ); if( version->DataIsDirectory ) { child = ( PIMAGE_RESOURCE_DIRECTORY )( ( version->OffsetToData & 0x7FFFFFFF ) + (DWORD)resources ); version = ( PIMAGE_RESOURCE_DIRECTORY_ENTRY )( child + 1 ); data_entry = ( PIMAGE_RESOURCE_DATA_ENTRY )( ( version->OffsetToData & 0x7FFFFFFF ) + (DWORD)resources ); version_info = ( PVS_VERSIONINFO )GetPtrFromRVA( data_entry->OffsetToData, nt_header, ( DWORD )lpFileBase ); } } } listItem += 1; } } 

这里最有趣的部分是函数GetPtrFromRVA,它将被用于将VirtualAddress转换为从文件开头偏移。