您的位置:首页 > 编程语言 > PHP开发

自己实现GetProcAddress

2010-05-20 01:47 495 查看
不必多说! 自己看看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->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的功能了。纯属个人娱乐。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: