Информация взята с http://www.firststeps.ru/mfc/winapi/r.php?28 Пришло время научиться получать список экпортируемых функций из DLL. Учтите, что мы с Вами экпортируем все функции даже не документированные. В структуре IMAGE_DIRECTORY_ENTRY_EXPORT есть ссылки на три массива. Один из этих массивов ссылается на данные с именами функций: typedef struct _IMAGE_EXPORT_DIRECTORY { ...... DWORD AddressOfFunctions; DWORD AddressOfNames; // массив указателей на имена функций DWORD AddressOfNameOrdinals; } IMAGE_EXPORT_DIRECTORY, *PIMAGE_EXPORT_DIRECTORY; Итак, сейчас давайте создадим программу, которая будет выводить в файл список всех функций из модуля user32.dll. Сначала создадим ссылку на библиотеку работы с потоками: // TestAPI.cpp : Defines the entry point for the application. // #include "stdafx.h" #include "fstream.h" ....... А теперь новый код: ...... PIMAGE_EXPORT_DIRECTORY pImportDesc=NULL; pImportDesc = MakePtr(PIMAGE_EXPORT_DIRECTORY,hUser32, pPEHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress); PCSTR *l_ppszName = MakePtr(PCSTR*,pImportDesc->AddressOfNames, hUser32); DWORD x=pImportDesc->NumberOfNames; ofstream ofs("rez.txt"); for (DWORD i=0;i<x;i++) { char *p=MakePtr(char*,*l_ppszName,hUser32); ofs << p << endl; l_ppszName++; } ofs.close(); return TRUE; } Кстати эта программа тестировалась как на Windows 98, так и на Windows 2000. Были получены интересные выводы, которые я расскажу в следующем шаге. Ниже я приведу полный код программы, так как долго дописывал кусочки и Вы могли запутаться. Если Вы начали смотреть с этого шага, то прочитайте все предыдущие для лучшего понимания. Результат работы будет в файле rez.txt: ActivateKeyboardLayout AdjustWindowRect AdjustWindowRectEx AlignRects AnimateWindow AnyPopup AppendMenuA AppendMenuW ArrangeIconicWindows AttachThreadInput ...... Ну и полный код // TestAPI.cpp : Defines the entry point for the application. // #include "stdafx.h" #include "fstream.h" #define NTSIGNATURE(a) ((LPVOID)((BYTE *)a + ((PIMAGE_DOS_HEADER)a)->e_lfanew)) #define MakePtr(Type, Base, Offset) ((Type)(DWORD(Base) + (DWORD)(Offset))) int APIENTRY WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { HMODULE hUser32=NULL; hUser32=GetModuleHandle("user32"); if (hUser32==NULL) { MessageBox(NULL,"Error Load User32","Error",MB_OK); return FALSE; } PIMAGE_DOS_HEADER pDOSHead; pDOSHead = (PIMAGE_DOS_HEADER)hUser32; if ( pDOSHead->e_magic != IMAGE_DOS_SIGNATURE ) { MessageBox(NULL,"Error Dos Header signature MZ","Error",MB_OK); return FALSE; } PIMAGE_NT_HEADERS pPEHeader; pPEHeader=(PIMAGE_NT_HEADERS) NTSIGNATURE(pDOSHead); if ( pPEHeader->Signature != IMAGE_NT_SIGNATURE ) { MessageBox(NULL,"Error PE Header signature PE","Error",MB_OK); return FALSE; } IMAGE_FILE_HEADER FileHeader; FileHeader=(IMAGE_FILE_HEADER) pPEHeader->FileHeader; if (FileHeader.Machine!=IMAGE_FILE_MACHINE_I386) { MessageBox(NULL,"Error Not 386 Proccesor","Error",MB_OK); return FALSE; } IMAGE_OPTIONAL_HEADER32 OptionHeader; OptionHeader=(IMAGE_OPTIONAL_HEADER32) pPEHeader->OptionalHeader; PIMAGE_EXPORT_DIRECTORY pImportDesc=NULL; pImportDesc = MakePtr(PIMAGE_EXPORT_DIRECTORY,hUser32, pPEHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress); PCSTR *l_ppszName = MakePtr(PCSTR*,pImportDesc->AddressOfNames, hUser32); DWORD x=pImportDesc->NumberOfNames; ofstream ofs("rez.txt"); for (DWORD i=0;i<x;i++) { char *p=MakePtr(char*,*l_ppszName,hUser32); ofs << p << endl; l_ppszName++; } ofs.close(); return TRUE; }
|