Модераторы: xvr

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Выделение памяти с правами на запуск функции, Выделить память и запустить в ней ф-ю 
V
    Опции темы
jeka23
Дата 29.3.2008, 23:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Добрый день.

Господа программеры, прошу помочь кому не сложно с небольшой проблемкой:

Если обяснять просто, то ситуация такова:
Пишу собственный загрузчик. Выделяю память с помошью malloc, вписываю туда бинарный код из исполняемого файла, а потом ссылаюсь на эту память с помошью указателя на функцию и вызываю. Происходит Segmentation Fault, в ассме четко видно, что не позволяет запустить функцию, хотя в памяти видно, что бинарный код ф-ии верный и все правильно. 100%, что malloc не дает прав на EXECUTE.

Как выделить память чтобы были права на EXECUTE?

Заранее благодарю!
PM MAIL   Вверх
RasenHerz
Дата 30.3.2008, 02:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



начнем с самого начала...
  во-первых, я глубоко сомневаюсь, что ты пишешь загрузчик  smile, загрузчики пишут либо на асме либо на С с НУЛЯ.
  во-вторых, шелл-код - это плохо  smile , и если ты хочешь использовать его при загруженном ядре, то скорее всего тебе придется обламаться: ядро не допускает передачу управления в сегмент данных, чтобы обойти это ограничение тебе надо ОЧЕНЬ постараться и как минимум хорошо разбираться в устройстве ядра (в том, что ты в нем разбираешься я очень сомневаюсь, т.к. иначе ты не создал бы этот пост).
  в-третьих, если даже ты и начнешь выполнять код на уровне ядра(а для этого надо написать модуль, и загрузить его в ядро(конечно же root'ом)), то здесь поджитает следующая проблема: стандартная библиотека С в ядре не работает и ее использование в ядре НЕВОЗМОЖНО, так что придется тебе , в основном оперировать ф-цией do_mmap() (я молчу про то что ты должен на зубок знать ассемблер)

  в общем, ты слишком уж замахнулся =))) так что если хочешь все-таки написать эту программу, то следующая лит-ра тебе не будет лишней: Д.Бовет, М. Чезати "Ядро Linux", Р. Лав "Разработка ядра Linux" + С.А. Раго, Стивенс "Unix. Профессиональное программирование"
PM MAIL   Вверх
MAKCim
Дата 30.3.2008, 10:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Воін дZэна
****


Профиль
Группа: Экс. модератор
Сообщений: 5644
Регистрация: 10.12.2005
Где: Менск, РБ

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



Цитата(jeka23 @  29.3.2008,  23:53 Найти цитируемый пост)
Происходит Segmentation Fault, в ассме четко видно, что не позволяет запустить функцию, хотя в памяти видно, что бинарный код ф-ии верный и все правильно. 100%, что malloc не дает прав на EXECUTE.

1. показывай код
2. защита от выполнения может быть только на аппаратном уровне
какой процессор используется?
Цитата(RasenHerz @  30.3.2008,  02:18 Найти цитируемый пост)
ядро не допускает передачу управления в сегмент данных

бред
для процессоров без поддержки NX-бита проблемы нет
если NX-бит поддерживается и используется проблема может быть, но она решается через __ioremap() несколькими строчками
да, кроме того, с чего вы взяли, что jeka23 работает с ядром?
загрузчик вполне может работать на пользовательском уровне и отображать некий код на линейное адресное пространство текущего процесса с разрешением всех релокаций
(такое может быть, например, если используется специфичный формат входных файлов, о котором не знает LD, для реализации какой-нибудь виртуальной машины)


--------------------
Ах, у елі, ах, у ёлкі, ах, у елі злыя волкі ©

PM MAIL   Вверх
bsa
Дата 30.3.2008, 11:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 9185
Регистрация: 6.4.2006
Где: Москва, Россия

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



А можно просто посмотреть исходники /lib/ld-x.y.z.so
PM   Вверх
RasenHerz
Дата 30.3.2008, 13:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Цитата

бред
для процессоров без поддержки NX-бита проблемы нет
если NX-бит поддерживается и используется проблема может быть, но она решается через __ioremap() несколькими строчками
да, кроме того, с чего вы взяли, что jeka23 работает с ядром?
загрузчик вполне может работать на пользовательском уровне и отображать некий код на линейное адресное пространство текущего процесса с разрешением всех релокаций
(такое может быть, например, если используется специфичный формат входных файлов, о котором не знает LD, для реализации какой-нибудь виртуальной машины)

пусть покажет исходный код, без него мне будет крайне тяжело продолжать обсуждения в топике.
MAKCim, вы должны знать что именно ф-ция do_mmap() из файла <mm.h>, выделяет новый "участок" линейных адресов(первый желаемый адрес может попробовать указать программист) который по-умолчанию помечается как готовый на ЗАПИСЬ. ЧТЕНИЕ И, самое главное, ИСПОЛНЕНИЕ. думаю, самое то будет разместить шелл-код именно там =), чем сидеть и извращаться с инлайн-ассемблером ;).

P.S. я не говорю что jeka23 работает именно с ядром, просто осуществить все задуманное легче всего через интерфейсы ядра.
PM MAIL   Вверх
MAKCim
Дата 30.3.2008, 13:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Воін дZэна
****


Профиль
Группа: Экс. модератор
Сообщений: 5644
Регистрация: 10.12.2005
Где: Менск, РБ

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



Цитата(RasenHerz @  30.3.2008,  13:02 Найти цитируемый пост)
MAKCim, вы должны знать что именно ф-ция do_mmap() из файла <mm.h>, выделяет новый "участок" линейных адресов(первый желаемый адрес может попробовать указать программист) который по-умолчанию помечается как готовый на ЗАПИСЬ. ЧТЕНИЕ И, самое главное, ИСПОЛНЕНИЕ

это, конечно, хорошо
я с этим и не спорю
но вопрос то был в этом
Цитата(RasenHerz @  30.3.2008,  02:18 Найти цитируемый пост)
ядро не допускает передачу управления в сегмент данных,


Цитата(RasenHerz @  30.3.2008,  13:02 Найти цитируемый пост)
просто осуществить все задуманное легче всего через интерфейсы ядра. 

все зависит от того, что надо получить в итоге


--------------------
Ах, у елі, ах, у ёлкі, ах, у елі злыя волкі ©

PM MAIL   Вверх
RasenHerz
Дата 30.3.2008, 17:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Цитата

это, конечно, хорошо
я с этим и не спорю
но вопрос то был в этом
Цитата

Цитата(RasenHerz @  30.3.2008,  02:18 Найти цитируемый пост)
ядро не допускает передачу управления в сегмент данных,

Цитата

Цитата(RasenHerz @  30.3.2008,  13:02 Найти цитируемый пост)
просто осуществить все задуманное легче всего через интерфейсы ядра. 

все зависит от того, что надо получить в итоге

что-то я не очень понимаю о чем вы говорите. но давайте, попробуем разобраться =):
 1) Вот типичный шелл:
Код

#include <stdio.h>

typedef int (*FUNC)();

int main(int argc, char **argv){
  char data_segment[10] = {0x55, 0x89, 0xe5, 0xb8, 0x1,
                           0x0, 0x0, 0x0, 0x5d, 0xc3 }; // ф-ция возвратит "1"
  printf("%i\n", ((FUNC)data_segment)()); //убедимся в этом =)))
  return 0;
}

с тем, что ядро такие штуки не допускает я, конечно, загнул, т.к. являюсь ярым противником таких садистических увлечений =), но согласитесь, запуск шелла из собственного стека(!!!) это уже чересчур...
не проще ли нормално "попросить" ядро выделить адреса для кода???
 2) Я все же жду от автора топика исходный код... =)
PM MAIL   Вверх
MAKCim
Дата 30.3.2008, 19:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Воін дZэна
****


Профиль
Группа: Экс. модератор
Сообщений: 5644
Регистрация: 10.12.2005
Где: Менск, РБ

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



RasenHerz
я не понимаю, к чему ваш последний пост 
причем здесь стек...


--------------------
Ах, у елі, ах, у ёлкі, ах, у елі злыя волкі ©

PM MAIL   Вверх
bsa
Дата 30.3.2008, 23:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 9185
Регистрация: 6.4.2006
Где: Москва, Россия

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



Цитата(MAKCim @ 30.3.2008,  19:52)
RasenHerz
я не понимаю, к чему ваш последний пост 
причем здесь стек...

"Чукча не читатель - чукча писатель" smile 
PM   Вверх
RasenHerz
Дата 31.3.2008, 17:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Цитата

Как выделить память чтобы были права на EXECUTE?

<...> именно ф-ция do_mmap() из файла <mm.h>, выделяет новый "участок" линейных адресов(первый желаемый адрес может попробовать указать программист) который по-умолчанию помечается как готовый на ЗАПИСЬ. ЧТЕНИЕ И, самое главное, ИСПОЛНЕНИЕ. думаю, самое то будет разместить шелл-код именно там =), чем сидеть и извращаться с инлайн-ассемблером ;).
Цитата

ядро не допускает передачу управления в сегмент данных,

с тем, что ядро такие штуки не допускает я, конечно, загнул,<...>
Цитата

Выделяю память с помошью malloc, вписываю туда бинарный код из исполняемого файла, а потом ссылаюсь на эту память с помошью указателя на функцию и вызываю. Происходит Segmentation Fault,

Вот типичный шелл:

Код

#include <stdio.h>
typedef int (*FUNC)();
int main(int argc, char **argv){
  char data_segment[10] = {0x55, 0x89, 0xe5, 0xb8, 0x1,
                           0x0, 0x0, 0x0, 0x5d, 0xc3 }; // ф-ция возвратит "1"
  printf("%i\n", ((FUNC)data_segment)()); //убедимся в этом =)))
  return 0;
}

ничего не стоит переделать этот код для размещения шела в куче.
Цитата

я не понимаю, к чему ваш последний пост 
причем здесь стек...

теперь все всем понятно? могу для особо одаренных объяснить более подробно....
PM MAIL   Вверх
MAKCim
Дата 31.3.2008, 17:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Воін дZэна
****


Профиль
Группа: Экс. модератор
Сообщений: 5644
Регистрация: 10.12.2005
Где: Менск, РБ

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



Цитата(RasenHerz @  31.3.2008,  17:50 Найти цитируемый пост)
ничего не стоит переделать этот код для размещения шела в куче.

товарищ jeka23 использует malloc() (-> mmap()/brk() -> |kernel| -> do_mmap()) 
т. е heap
Цитата(RasenHerz @  31.3.2008,  17:50 Найти цитируемый пост)
теперь все всем понятно? могу для особо одаренных объяснить более подробно.... 

не понятно  smile 


--------------------
Ах, у елі, ах, у ёлкі, ах, у елі злыя волкі ©

PM MAIL   Вверх
RasenHerz
Дата 31.3.2008, 18:41 (ссылка)    | (голосов:2) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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




Модератор: Сообщение скрыто.

PM MAIL   Вверх
MAKCim
Дата 31.3.2008, 21:04 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Воін дZэна
****


Профиль
Группа: Экс. модератор
Сообщений: 5644
Регистрация: 10.12.2005
Где: Менск, РБ

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



RasenHerz

 ! 
MAKCim
Модератор: В следующий раз будет бан!



--------------------
Ах, у елі, ах, у ёлкі, ах, у елі злыя волкі ©

PM MAIL   Вверх
RasenHerz
Дата 1.4.2008, 12:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



за что предупреждение??? по-моему я никого не оскорбил...
PM MAIL   Вверх
jeka23
Дата 1.4.2008, 21:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



И сново здравствуйте.

Уведомление на почту не работает почему-то, поэтому я и не предпологал, что мне люди отозвались, за что огромное Вам спасибо.

И в правду, MAKCim прав - ядро здесь не причем, загрузчик пишется на пользовательском уровне. Большое спасибо за список литературы, я эти книжки с удовольствием читал уже, но вот  до практики написания модулей никак не смог дойти, устройство ядра было просто интересно. И ассмом я немного владею, но не на профи уровне. Слаб я еще в таких вопросах как собственный загрузчик, но доделать работу очень надо, поэтому и обратился, прошу помочь.

Народ.... признаю, что не совсем хорошо так, но код в студию никак выложить не могу, если кто из своих увидят - голову оторвут....

Обясню ситуацию чуть подробней:
Есть движок на пользовательском уровне, который переписывается отдельно под разные платформы. К этому движку идут бинарники, не прилинкованы ни к одной функции винды, но собранные под виндой с целью использования их под разными платформами. Я был конечно не прав, что использовал mallocRasenHerz прав. Заменил на 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++ компилятором..... Может кто-нить подсказать как это делается?

Еще раз извиняюсь, что не имею права давать код! smile 


PM MAIL   Вверх
MAKCim
Дата 1.4.2008, 22:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Воін дZэна
****


Профиль
Группа: Экс. модератор
Сообщений: 5644
Регистрация: 10.12.2005
Где: Менск, РБ

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



Цитата(jeka23 @  1.4.2008,  21:46 Найти цитируемый пост)
но никак не могу найти как это сделать с g++ компилятором..... Может кто-нить подсказать как это делается?

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



--------------------
Ах, у елі, ах, у ёлкі, ах, у елі злыя волкі ©

PM MAIL   Вверх
jeka23
Дата 1.4.2008, 22:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Цитата

нужно использовать mmap() с ненулевым первым параметром
если mmap() возвращает ошибку, значит данный участок линейного адресного пространства использовать нельзя


Я так и делаю: первый параметр mmap - желаемый адрес проецирования бинарника, который я извликаю из самого бинарника. Он железно жашит в бинарнике как 0x33310000, но память в отладчике сразу помечается как out of bounds
В таком же "движке" под винду просто используется желаемый адрес проецирования самого "движка" под адресом 0x33300000, и соответственно бинарник может проецироваться в память рядом с "движком" по адресу 0x33310000. В моем "движке" под линукс нужно просто задать базовый адрес проецирования в виде 0x33300000 и по логике все должно заработать, но только как его задать.... Компилятор тут конечно не причем, таие вещи задаются линковщику, но как... не могу в инете ничег накопать smile 

Цитата

такой вопрос, создавать новый процесс можно? или все надо делать в контексте текущего?


создавать процесс можно, но это получится крайне не красивое решение так как в бинарнике хранятся множество функций, которые нужно вызывать в разных участках "движка", и каждый раз для этого создавать процесс ну никак не будет красиво выглядеть..



PM MAIL   Вверх
RasenHerz
Дата 1.4.2008, 22:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



так вы пишите загрузчик для *.exe файлов? посмотрите сорцы Wine. думаю обычным копированием шелла вы не обойдетесь - между принципиальная разница - разница между сегментацией в Linux и Windows просто огромна. все будет гораздо сложнее если в шелле будет вызываться какой-либо метод, придется очень многое исправлять.... но если вы дадите мне таблицу соответствия ассемблерных команд их hex значению (извините за безграмотность) - к примеру, ret - 0xc3 и т.д., то я возможно чем то смогу вам помочь. и пожалуйста, выложите проблемный кусок кода здесь... я все-таки не телепат... smile 
PM MAIL   Вверх
jeka23
Дата 1.4.2008, 23:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Я очень благодарен Вам за желание помочь.

Загрузчик я не пишу, он уже написан другим человеком, с которым компания потеряла связь. Все что мне нужно сделать - это воспользоваться им из "движка" чтобы подгрузить бинарники и вызвать функции этих бинарников так же в "движке" (понимаю, что уже тошнит от слова "движок", но стараюсь изясняться яснее smile ).

И так:

функция для выделения памяти под бинарник ПОКА выглядет так:

Цитата

virtual void* alloc_pagealign(void* Address, SIZE_T cb)
    {
  int fd2 = open("/tmp/mmaptest2",
    (O_CREAT | O_TRUNC | O_RDWR),
    (S_IRWXU | S_IRWXG | S_IRWXO) );
  Address = mmap(Address, cb, PROT_READ|PROT_WRITE|PROT_EXEC, MAP_PRIVATE, fd2, 0);
  return Address;
    }


в самом загрузчике память под бинарник выделяется так:

Цитата

LPBYTE hmod = (LPBYTE)alloc_pagealign((LPVOID)(DWORD_PTR)
  inth.OptionalHeader.ImageBase, ImageSize);


я продефайнил все майкросовские типы, например DWORD, руководитель проекта так попросил.

Функции загрузчика по распатрашению PE заголовков думаю выкладывать нет смысла, они роли не сыграют, к тому же в дебагире 20 раз проверенно - работает четко. OptionalHeader.ImageBase как Вы понимаете - базовый адрес проецирования бинарника, который был вытащен загрузчиком из PE заголовка самого бинарника, и постоянно раввен 0x33310000.

Но вот и тут-то пока все падает с SIGBUS так как только в выделеную память с помошью mmap происходит запись с помошью memcpy - все валицо smile 

Цитата

но если вы дадите мне таблицу соответствия ассемблерных команд их hex значению (извините за безграмотность) - к примеру, ret - 0xc3 и т.д., то я возможно чем то смогу вам помочь


с удовольствием дам, только не могу понять о чем Вы smile , обясните что делать - выложу.



Вообще проблем вроде не должно быть в данной задаче, так как бинарники написаны кросплатформенно и любая ф-ия типа strcpy переписана в самом бинарнике чтобы не ссылаться ни на одну библиотеку винды.

В дальнейшем мне нужно с помошью функции загрузчика GetProcAddr вытащить какую-нибудь функцию из загруженого бинаоника и вызвать ее, как например тут:

Цитата

void (CDECL* SetNameInfo)(naming_info*) = 
    (void (CDECL* )(naming_info*))GetProcAddr(hmod, 114);

  if(!SetNameInfo)
  {
    //error
  } 

  SetNameInfo(&m_bases.ni);


и когда я использовал malloc, то бинарник грузился нормально и на строке кода SetNameInfo(&m_bases.ni); я сравнивал ассемблерский код, нахдящийся по адресу SetNameInfo в отладчике под линуксом и под виндой в аналогичном "движке" - код абсалютно одинаков, кроме смещений, которые заменяет сам загрузчик. Загрузчик работает правильно. Просто при использовании malloc все падало с Sigmentation fault так как malloc не дает права на запуск в памяти, да и использовать malloc нельзя так как загрузчик четко указывает желаемые адреса проецирования, а в malloc такой возможности нет.

Если чего не понятно - с прашивайте, с удовольствием обясню, и еще раз спасибо.
PM MAIL   Вверх
MAKCim
Дата 2.4.2008, 09:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Воін дZэна
****


Профиль
Группа: Экс. модератор
Сообщений: 5644
Регистрация: 10.12.2005
Где: Менск, РБ

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



Цитата(jeka23 @  1.4.2008,  22:49 Найти цитируемый пост)
создавать процесс можно, но это получится крайне не красивое решение так как в бинарнике хранятся множество функций, которые нужно вызывать в разных участках "движка", и каждый раз для этого создавать процесс ну никак не будет красиво выглядеть..

зачем?
фишка в том, что можно создать фиктивный исполняемый файл, который будет отображаться через sys_execve как раз чуть ниже 0x33310000 (адрес указывается)
код, отображенный ниже 0x33310000, будет отображать любой образ по адресам >= 0x33310000


--------------------
Ах, у елі, ах, у ёлкі, ах, у елі злыя волкі ©

PM MAIL   Вверх
xvr
Дата 2.4.2008, 12:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

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



Цитата(jeka23 @ 1.4.2008,  23:55)
И так:

функция для выделения памяти под бинарник ПОКА выглядет так:

Цитата

virtual void* alloc_pagealign(void* Address, SIZE_T cb)
    {
  int fd2 = open("/tmp/mmaptest2",
    (O_CREAT | O_TRUNC | O_RDWR),
    (S_IRWXU | S_IRWXG | S_IRWXO) );
  Address = mmap(Address, cb, PROT_READ|PROT_WRITE|PROT_EXEC, MAP_PRIVATE, fd2, 0);
  return Address;
    }


в самом загрузчике память под бинарник выделяется так:

Цитата

LPBYTE hmod = (LPBYTE)alloc_pagealign((LPVOID)(DWORD_PTR)
  inth.OptionalHeader.ImageBase, ImageSize);


я продефайнил все майкросовские типы, например DWORD, руководитель проекта так попросил.

Функции загрузчика по распатрашению PE заголовков думаю выкладывать нет смысла, они роли не сыграют, к тому же в дебагире 20 раз проверенно - работает четко. OptionalHeader.ImageBase как Вы понимаете - базовый адрес проецирования бинарника, который был вытащен загрузчиком из PE заголовка самого бинарника, и постоянно раввен 0x33310000.

Но вот и тут-то пока все падает с SIGBUS так как только в выделеную память с помошью mmap происходит запись с помошью memcpy - все валицо smile 

А зачем выделять память через mmap? Мэпируйте сразу ваш файл (PE) на нужные адреса.
PM MAIL   Вверх
jeka23
Дата 2.4.2008, 12:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Нашел наконец как задать желаемый адрес проецирования, только не могу понять почему ругается:

Код

g++ -g -O -c test.cpp
ld -image-base 0x33300000 test.o
g++ -g -o myapp test.o

ld: bad -rpath option


Кто-нибудь знает как успокоить линковщик? Немогу вообще понять зачем ему rpath если LD_RUN_PATH переменная используется....

Добавлено через 5 минут и 52 секунды
Цитата

А зачем выделять память через mmap? Мэпируйте сразу ваш файл (PE) на нужные адреса. 


Так оно по любому так и получается: alloc_pagealign выделяет память под PE, а потом туда через memcpy заливается сам бинарник. Просто "на нужные адреса" не получается получить память из за того, что мой "движок" не спроецирован на нужные мне адреса, вот и спрашиваю у народа:

Цитата

Нашел наконец как задать желаемый адрес проецирования, только не могу понять почему ругается:

Выделить всёкод C++

g++ -g -O -c test.cpp
ld -image-base 0x33300000 test.o
g++ -g -o myapp test.o
ld: bad -rpath option


Кто-нибудь знает как успокоить линковщик? Немогу вообще понять зачем ему rpath если LD_RUN_PATH переменная используется.... 

PM MAIL   Вверх
jeka23
Дата 2.4.2008, 14:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



....не могу понять, почему вот такой код валится с сигналом SIGBUS:

Код

#include <errno.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/mman.h>
#include <string.h>

int main()
{
    int fd2 = open("/tmp/q",O_RDWR,0);

    printf("fd: %d\n",fd2);
    void* Address = mmap(0, 100, PROT_READ|PROT_WRITE|PROT_EXEC, MAP_PRIVATE, fd2, 0);
    
    printf("addr: %d\n",Address);

    char *s=new char[100];
    memcpy(Address,s,30);

    return 0;
}


Почему я не могу писать в Address?
PM MAIL   Вверх
MAKCim
Дата 2.4.2008, 16:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Воін дZэна
****


Профиль
Группа: Экс. модератор
Сообщений: 5644
Регистрация: 10.12.2005
Где: Менск, РБ

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



jeka23,
Цитата(jeka23 @  2.4.2008,  14:38 Найти цитируемый пост)
Почему я не могу писать в Address? 

mmap() точно не возвращает значение MAP_FAILED?
errno равна нулю после mmap()?

ход решения такой
1. формируем специальный исполняемый файл, который будет отображать PE по нужному адресу (0x33310000) через mmap()
сам исполняемый файл будет создан таким образом, что ядро будет отображать его по адресу X < 0x33310000 так, что значение 0x33310000 - X будет равно его размеру
2. пишем загрузчик
загрузчик порождает новый процесс, в контексте нового процесса выполняем
execve(), перадавая в качестве параметра путь к отображаемому PE

если хочешь, могу вечером сделать такой файл, это несложно


--------------------
Ах, у елі, ах, у ёлкі, ах, у елі злыя волкі ©

PM MAIL   Вверх
jeka23
Дата 2.4.2008, 17:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



MAKCim, очень благодарен, mmap сработал, просто q был нулевого размера, поэтому и валилось. Пока продвигаюсь дальше, вскоре отпишусь и разясню ситуацию, думаю можно будет обойтись без другого процесса..
PM MAIL   Вверх
jeka23
Дата 2.4.2008, 18:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Уважаемые программеры, в последний раз благодарю вас всех за уделенное мне время smile 
Загрузчик заработал, нужно было просто правильно воспользоваться mmap и не важно какие адреса используются, смешно и стыдно smile 

Помечаю пост как "решенный", удачи Вам и еще раз спасибо.



P.S.: Будущее за linux-ом и Россией, так как и то и другое было основано на идее.
PM MAIL   Вверх
Страницы: (2) [Все] 1 2 
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С/С++: Программирование под Unix/Linux"
xvr
  • Проставьте несколько ключевых слов темы, чтобы её можно было легче найти.
  • Не забывайте пользоваться кнопкой "Код".
  • Вопросы мобильной разработки тут
  • Телепатов на форуме нет! Задавайте чёткий, конкретный и полный вопрос. Указывайте полностью ошибки компилятора и компоновщика.
  • Новое сообщение должно иметь прямое отношение к разделу форума. Флуд, флейм, оффтопик запрещены.
  • Категорически запрещается обсуждение вареза, "кряков", взлома программ и т.д.

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

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


 




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


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

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