LLDB и адреса памяти библиотечных функций - PullRequest
2 голосов
/ 16 февраля 2020

У меня есть программа "Hello World", к которой я подключил lldb. Я пытаюсь ответить на несколько вопросов для себя о результатах, которые я получаю, когда пытаюсь получить адрес библиотечных функций:

(lldb) image lookup -n printf
1 match found in /usr/lib/system/libsystem_c.dylib:
        Address: libsystem_c.dylib[0x000000000003f550] (libsystem_c.dylib.__TEXT.__text + 253892)
        Summary: libsystem_c.dylib`printf
(lldb) image lookup -n scanf
1 match found in /usr/lib/system/libsystem_c.dylib:
        Address: libsystem_c.dylib[0x000000000003fc69] (libsystem_c.dylib.__TEXT.__text + 255709)
        Summary: libsystem_c.dylib`scanf
(lldb) expr &printf
(int (*)(const char *__restrict, ...)) $2 = 0x00007fff6f8c5550 (libsystem_c.dylib`printf)
(lldb) expr &scanf
error: unsupported expression with unknown type

У меня есть три вопроса здесь:

  1. Какой адрес 0x00007fff6f8c5550? Я предполагаю, что это указатель на функцию printf. Это виртуальный адрес, который существует только в отображенном пространстве текущего процесса? Если да, то почему другая программа возвращает тот же адрес для printf?

  2. Если предположить, что это какой-то глобальный общий адрес, который одинаков для всех процессов, это изменило бы содержимое данных в этот адрес (который я пока не смог сделать) создает копию измененной страницы памяти и изменится ли адрес? (Я работаю в операционной системе Ma c и предполагаю, что один процесс не может изменить общую память для другого процесса)

  3. Почему expr &scanf не работает, а expr &printf работает?

1 Ответ

3 голосов
/ 16 февраля 2020
  1. Какой адрес 0x00007fff6f8c5550? Я предполагаю, что это указатель на функцию printf.

Да, это правильно.

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

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

Если да, почему другая программа возвращает тот же адрес для printf?

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

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

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

(я работаю в ОС Ma c, и я предполагаю, что один процесс не может изменить общую память на другой process)

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

Почему expr &scanf не работает, а expr &printf работает?

Ваша программа (предположительно) не использует scanf, поэтому отладочной информации об этом нет. Главное, что отсутствует lldb - это тип scanf. Если вы используете выражение приведения, оно может работать:

(lldb) p scanf
error: 'scanf' has unknown type; cast it to its declared type to use it
(lldb) p &scanf
error: unsupported expression with unknown type
(lldb) p (int(*)(const char * __restrict, ...))scanf
(int (*)(const char *__restrict, ...)) $3 = 0x00007fffd7e958d4 (libsystem_c.dylib`scanf)

И наоборот, оно работает для printf, потому что ваша программа его использует.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...