Какое смещение ctypes._FuncPtr принимает в качестве входных данных? - PullRequest
1 голос
/ 17 марта 2020

Я загружаю динамическую c библиотеку в python, для простоты, скажем, glib c:

>>> import ctypes
>>> libc = ctypes.CDLL("libc.so.6") 

Доступ к функциям из этой библиотеки обычно работает путем указания символа, т.е.

>>> libc.system(b"whoami")

Источник этой функции выглядит следующим образом (из /usr/lib/python3.7/ctypes/__init__.py):

366     def __getattr__(self, name):
367         if name.startswith('__') and name.endswith('__'):
368             raise AttributeError(name)
369         func = self.__getitem__(name)
370         setattr(self, name, func)                                                                                                                                                                              
371         return func
372 
373     def __getitem__(self, name_or_ordinal):
374         func = self._FuncPtr((name_or_ordinal, self))
375         if not isinstance(name_or_ordinal, int):
376             func.__name__ = name_or_ordinal
377         return func

Поэтому я подозреваю, что вы также можете указать смещение для вызова функции, то есть что-то вроде этого:

>>> libc[0xabcd](b"foo")

Однако я всегда сталкиваюсь с определенным SEGFAULT при попытке сделать это. Мне было интересно, как я могу получить правильное смещение для функции?

В случае с glib c простой поиск символов и передача их соответствующего адреса, похоже, не работает. Так что я, наверное, что-то упускаю.

1 Ответ

1 голос
/ 17 марта 2020

Не уверен в эквиваленте в Linux, но Windows имеет dumpbin для отображения списка экспорта DLL, и можно использовать порядковый номер экспорта:

C:\Windows\System32>dumpbin /exports msvcrt.dll|findstr system
       1024  3FF 00017DA0 _wsystem
       1249  4E0 00017EC0 system

C:\Windows\System32>py
Python 3.8.1 (tags/v3.8.1:1b293b6, Dec 18 2019, 23:11:46) [MSC v.1916 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> from ctypes import *
>>> crt = CDLL('msvcrt')
>>> crt[1249](b'echo hello')  # by ordinal
hello
0
>>> crt['system'](b'echo hello') # by name
hello
0
...