· Начало · Отвђтить · Статистика · Поиск · FAQ · Правила · Установки · Язык · Выход · WASM.RU · Noir.Ru ·

 WASM Phorum —› WASM.RESEARCH —› ForwarderChain

. 1 . 2 . 3 . >>

Посл.отвђт Сообщенiе


Дата: Июл 25, 2003 23:36:24 · Поправил: volodya

Вопрос о старой привязке.
Проблема:
есть Dll, положим, у которой ручками приделана API-функция, которая немедленно форвардится куда-то, предположим, это будет Hi.

Имеем: dll.def
EXPORTS
         Hi = USER32.MessageBoxA


Теперь exe. Когда зовется LoadLibrary/GetProcAddress - все нормально. Функцию можно вызвать.
Что-то где-то так:
Hi(NULL, "Ща спою", "Не, ща точно спою!", MB_OK);


Если позвать указателем на функцию после GetProcAddress, то все ОК, если попытаться слинковать статически - ничего не выходит. Unresolved external Hi и хоть ты умри. Я бы думал, что это вообще невозможно, но есть же kernel32.dll, где тоже есть форварды, и линкуется статически, собака!
Точно, я что-то неправильно линкую! Или где-то что-то неверно определяю!
Да, extern "C" не предлагать!


Дата: Июл 26, 2003 00:01:38

А нормальные экспорты (без forward) из этой DLL линкуются?

но есть же kernel32.dll
А ты использовал форварды из kernel32.lib?

Или где-то что-то неверно определяю!
Верно подмечено :)

Это всё под VC?


Дата: Июл 26, 2003 00:04:40 · Поправил: volodya

А нормальные экспорты (без forward) из этой DLL линкуются?

Канечно, дарагой!

А ты использовал форварды из kernel32.lib?

Их использовал любой, кто хоть раз звал HeapAlloc и т.п. Просто линкер меня не пропускает при статической линковке. Можно создать файл руками, но ЭТО НЕ ВЫХОД!

Все под VC. Проблема в том, что Hi незаманглена в таблице экспорта dll, а компилятор манглит ее в таблице импорта exe и ессно, ждет, что увидит нечто такое в dll, а его там нет :(


Дата: Июл 26, 2003 01:21:57

Hi незаманглена в таблице экспорта dll
В EXP'е её обзывают как _Hi@16, а VC ищет просто _Hi (без @16)...


Дата: Июл 26, 2003 02:31:31

Разобрался, вроде...
Так вот, определил я этот Hi просто как H:
EXPORTS H = USER32.MessageBoxA

Линкер обозвал это дело _H@16
Я открыл lib в хексе и заменил все _H@16 на _HHHH.
Потом, в VC,
extern "C" int HHHH(int,char*,char*,int);
. . .
HHHH(NULL, "Ща спою", "Не, ща точно спою!", MB_OK);

Даже karaoke запустил для реализма :)

ЗЫ: Другого способа я не нашёл...


Дата: Июл 26, 2003 05:31:24

Quantum

А линкер и не ожидал такой безцеремонной подмены и схавал за милую
душу :-) Опять сплоховало чудо программерской мысли от Microsoft
перед живым человеческим гением, свежа в памяти ещё недавняя история
с DLL2LiB :-)))))


Дата: Июл 26, 2003 05:35:29

Хреново. А как же тогда статически слинковать по ординалу? Опять хаканьем либы? ЭТО НЕ ВЫХОД!


Дата: Июл 26, 2003 06:06:45

Asterix
:)))

volodya
А как же тогда статически слинковать по ординалу?
?!
Не понял... Я ж как раз статически всё и слинковал. Хаканье либы элементарно проделать посредством search&replace в WinHex. Может я не так понял проблему?

ЗЫ: Я не совсем догоняю почему в VC и MASM32 такие различия на стадии линковки (линкер ведь почти один и тот же) Копался я тут с параметрами командной строки LINK.EXE и ничего конкретного про @XX не нашёл :(


Дата: Июл 26, 2003 18:57:07

Не понял...

Поясняю. Ты делал линк по имени. Можно, чтобы не мучатсья с хаканьем либы, попытаться слинковать по ординалу. Для этого в таблице экспорта dll:

EXPORTS H = USER32.MessageBoxA @5 NONAME

Все, тогда в таблице экспорта никакого H не будет, будет только пятерочка.
Динамически ее можно позвать GetProcAddress(MAKEINTRESOURCE(5)); как прилинковать по ординалу статически - я не знаю :(


Дата: Июл 26, 2003 19:35:37

volodya
Точно... Я об этом когда-то читал, но никогда ординалами не пользовался. Сейчас поэкспериментируем...

Asterix
Если ординалы можно юзать для статической линковки, хак для Dll2Lib радикально упрощается... Правда, я в этом сильно сомневаюсь (линкер вряд ли сможет определить в какой именно либе следует ресолвить ординал)


Дата: Июл 26, 2003 20:06:24

Копался я тут с параметрами командной строки LINK.EXE и ничего конкретного про @XX не нашёл :(
А не нашёл я ничего потому что этот @XX добавляет не линкер а компилятор! MASM32 превращает "Hi PROC" в _Hi@0.


Дата: Июл 26, 2003 21:28:32

volodya
как прилинковать по ординалу статически
Эврика!!! Экспертиза завершилась успешно! Модификатор NONAME убирает имя ф-ции из таблицы экспорта DLL, но в LIB импорта это имя таки попадает. Поэтому HHHH(int,char*,char*,int) можно спокойно объявлять в VC (проверил). Проблема с манглом пока ещё не решена...


Дата: Июл 26, 2003 22:47:06

Ммда... бросаю я это дело. В общем, проблему с манглом легко решить если реально экспортируется ф-ция (не форвард) двумя способами (помимо хака):
1. Убрать мангл вообще. Для этого достаточно объявить SYSCALL в PROC и PROTO.
2. Произвольно заманглить примерно так:
EXPORTS ?ownermangled@@XXYY@Z = realproc, где realproc -- это настоящее имя ф-ции в *.OBJ.
НО оба метода бессильны перед форвардингом!!! Володя, передаю тебе эстафету :)


Дата: Июл 27, 2003 01:28:18

Ок, но я сошел с дистанции перед постом :( Сорри. Кстати, можешь утешить себя - никто из тех, с кем я советовался, не знает как решить проблему изящно. Хаканье либы - это несерьезно :)


Дата: Июл 27, 2003 02:03:44

volodya
Забыл добавить...
Проблема имеет место только когда форвард идёт на STDCALL, вроде User32!MessageBoxA. Линкер "видит", что MessageBox определён (в user32.lib, например) как _MessageBoxA@16 и передаёт этот противный мангл на символ "Hi". Если пофиксить символ MessageBox в user32.lib, проблема решается автоматом, но потом прога не будет грузиться. С другой стороны, если таргет форварда определён как SYSCALL, проблем в этом отношении вообще не возникает. Смутное подозрение: в MS специально придумали этот манглинг шоб нам веселее жилось :)

. 1 . 2 . 3 . >>


Powered by miniBB 1.6 © 2001-2002
Время загрузки страницы (сек.): 0.047