Есть ли способ найти все функции, предоставляемые dll

Я искал способ получить все строки, которые сопоставляются с именами функций в dll.

Под этим я подразумеваю все строки, для которых можно вызвать GetProcAddress. Если вы делаете шестнадцатеричный дамп dll, символы (строки) есть, но я полагаю, что для получения этих имен должен быть системный вызов.


person minty    schedule 12.01.2009    source источник
comment
просто придирка, но я думаю, что вы имели в виду › но я полагаю, что должен быть системный вызов   -  person Ryan Guill    schedule 13.01.2009
comment
Если вы ищете способ сделать это программно, см. мой ответ ниже.   -  person Aaron    schedule 16.01.2009
comment
Также имейте в виду, что библиотеки DLL могут экспортировать функции, не имеющие строковых имен, и доступ к ним должен осуществляться через их порядковый номер.   -  person josh poley    schedule 02.10.2013
comment
Данные также можно экспортировать по порядковому номеру. Однако в обоих случаях по-прежнему можно использовать GetProcAddress (...) с использованием имени. Вам просто нужно использовать псевдоним, который вам дает MAKEINTRESOURCEA (<ordinal>); вы никогда не найдете это имя, пройдясь по таблице экспорта исполняемого образа, но GetProcAddress прекрасно знает, что с ним делать ;)   -  person Andon M. Coleman    schedule 03.12.2016


Ответы (13)


Это требует некоторой работы, но вы можете сделать это программно, используя библиотека DbgHelp от Microsoft.

«Отладка приложений для Microsoft .Net и Microsoft Windows» Джона Роббинса — превосходная (хотя и немного старая) книга, содержащая подробности использования и полный исходный код. И вы можете купить его на Amazon по дешевке!

person Aaron    schedule 14.01.2009

Если у вас есть MS Visual Studio, есть инструмент командной строки под названием DUMPBIN.

dumpbin /exports <nameofdll>
person Die in Sente    schedule 12.01.2009
comment
...также известный как: link.exe /dump /exports - person reuben; 14.01.2009
comment
Вам даже не нужен VS. Вы можете просто загрузить MS Windows SDK и использовать в нем оболочку CMD. Очень полезно. - person MeanwhileInHell; 12.11.2013
comment
Имена, которые он сообщает, по-прежнему искажены, но вы можете быстро исправить их с помощью demangler.com. - person Evgen; 07.02.2018

В Windows существует три различных типа DLL:

  1. Классические библиотеки DLL, которые предоставляют все доступные функции в таблице экспорта библиотеки DLL. Вы можете использовать dumpbin.exe или depend.exe из Visual Studio или бесплатный обходчик зависимостей для изучения этих типов. . Matt Pietrek написал множество статей и утилит для работы с PE-файлами Win32. Взгляните на его классические статьи журнала MSDN Magazine. Библиотеки C++, содержащие экспортированные классы, будут экспортировать каждый метод в классе. К сожалению, он экспортирует искаженные имена, поэтому вывод dumpbin практически нечитаем. Вам нужно будет использовать такую ​​программу, как vc++_filt.exe, чтобы разобрать вывод.

  2. Библиотеки COM, предоставляющие COM-объекты. Эти библиотеки DLL предоставляют несколько обычных экспортируемых функций (DllRegisterServer и т. д.), которые позволяют системе COM создавать экземпляры объектов. Есть много утилит, которые могут просматривать эти библиотеки DLL, но если они не имеют встроенных библиотек типов, их может быть довольно сложно исследовать. 4Разработчики имеют ряд хороших инструментов COM/ActiveX

  3. Библиотеки .NET, содержащие сборки .NET. Как правило, вы должны использовать такой инструмент, как .NET Reflector, чтобы копаться в них.

Редактировать: ссылка 4Developers не работает.

person Mike Thompson    schedule 13.01.2009

Также существует программа DEPENDs по адресу http://www.dependencywalker.com/.

person Die in Sente    schedule 12.01.2009
comment
В качестве альтернативы Depends также доступен при установке платформы SDK. - person Greg Domjan; 13.01.2009
comment
@Greg Версия в SDK на несколько версий старше, чем на веб-сайте. Возможно, с этим все в порядке, но может также порекомендовать источник .. - person Aaron; 14.01.2009

Попробуйте этот (Linux) код C:

#include <fcntl.h>
#include <stdio.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>

unsigned int vpe2offset(void * base, unsigned int vpe) {
    unsigned int * ptr = base;
    unsigned int pe_offset;
    unsigned short num_sections;

    pe_offset = ptr[0x3c/4];                             //PE header offset
    ptr = base + pe_offset;                              //PE header address
    num_sections = ((unsigned short*)ptr)[6/2];          //Section count
    ptr = ((void*)base) + 0x18 + 0x60 + 16*8 + pe_offset;//Address of first section

    while (num_sections--) {
        if (vpe >= ptr[0x0c/4] && vpe < ptr[0x0c/4] + ptr[0x10/4]) {
            return vpe - ptr[0x0c/4] + ptr[0x14/4];
        }
        ptr += 0x28/4;
    }

    return 0;
}

void iterate_exports(void * base, int(*iterator)(char*)) {
    unsigned int * ptr = base;
    unsigned int pe_offset,
                 exports_offset,
                 number_of_names,
                 address_of_names;

    pe_offset = ptr[0x3c/4];
    ptr = base + pe_offset;
    exports_offset = ptr[0x78/4];
    ptr = base + vpe2offset(base, exports_offset);
    number_of_names = ptr[0x18/4];
    address_of_names = ptr[0x20/4];
    ptr = base + vpe2offset(base, address_of_names);
    while (number_of_names-- && iterator((char*)(base + vpe2offset(base, ptr++[0])))) {
        /* Do nothing */
    }
}

int print_symbol_name(char * name) {
    printf("%s\n", name);
    return 1;
}

int main(int argc, char const *argv[]) {
    int fd;
    struct stat st;
    void * base;

    if (argc == 1) {
        printf("Usage: %s <dll>\n", argv[0]);
    } else if (stat(argv[1], &st) == 0 && (fd = open(argv[1], O_RDONLY)) >= 0) {
        base = mmap(NULL, st.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
        if (base != MAP_FAILED) {
            iterate_exports(base, print_symbol_name);
            munmap(base, st.st_size);
        } else {
            fprintf(stderr, "Could not map \"%s\".\n", argv[1]);
        }
        close(fd);
    } else {
        fprintf(stderr, "Could not open \"%s\" for reading.\n", argv[1]);
    }
    return 0;
}

Он следует ссылкам внутри PE-файла и, наконец, вызывает функцию обратного вызова для каждого экспортированного символа. Обзор формата файла PE см. здесь: http://www.openrce.org/reference_library/files/reference/PE%20Format.pdf

person Robert Larsen    schedule 04.06.2012

Я не знаю API WIn32 для этого: вместо этого вы (или один из инструментов, упомянутых в других сообщениях) делаете это, зная двоичный формат PE-файла и читая файл: см. http://msdn.microsoft.com/en-us/magazine/cc301808.aspx ( и в этой статье упоминалась утилита "PEDUMP").

person ChrisW    schedule 12.01.2009
comment
Отличный ответ, за который я голосую, но я добавлю ссылку на окончательный справочный документ по формату файла PE: microsoft.com/whdc/system/platform/firmware/PECOFF.mspx - person Die in Sente; 13.01.2009

Я использую dumpbinGUI, который дает вам список экспортируемых (и много больше) щелкнув правой кнопкой мыши в проводнике Windows. dumpbin и depends также дадут вам списки.

person ctacke    schedule 12.01.2009

Вам нужно проверить PE-заголовок .dll, так как в конечном итоге это то, что Windows делает в любом случае.

Предполагая, что у вас есть указатель на IMAGE_OPTIONAL_HEADER .dll (вы можете либо использовать функцию ImageNtHeader dbghelp с дескриптором .dll, загруженной через LoadLibrary, либо попытаться найти ее самостоятельно, если вы сами знаете макет .dll), вам понадобится чтобы посмотреть на optional_header->DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT], найдите таблицу экспорта относительно необязательного заголовка со смещением там, затем пройдитесь по таблице экспорта (это IMAGE_EXPORT_DIRECTORY).

Для забавы: обратно совместимый PE-образ начинается с IMAGE_DOS_HEADER; смещение IMAGE_NT_HEADER равно IMAGE_DOS_HEADER::e_lfanew, а IMAGE_OPTIONAL_HEADER встроено в заголовок NT.

person MSN    schedule 13.01.2009

есть программа под названием dll export viewer, которую вы можете использовать: http://www.nirsoft.net/utils/dll_export_viewer.html

person Community    schedule 13.01.2009

Я всегда должен это делать. Я просто захожу на один из этих сайтов. На них размещается информация, которая нам обычно нужна.

Информация о DLL-файле Windows 7

Информация о DLL-файле Windows XP

person claws    schedule 06.08.2010

Вы также можете использовать linux-инструмент «objdump» под Windows, но вам, возможно, придется сначала установить cygwin.

Я использую следующие команды:

# feed the output to less
objdump -x nameOfThe.Dll| less
# or use egrep to filter
objdump -x /cygdrive/c/Windows/system32/user32.dll | \ 
    egrep "^\s*\[[ [:digit:]]{4}\] \w{1,}" | less
person minus one    schedule 07.04.2017

Я предполагаю, что вы в конечном итоге разберете PE-файл и разберетесь сами, если хотите найти имена функций неизвестной dll во время выполнения или в крайне бесполезной системе («dumpbin»); магия.

Вам следует более четко представлять, чего вы хотите.

Библиотека BFD делает то, что вы хотите (и кухонную раковину), что является основным компонент нескольких инструментов GNU binutils. Я не могу быть уверен, что это будет соответствовать вашей проблеме.

person artificialidiot    schedule 12.01.2009

Вам не нужен какой-либо инструмент, и вам не нужно анализировать PE. Просто используйте стандартный API Win32 (D)

Код (на C) много раз публиковался на сайте Adv.Win32 aping (news://comp.os.ms-windows.programmer.win32) (с 1992...)

person Community    schedule 13.01.2009
comment
Можете ли вы показать код, чтобы сделать это? Даже ссылка на конкретную функцию поможет. - person minty; 16.01.2009