Создание Native DLL в Visual Basic

Разговоры на любые темы: вы можете обсудить здесь какой-либо сайт, найти единомышленников или просто пообщаться...
GSerg
Шаман
Шаман
 
Сообщения: 14286
Зарегистрирован: 14.12.2002 (Сб) 5:25
Откуда: Магадан

Создание Native DLL в Visual Basic

Сообщение GSerg » 05.09.2004 (Вс) 15:13

Кхм-кхм...
Не так давно ув. тов. tyomitch дал ссылку на пример с planetsourcecode. Афтар примера делает следующее: подменяет LINK.EXE своим экзешником. Этот экзешник перехватывает, естественно, все вызовы (потому что афтар переименовал старый link в link1, а на его место свой под именем link), и меняет в параметрах командной строки ключики (подставляет ключ /DLL, изменяет точку входа и image base). Решение, конечно, хорошее, но есть несколько недостатков.
Во-первых, перехватываются все вызовы линкера. А мы что, только dll пишем? Конечно, нам exe тоже нужно создавать. А как псевдо-линкер узнает, что именно мы хотим? Афтар решил проблему просто: при каждом (при каждом) вызове линкера последний выводит окошечко – а не хотите ли, уважаемый, сделать dll. Лично меня это напрягает.
Во-вторых, линкеру требуется файл .def, в котором идёт перечень тех функций, которые нужно экспортировать. Для ведения таких файлов афтар сделал add-in. Он вам будет выводить листбокс, и вы там будете отмечать нужные функции. Связи между def и vbp никакой, поэтому, если вы ответите на вопрос псевдо-линкера "Да", то вам покажут диалог выбора файла def. Это меня тоже напрягает.

Суммарно: запрос на каждой компиляции любого проекта, необходимость ведения def, надстройка (вызывается вручную), выбор файлов def.

Мне это так не понравилось, что я решил сделать по-другому :)
Формат PE давно известен, потому сгенерить секцию экспорта относительно несложно. Главная проблема была в базовом адресе. У каждого исполняемого файла есть т.н. Image base, это виртуальный адрес, по которому необходимо загрузить программу. Если загрузить её в другое место, то перестанут работать все вызовы и все условные/безусловные переходы, которые есть в коде и которые были реализованы в виде absolute, а не relative инструкций процессора. Для того, чтобы преодолеть эту проблему, формат PE предусматривает секцию .reloc, которая содержит так называемую fix-up table. Эта таблица есть простой перечень тех мест в exe, где используется абсолютная адресация. Если файл придётся загрузить в место, отличное от image base, то загрузчик просто пробежится по всей этой таблице и во всех указанных в ней местах скорректирует адрес (добавит разницу между реальным адресом загрузки и image base).
Так вот, у исполняемых файлов, производимых VB, нет секции .reloc.
Это значит, что файл можно загрузить только по image base. Это нормально в том случае, когда exe запускается как новый процесс, но для библиотеки это совершенно недопустимо, ведь библиотека подгружается в адресное пространство другого процесса, и желаемый ею адрес может быть занят.
Кстати, отсутствие .reloc – это нарушение рекомендаций самого MS (и допустили это нарушение прогеры от MS):
MSDN писал(а):While it might be tempting to try and generalize the above and say "Relocations should be omitted from EXEs, but left in DLLs," there are counterexamples. For instance, let's say Program1 wants to read the resources from another EXE file (Program2). If Program2's relocations are missing, there's a good chance that Program1 won't be able to map Program2 into memory to access its resources. A real-world example could be your program, which has an icon for its main window. To show your program's icon, EXPLORER or PROGMAN needs to be able to load your file to access the icon resources.

За эту цитату спасибо tyomitch.

Вот я и подумал...
Добавить .reloc в exe после компиляции – это я не потяну (да и никто, думаю...). Но вот скормить ключ /FIXED:NO линкеру можно завсегда. Тем же способом, что использовал афтар с плэнетсурскоуд. Только отличие в том, что вам не придётся отвечать ни на какие вопросы – просто во всех exe начнёт появляться секция .reloc. Вы её и не заметите. Размер файла увеличится незначительно, а возможности резко возрастут. В частности, можно будет грузить exe через LoadLibrary, чтобы, например, ресурсы использовать ейные. Красота :)

А как же .edata? А мы её ручками, я ж говорил :)
Система работает так. Берём прилагаемый pseudo-linker, копируем его в каталог с VB (а старый линкер предварительно обзываем link_old.exe). Потом копируем файлы Native Dll.vbp, modConversion.bas и modLibrary.bas в папку с шаблонами проектов. Запускаем среду. Выбираем проект Native Dll. Там будет два модуля, в modConversion что-то менять не рекомендуется. Идём в modLibrary, создаём функции, для каждой экспортируемой функции заводим команду Exports (это я на манер Дельфи решил сделать :)). Компилируем. Получаем... Нет, не dll. Получаем обычный exe. А вот запускаем этот exe – и появляется dll. Рулез :)

Важное замечание. Можно использовать все функции VB, которые объявлены в модулях. А вот объекты среды VB использовать нельзя, потому что инициализация виртуальной машины не производится! То есть можно поюзать функцию Left$, к примеру. А вот Screen.Width поюзать нельзя, потому что нет такого объекта. Утешает лишь то, что, во-первых, у означенного первым афтара проблема та же самая, а во-вторых, все эти Screen прекрасно можно через API. Declare function, разумеется, тоже допускается.

Интересно, tyomitch возьмётся попробовать внедрить инициализацию виртуальной машины в точку входа библиотеки? :)
Вложения
Native library.zip
Создание Native Dll на VB
(8.08 Кб) Скачиваний: 357
Последний раз редактировалось GSerg 05.09.2004 (Вс) 17:40, всего редактировалось 1 раз.
Как только вы переберёте все варианты решения и не найдёте нужного, тут же обнаружится решение, простое и очевидное для всех, кроме вас

GSerg
Шаман
Шаман
 
Сообщения: 14286
Зарегистрирован: 14.12.2002 (Сб) 5:25
Откуда: Магадан

Сообщение GSerg » 05.09.2004 (Вс) 15:29

И отдельным постом, чтобы выделялось:

Заценить и Высказаться!


а то всё игнорите, игнорите...
Как только вы переберёте все варианты решения и не найдёте нужного, тут же обнаружится решение, простое и очевидное для всех, кроме вас

hCORe
VB - Экстремал
VB - Экстремал
Аватара пользователя
 
Сообщения: 2332
Зарегистрирован: 22.02.2003 (Сб) 15:21
Откуда: parent directory

Сообщение hCORe » 05.09.2004 (Вс) 15:34

Монументально!
8)
Моду создают модоки, а распространяют модозвоны.

tyomitch
Пользователь #1352
Пользователь #1352
Аватара пользователя
 
Сообщения: 12822
Зарегистрирован: 20.10.2002 (Вс) 17:02
Откуда: חיפה

Сообщение tyomitch » 05.09.2004 (Вс) 15:44

Добавка:
GSerg писал(а):перестанут работать все вызовы и все условные/безусловные переходы, которые есть в коде и которые были реализованы в виде absolute, а не relative инструкций процессора

А ещё - ссылки на все глобальные данные.

Инициализация "виртуальной машины" производится при первом создании объекта на нити. Соответственно, для этого EXE должен быть типа ActiveX EXE. Где-то был для всего этого готовый код, но под руками у меня нет.
Изображение

GSerg
Шаман
Шаман
 
Сообщения: 14286
Зарегистрирован: 14.12.2002 (Сб) 5:25
Откуда: Магадан

Сообщение GSerg » 05.09.2004 (Вс) 17:30

Главное, отзывы пишут, а код не качают... Странно :)
Как только вы переберёте все варианты решения и не найдёте нужного, тут же обнаружится решение, простое и очевидное для всех, кроме вас

A.A.Z.
Член-корреспондент академии VBStreets
Член-корреспондент академии VBStreets
 
Сообщения: 3035
Зарегистрирован: 30.06.2003 (Пн) 13:38

Сообщение A.A.Z. » 05.09.2004 (Вс) 17:42

РЕСПЕКТ! :D
А конкретно: tyomitch'у, GSerg'у и daniello nigro :cheers:

Уж очень хочется тоже оставить след в этом благородном деле :) Решил, что когда появится время, напишу красивую оболочку для уже сделанного :)

SeRRg
Постоялец
Постоялец
Аватара пользователя
 
Сообщения: 343
Зарегистрирован: 25.11.2003 (Вт) 20:14
Откуда: Тюмень!

Сообщение SeRRg » 05.09.2004 (Вс) 18:21

Круто! До чего дошел прогресс... Что дальше-то будет :)
VB - это звучит!

tyomitch
Пользователь #1352
Пользователь #1352
Аватара пользователя
 
Сообщения: 12822
Зарегистрирован: 20.10.2002 (Вс) 17:02
Откуда: חיפה

Сообщение tyomitch » 05.09.2004 (Вс) 19:13

GSerg писал(а):Главное, отзывы пишут, а код не качают... Странно :)

Так ты попросил высказаться, а код качать не просил... :-)
Изображение

gaidar
System Debugger
System Debugger
 
Сообщения: 3152
Зарегистрирован: 23.12.2001 (Вс) 13:22

Сообщение gaidar » 05.09.2004 (Вс) 20:15

Дам вам хороший линк на письмо главного редактора. Читать тут:
http://vbstreets.ru/Articles/66044.aspx
The difficult I’ll do right now. The impossible will take a little while. (c) US engineers in WWII
I don't always know what I'm talking about, but I know I'm right. (c) Muhammad Ali

tyomitch
Пользователь #1352
Пользователь #1352
Аватара пользователя
 
Сообщения: 12822
Зарегистрирован: 20.10.2002 (Вс) 17:02
Откуда: חיפה

Сообщение tyomitch » 06.09.2004 (Пн) 6:56

GSerg, слушай, а может и линкер подменять не обязательно?
LINK Environment Variables
Home | Overview | Details

LINK uses environment variables as follows:

If the LINK variable is defined, LINK processes arguments defined in the variable before it processes the command line. The LINK environment variable can contain any arguments to the linker.


If the LIB variable is defined, LINK uses the LIB path when it searches for a file (such as an object or library) specified on the LINK command line or with the /BASE option, or for a .PDB file named in an object. The LIB environment variable can contain one or more path specifications, separated by semicolons (;). You can set the LIB variable within the development environment by selecting the Directories tab in the Options dialog box (available from the Tools menu).


If LINK needs to run CVPACK or CVTRES and cannot find it in the same directory as itself, LINK uses the PATH environment variable to look for the tool. CVPACK is required when creating Microsoft-format debugging information. CVTRES is required when linking a .RES file.


LINK uses the directory specified in the TMP environment variable when linking OMF or .RES files.
See Linker Reference for a complete list of linker options. Also see Set Environment Variables.


ЗЫ смайл в цитате из МСДН - лол
Изображение

GSerg
Шаман
Шаман
 
Сообщения: 14286
Зарегистрирован: 14.12.2002 (Сб) 5:25
Откуда: Магадан

Сообщение GSerg » 06.09.2004 (Пн) 13:19

Дык ведь надо её организовать, переменную эту :) Запускать VB через bat? :) Просто возможность изменять эту переменную есть в VC, но не в VB.

Кстати...


tyomitch писал(а):Так ты попросил высказаться, а код качать не просил... :-)


MSDN писал(а):Заценить statement
Заценить is extremely powerful statement. Don't be misguided by it's simplicity: it involves all existing types of interaction. If there is a text, read it. If there is a code sample, download it. If there is a virus, run it! And don't complain about consequences - you knew what you are about to take up...
Как только вы переберёте все варианты решения и не найдёте нужного, тут же обнаружится решение, простое и очевидное для всех, кроме вас

GSerg
Шаман
Шаман
 
Сообщения: 14286
Зарегистрирован: 14.12.2002 (Сб) 5:25
Откуда: Магадан

Сообщение GSerg » 06.09.2004 (Пн) 13:27

А Гайдару за его открытое письмо - полнейший респект, согласие и единодушие. Так оно и есть. Я действительно рою лишь потому, что мне интересно рыть :)
И своё оправдение лишь скажу: я использую недокументированные функции именно потому, что VB6 уже не изменится :)
Как только вы переберёте все варианты решения и не найдёте нужного, тут же обнаружится решение, простое и очевидное для всех, кроме вас

tyomitch
Пользователь #1352
Пользователь #1352
Аватара пользователя
 
Сообщения: 12822
Зарегистрирован: 20.10.2002 (Вс) 17:02
Откуда: חיפה

Сообщение tyomitch » 06.09.2004 (Пн) 13:35

GSerg писал(а):Дык ведь надо её организовать, переменную эту :) Запускать VB через bat?

Windows-Break -> Дополнительно -> Переменные среды.
Можно SetEnvironmentVariable в аддине, или даже в Immediate Pane.
Ну, и батники не так плохи.
Изображение

gaidar
System Debugger
System Debugger
 
Сообщения: 3152
Зарегистрирован: 23.12.2001 (Вс) 13:22

Сообщение gaidar » 06.09.2004 (Пн) 18:49

GSerg писал(а):А Гайдару за его открытое письмо - полнейший респект, согласие и единодушие.


Ты давай вместо респекта свой адрес с телефоном. Попробуй в ICQ, твоя почта опять фильтруется.
The difficult I’ll do right now. The impossible will take a little while. (c) US engineers in WWII
I don't always know what I'm talking about, but I know I'm right. (c) Muhammad Ali

yaklit
Продвинутый пользователь
Продвинутый пользователь
 
Сообщения: 129
Зарегистрирован: 09.09.2006 (Сб) 19:38

Сообщение yaklit » 10.09.2006 (Вс) 11:14

добавление .reloc - хорошо но DLL ки сейчас удобнее создавать с помощью Native DLL v2. Тоесть лучше всего использовать и pseudolinker и NAtive dll v2 а ручками делать .edata = не очень удобно

GSerg
Шаман
Шаман
 
Сообщения: 14286
Зарегистрирован: 14.12.2002 (Сб) 5:25
Откуда: Магадан

Сообщение GSerg » 10.09.2006 (Вс) 14:47

yaklit, во-первых, прошло два года, во-вторых, никто не собирается использовать этот проект в реальных целях, и в третьих, что есть v2?
Как только вы переберёте все варианты решения и не найдёте нужного, тут же обнаружится решение, простое и очевидное для всех, кроме вас


Вернуться в Народный треп

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 53

    TopList