Список функций из DLL AddressOfNames
Пришло время научиться получать список экпортируемых функций из 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;
}