Аналог DumpBin

=== Аналог DumpBin ===
Иногда на форуме проскакивает такой вопрос: "Как можно поглядеть экспортируемые функции какой либо длл'ины?".
Можно конечно же воспользоваться стандартными утилитами, но можно попробовать написать и что нить свое.
Сейчас я попробую показать такой пример. Напишем пример, который делает именно это - вытаскивает экспорт модуля.
Подробно расписывать тут ничего не буду, тут идет разбор элементов PE заголовка - нахождение таблицы экспорта, перечисление ф-ий. Недостаток этого примера в том, что он работает уже с подгруженными модулями, т.к. для нахождения базы используется GetModuleHandle(). 
Вставка:
The GetModuleHandle function returns a module handle for the specified module if the file has been mapped into the address 
space of the calling process. 
Для расширения возможностей - просмотра всех модулей, надо использовать что нить другое, например "мэпирование" (CreateFileMapping() итд). Ведь надо хоть что нить самому сделать....
program ExpDump;
uses windows;
var
 ImageBase : DWord;
 DosHeader : PImageDosHeader;
 PeHeader : PImageNtHeaders;
 PExport : PImageExportDirectory;
 pname : PDWord;
 name : PChar;
 i : Integer;
 cmdline : string;
//#### ?-??: ????? ? ????
function Dump(const log: PChar): boolean;
var
 hFile: THandle;
 dwError: DWord;
 dwWritten: DWord;
 buffer: PChar;
begin
 hFile := CreateFile(PChar(cmdline + '_fexport.txt'), GENERIC_WRITE, 0, nil, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);
 if (hFile = INVALID_HANDLE_VALUE) then
 begin
 Result := FALSE;
 exit;
 end;
 dwError := SetFilePointer(hFile, 0, nil, FILE_END);
 if (dwError = $FFFFFFFF) then
 begin
 CloseHandle(hFile);
 Result := FALSE;
 exit;
 end;
 buffer := PChar(log + #13#10);
 WriteFile(hFile, buffer^, length(buffer), dwWritten, nil);
 if (dwWritten < DWord(length(buffer))) then
 begin
 CloseHandle(hFile);
 Result := FALSE;
 exit;
 end;
 CloseHandle(hFile);
 Result := TRUE;
end;
//####
//#### Start
begin
 if (ParamCount < 1) then
 halt(0)
 else
 cmdline := ParamStr(1);
 ImageBase := GetModuleHandle(PChar(cmdline));
 if (ImageBase = 0) then
 begin
 MessageBox(0, 'Error Load Module', 'Error', MB_OK);
 halt(0);
 end;
 DosHeader := PImageDosHeader(ImageBase);
 if (DosHeader^.e_magic <> IMAGE_DOS_SIGNATURE) then
 begin
 MessageBox(0, 'Error Dos Header', 'Error', MB_OK);
 halt(0);
 end;
 PEHeader := PImageNtHeaders(DWord(ImageBase) + DWord(DosHeader^._lfanew));
 if (PEHeader^.Signature <> IMAGE_NT_SIGNATURE) then
 begin
 MessageBox(0, 'Error PE Header', 'Error', MB_OK);
 halt(0);
 end;
 PExport := PImageExportDirectory(ImageBase + DWord(PEHeader^.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress));
 pname := PDWord(ImageBase + DWord(PExport^.AddressOfNames));
 Dump(PChar('Programm ExpDump =)'));
 Dump(PChar(cmdline + ' functions:'));
 Dump(PChar(#13#10));
 for i := 0 to PExport^.NumberOfNames - 1 do
 begin
 name := PChar(PDWord(DWord(ImageBase) + PDword(pname)^));
 if (not Dump(name)) then halt(0);
 Inc(pname);
 end;
end.
//#### End 
Пример использования:
 ExpDump.Exe User32.dll
В результате:
 Programm ExpDump =)
 user32.dll functions:
 
 ActivateKeyboardLayout
 AdjustWindowRect
 AdjustWindowRectEx
 AlignRects
 AllowForegroundActivation
 AllowSetForegroundWindow
 AnimateWindow
 AnyPopup
 AppendMenuA
 AppendMenuW
 ArrangeIconicWindows
 AttachThreadInput
 BeginDeferWindowPos
 BeginPaint
 BlockInput
 ...
Для улучшения можно доделать так: 
 ImageBase := GetModuleHandle(PChar(cmdline));
 if (ImageBase = 0) then
 begin
 ImageBase := LoadLibrary(PChar(cmdline));
 if (ImageBase = 0) then
 begin
 MessageBox(0, 'Error Load Module', 'Error', MB_OK);
 halt(0);
 end;
 end;
И не забудьте в конце FreeLibrary() 
Source: Взято из http://forum.sources.ru
ID: 02003