информационная безопасность
без паники и всерьез
 подробно о проектеRambler's Top100
За кого нас держат?Страшный баг в WindowsSpanning Tree Protocol: недокументированное применение
BugTraq.Ru
Русский BugTraq
 Анализ криптографических сетевых... 
 Модель надежности двухузлового... 
 Специальные марковские модели надежности... 
 Очередное исследование 19 миллиардов... 
 Оптимизация ввода-вывода как инструмент... 
 Зловреды выбирают Lisp и Delphi 
главная обзор RSN блог библиотека закон бред форум dnet о проекте
bugtraq.ru / форум / programming
Имя Пароль
если вы видите этот текст, отключите в настройках форума использование JavaScript
ФОРУМ
все доски
FAQ
IRC
новые сообщения
site updates
guestbook
beginners
sysadmin
programming
operating systems
theory
web building
software
hardware
networking
law
hacking
gadgets
job
dnet
humor
miscellaneous
scrap
регистрация





Легенда:
  новое сообщение
  закрытая нитка
  новое сообщение
  в закрытой нитке
  старое сообщение
[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-2025 Dmitry Leonov   Page build time: 0 s   Design: Vadim Derkach