![]() |
|
Модераторы: feodorv, GremlinProg, xvr, Fixin |
![]()
|
|
| null56 |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 721 Регистрация: 19.3.2008 Репутация: нет Всего: 12 |
Всем привет
Задача: пройти по файлам dll, найти функцию по имени, успешно вызвать Решение:
Результат: всё по идее хорошо, но если прототип совпадает, а если нет? я так понимаю (и получаю) падение программы. у функции нет контроля над тем, что ты пытаешься загрузить, есть имя в def и адрес, к прототипу любого вида можно привезти Вопрос: можно ли как - нибудь избежать падения, при динамическом импорте функций из библиотек, при несовпадании прототипов? какие - нибудь дополнительные проверки или другие функции для этих целей. Надеюсь вопрос понятен, заранее благодарен за помощь |
|||
|
||||
| 12usver12 |
|
|||
|
Бывалый ![]() Профиль Группа: Участник Сообщений: 247 Регистрация: 5.1.2007 Репутация: 1 Всего: 1 |
в отдельном потоке вызывать и ставить хук на завершении функции и смотреть адрес возврата
|
|||
|
||||
| borisbn |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 4875 Регистрация: 6.2.2010 Где: Ростов-на-Дону Репутация: 6 Всего: 135 |
Если библиотеки твои (или сделаны по твоим правилам), то можно в них заменить __cdecl на __stdcall, а также убрать extern "C". В этом случае прототип будет выглядеть как-то так
func_name@4i4i -------------------- Женщины отличаются от программистов тем, что у них чары состоят из стрингов |
|||
|
||||
| Abyx |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 601 Регистрация: 3.11.2009 Репутация: 2 Всего: 10 |
проверять esp
|
|||
|
||||
| null56 |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 721 Регистрация: 19.3.2008 Репутация: нет Всего: 12 |
borisbn, да, библы мои, но никогда не слышал об этом способе
Abyx, а можно по подробнее и что я должен там обнаружить? |
|||
|
||||
| xvr |
|
|||
|
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 7046 Регистрация: 28.8.2007 Где: Дублин, Ирландия Репутация: 40 Всего: 223 |
Полной информации о прототипе функции в dll нет. Есть масса способов извлечь некоторую информацию о вызываемой функции. Большую часть их уже озвучили, могу добавить еще:
|
|||
|
||||
| jonie |
|
|||
|
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 5613 Регистрация: 21.8.2005 Где: Владимир Репутация: 7 Всего: 118 |
все игры с стеком справдливы только для win32 (!) это важно....
-------------------- Что-то не поняли? -> Напейтесь до зеленых человечков... эта сверхцивилизация Вам поможет... |
|||
|
||||
| Dem_max |
|
|||
![]() Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1780 Регистрация: 12.4.2007 Репутация: 16 Всего: 39 |
Очень сложно, если нужен контроль параметров вызываемой функции. -------------------- Американские программисты долго не могли понять, почему русские при зависании Windоws всё время повторяют "Твой зайка написал" ("Yоur bunnу wrоte") |
|||
|
||||
| Abyx |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 601 Регистрация: 3.11.2009 Репутация: 2 Всего: 10 |
borisbn, xvr, при чем тут манглинг?
Если известно имя функции, то очевидно известен ее прототип, в том числе число параметров. Если функция неправильная, то никакой манглинг тут не поможет. Импортируется функция вместе с манглингом, GetProcAddress(hlib, "foo@8"), расшифровка никакой новой информации не даст. Проверка esp позволит узнать правильное ли было количество параметров у функции, после ее вызова, не более того. |
|||
|
||||
| GremlinProg |
|
|||
|
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 2706 Регистрация: 9.8.2005 Где: Тюмень Репутация: 99 Всего: 106 |
при декорировании например C++ прототип и кодируется именем функции, stdcall - тоже, но в меньшей степени: тут можно определить только размер фрейма так что манглинг тут многое может прояснить, конечно, все можно получить из отладочной секции, но доступ к имени гораздо проще, рекомендую декорирование C++ взять на контроль, если надо обязательно знать прототип, в vs есть утилитка undname.exe и есть соответствующая API недостаток у них только есть небольшой: слишком длинные имена не распознают, это особенно актуально при экспорте шаблонных имплементаций -------------------- "Гений всегда разумнее, чем умнее. Ум — это машина, разум — водитель этой машины." |
|||
|
||||
| Abyx |
|
||||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 601 Регистрация: 3.11.2009 Репутация: 2 Всего: 10 |
Как я понимаю, у ТСа проблема в том, что он не уверен, что функция в длл будет иметь ожидаемый прототип.
Например - длл это плагин, написанный сторонним разработчиком на другом языке. В этом случае, ТС может специфицировать что функция имеет прототип extern "C" void __stdcall foo(int a, int b); соответственно в таблице экспорта длл должно быть имя "foo@8" но человек пишущий длл, может писать ее на другом языке, и напишет
Добавлено @ 10:43 какбэ от того что ТС напишет
ничего не поменяется кроме того что это усложнит жизнь тому кто пишет длл Это сообщение отредактировал(а) Abyx - 3.6.2010, 10:45 |
||||
|
|||||
| null56 |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 721 Регистрация: 19.3.2008 Репутация: нет Всего: 12 |
Abyx, да про это и речь, что там вообще может быть всё что угодно, те же 8 байт параметров и та же функция... а в функции происходит работа вообще с другими типами... Мне нужна длл с моими четкими параметрами (TCHAR *, std :: vector<std::basic_string<TCHAR> > &) = те же 8 байтов (для 32 бит)
Но GremlinProg, xvr, про декорирование имен говорят, сейчас читаю и пытаюсь понять, зашит ли там при сборке длл прототип, если да, то это как раз то что нужно.... http://en.wikipedia.org/wiki/Name_mangling |
|||
|
||||
| Abyx |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 601 Регистрация: 3.11.2009 Репутация: 2 Всего: 10 |
||||
|
||||
| GremlinProg |
|
||||
|
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 2706 Регистрация: 9.8.2005 Где: Тюмень Репутация: 99 Всего: 106 |
ну да, есть такой вариант, но я бы не стал беспокоиться по поводу неправильного имени, т.к. эта ошибка будет очевидна: повреждение стека отладочная версия обнаружит сразу, если параметры передаются в нем, если нет - тем более, значит функция обработает параметры, которые не были переданы гораздо проще приложение может упасть в самой библиотеке :) try-except не защитит только от ошибки со стеком, т.к. она фатальна в любой ситуации, все остальное поймает -------------------- "Гений всегда разумнее, чем умнее. Ум — это машина, разум — водитель этой машины." |
||||
|
|||||
| Abyx |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 601 Регистрация: 3.11.2009 Репутация: 2 Всего: 10 |
восстановление ebp решает все ошибки со стеком %)
т.е. try сохраняет ebp, и при отлове эксепшена ebp восстанавливается, а в эпилоге функции восстанавливается и esp собственно если в функции есть ebp-фрейм, на ошибки с esp можно не обращать внимания, лишь бы esp не поднимался выше нижней границы фрейма Это сообщение отредактировал(а) Abyx - 3.6.2010, 11:09 |
|||
|
||||
![]()
|
| Правила форума "C/C++: Системное программирование и WinAPI" | |
|
|
На данный раздел распространяются Правила форума и Правила раздела С++:Общие вопросы . Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Chipset, Step, Fixin, GremlinProg, xvr. feodorv. |
| 0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
| 0 Пользователей: | |
| « Предыдущая тема | C/C++: Системное программирование и WinAPI | Следующая тема » |
|
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |