![]() |
Модераторы: xvr |
![]() ![]() ![]() |
|
jeka23 |
|
|||
Новичок Профиль Группа: Участник Сообщений: 8 Регистрация: 29.3.2008 Репутация: нет Всего: нет |
Добрый день.
Господа программеры, прошу помочь кому не сложно с небольшой проблемкой: Если обяснять просто, то ситуация такова: Пишу собственный загрузчик. Выделяю память с помошью malloc, вписываю туда бинарный код из исполняемого файла, а потом ссылаюсь на эту память с помошью указателя на функцию и вызываю. Происходит Segmentation Fault, в ассме четко видно, что не позволяет запустить функцию, хотя в памяти видно, что бинарный код ф-ии верный и все правильно. 100%, что malloc не дает прав на EXECUTE. Как выделить память чтобы были права на EXECUTE? Заранее благодарю! |
|||
|
||||
RasenHerz |
|
|||
![]() Новичок Профиль Группа: Участник Сообщений: 16 Регистрация: 20.3.2008 Где: Санкт-Петербург Репутация: нет Всего: нет |
начнем с самого начала...
во-первых, я глубоко сомневаюсь, что ты пишешь загрузчик ![]() во-вторых, шелл-код - это плохо ![]() в-третьих, если даже ты и начнешь выполнять код на уровне ядра(а для этого надо написать модуль, и загрузить его в ядро(конечно же root'ом)), то здесь поджитает следующая проблема: стандартная библиотека С в ядре не работает и ее использование в ядре НЕВОЗМОЖНО, так что придется тебе , в основном оперировать ф-цией do_mmap() (я молчу про то что ты должен на зубок знать ассемблер) в общем, ты слишком уж замахнулся =))) так что если хочешь все-таки написать эту программу, то следующая лит-ра тебе не будет лишней: Д.Бовет, М. Чезати "Ядро Linux", Р. Лав "Разработка ядра Linux" + С.А. Раго, Стивенс "Unix. Профессиональное программирование" |
|||
|
||||
MAKCim |
|
|||
![]() Воін дZэна ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 5644 Регистрация: 10.12.2005 Где: Менск, РБ Репутация: 84 Всего: 207 |
1. показывай код 2. защита от выполнения может быть только на аппаратном уровне какой процессор используется? бред для процессоров без поддержки NX-бита проблемы нет если NX-бит поддерживается и используется проблема может быть, но она решается через __ioremap() несколькими строчками да, кроме того, с чего вы взяли, что jeka23 работает с ядром? загрузчик вполне может работать на пользовательском уровне и отображать некий код на линейное адресное пространство текущего процесса с разрешением всех релокаций (такое может быть, например, если используется специфичный формат входных файлов, о котором не знает LD, для реализации какой-нибудь виртуальной машины) -------------------- Ах, у елі, ах, у ёлкі, ах, у елі злыя волкі © |
|||
|
||||
bsa |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 9185 Регистрация: 6.4.2006 Где: Москва, Россия Репутация: 16 Всего: 196 |
А можно просто посмотреть исходники /lib/ld-x.y.z.so
|
|||
|
||||
RasenHerz |
|
|||
![]() Новичок Профиль Группа: Участник Сообщений: 16 Регистрация: 20.3.2008 Где: Санкт-Петербург Репутация: нет Всего: нет |
пусть покажет исходный код, без него мне будет крайне тяжело продолжать обсуждения в топике. MAKCim, вы должны знать что именно ф-ция do_mmap() из файла <mm.h>, выделяет новый "участок" линейных адресов(первый желаемый адрес может попробовать указать программист) который по-умолчанию помечается как готовый на ЗАПИСЬ. ЧТЕНИЕ И, самое главное, ИСПОЛНЕНИЕ. думаю, самое то будет разместить шелл-код именно там =), чем сидеть и извращаться с инлайн-ассемблером ;). P.S. я не говорю что jeka23 работает именно с ядром, просто осуществить все задуманное легче всего через интерфейсы ядра. |
|||
|
||||
MAKCim |
|
|||
![]() Воін дZэна ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 5644 Регистрация: 10.12.2005 Где: Менск, РБ Репутация: 84 Всего: 207 |
это, конечно, хорошо я с этим и не спорю но вопрос то был в этом
все зависит от того, что надо получить в итоге -------------------- Ах, у елі, ах, у ёлкі, ах, у елі злыя волкі © |
|||
|
||||
RasenHerz |
|
||||||||
![]() Новичок Профиль Группа: Участник Сообщений: 16 Регистрация: 20.3.2008 Где: Санкт-Петербург Репутация: нет Всего: нет |
что-то я не очень понимаю о чем вы говорите. но давайте, попробуем разобраться =): 1) Вот типичный шелл:
с тем, что ядро такие штуки не допускает я, конечно, загнул, т.к. являюсь ярым противником таких садистических увлечений =), но согласитесь, запуск шелла из собственного стека(!!!) это уже чересчур... не проще ли нормално "попросить" ядро выделить адреса для кода??? 2) Я все же жду от автора топика исходный код... =) |
||||||||
|
|||||||||
MAKCim |
|
|||
![]() Воін дZэна ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 5644 Регистрация: 10.12.2005 Где: Менск, РБ Репутация: 84 Всего: 207 |
RasenHerz,
я не понимаю, к чему ваш последний пост причем здесь стек... -------------------- Ах, у елі, ах, у ёлкі, ах, у елі злыя волкі © |
|||
|
||||
bsa |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 9185 Регистрация: 6.4.2006 Где: Москва, Россия Репутация: 16 Всего: 196 |
"Чукча не читатель - чукча писатель" ![]() |
|||
|
||||
RasenHerz |
|
||||||||||
![]() Новичок Профиль Группа: Участник Сообщений: 16 Регистрация: 20.3.2008 Где: Санкт-Петербург Репутация: нет Всего: нет |
<...> именно ф-ция do_mmap() из файла <mm.h>, выделяет новый "участок" линейных адресов(первый желаемый адрес может попробовать указать программист) который по-умолчанию помечается как готовый на ЗАПИСЬ. ЧТЕНИЕ И, самое главное, ИСПОЛНЕНИЕ. думаю, самое то будет разместить шелл-код именно там =), чем сидеть и извращаться с инлайн-ассемблером ;).
с тем, что ядро такие штуки не допускает я, конечно, загнул,<...>
Вот типичный шелл:
ничего не стоит переделать этот код для размещения шела в куче.
теперь все всем понятно? могу для особо одаренных объяснить более подробно.... |
||||||||||
|
|||||||||||
MAKCim |
|
||||
![]() Воін дZэна ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 5644 Регистрация: 10.12.2005 Где: Менск, РБ Репутация: 84 Всего: 207 |
товарищ jeka23 использует malloc() (-> mmap()/brk() -> |kernel| -> do_mmap()) т. е heap
не понятно ![]() -------------------- Ах, у елі, ах, у ёлкі, ах, у елі злыя волкі © |
||||
|
|||||
RasenHerz |
|
|||
![]() Новичок Профиль Группа: Участник Сообщений: 16 Регистрация: 20.3.2008 Где: Санкт-Петербург Репутация: нет Всего: нет |
Модератор: Сообщение скрыто. |
|||
|
||||
MAKCim |
|
|||
![]() Воін дZэна ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 5644 Регистрация: 10.12.2005 Где: Менск, РБ Репутация: 84 Всего: 207 |
RasenHerz,
-------------------- Ах, у елі, ах, у ёлкі, ах, у елі злыя волкі © |
|||
|
||||
RasenHerz |
|
|||
![]() Новичок Профиль Группа: Участник Сообщений: 16 Регистрация: 20.3.2008 Где: Санкт-Петербург Репутация: нет Всего: нет |
за что предупреждение??? по-моему я никого не оскорбил...
|
|||
|
||||
jeka23 |
|
|||
Новичок Профиль Группа: Участник Сообщений: 8 Регистрация: 29.3.2008 Репутация: нет Всего: нет |
И сново здравствуйте.
Уведомление на почту не работает почему-то, поэтому я и не предпологал, что мне люди отозвались, за что огромное Вам спасибо. И в правду, MAKCim прав - ядро здесь не причем, загрузчик пишется на пользовательском уровне. Большое спасибо за список литературы, я эти книжки с удовольствием читал уже, но вот до практики написания модулей никак не смог дойти, устройство ядра было просто интересно. И ассмом я немного владею, но не на профи уровне. Слаб я еще в таких вопросах как собственный загрузчик, но доделать работу очень надо, поэтому и обратился, прошу помочь. Народ.... признаю, что не совсем хорошо так, но код в студию никак выложить не могу, если кто из своих увидят - голову оторвут.... Обясню ситуацию чуть подробней: Есть движок на пользовательском уровне, который переписывается отдельно под разные платформы. К этому движку идут бинарники, не прилинкованы ни к одной функции винды, но собранные под виндой с целью использования их под разными платформами. Я был конечно не прав, что использовал malloc, RasenHerz прав. Заменил на mmap с флагом PROM_EXEC и теперь ситуация немного другая: У данных бинарников задан base image address - 0x33310000, а base image address у такого же "движка" под винду - 0x33300000 и расчет идет на то, что и под линуксом base image address будет задан 0x33300000 у "движка", а у меня получается такая ситуация, что "движок" под линуксом грузится на произвольный адрес (например 0x85af34ec23) и когда с помошью mmap выделяется память и первый параметр передается желаемый адрес выделяемой памяти(0x33310000), то память выделяется, но сразу же помечается как "out of bounds" и дальнейшая работа загрузчика не может продолжатся так как на первом же memcpy все валится с SIGBUS. Я так понимаю, что вся фишка в том, что мне нужно base image address у линуксового "движка" поставить в 0x33310000, но никак не могу найти как это сделать с g++ компилятором..... Может кто-нить подсказать как это делается? Еще раз извиняюсь, что не имею права давать код! ![]() |
|||
|
||||
MAKCim |
|
|||
![]() Воін дZэна ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 5644 Регистрация: 10.12.2005 Где: Менск, РБ Репутация: 84 Всего: 207 |
компилятор здесь не причем нужно использовать mmap() с ненулевым первым параметром если mmap() возвращает ошибку, значит данный участок линейного адресного пространства использовать нельзя такой вопрос, создавать новый процесс можно? или все надо делать в контексте текущего? -------------------- Ах, у елі, ах, у ёлкі, ах, у елі злыя волкі © |
|||
|
||||
jeka23 |
|
||||
Новичок Профиль Группа: Участник Сообщений: 8 Регистрация: 29.3.2008 Репутация: нет Всего: нет |
Я так и делаю: первый параметр mmap - желаемый адрес проецирования бинарника, который я извликаю из самого бинарника. Он железно жашит в бинарнике как 0x33310000, но память в отладчике сразу помечается как out of bounds В таком же "движке" под винду просто используется желаемый адрес проецирования самого "движка" под адресом 0x33300000, и соответственно бинарник может проецироваться в память рядом с "движком" по адресу 0x33310000. В моем "движке" под линукс нужно просто задать базовый адрес проецирования в виде 0x33300000 и по логике все должно заработать, но только как его задать.... Компилятор тут конечно не причем, таие вещи задаются линковщику, но как... не могу в инете ничег накопать ![]()
создавать процесс можно, но это получится крайне не красивое решение так как в бинарнике хранятся множество функций, которые нужно вызывать в разных участках "движка", и каждый раз для этого создавать процесс ну никак не будет красиво выглядеть.. |
||||
|
|||||
RasenHerz |
|
|||
![]() Новичок Профиль Группа: Участник Сообщений: 16 Регистрация: 20.3.2008 Где: Санкт-Петербург Репутация: нет Всего: нет |
так вы пишите загрузчик для *.exe файлов? посмотрите сорцы Wine. думаю обычным копированием шелла вы не обойдетесь - между принципиальная разница - разница между сегментацией в Linux и Windows просто огромна. все будет гораздо сложнее если в шелле будет вызываться какой-либо метод, придется очень многое исправлять.... но если вы дадите мне таблицу соответствия ассемблерных команд их hex значению (извините за безграмотность) - к примеру, ret - 0xc3 и т.д., то я возможно чем то смогу вам помочь. и пожалуйста, выложите проблемный кусок кода здесь... я все-таки не телепат...
![]() |
|||
|
||||
jeka23 |
|
||||||||
Новичок Профиль Группа: Участник Сообщений: 8 Регистрация: 29.3.2008 Репутация: нет Всего: нет |
Я очень благодарен Вам за желание помочь.
Загрузчик я не пишу, он уже написан другим человеком, с которым компания потеряла связь. Все что мне нужно сделать - это воспользоваться им из "движка" чтобы подгрузить бинарники и вызвать функции этих бинарников так же в "движке" (понимаю, что уже тошнит от слова "движок", но стараюсь изясняться яснее ![]() И так: функция для выделения памяти под бинарник ПОКА выглядет так:
в самом загрузчике память под бинарник выделяется так:
я продефайнил все майкросовские типы, например DWORD, руководитель проекта так попросил. Функции загрузчика по распатрашению PE заголовков думаю выкладывать нет смысла, они роли не сыграют, к тому же в дебагире 20 раз проверенно - работает четко. OptionalHeader.ImageBase как Вы понимаете - базовый адрес проецирования бинарника, который был вытащен загрузчиком из PE заголовка самого бинарника, и постоянно раввен 0x33310000. Но вот и тут-то пока все падает с SIGBUS так как только в выделеную память с помошью mmap происходит запись с помошью memcpy - все валицо ![]()
с удовольствием дам, только не могу понять о чем Вы ![]() Вообще проблем вроде не должно быть в данной задаче, так как бинарники написаны кросплатформенно и любая ф-ия типа strcpy переписана в самом бинарнике чтобы не ссылаться ни на одну библиотеку винды. В дальнейшем мне нужно с помошью функции загрузчика GetProcAddr вытащить какую-нибудь функцию из загруженого бинаоника и вызвать ее, как например тут:
и когда я использовал malloc, то бинарник грузился нормально и на строке кода SetNameInfo(&m_bases.ni); я сравнивал ассемблерский код, нахдящийся по адресу SetNameInfo в отладчике под линуксом и под виндой в аналогичном "движке" - код абсалютно одинаков, кроме смещений, которые заменяет сам загрузчик. Загрузчик работает правильно. Просто при использовании malloc все падало с Sigmentation fault так как malloc не дает права на запуск в памяти, да и использовать malloc нельзя так как загрузчик четко указывает желаемые адреса проецирования, а в malloc такой возможности нет. Если чего не понятно - с прашивайте, с удовольствием обясню, и еще раз спасибо. |
||||||||
|
|||||||||
MAKCim |
|
|||
![]() Воін дZэна ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 5644 Регистрация: 10.12.2005 Где: Менск, РБ Репутация: 84 Всего: 207 |
зачем? фишка в том, что можно создать фиктивный исполняемый файл, который будет отображаться через sys_execve как раз чуть ниже 0x33310000 (адрес указывается) код, отображенный ниже 0x33310000, будет отображать любой образ по адресам >= 0x33310000 -------------------- Ах, у елі, ах, у ёлкі, ах, у елі злыя волкі © |
|||
|
||||
xvr |
|
||||||
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 7046 Регистрация: 28.8.2007 Где: Дублин, Ирландия Репутация: 20 Всего: 223 |
А зачем выделять память через mmap? Мэпируйте сразу ваш файл (PE) на нужные адреса. |
||||||
|
|||||||
jeka23 |
|
||||||
Новичок Профиль Группа: Участник Сообщений: 8 Регистрация: 29.3.2008 Репутация: нет Всего: нет |
Нашел наконец как задать желаемый адрес проецирования, только не могу понять почему ругается:
Кто-нибудь знает как успокоить линковщик? Немогу вообще понять зачем ему rpath если LD_RUN_PATH переменная используется.... Добавлено через 5 минут и 52 секунды
Так оно по любому так и получается: alloc_pagealign выделяет память под PE, а потом туда через memcpy заливается сам бинарник. Просто "на нужные адреса" не получается получить память из за того, что мой "движок" не спроецирован на нужные мне адреса, вот и спрашиваю у народа:
|
||||||
|
|||||||
jeka23 |
|
|||
Новичок Профиль Группа: Участник Сообщений: 8 Регистрация: 29.3.2008 Репутация: нет Всего: нет |
....не могу понять, почему вот такой код валится с сигналом SIGBUS:
Почему я не могу писать в Address? |
|||
|
||||
MAKCim |
|
|||
![]() Воін дZэна ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 5644 Регистрация: 10.12.2005 Где: Менск, РБ Репутация: 84 Всего: 207 |
jeka23,
mmap() точно не возвращает значение MAP_FAILED? errno равна нулю после mmap()? ход решения такой 1. формируем специальный исполняемый файл, который будет отображать PE по нужному адресу (0x33310000) через mmap() сам исполняемый файл будет создан таким образом, что ядро будет отображать его по адресу X < 0x33310000 так, что значение 0x33310000 - X будет равно его размеру 2. пишем загрузчик загрузчик порождает новый процесс, в контексте нового процесса выполняем execve(), перадавая в качестве параметра путь к отображаемому PE если хочешь, могу вечером сделать такой файл, это несложно -------------------- Ах, у елі, ах, у ёлкі, ах, у елі злыя волкі © |
|||
|
||||
jeka23 |
|
|||
Новичок Профиль Группа: Участник Сообщений: 8 Регистрация: 29.3.2008 Репутация: нет Всего: нет |
MAKCim, очень благодарен, mmap сработал, просто q был нулевого размера, поэтому и валилось. Пока продвигаюсь дальше, вскоре отпишусь и разясню ситуацию, думаю можно будет обойтись без другого процесса..
|
|||
|
||||
jeka23 |
|
|||
Новичок Профиль Группа: Участник Сообщений: 8 Регистрация: 29.3.2008 Репутация: нет Всего: нет |
Уважаемые программеры, в последний раз благодарю вас всех за уделенное мне время
![]() Загрузчик заработал, нужно было просто правильно воспользоваться mmap и не важно какие адреса используются, смешно и стыдно ![]() Помечаю пост как "решенный", удачи Вам и еще раз спасибо. P.S.: Будущее за linux-ом и Россией, так как и то и другое было основано на идее. |
|||
|
||||
![]() ![]() ![]() |
Правила форума "С/С++: Программирование под Unix/Linux" | |
|
Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, xvr. |
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
0 Пользователей: | |
« Предыдущая тема | C/C++: Программирование под Unix/Linux | Следующая тема » |
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |