Вызов функции в c ++ dll без заголовка - PullRequest
14 голосов
/ 17 февраля 2009

Я хотел бы вызвать метод из библиотеки DLL, но у меня нет ни источника, ни файла заголовка. Я пытался использовать dumpbin / exports, чтобы увидеть название метода, но я могу найти сигнатуру метода?

Есть ли способ вызвать этот метод?

Спасибо

Ответы [ 6 ]

10 голосов
/ 17 февраля 2009

Если функция C ++, вы можете получить сигнатуру функции из искаженного имени. Dependency Walker - это один из инструментов, который сделает это за вас. Однако, если DLL была создана с помощью связи C (Dependency Walker скажет вам об этом), то вам не повезло.

6 голосов
/ 17 февраля 2009

Язык C ++ ничего не знает о DLL.

Это на Windows? Один из способов:

  • открыть библиотеку в depends.exe, поставляемом с (Visual Studio)
  • проверить подпись функции, которую вы хотите вызвать
  • используйте LoadLibrary() для загрузки этой библиотеки (будьте осторожны с путем)
  • используйте GetProcAddress(), чтобы получить указатель на функцию, которую вы хотите вызвать
  • использовать этот указатель на функцию для вызова с допустимыми аргументами
  • используйте FreeLibrary(), чтобы освободить ручку

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

Существует некоторый подобный механизм для * nixes с dlopen, но моя память начинает отказывать после этого. Что-то под названием objdump или nm должно помочь вам начать проверку функции (ей).

5 голосов
/ 17 февраля 2009

Как вы обнаружили, список экспорта в DLL хранит только имена, а не подписи. Если ваша DLL экспортирует функции C, вам, вероятно, придется разобрать и перепроектировать функции для определения сигнатур методов. Однако C ++ кодирует сигнатуру метода в имени экспорта. Этот процесс объединения имени метода и подписи называется «искажение имени» . Этот вопрос Stackoverflow содержит ссылку для определения сигнатуры метода из искаженного имени экспорта.

Попробуйте бесплатную "Обозреватель зависимостей" (a.k.a. "зависит") . Опция «Undecorate C ++ Functions» должна определять сигнатуру метода C ++.

3 голосов
/ 08 марта 2009

Можно определить сигнатуру функции C, проанализировав начало ее разборки. Аргументы функции будут в стеке, и функция сделает несколько «всплывающих окон», чтобы прочитать их в обратном порядке. Вы не найдете имена аргументов, но вы сможете узнать их количество и типы. С возвращаемым значением все может стать более сложным - это может быть через регистр 'eax' или через специальный указатель, переданный функции в качестве последнего псевдо-аргумента (в верхней части стека).

1 голос
/ 17 февраля 2009

Вызов внешних функций - отличный способ прерывания работы программы при обновлении сторонней DLL.

Тем не менее, утилита undname также может быть полезна.

1 голос
/ 17 февраля 2009

Если вы действительно знаете или сильно подозреваете, что функция есть, вы можете динамически загрузить DLL с помощью loadLibrary и получить указатель на функцию с помощью getProcAddress. См MSDN

Обратите внимание, что это ручной, динамический способ загрузки библиотеки; вам все равно нужно будет знать правильную сигнатуру функции для сопоставления с указателем функции, чтобы использовать ее. AFAIK, нет никакого способа использовать dll во время загрузки и использовать функции без заголовочного файла.

...