The OpenNET Project / Index page

[ новости /+++ | форум | wiki | теги | ]

форумы  помощь  поиск  регистрация  майллист  ВХОД  слежка  RSS
"Как получить адрес программы в оперативной памяти?"
Вариант для распечатки Архивированная нить - только для чтения! 
Пред. тема | След. тема 
Форумы Программирование под UNIX (Public)
Изначальное сообщение [Проследить за развитием треда]

"Как получить адрес программы в оперативной памяти?"
Сообщение от retro emailИскать по авторуВ закладки on 21-Май-03, 14:46  (MSK)
Подскажите, пжста, как можно получить адрес текущий программы, написанной на си (адрес исполняемого файла)?
  Рекомендовать в FAQ | Cообщить модератору | Наверх

 Оглавление

Индекс форумов | Темы | Пред. тема | След. тема
Сообщения по теме

1. "Как получить адрес программы в оперативной памяти?"
Сообщение от Olej emailИскать по авторуВ закладки on 21-Май-03, 15:56  (MSK)
>Подскажите, пжста, как можно получить адрес текущий программы, написанной на си (адрес исполняемого файла)?

Не очень понятен вопрос... Но, скорее всего - ответ такой: "никак"!
От OS зависит, но если это 32-бит многозадачная OS в виртуализацией и т.д. ... то все программы будут начинаться с одного и того-же стартового адреса. Это если говорить об логических адресах.

А если об физических (адрес в чипе RAM) то тут совсем ... приехали.
Адрес "начала" может быть, напр. 0хсссссс (кстати, адрес "конца" - вполне может быть 0хbbbb00), но, пока мы это определили ... он уже стал 0x00aaaa! И это даже если образ программы "невыгружаемый", т.е. без виртуализации через диск.

  Рекомендовать в FAQ | Cообщить модератору | Наверх

2. "Как получить адрес программы в оперативной памяти?"
Сообщение от retro emailИскать по авторуВ закладки on 21-Май-03, 16:54  (MSK)
>>Подскажите, пжста, как можно получить адрес текущий программы, написанной на си (адрес исполняемого файла)?
>
>Не очень понятен вопрос... Но, скорее всего - ответ такой: "никак"!
>От OS зависит, но если это 32-бит многозадачная OS в виртуализацией и
>т.д. ... то все программы будут начинаться с одного и того-же
>стартового адреса. Это если говорить об логических адресах.
>
>А если об физических (адрес в чипе RAM) то тут совсем ...
>приехали.
>Адрес "начала" может быть, напр. 0хсссссс (кстати, адрес "конца" - вполне может
>быть 0хbbbb00), но, пока мы это определили ... он уже стал
>0x00aaaa! И это даже если образ программы "невыгружаемый", т.е. без виртуализации
>через диск.
Требуется определить физический адрес первого байта программы в ОП;
скажем что-то, типа:

mian()
{
printf("%d",main);
}


  Рекомендовать в FAQ | Cообщить модератору | Наверх

3. "Как получить адрес программы в оперативной памяти?"
Сообщение от Olej emailИскать по авторуВ закладки on 21-Май-03, 17:54  (MSK)
>Требуется определить физический адрес первого байта программы в ОП;
>скажем что-то, типа:
>
>mian()
>{
>printf("%d",main);
>}

Ещё раз:
Что значит физический адрес в ОП, именно физический адрес в RAM? К тому времени, пока вы его определите - он уже может быть другим...

И что значит первого байта программы? Адрес main?:

void main() {
  printf ( "%X", &main );
};

Или адрес 1-й выполняемой инструкции кода - инициализация среды, static переменных... ведь достаточно много выполняется до main()... Или адрес адрес образа задачи, отображённого на RAM из ELF-формата файла?... И какая конкретно OS - каждая имеет свои соглашения о начальных адресах загрузки.

И это всё будут только логические адреса, для преобразования их в физические .... ой-ой-ой:
- будучи root вы должны получить превилегированный режим - кольца защиты 0;
- от регистра страниц процессора - двигаться по цепочке от LDT ... выполнить всю реконструкцию преобразования адресных страниц...

Что это может дать? Может проще сформулировать конечную проблему, которую нужно решить таким загадочным способом?

  Рекомендовать в FAQ | Cообщить модератору | Наверх

4. "Как получить адрес программы в оперативной памяти?"
Сообщение от Bob emailИскать по авторуВ закладки on 31-Май-03, 22:19  (MSK)
>Требуется определить физический адрес первого байта программы в ОП;
>скажем что-то, типа:
>
>mian()
>{
>printf("%d",main);
>}


Чтобы найти адрес функции main, проанализируем заголовок исполняемого файла формата ELF32. Структура заголовка находится в файле <linux/elf.h>. Поле e_entry структуры struct elf32_hdr содержит стартовый адрес программы. Найти его можно следующим способом:


#include <stdio.h>
#include <linux/elf.h>
#include <fcntl.h>

int main (int argc, char **argv)
{
int fd, kmem;
unsigned long addr = 0; - здесь мы сохраним адрес main
struct elf32_hdr ehdr;

memset(&ehdr, 0, sizeof(struct elf32_hdr));

Откроем исполняемый файл и прочитаем заголовок:

fd=open(argv[0], O_RDONLY);
read(fd, (char *)&ehdr, sizeof(struct elf32_hdr));
close(fd);

Отобразим стартовый адрес программы:
printf("start\t-\t0xx\n", ehdr.e_entry);

Итак, стартовый адрес у нас есть.
Адрес main находится по смещению 24 байта относительно стартового адреса (ниже рассмотрено, почему это так). Воспользуемся файлом /dev/kmem, в котором отображено все виртуальное адресное пространство. Любой адрес задается как смещение в этом файле:

kmem=open("/dev/kmem", O_RDONLY);
lseek(kmem, ehdr.e_entry+24, 0);
read(kmem, (char *)&addr, 4);
close(kmem);

Адрес функции main:
printf("main\t-\t0xx\n",addr);

return 0;
}


Дизассемблируем исполняемый файл при помощи objdump и найдем стартовый адрес. По этому адресу будет расположена секция <_start>. Рассмотрев ассемблерный листинг, мы увидим, что сначала в стек загружаются параметры, а затем следует вызов библиотечной функции __libc_start_main (call <адрес><_init+0x48>). Первым параметром этой функции является адрес main. Этот параметр загружается в стек последним. Адрес main находится по смещению 24 байт относительно стартового адреса.

  Рекомендовать в FAQ | Cообщить модератору | Наверх

5. "Как получить адрес программы в оперативной памяти?"
Сообщение от Bob Искать по авторуВ закладки on 02-Июн-03, 09:59  (MSK)
>Cтартовый адрес программы:
> printf("start\t-\t0xx\n", ehdr.e_entry);

printf("start\t-\t0xx\n", ehdr.e_entry);

>Адрес функции main:
> printf("main\t-\t0xx\n",addr);

printf("main\t-\t0xx\n",addr);

  Рекомендовать в FAQ | Cообщить модератору | Наверх

6. "Как получить адрес программы в оперативной памяти?"
Сообщение от Olej emailИскать по авторуВ закладки on 02-Июн-03, 14:32  (MSK)
>>Cтартовый адрес программы:
>> printf("start\t-\t0xx\n", ehdr.e_entry);
>
>printf("start\t-\t0xx\n", ehdr.e_entry);
>
>>Адрес функции main:
>> printf("main\t-\t0xx\n",addr);
>
>printf("main\t-\t0xx\n",addr);

Всё это, наверное, правильно, за исключением:

1. мало значимо: что это сделано reverse engeniging-ом, т.е. будет работать в Linux - этой версии (но может измениться в следующих), и может не работать в других UNIX-клонах, даже использующих elf-формат...

2. что гораздо важнее: это всё будут - логические адреса, которые проходят ещё одну ступень перетрансляции в физические адреса (о которых и спрашивали в вопросе).

  Рекомендовать в FAQ | Cообщить модератору | Наверх

7. "Как получить адрес программы в оперативной памяти?"
Сообщение от Bob emailИскать по авторуВ закладки on 02-Июн-03, 15:39  (MSK)
>
>Всё это, наверное, правильно, за исключением:
>
>1. мало значимо: что это сделано reverse engeniging-ом, т.е. будет работать в
>Linux - этой версии (но может измениться в следующих), и может
>не работать в других UNIX-клонах, даже использующих elf-формат...
>

Работает с ядрами 2.2.16, 2.4.17, 2.4.20, компилятор gcc-2.95.3.
Насчет других клонов - возможно, работать не будет, я не проверял. Если не ошибаюсь, в вопросе платформа не указана.

>2. что гораздо важнее: это всё будут - логические адреса, которые проходят
>ещё одну ступень перетрансляции в физические адреса (о которых и спрашивали
>в вопросе).

Все таки интересно, почему не устроит виртуальный адрес. Какая изначально задача ставилась перед автором вопроса? Если б это знать - можно было бы выйти и на физический адрес. Ну ладно, чем мог - помог.

P.S. Кстати, знак процента не отображается, почему то..

  Рекомендовать в FAQ | Cообщить модератору | Наверх


Удалить

Индекс форумов | Темы | Пред. тема | След. тема
Пожалуйста, прежде чем написать сообщение, ознакомьтесь с данными рекомендациями.




Спонсоры:
PostgresPro
Inferno Solutions
Hosting by Hoster.ru
Хостинг:

Закладки на сайте
Проследить за страницей
Created 1996-2022 by Maxim Chirkov
Добавить, Поддержать, Вебмастеру