2009-01-07 3 views
5

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

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

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

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

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

ответ

2

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

http://www.swig.org/

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

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

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

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

0

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

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

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

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

импорт ctypes FUNC = GetAttr (ctypes.windll.msvcrt, "@@ myfunc") retval = func (None)

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

Здесь я не показываю, как развязать имя, чтобы получить вызывающую подпись, и, следовательно, необходимые аргументы. Для этого потребуется деманглер, и они очень специфичны для бренда И ВЕРСИЯ компилятора C++, используемого для создания DLL.

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

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