Модераторы: feodorv, GremlinProg, xvr, Fixin
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Непонятки с памятью процесса, Освобождение, выделение... 
:(
    Опции темы
Zmaster555
Дата 21.2.2013, 16:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 22
Регистрация: 14.1.2013

Репутация: нет
Всего: нет



Итак, я запускаю мое приложение в OllyDebugger, вижу такую карту памяти:

user posted image

Тут все хорошо, обратите внимание на размеры первых трех секций, все по 1к, все хорошо. Образ лежит по стандартному IB. Идем дальше. В процессе работы, эта программа выделяет кусок памяти, записывает туда код, передает управление на этот код. Этот код первым делом вызывает ZwUnmapViewOfSection, чтобы убить старый образ, после вызова этой функции карта памяти следующая: 

user posted image

Как видим, образ удален, все хорошо. Продолжаем. Хочу выделить память под новый образ. Резервирую регион размером 0x15000, успешно выделяю память под PE заголовок. Дальше выделяю память под секцию кода нового образа. Секция кода нового образа равна 0x3000, я выделяю это кол-во байт, начиная с 0x00401000. И тут пошел хардкор, смотрим карту памяти: 

user posted image

WTF? Я не выделял 3 куска по 1к, я выделил один 3к. Что за бред произошел? Почему он мне показывает старую карту? Из-за этого приложение работает неправильно, вылетает с ошибками на некоторых частях кода (когда есть инструкция по адресу 0x00401035, а следующая только по 0x00401039, то он пытается что-то исполнить с интрукцией между этими адресами, т.е. код расположен неправильно, хотя некоторые его части исполняются). И дальше, когда выделяю память до конца, опять появляется в карте памяти секция ресурсов, размером 10к. Ну а т.к. размер нового образа больше старого на 1к, то после "секции ресурсов" есть еще кусок памяти размером 1к.

user posted image

Что происходит? Куда копать? Таблицы памяти, PEB? Благодарен за любую помощь, ответ нужен как можно быстрее.

P.S. Радикал, гори в аду!
PM MAIL   Вверх
DarthTon
Дата 21.2.2013, 18:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 106
Регистрация: 7.2.2009

Репутация: 5
Всего: 6



Возможно просто Олли криво отображает структуру памяти. Попробуйте посмотреть её чем-нибудь другим, например VMMap от Sysinternals. Потому что у меня не возникало подобных проблем со связкой NtUnmapViewOfSection + VirtualAlloc.
PM MAIL   Вверх
Zmaster555
Дата 21.2.2013, 19:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 22
Регистрация: 14.1.2013

Репутация: нет
Всего: нет



DarthTon, скачал софтину (кстати, очень неплохая вещь, спасибо), вот что показывает:

user posted image

Как видим, опять неправильно, правда уже немного по-другому неправильно. Под код выделено 3к, но данные (оригинальный VASize которых 0xf000) и ресурсы свалены в кучу. И что самое интересное, атрибуты секций установлены как у старого образа. В новом, у меня у всех секций стоят RWE. Что-то тут не чисто. В итоге программа запускается, но в какой-то момент падает, сейчас расскажу как. Падает на участке кода с адресом 0x004016D0, смотрю в район этого адреса и вижу (падает на инструкции hlt):

user posted image

А вот, как должно быть на самом деле (как в оригинальном образе):

user posted image

Как видим, байты одни и те же, но почему-то процессор разобрал их не правильно. И причина видна только одна - вышеуказанная.
DarthTon, спасибо за ответ, жду еще одного smile
PM MAIL   Вверх
DarthTon
Дата 21.2.2013, 19:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 106
Регистрация: 7.2.2009

Репутация: 5
Всего: 6



Тут Олли похоже опять не правильно дизасемблировал инструкцию smile (потому что инструкция hlt привелегированая и не может быть сгенерирована компилятором в Ring3 коде). Какой байт находится в новом образе по адресу 0x004016CF, не 0xE8 случайно?. Если 0xE8, то код в новом образе такой же как и в старом(в таком случае можно попробовать вызвать Analysis->Analyze all в Олли чтобы он нормально сдизасемблировал, или воспользоваться другим дизассемблром, например, IDA Pro Free), если нет то что-то не так скопировалось в новый образ.
PM MAIL   Вверх
Zmaster555
Дата 21.2.2013, 20:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 22
Регистрация: 14.1.2013

Репутация: нет
Всего: нет



Да, байт 0xE8, два образа абсолютно идентичные, проверял. Но тут дело не только в Олли, я ведь запускаю программу в системе и там уже получаю ошибку (и то не сразу, а после того как сделаю определенное действие) следующего вида:

user posted image

Ну тыкаю кнопку отладить, открывается асм листинг в VisualStudio и там такое:

user posted image

Ну и тут уже можно заказывать койку в психбольнице...

Цитата

не возникало подобных проблем со связкой NtUnmapViewOfSection + VirtualAlloc. 


А можно рассказать подробнее как вы делали? По частям выделяли память, либо все сразу, алгоритм, что за чем и прочие тонкости, может я что упускаю из виду...
PM MAIL   Вверх
Zmaster555
Дата 21.2.2013, 21:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 22
Регистрация: 14.1.2013

Репутация: нет
Всего: нет



Только что попробовал так:
VirtualAlloc(0x00400000, 0x15000, MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE)
ну и дальше скопировал образ целиком туда и передал управление на точку входа. Результат тот же, вылетает по тому же адресу, на той же инструкции. Карта памяти в Олли такая же идиотская, но VMMAP показывает уже нормальную (т.е. все 84 килобайта RWE одной секцией). 

Это сообщение отредактировал(а) Zmaster555 - 21.2.2013, 21:07
PM MAIL   Вверх
DarthTon
Дата 21.2.2013, 21:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 106
Регистрация: 7.2.2009

Репутация: 5
Всего: 6



Ну у меня слегка другой подход был. Я создавал новый процесс с флагом SUSPENDED, вызывал NtUnmapViewOfSection с адресом ImageBase, после этого VirtualAllocEx(..., ImageBase, MEM_COMMIT|MEM_RESERVE, PAGE_EXECUTE_READWRITE) и размером равным SizeofImage. После этого копировал все секкции разом, менял EIP потока и возобновлял процесс. 

Но вообще, судя по тому что оно падает именно в том месте, означает что был непосредственный переход именно на адрес 0x004016D0, т.к. при последовательном выполнении инструкций выполнилась бы инструкция 0x004016CF (call). Неплохо было бы отследить откуда поток попадает на адрес 0x004016D0.
PM MAIL   Вверх
Zmaster555
Дата 21.2.2013, 21:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 22
Регистрация: 14.1.2013

Репутация: нет
Всего: нет



Хм, ваш подход более грамотный, сейчас если не получится отследить как процессор попадает на ошибочный адрес, то попробую реализовать как у вас, думаю много времени не займет.
PM MAIL   Вверх
Zmaster555
Дата 21.2.2013, 22:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 22
Регистрация: 14.1.2013

Репутация: нет
Всего: нет



DarthTon, насчет вашего способа. Если екзешник копирует сам себя в другое место, то ведь он скопирует себя уже распакованного, т.е. уже новый процесс (или нет?), который мы создали. А если, к примеру, нужно чтобы он копировал сам себя в упакованном виде, то как бы вы поступили?

Это сообщение отредактировал(а) Zmaster555 - 21.2.2013, 22:07
PM MAIL   Вверх
DarthTon
Дата 21.2.2013, 22:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 106
Регистрация: 7.2.2009

Репутация: 5
Всего: 6



Я делал так. Брал екзешник, паковал его целиком, собирал новый екзешник-обертку програмно и пихал в неё упакованный образ. В итоге в зависимости от того как собрана обертка, она может скопировать или упакованные данные, или уже распакованные.

Это сообщение отредактировал(а) DarthTon - 21.2.2013, 22:27
PM MAIL   Вверх
Zmaster555
Дата 21.2.2013, 22:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 22
Регистрация: 14.1.2013

Репутация: нет
Всего: нет



DarthTon, можно более подробнее, и я в свою очередь тоже подробнее:
Есть exe, который нужно упаковать... ну вернее закриптовать. Я его пихаю в свой exeшник, который при запуске делает все необходимое чтобы обеспечить жизнь тому экзешнику, который в нем (т.е. исходный). В итоге передаем управление на исходный (правда с некоторыми проблемами, которые выше smile), и он в свою очередь проверяет, к примеру, если он запущен не из D:\, то скопировать себя в D:\, запустить себя оттуда, а этот экземпляр завершить. Так вот если я буду создавать новый экзешник-обертку, то ведь когда дойдет дело до копирования себя, то он и скопирует себя в обертке в D:\ и при следующем запуске (из автозапуска всмысле) его, он уже запуститься в некриптованном виде. Плюс еще останется жить тот файл, который был запущен самым первым (который создал обертку), который получается больше не нужен?.. Что-то я совсем запутался.

Это сообщение отредактировал(а) Zmaster555 - 21.2.2013, 22:49
PM MAIL   Вверх
Dem_max
Дата 22.2.2013, 03:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1780
Регистрация: 12.4.2007

Репутация: 16
Всего: 39



ТС а ты учитываешь выравнивание при копировании в новый образ, может у тебя начало нового образа по не выровненному образу.


--------------------
Американские программисты долго не могли понять, почему русские при зависании Windоws всё время повторяют "Твой зайка написал" ("Yоur bunnу wrоte")
PM MAIL   Вверх
Zmaster555
Дата 22.2.2013, 06:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 22
Регистрация: 14.1.2013

Репутация: нет
Всего: нет



Учитываю, разумеется.

Добавлено через 5 минут и 24 секунды
Итак, пока что проблема решена благодаря созданию нового потока, т.е. память под новый образ выделяется в новом потоке (новый TEB, новый стэк и т.д.) и в нем же образ и исполняется. Старый поток убивается. Но буду еще пробовать, тестировать, экспериментировать, может какая ошибка, да вылетит.
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "C/C++: Системное программирование и WinAPI"
Fixin
GremlinProg
xvr
feodorv
  • Большое количество информации и примеров с использованием функций WinAPI можно найти в MSDN
  • Описание сообщений, уведомлений и примеров с использованием компонент WinAPI (BUTTON, EDIT, STATIC, и т.п.), можно найти в MSDN Control Library
  • Непосредственно, перед созданием новой темы, проверьте заголовок и удостоверьтесь, что он отражает суть обсуждения.
  • После заполнения поля "Название темы", обратите внимание на наличие и содержание панели "А здесь смотрели?", возможно Ваш вопрос уже был решен.
  • Приводите часть кода, в которой предположительно находится проблема или ошибка.
  • Если указываете код, пользуйтесь тегами [code][/code], или их кнопочными аналогами.
  • Если вопрос решен, воспользуйтесь соответствующей ссылкой, расположенной напротив названия темы.
  • Один топик - один вопрос!
  • Перед тем как создать тему - прочтите это .

На данный раздел распространяются Правила форума и Правила раздела С++:Общие вопросы .


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Chipset, Step, Fixin, GremlinProg, xvr. feodorv.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Системное программирование и WinAPI | Следующая тема »


 




[ Время генерации скрипта: 0.0515 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.