> как отучить вс заниматся этой дурью для экспортируемых > __stdcall функций? я ща вставляю вначало строчку типа > такой: > #pragma comment(linker, "/export:MyFunc=_MyFunc@4") > получается 2 экспортируемых фуникции указывающих на один и > тот же код- одна разукрашенная, а вторая нет. криво как-то, > может есть более ровный путь?
Лучше бы и не вставлять, а или пользоваться fastcall/cdecl или юзать как есть. __stdcall это соглашение при котором параметры выкладываются с начала, и, самое главное, за очистку стека отвечает вызываемая функция. Поэтому и нужно чтобы в названии, которое видит линкер присутствовало количество снимаемых байт. А то какой нить модуль экспортнет __stdcall функцию с одним количеством аргументов, а другой модуль импортнет ее по такому же названию, но с другим. Линкер это все тихо слинкует. Результат: срыв стека и крах.
Если же ты делаешь dll-ку (то есть функция экспортируется не из lib-ы), то нужно использовать __declspec(dllexport) - в этом соглашении в dll-ку функция экспортнется по своему нормальному названию.
Точно так же как обычное cpp-оское мангление сделано для того, чтоб линкер видел разные названия для функций, имеющих разные типы аргументов. Прототипов то ему не дано увидеть.
> Вопрос на тему: асм, вирусы, РЕ формат, таблица експорта > функций, хеши. > > Как генерируется хеш для имени экспортиремой функции... > Алгоритм, если есть =) В Export Directory Table есть три смещения: Address Table RVA, Name Pointers RVA и Ordinal Table RVA для указания точек входа, имен и ординалов экспортируемых функций. А если ты о манглении в CPP, то это не хеш, а инфа о типе функции и относится не к PE, а к компилятору. В принципе мангляние не стандартизировано, в WinAPI есть функция UnDecorateSymbolName() для демангляния
> В Export Directory Table есть три смещения: Address Table > RVA, Name Pointers RVA и Ordinal Table RVA для указания > точек входа, имен и ординалов экспортируемых функций.
> > В Export Directory Table есть три смещения: Address > Table > > RVA, Name Pointers RVA и Ordinal Table RVA для > указания > > точек входа, имен и ординалов экспортируемых функций. > > ied=RVA(nt->OptionalHeader.DataDirectory[0].VirtualAddre > ss); > sym=RVA(ied->AddressOfNames); > > Правильно, а sym указывает на таблицу функций! > Нахожу checksum для имени функции и сравниваю. В данном случае sym указывает на таблицу ИМЕН функций. Не надо checksum, там хранятся RVA на САМИ ИМЕНА, а ни на какие хеши или суммы. В export directory есть три параллельных массива. И можно найти функцию по имени или ординалу, а потом найти ее точку входа (по такому же индексу в массиве) в массиве AddressOfFunctions.
как отучить вс заниматся этой дурью для экспортируемых __stdcall функций? я ща вставляю вначало строчку типа такой:
#pragma comment(linker, "/export:MyFunc=_MyFunc@4")
получается 2 экспортируемых фуникции указывающих на один и тот же код- одна разукрашенная, а вторая нет. криво как-то, может есть более ровный путь?
Опасно это05.08.03 17:16 Автор: amirul <Serge> Статус: The Elderman
> как отучить вс заниматся этой дурью для экспортируемых > __stdcall функций? я ща вставляю вначало строчку типа > такой: > #pragma comment(linker, "/export:MyFunc=_MyFunc@4") > получается 2 экспортируемых фуникции указывающих на один и > тот же код- одна разукрашенная, а вторая нет. криво как-то, > может есть более ровный путь?
Лучше бы и не вставлять, а или пользоваться fastcall/cdecl или юзать как есть. __stdcall это соглашение при котором параметры выкладываются с начала, и, самое главное, за очистку стека отвечает вызываемая функция. Поэтому и нужно чтобы в названии, которое видит линкер присутствовало количество снимаемых байт. А то какой нить модуль экспортнет __stdcall функцию с одним количеством аргументов, а другой модуль импортнет ее по такому же названию, но с другим. Линкер это все тихо слинкует. Результат: срыв стека и крах.
Если же ты делаешь dll-ку (то есть функция экспортируется не из lib-ы), то нужно использовать __declspec(dllexport) - в этом соглашении в dll-ку функция экспортнется по своему нормальному названию.
Точно так же как обычное cpp-оское мангление сделано для того, чтоб линкер видел разные названия для функций, имеющих разные типы аргументов. Прототипов то ему не дано увидеть.
> Лучше бы и не вставлять, а или пользоваться fastcall/cdecl > или юзать как есть. __stdcall это соглашение при котором > параметры выкладываются с начала, и, самое главное, за > очистку стека отвечает вызываемая функция. Поэтому и нужно > чтобы в названии, которое видит линкер присутствовало > количество снимаемых байт. А то какой нить модуль > экспортнет __stdcall функцию с одним количеством > аргументов, а другой модуль импортнет ее по такому же > названию, но с другим. Линкер это все тихо слинкует. > Результат: срыв стека и крах. ситуация такова что длл написанные на VC должны юзатся из борландовских прог. функций из длл экспортируются 2 штуки у каждой по 1му параметру так что ошибок в этом смысле можно не боятся. И кстати объявление WINAPI этоже тот же __stdcall, а никаких хвостов у функций нету.
> Если же ты делаешь dll-ку (то есть функция экспортируется > не из lib-ы), то нужно использовать __declspec(dllexport) > - в этом соглашении в dll-ку функция экспортнется по своему > нормальному названию. extern "C" __declspec(dllexport) DWORD __stdcall MyFunc(void *param);
украшает имя, а делать __cdecl не могу (ну никак низзя Ж)), кстати билдер при полностью таком же объявлении ниче не дорисовывает
Тогда забудь про dllexport и смотри в сторону def-файла05.08.03 18:49 Автор: amirul <Serge> Статус: The Elderman
> ситуация такова что длл написанные на VC должны юзатся из > борландовских прог. функций из длл экспортируются 2 штуки у > каждой по 1му параметру так что ошибок в этом смысле можно > не боятся. Ох не люблю я такого. Ну да ладно :-)
> И кстати объявление WINAPI этоже тот же > __stdcall, а никаких хвостов у функций нету. Тяжелое наследие паскаля. Насколько я помню в ранних windows.h было даже не WINAPI, а PASCAL.
> extern "C" __declspec(dllexport) DWORD __stdcall > MyFunc(void *param); > украшает имя, а делать __cdecl не могу (ну никак низзя Ж)), > кстати билдер при полностью таком же объявлении ниче не > дорисовывает Убери declspec совсем. И забудь про него. И добавь в проект файл mydll.def следующего содержания:
LIBRARY MYDLL
EXPORTS
MyFunc = _MyFunc@4
---
При импорте этой dll-ки нужно не указывать dllimport, а линковаться с созданным lib-файлом (это в VC). У борланда и VC форматы lib-ов разные, так что для борланда надо сделать lib-у тулзой implib