неправильные параметры ф-ции в DLL
От: sushko Россия  
Дата: 05.04.22 09:39
Оценка:
Есть моя программа (EXE) на C++/MFC, она установлена на 10050 компьютерах пользователей по всей Руси великой. Есть DLL сторонних разработчиков (программный интерфейс к устройству), кот. также используется на большом (сотни тысяч?) к-ве компьютеров. В процессе работы эта программа динамически загружает(LoadLibrary) эту DLL и вызывает из нее ф-цию int func(int param).

Идиётские разработчики DLL выпустили новую версию этой самой DLL, в которой та же (!) функция теперь описывается как int func(int param, char otherParam). Более того, выпустив новую версию DLL, эти альтернативно одаренные забыли (!) поменять в ней номер версии (VERSIONINFO) — их техподдержка признала эту ошибку. И теперь моя программа, соответственно, никак не может понять, какой набор параметров функции func() использовать. Реально программа сейчас использует старый интерфейс (int func(int param)), и если вдруг попадается пользователь с новой версией DLL, то программа тупо падает при попытке вызвать ф-цию func().

Вопрос: могу ли я как-то отловить это падение? Каким-нибудь try/catch? Если да, то каким именно?

(У меня нет у-ва, интерфейсом к которому служит DLL, и я тестировать на своем компьютере я не могу)
Бесплатный генератор отчетов для программ на C/C++
http://www.oxetta.com
Отредактировано 05.04.2022 9:55 sushko . Предыдущая версия .
Re: неправильные параметры ф-ции в DLL
От: cserg  
Дата: 05.04.22 10:17
Оценка: 1 (1)
Здравствуйте, sushko, Вы писали:

S>Вопрос: могу ли я как-то отловить это падение? Каким-нибудь try/catch? Если да, то каким именно?

MFC вроде не поддерживает SEH.

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

S>(У меня нет у-ва, интерфейсом к которому служит DLL, и я тестировать на своем компьютере я не могу)

Можно сделать фейковую DLL с пустыми телами методов, но которые будут возвращать какие-нибудь постоянные валидные значения.
Re: неправильные параметры ф-ции в DLL
От: kov_serg Россия  
Дата: 05.04.22 10:21
Оценка:
Здравствуйте, sushko, Вы писали:

S>Есть моя программа (EXE) на C++/MFC, она установлена на 10050 компьютерах пользователей по всей Руси великой. Есть DLL сторонних разработчиков (программный интерфейс к устройству), кот. также используется на большом (сотни тысяч?) к-ве компьютеров. В процессе работы эта программа динамически загружает(LoadLibrary) эту DLL и вызывает из нее ф-цию int func(int param).


S>Идиётские разработчики DLL выпустили новую версию этой самой DLL, в которой та же (!) функция теперь описывается как int func(int param, char otherParam). Более того, выпустив новую версию DLL, эти альтернативно одаренные забыли (!) поменять в ней номер версии (VERSIONINFO) — их техподдержка признала эту ошибку.

S>И теперь моя программа, соответственно, никак не может понять, какой набор параметров функции func() использовать.
Смотрите младшую часть адреса функции.

S>Реально программа сейчас использует старый интерфейс (int func(int param)), и если вдруг попадается пользователь с новой версией DLL, то программа тупо падает при попытке вызвать ф-цию func().

64bit dll ?
S>Вопрос: могу ли я как-то отловить это падение? Каким-нибудь try/catch? Если да, то каким именно?
очень сильно зависит от конкретного случая.

S>(У меня нет у-ва, интерфейсом к которому служит DLL, и я тестировать на своем компьютере я не могу)

Используйте вспомогательную программу (процесс) и смотрите поведение. Если он падает dll новая, если нет старая, после чего делайте запись в конфиге какой интерфейс использовать
Re[2]: неправильные параметры ф-ции в DLL
От: sushko Россия  
Дата: 05.04.22 11:03
Оценка:
Здравствуйте, kov_serg, Вы писали:

S>>И теперь моя программа, соответственно, никак не может понять, какой набор параметров функции func() использовать.

_>Смотрите младшую часть адреса функции.

А как на нее смотреть? Что я должен там увидеть и как мне использовать то, что я увижу?

S>>Реально программа сейчас использует старый интерфейс (int func(int param)), и если вдруг попадается пользователь с новой версией DLL, то программа тупо падает при попытке вызвать ф-цию func().

_>64bit dll ?

32bit

S>>(У меня нет у-ва, интерфейсом к которому служит DLL, и я тестировать на своем компьютере я не могу)

_>Используйте вспомогательную программу (процесс) и смотрите поведение. Если он падает dll новая, если нет старая, после чего делайте запись в конфиге какой интерфейс использовать

Не, это уже перебор
Бесплатный генератор отчетов для программ на C/C++
http://www.oxetta.com
Re[3]: неправильные параметры ф-ции в DLL
От: kov_serg Россия  
Дата: 05.04.22 11:22
Оценка: +2
Здравствуйте, sushko, Вы писали:

S>Здравствуйте, kov_serg, Вы писали:


S>>>И теперь моя программа, соответственно, никак не может понять, какой набор параметров функции func() использовать.

_>>Смотрите младшую часть адреса функции.
S>А как на нее смотреть? Что я должен там увидеть и как мне использовать то, что я увижу?
HMODULE h=LoadLibraryA("kernel32.dll");
void* p=GetProcAddress(h,"CreateFileA");
ptrdiff_t ofs=(char*)p-(char*)h;

Смотрите версию, и если она та самая где такая хрень. Сравниваете смещение целевой функции. (она скорее всего разная для разных версий).
По ней и ориентируетесь.

S>>>Реально программа сейчас использует старый интерфейс (int func(int param)), и если вдруг попадается пользователь с новой версией DLL, то программа тупо падает при попытке вызвать ф-цию func().

_>>64bit dll ?
S>32bit
Тогда вызов с корее всего __stdcall. Можно сделать такой костыль.
int __stdcall func_safe(int param, char otherParam);

И на ассемблере написать что-то типа:
   ...
   mov  esi,esp
   push otherParam
   push param
   call dll_func
   mov  esp,esi
   ...

Такой вариант будет работать с обеими версиями.

S>>>(У меня нет у-ва, интерфейсом к которому служит DLL, и я тестировать на своем компьютере я не могу)

_>>Используйте вспомогательную программу (процесс) и смотрите поведение. Если он падает dll новая, если нет старая, после чего делайте запись в конфиге какой интерфейс использовать
S>Не, это уже перебор
Почему же. Что вам мешает завести в конфигурационном файле, дополнительную опцию для лечения этого косяка?
Re: неправильные параметры ф-ции в DLL
От: Vi2 Удмуртия http://www.adem.ru
Дата: 05.04.22 11:26
Оценка:
Здравствуйте, sushko, Вы писали:

S>Есть моя программа (EXE) на C++/MFC, она установлена на 10050 компьютерах пользователей по всей Руси великой. Есть DLL сторонних разработчиков (программный интерфейс к устройству), кот. также используется на большом (сотни тысяч?) к-ве компьютеров. В процессе работы эта программа динамически загружает(LoadLibrary) эту DLL и вызывает из нее ф-цию int func(int param).


S>Идиётские разработчики DLL выпустили новую версию этой самой DLL, в которой та же (!) функция теперь описывается как int func(int param, char otherParam).


Обычно имя функции определяется по-разному, что-то типа _func@4 или _func@5, если только намеренно не приводится к непонятному _func.

Можно предложить вызывать с двумя параметрами и для старой версии. Я бы попробовал.
Vita
Выше головы не прыгнешь, ниже земли не упадешь, дальше границы не убежишь! © КВН НГУ
Re[3]: неправильные параметры ф-ции в DLL
От: cserg  
Дата: 05.04.22 11:26
Оценка: +1
Здравствуйте, sushko, Вы писали:

_>>Смотрите младшую часть адреса функции.

S>А как на нее смотреть? Что я должен там увидеть и как мне использовать то, что я увижу?
Если повезет, то пролог у новой функции будет отличаться от старой. Можно это использовать.
Re: неправильные параметры ф-ции в DLL
От: LuciferSaratov Россия  
Дата: 05.04.22 11:54
Оценка:
Здравствуйте, sushko, Вы писали:

S>Вопрос: могу ли я как-то отловить это падение? Каким-нибудь try/catch? Если да, то каким именно?


возникла следующая идея костыля.
нужно перед запуском основной программы протестировать DLL.

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

кроме того, если не хочется добавлять ещё один exe-файл к программе, это может делать и основной исполняемый файл, будучи запущенным второй раз с определенными параметрами командной строки.
Re[2]: неправильные параметры ф-ции в DLL
От: cserg  
Дата: 05.04.22 12:40
Оценка:
Здравствуйте, LuciferSaratov, Вы писали:

LS>возникла следующая идея костыля.

LS>нужно перед запуском основной программы протестировать DLL.
Хороший вариант, кторый уже предлагал kov_serg
Автор: kov_serg
Дата: 05.04.22
,
но может не прокатить, так как DLL является интерфейсом к устройству, а устройству от такого теста может поплохеть так, что придется его физически перезапускать, а у ТС устройства нет и проверить он не может.
Re[3]: неправильные параметры ф-ции в DLL
От: LuciferSaratov Россия  
Дата: 05.04.22 12:49
Оценка:
Здравствуйте, cserg, Вы писали:

C>Хороший вариант, кторый уже предлагал kov_serg
Автор: kov_serg
Дата: 05.04.22
,


да, точно, невнимательно прочитал.

C>но может не прокатить, так как DLL является интерфейсом к устройству, а устройству от такого теста может поплохеть так, что придется его физически перезапускать, а у ТС устройства нет и проверить он не может.


можно попробовать изучить интерфейс и вызывать эту функцию заведомо так, чтобы устройство она не трогала.
например, пропустить любые этапы инициализации устройства в расчете на то, что при этом DLL просигнализирует об ошибке.
то есть сделать только такие действия: загрузить DLL, получить адрес функции, вызвать её с некими некорректными параметрами, при которых ожидается сигнализация о неверном использовании функции.
Re[2]: неправильные параметры ф-ции в DLL
От: RonWilson Россия  
Дата: 05.04.22 13:11
Оценка:
Здравствуйте, kov_serg, Вы писали:

_>Используйте вспомогательную программу (процесс) и смотрите поведение. Если он падает dll новая, если нет старая, после чего делайте запись в конфиге какой интерфейс использовать


Прога упадет, запись будет сделана "ага, новая версия". Пользователь подумает — "подложу старую версию, чет криво как-то запускается". Прога опять упадет, буте сделана новая запись. Пользователь "чет стало хуже" и так далее
Re: неправильные параметры ф-ции в DLL
От: Pavel Dvorkin Россия  
Дата: 05.04.22 13:42
Оценка: 1 (1) +1
Здравствуйте, sushko, Вы писали:

S>Вопрос: могу ли я как-то отловить это падение? Каким-нибудь try/catch? Если да, то каким именно?


Тебе действительно нужно именно отловить ? Зачем ? Ну отловишь, а дальше что ? Работать же все равно не будет.

Если я правильно понимаю, надо при новой DLL просто прекращать работу приложения, так как все равно ничего хорошего не будет. Или в приложении реализовать иной код на случай новой DLL.

Следовательно, надо просто на старте определить, какая именно версия DLL будет загружена

Если даже VERSIONINFO нет — всяких штампов хватает. Например, количество импортов/экспортов может не совпадать, размеры секций и т.п.

Так что можно просто просто просмотреть заголовок PE этой DLL и принять решение.

Костыль, конечно, но работать должно.
With best regards
Pavel Dvorkin
Re: неправильные параметры ф-ции в DLL
От: qaz77  
Дата: 05.04.22 13:53
Оценка:
Здравствуйте, sushko, Вы писали:
Более того, выпустив новую версию DLL, эти альтернативно одаренные забыли (!) поменять в ней номер версии (VERSIONINFO) — их техподдержка признала эту ошибку.

Можно привязаться не к VERSIONINFO, а к размеру DLL, контрольной сумме, дате изменения.
Все это, конечно, костыль и не дает 100% гарантии, но практически может проблему решить.
Re[3]: неправильные параметры ф-ции в DLL
От: kov_serg Россия  
Дата: 05.04.22 14:13
Оценка:
Здравствуйте, RonWilson, Вы писали:

_>>Используйте вспомогательную программу (процесс) и смотрите поведение. Если он падает dll новая, если нет старая, после чего делайте запись в конфиге какой интерфейс использовать


RW>Прога упадет, запись будет сделана "ага, новая версия". Пользователь подумает — "подложу старую версию, чет криво как-то запускается". Прога опять упадет, буте сделана новая запись. Пользователь "чет стало хуже" и так далее

Вы не поняли. Библиотека запускает тестовый процесс, который или падает или нет. Пользователь ничего не видит.
Re[2]: неправильные параметры ф-ции в DLL
От: sushko Россия  
Дата: 05.04.22 15:44
Оценка:
Здравствуйте, cserg, Вы писали:

C>Надо искать другой способ. Чем еще новая DLL отличается от старой? Например, может быть в новой версии появилась новая функция?


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

Спасибо!
Бесплатный генератор отчетов для программ на C/C++
http://www.oxetta.com
Re[2]: неправильные параметры ф-ции в DLL
От: sushko Россия  
Дата: 05.04.22 16:08
Оценка:
Здравствуйте, Pavel Dvorkin, Вы писали:

PD>Тебе действительно нужно именно отловить ? Зачем ? Ну отловишь, а дальше что ? Работать же все равно не будет.


Почему не будет? Будет. Просто я в старую DLL буду передавать один параметр, а в новую — два.

typedef int (__stdcall *func_old)(int param);
typedef int (__stdcall *func_new)(int param, char anotherParam);

func_old pfnOld = NULL;
func_new pfnNew = NULL;
if (IsOldDLL())
  pfnOld = GetProcAddress();
else
  pfnNew = GetProcAddress();


Мне надо было просто понять, old или new. И уважаемый форумчанин cserg, да будет имя его прославлено навеки, предложил проверить, а не добавились ли в новой DLL ф-ции, отсутствующие в старой, и по этому признаку определять, новая DLL или старая. Почему сам не догадался — Бог весть
Бесплатный генератор отчетов для программ на C/C++
http://www.oxetta.com
Re[3]: неправильные параметры ф-ции в DLL
От: Pavel Dvorkin Россия  
Дата: 06.04.22 02:02
Оценка:
Здравствуйте, sushko, Вы писали:

PD>>Тебе действительно нужно именно отловить ? Зачем ? Ну отловишь, а дальше что ? Работать же все равно не будет.


S>Почему не будет? Будет. Просто я в старую DLL буду передавать один параметр, а в новую — два.


Ну так я же и написал чуть дальше —

Или в приложении реализовать иной код на случай новой DLL.

With best regards
Pavel Dvorkin
Re: неправильные параметры ф-ции в DLL
От: dmitry_npi Россия  
Дата: 26.04.22 06:26
Оценка:
Здравствуйте, sushko, Вы писали:

S>Идиётские разработчики DLL выпустили новую версию этой самой DLL, в которой та же (!) функция теперь описывается как int func(int param, char otherParam). Более того, выпустив новую версию DLL, эти альтернативно одаренные забыли (!) поменять в ней номер версии (VERSIONINFO)


Может быть, можно ориентироваться на размер DLL в байтах? Наверняка он отличается.
Атмосферная музыка — www.aventuel.net
Re: неправильные параметры ф-ции в DLL
От: Pzz Россия https://github.com/alexpevzner
Дата: 26.04.22 10:12
Оценка:
Здравствуйте, sushko, Вы писали:

S>Вопрос: могу ли я как-то отловить это падение? Каким-нибудь try/catch? Если да, то каким именно?


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

А нельзя как-то по вторичным половым признакам определить, с какой версией DLL ты имеешь дело? Ну, например, по наличию новых фукнций, которых раньше не было, по дате в подписи и т.п.?
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.