Запуск неэкспонированных .dll функций с python - PullRequest
5 голосов
/ 07 января 2009

Это может показаться странным вопросом, но я хотел бы знать, как я могу запустить функцию в .dll из «сигнатуры» памяти. Я не очень понимаю, как это работает на самом деле, но мне это очень нужно. Это способ запуска неэкспортированных функций из .dll, если вы знаете сигнатуру и адрес памяти. Например, у меня есть эти:

respawn_f "_ZN9CCSPlayer12RoundRespawnEv"
respawn_sig "568BF18B06FF90B80400008B86E80D00"
respawn_mask "xxxxx?xxx??xxxx?"

И, используя довольно изящный код C ++, вы можете использовать его для запуска функций из .dll.

Вот хорошо объясненная статья об этом: http://wiki.alliedmods.net/Signature_Scanning

Итак, возможно ли использовать Ctypes или любой другой способ сделать это внутри python?

Ответы [ 2 ]

2 голосов
/ 10 января 2009

Если вы уже можете запускать их с помощью C ++, тогда вы можете попробовать использовать SWIG для генерации оболочек Python для написанного вами кода C ++, что делает его вызываемым из python.

http://www.swig.org/

Некоторые предупреждения, которые я нашел с помощью SWIG:

Swig ищет типы на основе строкового значения. Например целочисленный тип в Python (int) будет выглядеть, чтобы убедиться, что тип cpp "int", иначе swig будет жаловаться о несоответствиях типов. Там нет автоматического преобразования.

Swig дословно копирует исходный код, поэтому даже объекты в одном и том же пространстве имен потребуется полная квалификация, чтобы файл cxx правильно компилировался.

Надеюсь, это поможет.

0 голосов
/ 27 января 2009

Вы сказали, что пытаетесь вызвать функцию, которая не была экспортирована; насколько я знаю, это невозможно из Python. Однако ваша проблема, похоже, заключается в том, что название искажено.

Вы можете вызвать произвольный экспорт, используя ctypes. Поскольку имя искажено и не является допустимым идентификатором Python, вы можете использовать getattr ().

Другой подход, если у вас есть правильная информация, - это найти экспорт по порядковому номеру, что вам нужно сделать, если имя не было экспортировано вообще. Одним из способов получения порядкового номера будет использование dumpbin.exe, включенного во многие скомпилированные языки Windows. На самом деле это внешний интерфейс компоновщика, поэтому, если у вас есть MS LinK.exe, вы также можете использовать его с соответствующими переключателями командной строки.

Чтобы получить ссылку на функцию (которая является объектом «указатель на функцию», связанный с ее адресом), вы можете использовать что-то вроде:

импортные типы func = getattr (ctypes.windll.msvcrt, "@@ myfunc") retval = func (нет)

Естественно, вы бы заменили 'msvcrt' на dll, которую вы специально хотите вызвать.

Что я здесь не показываю, так это то, как разобрать имя, чтобы получить вызывающую подпись, и, следовательно, необходимые аргументы. Для этого потребуется demangler, и он очень специфичен для марки AND VERSION компилятора C ++, используемого для создания DLL.

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

...