2009-01-07 42 views
5

這可能看起來像一個奇怪的問題,但我想知道如何從內存「簽名」中運行.dll中的函數。我不太瞭解它是如何實際工作的,但我非常需要它。它是一種在.dll中運行未導出函數的方法,如果你知道它的內存簽名和地址。 例如,我有這些:使用python運行未導出的.dll函數

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

而且使用一些非常漂亮的C++代碼,你可以用它來從一個.dll中運行的功能。

這裏是它很好的解釋文章: http://wiki.alliedmods.net/Signature_Scanning

因此,使用ctypes的或任何其他的方式來做到這裏面蟒蛇這可能嗎?

回答

2

如果您已經可以使用C++運行它們,那麼您可以嘗試使用SWIG爲您編寫的C++代碼生成python包裝,使其可以從python調用。

http://www.swig.org/

,我已經使用痛飲發現一些注意事項:

痛飲查找基於字符串值類型。例如 Python(int)中的整數類型將確保 cpp類型是「int」,否則swig將會抱怨關於類型不匹配的 。沒有自動轉換。

Swig會逐字複製源代碼,因此即使是相同命名空間 中的對象也需要完全限定,以便cxx文件能夠正確編譯。

希望有所幫助。

0

你說你試圖調用一個未導出的函數;據我所知,這不可能從Python。然而,你的問題似乎只是名字被打亂了。

您可以使用ctypes調用任意導出。由於名稱已被修改,並且不是有效的Python標識符,因此可以使用getattr()。

如果您擁有正確的信息,另一種方法是通過序號查找導出,如果根本沒有導出名稱,則必須執行此操作。獲得序號的一種方法是使用包含在許多Windows編譯語言中的dumpbin.exe。它實際上是鏈接器的前端,所以如果你有MS LinK.exe,你也可以使用適當的命令行開關。

要獲取函數引用(這是綁定到它的地址是「函數指針」對象)時,你可以使用類似:

進口ctypes的 FUNC = GETATTR(ctypes.windll.msvcrt, 「@@ myfunc」) retval = func(無)

當然,你會用你特別想調用的dll替換'msvcrt'。

我在這裏沒有展示的是如何取消激活名稱以派生調用簽名,因此必要的參數。這樣做需要使用demangler,並且這些對於用於創建DLL的C++編譯器的品牌和VERSION非常具體。

如果函數是stdcall,有一定數量的錯誤檢查,所以你有時可以擺弄一些東西,直到你弄明白爲止。但是如果函數是cdecl,那麼就沒有辦法自動檢查。同樣,如果合適,你必須記住包含額外的這個參數。