2014-01-20 2 views
-2

Я хотел бы найти адрес в файле .so переменной. Я не знаю названия if, я знаю только, что это целое число, и я знаю его значение. Я также знаю, что после того, как библиотека загружена и связана динамическим компоновщиком, адрес в памяти равен 0x6416A0 относительно адреса библиотеки. Это смещение больше размера самой динамической библиотеки. У меня есть только двоичная, скомпилированная версия библиотеки.Поиск адреса переменной в общей библиотеке

Чтобы найти адрес переменной в файле .so я смотрел на него с помощью objdump:

$ objdump -x /path/to/lib.so 
Program Header: 
LOAD off 0x0000000000000000 vaddr 0x0000000000000000 paddr 0x0000000000000000 align 2**21 
    filesz 0x0000000000505fa9 memsz 0x0000000000505fa9 flags r-x 
LOAD off 0x0000000000506000 vaddr 0x0000000000706000 paddr 0x0000000000706000 align 2**21 
    filesz 0x00000000000db8f0 memsz 0x00000000001764c0 flags rw- 
DYNAMIC off 0x00000000005210b0 vaddr 0x00000000007210b0 paddr 0x00000000007210b0 align 2**3 
    filesz 0x00000000000003e0 memsz 0x00000000000003e0 flags rw- 
EH_FRAME off 0x0000000000476898 vaddr 0x0000000000476898 paddr 0x0000000000476898 align 2**2 
    filesz 0x0000000000014674 memsz 0x0000000000014674 flags r-- 
STACK off 0x0000000000000000 vaddr 0x0000000000000000 paddr 0x0000000000000000 align 2**3 
    filesz 0x0000000000000000 memsz 0x0000000000000000 flags rw- 
[...] 

Выше я только показал Program Header, но адрес я ищу не в любом диапазоне адресов доступные разделы. Как вы видите, используемые адреса имеют размер 0x7210b0, но мой адрес не входит ни в один из диапазонов, которые я вижу.

Поскольку компоновщик использует mmap для загрузки содержимого файла .so, я предположил, что знание смещения в памяти эквивалентно знанию смещения в файле. Видимо, это неправильно. Может ли кто-нибудь помочь мне понять, как это работает? Есть ли простой способ сопоставить адрес памяти на адрес файла?

+0

Если вы даже не знаете, что называется переменной, тогда у вас будет небольшая работа по ее поиску. Это вроде как сказать: «Есть эта вещь, и я хочу ее найти. Она красная, но я не знаю, как она называется. Можете ли вы помочь мне найти ее?». Во всей серьезности, не можете ли вы просто построить и связать библиотеку с настройками? Почему вы все равно хотите найти, где это находится в библиотеке? –

+0

Может быть, 'nm' может помочь. – pentadecagon

+0

@ Phil_12d3 Конечно, я не могу построить и связать его - некоторые библиотеки входят в двоичную. Вопрос не в поиске _something red_: я знаю адрес переменной после связывания в памяти. То, что я не знаю, - это то, как компоновщик фактически загружает библиотеку, и на какую физическую часть файла входит карта адреса. – angainor

ответ

1

Если вы на системе Linux с GNU libc, и если переменная является известным именем в динамической таблице символов некоторого dynamically linked библиотеки, т.е. ELF общий объект, и если вы можете изменить код основной программы (или какой-либо общий объект, динамически связанный с ним, возможно, играя LD_PRELOAD трюки), вы можете использовать функцию dladdr(3) (с учетом указателя dladdr предоставляет структуру Dl_info с символом и именами общих объектов рядом с заданным указателем).

Поскольку динамически связанные библиотеки общих объектов часто являются mmap(2) -ed на не предсказуемых адресах (например, из-за ASLR), вам нужно сделать это во время выполнения. (См. Также /proc/self/maps из вашего процесса; прочитайте proc(5) и т. Д.)

Прочитано Drepper's paper: How to write Shared Libraries; быть в курсе VDSO ...

Обратите внимание, что данный *.so файл имеет несколько mmap -ED сегментов, и что некоторые из его данных (файл) неmmap -ed! Используйте pmap(1), чтобы узнать.

+0

Спасибо. К сожалению, я не знаю имя переменной. Тем не менее, ваш ответ и комментарий @ninjalj позволили мне решить проблему. В '/ proc/self/maps' я вижу, что библиотека mmaped несколько раз, с другим смещением в .so-файл. Один из диапазонов виртуальных адресов, перечисленных там, содержал адрес переменной, который я искал, и поэтому мне удалось найти соответствующий адрес в .so-файле. Brilliant! Благодарю. – angainor

+0

Вам не нужно знать имя переменной. 'dladdr' найдет его. Вы обязательно должны прочитать (длинную) бумагу Дреппера! –

+0

Верно, я вижу это сейчас. Но в моем случае переменная, кажется, не экспортируется (local?). Я буду играть снова с 'dladdr', но так как теперь я знаю адрес файла, я вижу, что он не указан рядом с любым экспортированным символом, показанным' objdump -T'. Поэтому я думаю, что 'dladdr' также не найдет его. Я прав? – angainor

Смежные вопросы