自己实现GetProcAddress

  不必多说! 自己看看PE文件格式详解就明白了。!

FARPROC _GetProcAddress(
                        HMODULE hModule,    // handle to DLL module
                        LPCSTR lpProcName   // function name
                        )
{
    DWORD mzbase , oldprotect , dwsize , i , dwFileOffset;
    WORD wOrdinals = 0;
    long    delta , dwOffset ;
    PIMAGE_DOS_HEADER m_pDosHeader;
    PIMAGE_OPTIONAL_HEADER m_pOptionHeader;
    PIMAGE_FILE_HEADER m_pFileHeader = 0;
    PIMAGE_SECTION_HEADER  m_pSectionHeader[64];
    mzbase =  (DWORD)hModule;    // hModule实际就是基地址,查看hModule的内存值,就会发现熟悉的MZ

    PIMAGE_NT_HEADERS pNTHeader =  (PIMAGE_NT_HEADERS) ( mzbase + pDosHeader->e_lfanew   );
    PBYTE m_pFileBuf = (PBYTE) mzbase;
    m_pDosHeader = ( PIMAGE_DOS_HEADER ) mzbase;
    m_pFileHeader = (PIMAGE_FILE_HEADER) (m_pFileBuf + m_pDosHeader->e_lfanew+4);
    m_pOptionHeader = (PIMAGE_OPTIONAL_HEADER)( mzbase + m_pDosHeader->e_lfanew + 4 + sizeof( IMAGE_FILE_HEADER ) );
    dwFileOffset = (DWORD)(m_pDosHeader->e_lfanew + sizeof( IMAGE_NT_HEADERS ));
    ZeroMemory(m_pSectionHeader, sizeof(PIMAGE_SECTION_HEADER)*m_pFileHeader->NumberOfSections);
    for(  i=0; i < m_pFileHeader->NumberOfSections; i++ ) {
        m_pSectionHeader[i] = (PIMAGE_SECTION_HEADER)(m_pFileBuf + dwFileOffset);
        dwFileOffset += sizeof(IMAGE_SECTION_HEADER);
    }
    PIMAGE_EXPORT_DIRECTORY pExportD=NULL;

    pExportD  = (PIMAGE_EXPORT_DIRECTORY)((DWORD) mzbase +    pNTHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress);  

    delta = pExportD->NumberOfFunctions;
    for ( UINT j=0 ; j < pExportD->NumberOfNames; j++) {
        DWORD dwAdName = pExportD>AddressOfNames + mzbase+j*4;
        dwAdName = *(DWORD*)dwAdName + mzbase;
        if ( lstrcmpi((char*)dwAdName,lpProcName)==0){
            DWORD dwOffsetOrdinal = pExportD-&gt;AddressOfNameOrdinals + mzbase + (j<<1) ;
            WORD widx =  *(WORD*)(dwOffsetOrdinal);
            DWORD dwFun = pExportD->AddressOfFunctions + mzbase + widx*4;
            dwFun = *(DWORD*)dwFun + mzbase;
            return (FARPROC)dwFun;
        }
    }
    return 0;
}

    如此一来,不需要知道kernel32.dll也可以实现GetProcAddress的功能了。纯属个人娱乐。
 

你可能感兴趣的:(职场,休闲,pe,GetProcAddress)