Функция вызова в dll С++ без заголовка

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

Можно ли вызвать этот метод?

Спасибо,

Ответы

Ответ 1

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

Ответ 2

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

Ответ 3

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

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

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

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

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

Ответ 4

Как вы обнаружили, в списке экспорта в DLL хранятся имена, а не подписи. Если ваша DLL экспортирует функции C, вам, вероятно, придется разбирать и реконструировать функции для определения сигнатур методов. Однако С++ кодирует подпись метода в имени экспорта. Этот процесс объединения имени и подписи метода называется "mangling name" . fooobar.com/questions/127268/... содержит ссылку для определения сигнатуры метода из измененного имени экспорта.

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

Ответ 5

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

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

Ответ 6

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

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