__stdcall or __cdecl

Все, что вы хотели знать о программизме, но боялись спросить.
Ответить
vg
Маньяк
Сообщения: 2803
Зарегистрирован: 29 май 2003, 22:29
Откуда: Магадан - Миссиссага

__stdcall or __cdecl

Сообщение vg »

Можно ли програмно определить, с какими соглашениями экспортируемых функций изготовлена DLL?
Типа есть DLL. Надо определить какие соглашения о вызовах были использованы для экспортируемых функций при её компиляции.

Спасибо.
Аватара пользователя
ajkj3em
Маньяк
Сообщения: 2063
Зарегистрирован: 12 ноя 2006, 06:53

Re: __stdcall or __cdecl

Сообщение ajkj3em »

vg писал(а):Можно ли програмно определить, с какими соглашениями экспортируемых функций изготовлена DLL?
Типа есть DLL. Надо определить какие соглашения о вызовах были использованы для экспортируемых функций при её компиляции.

Спасибо.
можно. самый простой способ - про-парсить первые 30-40 байт кода
функции и посмотреть какой она использует stack framing. если там
встречается инструкция ENTER - __stdcall, если нет - __cdecl.

в принципе можно определить по имени, если заканчивается на @16
(@ + <number>), то это точно __stdcall

но это всё хакерство, поскольку есть еще и __fastcall, с передачей
части параметров через регистры ... короче лучше знать наперед.
vg
Маньяк
Сообщения: 2803
Зарегистрирован: 29 май 2003, 22:29
Откуда: Магадан - Миссиссага

Re: __stdcall or __cdecl

Сообщение vg »

poneyhot писал(а): можно. самый простой способ - про-парсить первые 30-40 байт кода
функции и посмотреть какой она использует stack framing. если там
встречается инструкция ENTER - __stdcall, если нет - __cdecl.
Если это может быть сигнатурой, то может ли .НЕТ фраймворк использовать её для правильного маршалинга данных подключаемой DLL в управляемый код?
(про ENTER - это специфика intel? Я просто не разбираюсь в asm)
poneyhot писал(а): в принципе можно определить по имени, если заканчивается на @16
(@ + <number>), то это точно __stdcall
Там точно нет декорирования.
poneyhot писал(а): __fastcall, с передачей
части параметров через регистры ... короче лучше знать наперед.
__fastcall там точно нет.

Я не знаю asm. Но вот вопрос. Если мы пропарсили код до ret и посмотрели инструкции непосредственно предшевствующие возврату из процедуры, то можно ли там обнаружить инструкции по очистке стека и по ним судить о __stdcall/__cdecl (типа, кто очищает стек после занесения туда аргументов вызываемой функции)?

Спасибо за ответ.
Аватара пользователя
ajkj3em
Маньяк
Сообщения: 2063
Зарегистрирован: 12 ноя 2006, 06:53

Re: __stdcall or __cdecl

Сообщение ajkj3em »

vg писал(а): Если это может быть сигнатурой, то может ли .НЕТ фраймворк использовать её для правильного маршалинга данных подключаемой DLL в управляемый код?
понятия не имею .. и что любопытно - не хочу иметь :)
Я не знаю asm. Но вот вопрос. Если мы пропарсили код до ret и посмотрели инструкции непосредственно предшевствующие возврату из процедуры, то можно ли там обнаружить инструкции по очистке стека и по ним судить о __stdcall/__cdecl (типа, кто очищает стек после занесения туда аргументов вызываемой функции)?
можно (надо будет смотреть используется ли просто ret; или ret с
параметром), но так сложнее, потому что функция может возвращаться
из больше чем одного места.

enter и leave - это специальные x86 инструкции для работы с __stdcall
вызовами... посмотрел сейчас чего генерит vc++ 6.0 - и похоже, что он
их не использует, так что этот вариант отпадает.

другой вариант - вызвать как (скажем) __stdcall, дать отработать
и посмотреть что стало со stack pointer после возврата из функции.
причем можно вызвать с заведомо неправильными параметрами,
чтобы ничего полезного функция сделать не могла.

но это все равно хакерство, в production такую вещь сдавать - искать
проблем на свою задницу.
vg
Маньяк
Сообщения: 2803
Зарегистрирован: 29 май 2003, 22:29
Откуда: Магадан - Миссиссага

Сообщение vg »

Понятно. Спасибо.
Ответить