Динамические библиотеки имеют одинаковый адрес виртуальной памяти во всех программах? - PullRequest
1 голос
/ 25 марта 2019

Когда библиотека динамически связана с программой, имеет ли она тот же адрес в этой программе, что и в любой другой программе?

Когда я себе представляю, каждый процесс получает все адресное пространство, а затем всев этом процессе (в том числе динамические библиотеки, которые уже находятся в памяти) из-за ASLR отображаются на полуслучайные части.

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

Я написал две короткие программы c, которые использовали функцию «сна».В одном я распечатал адрес функции ожидания, а во втором я назначил указатель функции на этот адрес.Я запустил их обоих, и функция сна работала в обоих случаях.

#include <stdio.h>
#include <unistd.h>

int main()
{
    while(1)
    {
        printf("%s\n", &"hi");
        sleep(2);
        printf("pointer to sleep: %p\n", sleep);
    }
}
#include <stdio.h>
#include <unistd.h>

#define sleepagain ((void (*)(int))0x7fff7652e669) //addr of sleep from first program

int main()
{
    while(1)
    {
        printf("%s\n", &"test");
        sleepagain(2);
    }
}

Я не был уверен, что это покажет, но на самом деле это было: а) адрес был один и тот же каждый раз, когда я бегалпервая программа и б) этот сон все еще функционировал, когда я запускал вторую.

Я думаю, я понимаю, как это работает, но мне любопытно, если имеет , чтобы работать так, как работает, и чтопричины этого?

Просто чтобы сослаться на ответ, который я получил, когда посмотрел на otool -IvV, я получил:

a.out:
Indirect symbols for (__TEXT,__stubs) 2 entries
address            index name
0x0000000100000f62     2 _printf
0x0000000100000f68     3 _sleep
Indirect symbols for (__DATA,__nl_symbol_ptr) 2 entries
address            index name
0x0000000100001000     4 dyld_stub_binder
0x0000000100001008 ABSOLUTE
Indirect symbols for (__DATA,__got) 1 entries
address            index name
0x0000000100001010     3 _sleep
Indirect symbols for (__DATA,__la_symbol_ptr) 2 entries
address            index name
0x0000000100001018     2 _printf
0x0000000100001020     3 _sleep

Что также было в косвенном адресеlldb.Адрес был адрес самого сна:

Process 11209 launched: 'stuff/a.out' (x86_64)
hi
Process 11209 stopped
* thread #1, queue = 'com.apple.main-thread', stop reason = breakpoint 1.1
    frame #0: 0x00007fff7652e669 libsystem_c.dylib`sleep
libsystem_c.dylib`sleep:
->  0x7fff7652e669 <+0>: push   rbp
    0x7fff7652e66a <+1>: mov    rbp, rsp
    0x7fff7652e66d <+4>: push   rbx
    0x7fff7652e66e <+5>: sub    rsp, 0x28
Target 0: (a.out) stopped.

Для дополнительной информации:

$ otool -hv a.out
Mach header
      magic cputype cpusubtype  caps    filetype ncmds sizeofcmds      flags
MH_MAGIC_64  X86_64        ALL LIB64     EXECUTE    15       1296   NOUNDEFS DYLDLINK TWOLEVEL PIE

1 Ответ

2 голосов
/ 25 марта 2019

В macOS многие системные библиотеки являются частью общего кеша dyld. Есть картографирование всей машины. Таким образом, эти библиотеки заканчиваются по одному адресу во всех процессах одной и той же архитектуры (32- или 64-разрядной).

Расположение общего кеша dyld рандомизируется при загрузке системы. Таким образом, адреса библиотек будут одинаковыми от процесса к процессу до перезагрузки.

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

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

Попробуйте посмотреть на вывод из vmmap -v <pid>. Найдите строку с «машинной подкартой ВМ» и последующими.

...