Никак не пойму куда разружаются пользовательские библиотеки, понятно что в адресное пространство текущей программы, для каждой новой библиотеке выделяется новый сегмент или нет?
DJK Есть такая штука как виртуальная адресация, так получается что система один и тот-же образ (DLL) проецирует в адресные пространства разных процессов. А вообще, надо читать RTFM - теме самое место в Beginners...
Обижаешь, про виртуальную адресацию хорошо знаю. Как библиотеки при загрузки (базовый адрес у них одинаковый) записываются в текущий процесс, подмена каталога страниц или разные базовые значения для них указываются т.е. cs:start у них разный? Программа импортирует функции из (2 к примеру) библиотек, базовый адрес у них одинаковый, они загружаются в адресное пространство, вычисляются адреса экспортируемых функций. Так вопрос в том как они загружаютя и как вычисляюся адреса экспортируемых функций. Ведь загрузятся они в разные реальные адреса.
Так что же получается при каждом обращении к функции из библиотеки в cr3 заносится другое значение? Подменой каталогов страниц все это осуществляется? Адрес в процессе характеризуется CS:IP.
Nouzui Спасибо, кое-что объяснил. Но все же как это происходит объясните кто-нибудь пожалуйста на "пальцах" так сказать буду признателен.
"БиблиотЕнки" "разружаются" Сказалиже РТФМ!!!! Почитай что такое библиотека, что такое PE файлы, Что такое RVA,VA как устроена таблица экспорта, импорта, релоки можеш зацепить. И тогда процес "разрузки" библиотек до тебя дойдет.
DJK На пальцах: GetModuleHandle (для длл) -> GetProcAddress (для интересующих функций) -> wsprintf -> MessageBox Запускаешь несколько копий и любуешся результатом ))
Ребята вы, что меня beginner'ом считаете , все что вы говорите я прекрасно знаю (RVA, CS::IP, каталоги стриниц, страничная организация памяти ......), но мне нужно понять как это все реализуется (на словах или примерах). Что происходит с каталогом страниц, как он преобразовывается в результате загрузки новых и новых библиотек. Вот что меня интересует!!!
Ты определись что те нужно "Так вопрос в том как они загружаютя и как вычисляюся адреса экспортируемых функций. Ведь загрузятся они в разные реальные адреса.". Экспорт прописан по ВА поэтому для того чтоб узнать адрес всегото нужно ImageBase+VA. Библа грузится в свободную страницу памяти. Что тебя еще интересует?
DJK Говоришь все "прекрасно знаешь", а вопросы задаешь весьма странные Во-первых, ты про секцию .reloc слышал ? Библиотека компилируется с расчетом на определенный адрес ее образа ImageBase, но т.к. реально юзерская ДЛЛ может быть загружена по любому свободному адресу (виртуальному), то в PE включается секция релоков, в которой перечисляются смещения операндов всех инструкций, оперирующих с непосредственными адресами. Если ДЛЛ грузится по другому адресу, то загрузчик пересчитывает и изменяет все эти адреса, например был jmp 401234h, а станет jmp 1001234. Таблицу экпорта пересчитывать не нужно, т.к. в ней хранятся не виртуальные адреса, а RVA (относительно ImageBase), о чем уже сказал PaCHER В остальном загрузка юзерской ДЛЛ производится также как и приложения - создается точно такой же образ, но по другому адресу ImageBase. Как уже сказал n0name, выделение памяти осуществляется аналогично VirtualAlloc (точнее сказать CreateFileMapping + MapViewOfFile + атрибут copy-on-write) - резервируется диапазон(ы) виртуальных адресов (VAD), выделяется физ.память и создаются таблицы страниц, связывающие виртуальные адреса с физическими, и ссылки на новые таблицы страниц записываются в каталог страниц. При загрузке второй или любой N-й библиотеки для нее лишь выбирается новый еще не занятый ImageBase и дальше все также. Элементарно, Ватсон ! )) PS: думаю со всякими тонкостями типа прототипных PTE ради общего развития заморачиваться не стоит, а если хочется то читаем Руссиновича и т.д. и т.п.
не обязательно .reloc =) Хм, если библиотека уже присутствует в физ. памяти, то память вроде не выделяется опять, а VA связывается уже с загруженной ранее библиотекой.
n0name Ес-но Поскольку явного вопроса на эту тему (пока) не было, то и растекаться мыслью по древу я не стал и лишь намекнул на прототипные PTE и всезнающего Руссиновича
в самой винде достаточно много именно _stricmp( ".reloc", ... ) я бы не советовал фиксапы складывать в другую секцию
Хм. В заголовке же есть в Data Directories, директория "Base Relocation Table", мне казалось разумным что загрузчик должен по RVA и читать релоки. Хотя надо проверить.