Короче проблема в следующем. Выделяю блок памяти размером в 4кб, получаю указатель, выделяю ещё раз 4 кб - получаю ещё один указатель. Сравниваю их - разница в 0x10000, а должно быть в 0x1000. Между блоками никаких зарегестрированых участков нет. Флаг MEM_TOP_DOWN дает тот же результат, только с конца пространства пользователя. Подскажите метод или способ как можно выделять участки подряд, желательно без ручного управления и увеличения размера выделения до 0х10000.
rudik если хочешь предсказуемой работы VirtualAlloc обязательно сначала резервируй диапазон адресов, потом в нём уже выделяй страницы по мере необходимости http://www.wasm.ru/forum/viewtopic.php?pid=167377#p167377 http://www.wasm.ru/forum/viewtopic.php?pid=270546#p270546
Народ, проблема такая, распаковал я одну программу, но распаковал криво (пользовался распаковщиком), при запуске, распаковщик пытается прочитать страницу памяти по одному и тому же адресу, а ее нет и вылетает, но если я задаю в Ольке валидный участок то прога запускается как нада. А проблема в том, что я никак не могу выделить участок памяти по нужному адресу (00141000), vmmap показывает 60кб, т.е до адреса 00150000 (стека), а тут почитал что VirtualAlloc может тока 64 кб резервировать ?? Как быть ?
Резервировать можно минимум одну страницу, это 4k. Что возвращается за код ошибки при выделении памяти и состояние региона какое ?
lobzik Если 64К регион 140000h свободен, то и запрашивай выделение по адресу 140000h с флагами MEM_RESERVE+MEM_COMMIT. А если этот регион уже зарезервирован и в нем выделена одна страница, то запрашивай память по адресу 141000h с флагом MEM_COMMIT
Clerk состояние FREE, код ошибки 487 (dec). leo, регион свободен, но не получается выделить, ошибка, нужно именно там где нужно.
Значит STATUS_CONFLICTING_ADDRESSES. Значит вызывай NtQueryVirtualMemory(MemoryBasicInformation) для этого региона, там видно будет.
Видимо эти участки памяти как то зарезервированы системой, но всеравно же их можно как то увеличить .. от чего они зависят ? мб можно как то при запуске программы увеличить?
NtQueryVirtualMemory(MemoryBasicInformation) = VirtualQuery если я неошибаюсь, она показывает State Free и Protect ReadOnly.
Вощем спасибо всем ) проблема решилась другим способом, подредактировав ПЕ хедер, увеличил стэк до размера нужной секции, вощем рабтает и ладно ))
lobzik Я вроде ясно выразился - зарезервировать память можно только по адресу, кратному 64К. Поэтому если ты юзаешь MEM_RESERVE+MEM_COMMIT, то запрашивай адрес 140000h и соотв-но увеличь запрашиваемый размер на 4К (че те жалко лишнюю страницу прихватить ?). Если страница по адресу 140000h занята (о чем видимо свидетельствует MEM_FREE + PAGE_READONLY), то нужно запрашивать память по адресу 141000h только с флагом MEM_COMMIT, т.к. этот регион уже "кем-то" зарезервирован до тебя
Насчет резервирования понятно, но всеравно она(функция) нехочет делать так как нада, она резервирует тока гдето в другом месте, т.е запрашиваю память по адресу 141000h только с флагом MEM_COMMIT(при условии что это свободная память и никем незарезервирована), а мне гдето из бутово поинтер прилетает. Вот сам попробуй расшарить страницу гденибуть в 00130000 или 00140000, хотябы 4кб.
lobzik Не-е, ты не lobzik, ты buzz-saw - как пошел пилить в одном направлении, так и шуруешь, не слыша что тебе говорят Последний раз повторяю, раз память по адресу 141000h НЕ зарезервирована (MEM_FREE), то VirtualAlloc в принципе не может вернуть тебе этот адрес, т.к. начальный адрес для резервирования всегда округляется вниз на границу 64К. Поэтому и нужно запрашивать память по кратному адресу 140000h, но размер задать так, чтобы он захватил и нужный тебе адрес 141000h. Если все будет OK и VirtualAlloc вернет адрес 140000h, то просто прибавишь к нему 1000h и получишь свой адрес 141000h. Как ты не поймешь, что дело не в начальном адресе выделенного блока, а в том, чтобы этот выделенный блок накрыл твой адрес 141000h - тогда все будет ОК
PS: Да, и с размером не промахнись, а то можешь выскочить на следующий зарезервированный блок и опять получишь облом-с
Clerk А я разве говорил, что нельзя резервировать меньше 64К ? Просто начальный адрес для резерва всегда округляется вниз на 64К границу, поэтому если задавать размер резерва меньше (или некратным) 64К, то оставшиеся свободные страницы в конце 64К-блока будут вообще не доступны, т.к. увеличить размер резерва повторным вызовом VirtualAlloc в этом случае не получиться.
PS: Поэтому я и толкую, что раз страница 141000h не зарезервирована (MEM_FREE), то нужно проверить состояние предыдущей выравненной страницы 140000h - если она тоже MEM_FREE, до удасться зарезервировать и выделить нужное число страниц по этому адресу, прихватив и 141000h, и еще сколько нужно. А если память по адресу 140000h уже зарезервирована\выделена, то ловить тут вообще нечего PPS: речь ес-но идет о VirtualAlloc, че там у вас в нативе или в ядре творится, я не знаю