Пишу я загрузчик PE в память. Так как все pe обычно базозависимые, приходится грузить файл по их imagebase. Проблема в том, что в этом месте память уже занята стеком какого-то левого потока. При попытке освободить ее, все падает. Как можно решить эту проблему? С, vs2010
Интересно можно так?: Проанализировать чем занят блок, допустим если стек потока, тогда суспендить поток, выделить новую память под стек, поменять контекст того потока скопировать туда данные, освободить нужную память, возобновить поток. Что-то в этом роде? Или бред?
Это конечно можно, но уж очень черезжопно. Я вообще думал что можно как-то линкеру указать, что какая-либо область памяти зарезервирована под мое приложение.
ну вот у калькулятора допустим imagebase 4000000h. У него базозависимый код, т.е. надо грузить его по этому адресу. А стек потока взял и разместился по адресу, равному imagebase+sizeofimage/2, то есть влезет только половина памяти его. По этому я хочу как-то зарезервировать допустим память от 4000000 до 7000000 под себя еще на этапе линкования
float Проблему можно решить немного другой реализацией загрузчика. Думайте головой,как сделать по другому ничего не портя при этом и не освобождая.
> А стек потока взял и разместился по адресу, равному imagebase+sizeofimage/2 невозможно, потому что память [imagebase, imagesize + sizeofimage] уже выделена.
ну если тебе надо грузить именно свой ехе по другому адресу и у тебя есть возможность делать манипуляции с линкером, тогда лучше добавь релоки. Это проще и работать будет везде. Более-менее разумного решения подобной проблемы я в сети не встречал. Обычно или закрывали глаза на частичную несовместимость, или писали базонезависимый код. Релоки - это самое правильное решение, предусмотренное самой виндой
загрузчик мой, ехе чужой. Вы уверены что релоки могут решить проблему инструкций подобной этой?: где юзается абсолютная адрессация.
float пишите дизасм-енджин-генератор-релоков))) а если по теме, то манипулировать флагами /BASE, /FIXED, /STACK и тд... ЗЫ по-моему свой PE-лоудер еще не написал только ленивый)))
sysexit не выйдет. текущие адреса стека уже находятся в регистрах (ebp, например), самом стеке, памяти, итд (fs:0, например). float для того они и предназначены
ну релоки были созданы для одного единственного случая - абсолютной адресации. Для относительной адресации они вообще не нужны. Но, если ехе чужой, ничего ты не сделаешь. В свое время сталкивался с такими же проблемами - потом забил на файлы без релоков.
Пройтись и поправить все значения в стеке которые принадлежат адресам старого стека?(естественно бажно, ну все же). Контекст потока разве сложно править?
> было бы замечательно, но поток создается еще перед заходом в _tmain() память выделяется еще до создания потока.
Снять атрибуты с памяти. Дать стеку "просраться" предварительно выравнять память(в смысле соединить всю память, так что бы память была не разрывной с 400000 - image_to_load + sizeof(stack) посчитать полее точно) , у стека получится большое смещения, но память будет валидной так что overflow не будет ...