周星星 阅读(1408) 评论(1)

#include <windows.h>
#include <iostream>
using namespace std;
class bar
{
public:
    bar( const char* exename )
    {
        hFile_ = CreateFile( exename, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0 );
        ULONGLONG dwFileLen_0;
        ((LPDWORD)&dwFileLen_0)[0] = GetFileSize( hFile_, &((LPDWORD)&dwFileLen_0)[1] );
        cout << "File Length = " << dwFileLen_0 << endl;
    }
    ~bar()
    {
        if( hFile_ == INVALID_HANDLE_VALUE )
            CloseHandle( hFile_ );
    }
    bool ReadMemory( LONGLONG qwOffset, DWORD dwSize, BYTE* pByte )
    {
        LONGLONG qwOffset2 = qwOffset;
        ((LPDWORD)&qwOffset2)[0] = SetFilePointer( hFile_, ((PLONG)&qwOffset2)[0], &((PLONG)&qwOffset2)[1], FILE_BEGIN );
        if( ( qwOffset2 != qwOffset )
            || ( ((LPDWORD)&qwOffset2)[0]==INVALID_SET_FILE_POINTER && GetLastError()!=NO_ERROR ) )
            return false;
        DWORD dwSize2 = dwSize;
        BOOL f = ReadFile( hFile_, pByte, dwSize, &dwSize2, 0 );
        if( !f || dwSize2!=dwSize )
            return false;
        return true;
    }
private:
    HANDLE hFile_;
};
int foo( const char* exename )
{
    bar _AtlModule( exename );
    DWORD Offset_raw = 0;
    DWORD Offset_DosHdr = Offset_raw;
    WORD DosHdr_e_magic;
    if( !_AtlModule.ReadMemory(Offset_DosHdr+offsetof(IMAGE_DOS_HEADER,e_magic),sizeof(DosHdr_e_magic),(LPBYTE)&DosHdr_e_magic) ) return -1;
    if( IMAGE_DOS_SIGNATURE != DosHdr_e_magic ) return -2;
    LONG DosHdr_e_lfanew;
    if( !_AtlModule.ReadMemory(Offset_DosHdr+offsetof(IMAGE_DOS_HEADER,e_lfanew),sizeof(DosHdr_e_lfanew),(LPBYTE)&DosHdr_e_lfanew) ) return -1;
    DWORD Offset_PeHdr = Offset_DosHdr + DosHdr_e_lfanew;
    DWORD PE_Signature;
    if( !_AtlModule.ReadMemory(Offset_PeHdr,sizeof(PE_Signature),(LPBYTE)&PE_Signature) ) return -1;
    if( PE_Signature != IMAGE_NT_SIGNATURE ) return -2;
    DWORD Offset_FileHdr = Offset_PeHdr + sizeof(DWORD);
    WORD FileHdr_NumberOfSections;
    if( !_AtlModule.ReadMemory(Offset_FileHdr+offsetof(IMAGE_FILE_HEADER,NumberOfSections),sizeof(FileHdr_NumberOfSections),(LPBYTE)&FileHdr_NumberOfSections) ) return -1;
    WORD FileHdr_SizeOfOptionalHeader;
    if( !_AtlModule.ReadMemory(Offset_FileHdr+offsetof(IMAGE_FILE_HEADER,SizeOfOptionalHeader),sizeof(FileHdr_SizeOfOptionalHeader),(LPBYTE)&FileHdr_SizeOfOptionalHeader) ) return -1;
    if( FileHdr_SizeOfOptionalHeader!=sizeof(IMAGE_OPTIONAL_HEADER32) && FileHdr_SizeOfOptionalHeader!=sizeof(IMAGE_OPTIONAL_HEADER64) ) return -2;
    
    DWORD Offset_OptlHdr = Offset_FileHdr + sizeof(IMAGE_FILE_HEADER);
    DWORD OptlHdr_SizeOfImage;
    DWORD OptlHdr_NumberOfRvaAndSizes;
    DWORD DebugDirectoryEntryRva;
    if( FileHdr_SizeOfOptionalHeader == sizeof(IMAGE_OPTIONAL_HEADER32) )
    {
        if( !_AtlModule.ReadMemory(Offset_OptlHdr+offsetof(IMAGE_OPTIONAL_HEADER32,SizeOfImage),sizeof(OptlHdr_SizeOfImage),(LPBYTE)&OptlHdr_SizeOfImage) ) return -1;
OptlHdr_SizeOfImage &= 0x0000FFFF;
        if( !_AtlModule.ReadMemory(Offset_OptlHdr+offsetof(IMAGE_OPTIONAL_HEADER32,NumberOfRvaAndSizes),sizeof(OptlHdr_NumberOfRvaAndSizes),(LPBYTE)&OptlHdr_NumberOfRvaAndSizes) ) return -1;
        if( OptlHdr_NumberOfRvaAndSizes > IMAGE_DIRECTORY_ENTRY_DEBUG )
        {
            if( !_AtlModule.ReadMemory(Offset_OptlHdr+offsetof(IMAGE_OPTIONAL_HEADER32,DataDirectory)+IMAGE_DIRECTORY_ENTRY_DEBUG*sizeof(IMAGE_DATA_DIRECTORY)+offsetof(IMAGE_DATA_DIRECTORY,VirtualAddress),sizeof(DebugDirectoryEntryRva),(LPBYTE)&DebugDirectoryEntryRva) ) return -1;
        }
    }
    else
    {
        if( !_AtlModule.ReadMemory(Offset_OptlHdr+offsetof(IMAGE_OPTIONAL_HEADER64,SizeOfImage),sizeof(OptlHdr_SizeOfImage),(LPBYTE)&OptlHdr_SizeOfImage) ) return -1;
        if( !_AtlModule.ReadMemory(Offset_OptlHdr+offsetof(IMAGE_OPTIONAL_HEADER64,NumberOfRvaAndSizes),sizeof(OptlHdr_NumberOfRvaAndSizes),(LPBYTE)&OptlHdr_NumberOfRvaAndSizes) ) return -1;
        if( OptlHdr_NumberOfRvaAndSizes > IMAGE_DIRECTORY_ENTRY_DEBUG )
        {
            if( !_AtlModule.ReadMemory(Offset_OptlHdr+offsetof(IMAGE_OPTIONAL_HEADER64,DataDirectory)+IMAGE_DIRECTORY_ENTRY_DEBUG*sizeof(IMAGE_DATA_DIRECTORY)+offsetof(IMAGE_DATA_DIRECTORY,VirtualAddress),sizeof(DebugDirectoryEntryRva),(LPBYTE)&DebugDirectoryEntryRva) ) return -1;
        }
    }
    cout << "File Length = " << OptlHdr_SizeOfImage << endl;
    if( OptlHdr_NumberOfRvaAndSizes <= IMAGE_DIRECTORY_ENTRY_DEBUG )
    {
        cout << "No EFI_IMAGE_DIRECTORY_ENTRY_DEBUG." << endl;
        return 0;
    }
    DWORD Debug_RVA = 0;
    {
        DWORD Offset_SectionHdr = Offset_OptlHdr + FileHdr_SizeOfOptionalHeader;
        for( size_t i=0; i<FileHdr_NumberOfSections; ++i )
        {
            DWORD Section_VirtualAddress;
            DWORD Section_VirtualSize;
            if( !_AtlModule.ReadMemory(Offset_SectionHdr+i*sizeof(IMAGE_SECTION_HEADER)+offsetof(IMAGE_SECTION_HEADER,VirtualAddress),sizeof(Section_VirtualAddress),(LPBYTE)&Section_VirtualAddress) ) return -1;
            if( !_AtlModule.ReadMemory(Offset_SectionHdr+i*sizeof(IMAGE_SECTION_HEADER)+offsetof(IMAGE_SECTION_HEADER,Misc.VirtualSize),sizeof(Section_VirtualSize),(LPBYTE)&Section_VirtualSize) ) return -1;
            if( DebugDirectoryEntryRva>=Section_VirtualAddress && DebugDirectoryEntryRva<Section_VirtualAddress+Section_VirtualSize )
            {
                DWORD Section_PointerToRawData;
                if( !_AtlModule.ReadMemory(Offset_SectionHdr+i*sizeof(IMAGE_SECTION_HEADER)+offsetof(IMAGE_SECTION_HEADER,PointerToRawData),sizeof(Section_PointerToRawData),(LPBYTE)&Section_PointerToRawData) ) return -1;
                Debug_RVA = Section_PointerToRawData + ( DebugDirectoryEntryRva - Section_VirtualAddress );
                break;
            }
        }
    }
    if( Debug_RVA == 0 ) return -2;
    typedef struct 
    {
        UINT32  Characteristics;
        UINT32  TimeDateStamp;
        UINT16  MajorVersion;
        UINT16  MinorVersion;
        UINT32  Type;
        UINT32  SizeOfData;
        UINT32  RVA;
        UINT32  FileOffset;
    } EFI_IMAGE_DEBUG_DIRECTORY_ENTRY;
    #define EFI_IMAGE_DEBUG_TYPE_CODEVIEW 2
    #define CODEVIEW_SIGNATURE_NB10 0x3031424E  // "NB10"
    #define CODEVIEW_SIGNATURE_RSDS 0x53445352  // "RSDS"
    typedef struct 
    {
        UINT32  Signature;
        UINT32  Unknown;
        UINT32  Unknown2;
        UINT32  Unknown3;
        // Filename of .PDB goes here
    } EFI_IMAGE_DEBUG_CODEVIEW_NB10_ENTRY;
    typedef struct
    {
        UINT32  Signature;
        UINT32  Unknown;
        UINT32  Unknown2;
        UINT32  Unknown3;
        UINT32  Unknown4;
        UINT32  Unknown5;
        // Filename of .PDB goes here
    } EFI_IMAGE_DEBUG_CODEVIEW_RSDS_ENTRY;
    UINT32 Debug_Type;
    if( !_AtlModule.ReadMemory(Offset_raw+Debug_RVA+offsetof(EFI_IMAGE_DEBUG_DIRECTORY_ENTRY,Type),sizeof(Debug_Type),(LPBYTE)&Debug_Type) ) return -1;
    if( Debug_Type != EFI_IMAGE_DEBUG_TYPE_CODEVIEW ) return -2;
    UINT32 CodeView;
    if( !_AtlModule.ReadMemory(Offset_raw+Debug_RVA+offsetof(EFI_IMAGE_DEBUG_DIRECTORY_ENTRY,RVA),sizeof(CodeView),(LPBYTE)&CodeView) ) return -1;
if( FileHdr_SizeOfOptionalHeader == sizeof(IMAGE_OPTIONAL_HEADER32) ) CodeView &= 0x0000FFFF;
    UINT32 CodeView_Type;
    if( !_AtlModule.ReadMemory(Offset_raw+CodeView,sizeof(CodeView_Type),(LPBYTE)&CodeView_Type) ) return -1;
    if( CodeView_Type!=CODEVIEW_SIGNATURE_NB10 && CodeView_Type!=CODEVIEW_SIGNATURE_RSDS ) return -2;
    UINT32 Pdbname;
    if( CodeView_Type == CODEVIEW_SIGNATURE_NB10 )
        Pdbname = CodeView + sizeof(EFI_IMAGE_DEBUG_CODEVIEW_NB10_ENTRY);
    else
        Pdbname = CodeView + sizeof(EFI_IMAGE_DEBUG_CODEVIEW_RSDS_ENTRY);
    char buf[20];
    for( size_t i=0; ; ++i )
    {
        if( !_AtlModule.ReadMemory(Offset_raw+Pdbname+i*sizeof(buf),sizeof(buf),(LPBYTE)buf) ) return -1;
        size_t len = 0;
        for( ; len<sizeof(buf) && buf[len]!='\0'; ++len );
        cout.write( buf, len );
        if( len !=sizeof(buf) ) break;
    }
    cout << endl;
    return 0;
}
int main( void )
{
    //foo( "F:\\temp\\cpp16\\DXEDriver64.exe" );
    foo( "F:\\temp\\cpp16\\debug\\cpp16.exe" );
}


评论列表
Harrison
I just want to mention I'm all new to blignogg and site-building and absolutely enjoyed this web site. Almost certainly I’m want to bookmark your website . You definitely have fantastic posts. Thanks a lot for sharing your blog.

发表评论
切换编辑模式