Функция вызова в 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 также может быть полезна.