понимание общих библиотек с помощью gcc - PullRequest
4 голосов
/ 11 октября 2010

Я пытаюсь понять следующее поведение общих библиотек в C

Machine One

$ cat one.c 
#include<stdio.h>

int main() {
    printf ("%d", 45);
}
$ gcc one.c -o one -O3
$ ldd one
    linux-gate.so.1 =>  (0x00331000)
    libc.so.6 => /lib/tls/i686/cmov/libc.so.6 (0x00bc2000)
    /lib/ld-linux.so.2 (0x006dc000)
$ cat two.c 
int main() {
    int i = 0;
}
$ gcc two.c -o two -O3
$ ldd two
    linux-gate.so.1 =>  (0x006f7000)
    libc.so.6 => /lib/tls/i686/cmov/libc.so.6 (0x00110000)
    /lib/ld-linux.so.2 (0x00eb0000)
$

Машина Два

$ cat three.c
#include<stdio.h>

int main() {
    printf ("%d", 45);
}
$ gcc three.c -o three -O3
$ ldd three
    /usr/lib/libcwait.so (0xb7ffd000)
    libc.so.6 => /lib/tls/i686/nosegneg/libc.so.6 (0x002de000)
    /lib/ld-linux.so.2 (0x002bf000)
$

Несколько вещей, которые я не до конца понимаю:

  • Что означает адрес, указанный в скобках (например, (0x002de000))?

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

  • Зачем two вообще нужны какие-либо библиотеки? Я использовал -O3, а вывод на ассемблере

    $ gcc two.c -S -O3 
    $ cat two.s
        .file   "two.c"
        .text
        .p2align 4,,15
    .globl main
        .type   main, @function
    main:
        pushl   %ebp
        movl    %esp, %ebp
        popl    %ebp
        ret
        .size   main, .-main
        .ident  "GCC: (Ubuntu 4.4.3-4ubuntu5) 4.4.3"
        .section    .note.GNU-stack,"",@progbits
    $
    

    Зачем вообще нужны какие-либо библиотеки?

  • На второй машине, почему вместо linux-gate.so.1 используется /usr/lib/libcwait.so?

    Я думаю, это потому, что ядро ​​на Machine Two очень старое (2.6.9), а библиотека linux-gate.so.1 недоступна. Это причина?

Ответы [ 3 ]

5 голосов
/ 11 октября 2010

Что означает адрес, указанный в скобках (например, (0x002de000))?

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

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

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

Зачем двум вообще библиотеки?

libc.so.6 - это стандартная библиотека C (и другие вещи, такие как интерфейс к ядру), и она всегда связана по умолчанию. У gcc есть опции для управления этим, например, -nostdlib флаг

ld-linux.so является динамическим загрузчиком и отвечает за загрузку / перемещение других общих библиотек и запуск вашего приложения. На странице руководства для ld-linux.so вы найдете подробную информацию.

linux-gate.so.1 - это виртуальная библиотека, она существует только в памяти ядра. Он используется для выполнения системных вызовов ядра и определяет наиболее эффективный способ сделать это на основе вашего процессора. Вероятно, он был добавлен в Linux позже, чем ваша другая машина с ядром 2.6.9.

Я не знаю, что такое /usr/lib/libcwait.so, но есть вероятность, что вы можете получить некоторую информацию об этом, выполнив команду rpm -qif /usr/lib/libcwait.so

2 голосов
/ 11 октября 2010

Адреса в основном случайные числа. До разработки безопасных реализаций ldd последовательно указывал бы адреса памяти, куда были загружены программные разделы. Примерно пять лет назад многие разновидности Linux теперь намеренно рандомизируют адреса загрузки, чтобы расстроить потенциальных авторов вирусов и т. Д. Я скомпилировал one.c (как t.c) и неоднократно выполнял ldd:

[wally@zenetfedora .bin]$ cat t.c
#include <stdio.h>
int main()
{
    printf ("%d", 45);
}
[wally@zenetfedora .bin]$ gcc -o t t.c -O3
[wally@zenetfedora .bin]$ ldd t
    linux-gate.so.1 =>  (0x009e5000)
    libc.so.6 => /lib/libc.so.6 (0x002e4000)
    /lib/ld-linux.so.2 (0x002c2000)
[wally@zenetfedora .bin]$ ldd t
    linux-gate.so.1 =>  (0x00b8d000)
    libc.so.6 => /lib/libc.so.6 (0x002e4000)
    /lib/ld-linux.so.2 (0x002c2000)
[wally@zenetfedora .bin]$ ldd t
    linux-gate.so.1 =>  (0x00238000)
    libc.so.6 => /lib/libc.so.6 (0x002e4000)
    /lib/ld-linux.so.2 (0x002c2000)
[wally@zenetfedora .bin]$ ldd t
    linux-gate.so.1 =>  (0x002a0000)
    libc.so.6 => /lib/libc.so.6 (0x002e4000)
    /lib/ld-linux.so.2 (0x002c2000)
[wally@zenetfedora .bin]$ ldd t
    linux-gate.so.1 =>  (0x00f93000)
    libc.so.6 => /lib/libc.so.6 (0x002e4000)
    /lib/ld-linux.so.2 (0x002c2000)
[wally@zenetfedora .bin]$ ldd t
    linux-gate.so.1 =>  (0x00c7a000)
    libc.so.6 => /lib/libc.so.6 (0x002e4000)
    /lib/ld-linux.so.2 (0x002c2000)
[wally@zenetfedora .bin]$ ldd t
    linux-gate.so.1 =>  (0x00d1a000)
    libc.so.6 => /lib/libc.so.6 (0x002e4000)
    /lib/ld-linux.so.2 (0x002c2000)
[wally@zenetfedora .bin]$ ldd t
    linux-gate.so.1 =>  (0x00d12000)
    libc.so.6 => /lib/libc.so.6 (0x002e4000)
    /lib/ld-linux.so.2 (0x002c2000)

Адреса загрузки crtl и ld-linux согласованы, но linux-gate рандомизирован.

Библиотеки необходимы, потому что должны запускаться инициализация и завершение C. Конечно, они могут быть в значительной степени оптимизированы, поскольку stdin, stdout, stderr и т. Д. И т. Д. Не требуют инициализации. Тем не менее, crtl - это то, как main() вызывается.

Разные версии и версии Linux имеют различия. Эволюция glib имела много поворотов. Некоторые вещи были перемещены в другие библиотеки. Это почти то же самое, что и то, почему ваш местный продуктовый магазин перемещает вещи. Это не имеет большого значения.

1 голос
/ 11 октября 2010

Число - это адрес памяти, куда загружается библиотека при запуске исполняемого файла.Он определяется во время соединения и обычно рандомизирован, чтобы сделать адреса библиотечных функций непредсказуемыми и, следовательно, более сложными для использования в эксплойтах.Стандартная библиотека C по умолчанию связана GCC.libcwait, вероятно, другая библиотека по умолчанию, возможно, используемая в более старых версиях GCC.

...