информационная безопасность
без паники и всерьез
 подробно о проектеRambler's Top100
Портрет посетителяЗа кого нас держат?
BugTraq.Ru
Русский BugTraq
 Анализ криптографических сетевых... 
 Модель надежности двухузлового... 
 Специальные марковские модели надежности... 
 Ростелеком заподозрили в попытке... 
 Линуксовый ботнет, распространяющийся... 
 Конец поддержки Internet Explorer 
главная обзор RSN блог библиотека закон бред форум dnet о проекте
bugtraq.ru / форум / programming
Имя Пароль
ФОРУМ
если вы видите этот текст, отключите в настройках форума использование JavaScript
регистрация





Легенда:
  новое сообщение
  закрытая нитка
  новое сообщение
  в закрытой нитке
  старое сообщение
  • Напоминаю, что масса вопросов по функционированию форума снимается после прочтения его описания.
  • Новичкам также крайне полезно ознакомиться с данным документом.
[C++] В общем случае нельзя 17.10.05 10:55  Число просмотров: 1447
Автор: amirul <Serge> Статус: The Elderman
<"чистая" ссылка> <обсуждение закрыто>
> Типа есть DLL. Надо определить какие соглашения о вызовах
> были использованы для экспортируемых функций при её
> компиляции.

Но можно попробовать эвристик. Найти выход из функции, если перед выходом со стека снимается не только фрейм, но и аргументы - то 100% __stdcall:

mov	esp, ebp
pop	ebp
retn	N

---

Если же перед выходом аргументы не снимаются, то либо __cdecl, либо __stdcall без параметров:

mov	esp, ebp
pop	ebp
ret

---

Это если функцию вызывать нельзя. Если же такого ограничения нет, то перед вызовом (перед выкладыванием аргументов) сохраняешь старое значение указателя стека, вызываешь, проверяешь были ли сняты аргументы. Если были - __stdcall, если нет - __cdecl.
<programming>
[C++] __stdcall or __cdecl 17.10.05 03:32  
Автор: void <Grebnev Valery> Статус: Elderman
<"чистая" ссылка> <обсуждение закрыто>
Можно ли програмно определить, с какими соглашениями экспортируемых функций изготовлена DLL?
Типа есть DLL. Надо определить какие соглашения о вызовах были использованы для экспортируемых функций при её компиляции.

Спасибо.
[C++] В общем случае нельзя 17.10.05 10:55  
Автор: amirul <Serge> Статус: The Elderman
<"чистая" ссылка> <обсуждение закрыто>
> Типа есть DLL. Надо определить какие соглашения о вызовах
> были использованы для экспортируемых функций при её
> компиляции.

Но можно попробовать эвристик. Найти выход из функции, если перед выходом со стека снимается не только фрейм, но и аргументы - то 100% __stdcall:

mov	esp, ebp
pop	ebp
retn	N

---

Если же перед выходом аргументы не снимаются, то либо __cdecl, либо __stdcall без параметров:

mov	esp, ebp
pop	ebp
ret

---

Это если функцию вызывать нельзя. Если же такого ограничения нет, то перед вызовом (перед выкладыванием аргументов) сохраняешь старое значение указателя стека, вызываешь, проверяешь были ли сняты аргументы. Если были - __stdcall, если нет - __cdecl.
[Net] NET как-то по-другому работает со стеком. Не помню где читал, но там другая модель стека. 18.10.05 04:21  
Автор: void <Grebnev Valery> Статус: Elderman
<"чистая" ссылка> <обсуждение закрыто>
Спасибо за ответ. Вот ещё вопрос.

В VB.NET 2003 я объявил две одинаковые процедуры.

Declare Sub cdecl_Test Lib "cdeclmpilib.dll" (ByVal V1 As Double, ByVal V2 As Double)

Declare Sub std_Test Lib "stdmpilib.dll" (ByVal V1 As Double, ByVal V2 As Double)


Первая функция -
extern "C" __declspec(dllexport) void __stdcall std_Test( double v1, double v2 )
{
if ( hlib )
{
TCHAR s[512];

_stprintf( s, _T("v1 = %f v2 = %f"), v1, v2 );

MessageBox(NULL, s, "Test", MB_OK );
}
}
Вторая функция - такая же, только вместо __stdcall декларировано __cdecl соглашение

extern "C" __declspec(dllexport) void __cdecl cdecl_Test( double v1, double v2 )

Вопрос - почему обе функции вызываются нормально? Как .NET определяет соглашение о вызовах? Обычный VB 6.0, как и другой неуправляемый код валится при не соответствии соглашений о вызове.

Спасибо.
дотнет тут нипричем 21.10.05 16:23  
Автор: z0 <z0> Статус: Member
<"чистая" ссылка> <обсуждение закрыто>
> Вопрос - почему обе функции вызываются нормально? Как .NET
> определяет соглашение о вызовах? Обычный VB 6.0, как и
> другой неуправляемый код валится при не соответствии
> соглашений о вызове.
>
> Спасибо.

есть такая штука - декорация имен, это ее работа
Декроирование здесь нипричём. 22.10.05 21:40  
Автор: void <Grebnev Valery> Статус: Elderman
<"чистая" ссылка> <обсуждение закрыто>
> > Вопрос - почему обе функции вызываются нормально? Как
> .NET
> > определяет соглашение о вызовах? Обычный VB 6.0, как и
> > другой неуправляемый код валится при не соответствии
> > соглашений о вызове.
> >
> > Спасибо.
>
> есть такая штука - декорация имен, это ее работа
Декроирование здесь нипричём.
В DLLs (dumpbin /EXPORTS ....) имена не декорированы (я прописывал сам в def файле )
да действительно 25.10.05 14:47  
Автор: z0 <z0> Статус: Member
<"чистая" ссылка> <обсуждение закрыто>
да действительно
к моему собственному (и моего софтайса) удивлению оказалось
что CLR-runtime имеет код для вызова внешних функций типа

mov [loc_esp],esp
push [param_2]
push [param_1]
call [loc_entry]
... bla bla bla
mov esp,[loc_esp]

то есть благодаря тому что __stdcall и __cdecl отличаются только retn/retn X
то такому коду абсолютно монопенисуально что одно что другое
так что все равно что писАть (C#):
[DllImport("lib1.dll", CallingConvention=CallingConvention.StdCall)]
public static extern String proc1(int param1, int param2);
или
[DllImport("lib1.dll", CallingConvention=CallingConvention.Cdecl)]
public static extern String proc1(int param1, int param2);
результат одинаков (для данной реализации mscorwks.dll, конкретно FW 1.1)

так что признаю - был неправ
Спасибо за анализ. 27.10.05 01:30  
Автор: void <Grebnev Valery> Статус: Elderman
<"чистая" ссылка> <обсуждение закрыто>
Спасибо за анализ.

> mov [loc_esp],esp
> push [param_2]
> push [param_1]
> call [loc_entry]
> ... bla bla bla
> mov esp,[loc_esp]
>
> то есть благодаря тому что __stdcall и __cdecl отличаются
> только retn/retn X
> то такому коду абсолютно монопенисуально что одно что
> другое
> так что все равно что писАть (C#):
> [DllImport("lib1.dll",
> CallingConvention=CallingConvention.StdCall)]
> public static extern String proc1(int param1, int param2);
> или
> [DllImport("lib1.dll",
> CallingConvention=CallingConvention.Cdecl)]
> public static extern String proc1(int param1, int param2);
> результат одинаков (для данной реализации mscorwks.dll,
> конкретно FW 1.1)
1




Rambler's Top100
Рейтинг@Mail.ru


  Copyright © 2001-2022 Dmitry Leonov   Page build time: 0 s   Design: Vadim Derkach