Почему ctypes также загружает стандартные функции библиотеки C и как я могу это предотвратить?Python

Программы на Python
Anonymous
Почему ctypes также загружает стандартные функции библиотеки C и как я могу это предотвратить?

Сообщение Anonymous »

  • Загрузка самодельной общей библиотеки с помощью ctypes, похоже, каким-то образом обеспечивает доступ к функциям стандартной библиотеки C.
    Почему?
    Я ожидал появления ошибки AttributeError при попытке MRE ниже.
  • Как я мог ограничить такое поведение (если возможно)?
  • [тайбрейкер] : как разрешается имя функции при попытке доступа к ней, и если моя самоделка переопределяет стандартная функция библиотеки C?
Насколько я понимаю из документации, она должна возвращать представление загруженной общей библиотеки. Но похоже, что он ведет себя как нечто большее/иное, чем это.

MRE:

Код: Выделить всё

#!/usr/bin/env python3

import ctypes
import os

my_lib = ctypes.CDLL(os.path.abspath("libfoo.so"))

# I expect this to work (It does).
print(f"{my_lib.foo = }")
# I expect this to fail (It doesn't).
print(f"{my_lib.strncmp = }")
# I expect this to fail (It does).
print(f"{my_lib.bar = }")

Код: Выделить всё

    global foo

foo:
ret
  • сеанс оболочки:

Код: Выделить всё

$ make
nasm -f elf64 -o foo.o foo.s
gcc -shared -o libfoo.so foo.o
$ nm -a libfoo.so
0000000000000000 a
w __cxa_finalize@GLIBC_2.2.5
0000000000004000 d __dso_handle
0000000000003e48 d _DYNAMIC
00000000000010f4 t _fini
00000000000010f0 T foo
0000000000000000 a foo.s
0000000000003fe8 d _GLOBAL_OFFSET_TABLE_
w __gmon_start__
0000000000001000 t _init
w _ITM_deregisterTMCloneTable
w _ITM_registerTMCloneTable
0000000000004008 d __TMC_END__
$ ./test.py
my_lib.foo = 
my_lib.strncmp = 
Traceback (most recent call last):
File "/home/vmonteco/code/MREs/MRE_ctypes_give_access_to_stdlib/./test.py", line 13, in 
print(f"{my_lib.bar = }")
File "/home/vmonteco/.pyenv/versions/3.10.14/lib/python3.10/ctypes/__init__.py", line 387, in __getattr__
func = self.__getitem__(name)
File "/home/vmonteco/.pyenv/versions/3.10.14/lib/python3.10/ctypes/__init__.py", line 392, in __getitem__
func = self._FuncPtr((name_or_ordinal, self))
AttributeError: /home/vmonteco/code/MREs/MRE_ctypes_give_access_to_stdlib/libfoo.so: undefined symbol: bar
$ ldd libfoo.so
linux-vdso.so.1 (0x00007610a363b000)
libc.so.6 =>  /usr/lib/libc.so.6 (0x00007610a341d000)
/usr/lib64/ld-linux-x86-64.so.2 (0x00007610a363d000)
$ readelf -ld libfoo.so

Elf file type is DYN (Shared object file)
Entry point 0x0
There are 8 program headers, starting at offset 64

Program Headers:
Type           Offset             VirtAddr           PhysAddr
FileSiz            MemSiz              Flags  Align
LOAD           0x0000000000000000 0x0000000000000000 0x0000000000000000
0x0000000000000428 0x0000000000000428  R      0x1000
LOAD           0x0000000000001000 0x0000000000001000 0x0000000000001000
0x0000000000000101 0x0000000000000101  R E    0x1000
LOAD           0x0000000000002000 0x0000000000002000 0x0000000000002000
0x0000000000000004 0x0000000000000004  R      0x1000
LOAD           0x0000000000002e38 0x0000000000003e38 0x0000000000003e38
0x00000000000001d0 0x00000000000001d8  RW     0x1000
DYNAMIC        0x0000000000002e48 0x0000000000003e48 0x0000000000003e48
0x0000000000000180 0x0000000000000180  RW     0x8
NOTE           0x0000000000000200 0x0000000000000200 0x0000000000000200
0x0000000000000024 0x0000000000000024  R      0x4
GNU_STACK      0x0000000000000000 0x0000000000000000 0x0000000000000000
0x0000000000000000 0x0000000000000000  RW     0x10
GNU_RELRO      0x0000000000002e38 0x0000000000003e38 0x0000000000003e38
0x00000000000001c8 0x00000000000001c8  R      0x1

Section to Segment mapping:
Segment Sections...
00     .note.gnu.build-id .gnu.hash .dynsym .dynstr .gnu.version .gnu.version_r .rela.dyn
01     .init .text .fini
02     .eh_frame
03     .init_array .fini_array .dynamic .got .got.plt .data .bss
04     .dynamic
05     .note.gnu.build-id
06
07     .init_array .fini_array .dynamic .got .got.plt

Dynamic section at offset 0x2e48 contains 20 entries:
Tag        Type                         Name/Value
0x0000000000000001 (NEEDED)             Shared library: [libc.so.6]
0x000000000000000c (INIT)               0x1000
0x000000000000000d (FINI)               0x10f4
0x0000000000000019 (INIT_ARRAY)         0x3e38
0x000000000000001b (INIT_ARRAYSZ)       8 (bytes)
0x000000000000001a (FINI_ARRAY)         0x3e40
0x000000000000001c (FINI_ARRAYSZ)       8 (bytes)
0x000000006ffffef5 (GNU_HASH)           0x228
0x0000000000000005 (STRTAB)             0x2e0
0x0000000000000006 (SYMTAB)             0x250
0x000000000000000a (STRSZ)              111 (bytes)
0x000000000000000b (SYMENT)             24 (bytes)
0x0000000000000007 (RELA)               0x380
0x0000000000000008 (RELASZ)             168 (bytes)
0x0000000000000009 (RELAENT)            24 (bytes)
0x000000006ffffffe (VERNEED)            0x360
0x000000006fffffff (VERNEEDNUM)         1
0x000000006ffffff0 (VERSYM)             0x350
0x000000006ffffff9 (RELACOUNT)          3
0x0000000000000000 (NULL)               0x0
$
[Дополнение:] Версии и информация о системе:

Подробнее здесь: https://stackoverflow.com/questions/790 ... -prevent-t

Вернуться в «Python»