а если попробовать в моем загрузчике создать секцию по адресу 4000000 и достаточным размером, и забить в нее массив нулей? типа #pragma section( ".mem" ) __declspec(allocate(".mem")) char buffer[0x40000]; а прибить секцию к адресу вроде тоже как-то можно. upd: собственно насколько я понял, релоки как раз и могут разместить мою секцию по нужному мне адресу. Но msdn молчит. Их вообще в VC++ можно прописать какой-нибудь директивой?
нет, так сделать нельзя. Все секции должны непрерывно следовать друг за другом. Если будешь так делать, это то же самое, что тебе советовали в ответе №4 поковыряйся в опциях линкера. Там вроде две опции есть, чтобы в итоге были добавлены релоки.
Я так и не понял что конкретно мешает вам приравнять базу образа пакера к базе пакуемого бинаря? При загрузке вы (если нет травы, то образ вашего модуля) уже на целевых адресах. Себя анмапнули, бинарь на это место распаковали, в чем проблема?
Clerk Рассматривается вариант, при котором упакованный бинарь не содержит релоков. Манипуляции, описанные выше, нужны в любом случае. Загрузчик нативный или свой - роли тут не играет.
было уже. стуб распаковщика поместить ниже 400000. проследить чтоб в нем не было бсс и ресурсов. точнее бсс одна нужна - на начало запакованного кода. запакованный блок пририсовываем в хвост с учетом выравнивания по бсс, расширяем дату на него. переназначаем бсс так чтоб оно покрыло все нужное под распакованный код место. гдето так
qqwe Некрасивая база может не понравиться эвристикам, не тру. Хотя способ более красивый, без анмапов и прочего.
Clerk Прочитайте с первых постов, задача иная стоит изначально и она решаема. Зачем это другой вопрос.
deLight Если память занята, то каким бы образом она не освобождалась, ни к чему хорошему это не приведёт. Тотже стек потока - если на момент его останова была адресация локальных переменных например в ядро, то после смены стека поток отвалится. Необходимо резервировать память соновным модулем, меняя его базу.
ну скомпельте свой распаковщик в шел или с релоками, перенесите и распаковывайте на его место как уже говорили. не помню кто. правда, не знаю как ваши ав к изменению атрибутов памяти отнесутся. как вариант - колдовать с мапом даты перед распаковщиком. только не знаю выйдет ли. еще вариант - вызвать распаковщик из стандартного пролога (скажем, вместо мэйн). а само место под прогу объявить как дату (с запакованным образом) и бсс (чтоб места не жрало). распаковщик воткнуть куда нибудь. тогда все будет на местах. единственно что - ехекутировать дату потом нужно будет.
Clerk 1) Стек потока не может находиться на целевых адресах, тк они зарезервированы основным модулем, но при этом база та же, не обязательно смещать ее назад как в #26. 2) Поток один, какие остановы? В контексте первичного потока происходит unmap образа основного модуля, далее на эти адреса кладется распакованный бинарь. Никаких проблем нет, по факту. qqwe Ав к этому отнестись никак не могут при всем желании, для статического анализа признаков нет. В момент распаковки целевого образа эмулятор уже лежит.
Clerk Память в этом месте не может быть занята, если образ пакера загружается по адресам, на которые впоследствии будет распакован модуль. Сколько это еще повторить раз не знаю. Засыпаете уже все что-ли?
Clerk Без комментариев. В качестве развития научно-познавательных интересов, объясните присутсвующим как в области, занятой основным модулем (ImageBase...ImageBase+SizeOfImage) может размещаться стек потока. Ребята тоже ждут, тк они такого явно не проектировали: Соломон Руссиновичу (Катлер уже оглох от смеха): "Марк, когда они уже издадут WinInternals на белорусском?"
deLight Стек потока не в пределах первичного образа, а в пределах распаковываемого. А тебе есчо рано такими фотками кидать, сосунок.
Clerk Ну наконец-то! Я теперь с вами? float Если собрать теперь все вместе - генерируется модуль, база загрузки которого равна базе пакуемого бинарника. Размер образа должен быть не меньше чем соответственно поле SizeOfImage целевого модуля. Этим обеспечивается резервирование нужной вам области памяти. Получив управление упаковщик выделяет в адресном пространстве регион нужного размера и переносит туда упакованный модуль и базонезависимый код, который делает следующее: выгружает промапленный на необходимые адреса основной модуль (или ставит всему региону аттрибуты RW) и загружает в эту область нужный бинарник. Тут по сути два варианта или грузить самому, дублируя практически все необходимые действия загрузчика (настройка импорта, фикс значений в списке модулей) или заюзать способ с трассировкой нативного лоадера - достаточно красивое, но несколько сложное для новичка решение от нашего чудо-vx'ера.
> Если собрать теперь все вместе - генерируется модуль, база загрузки которого равна базе пакуемого бинарника. пост номер 4 =)