Python3使用restype定义kernel32.GetModuleHandleA的返回值,但是python输出的值非常大

时间:2018-10-19 04:54:33

标签: python windows ctypes

我正在研究"Python Grey Hat"这本书,这是我的职责之一,我一直在寻找这个问题很长时间,或者一直没有解决。

def func_resolve(self,dll,function):
    GetModuleHandle             = kernel32.GetModuleHandleA
    GetModuleHandle.argtypes    = [c_char_p]
    GetModuleHandle.restype     = c_void_p
    handle = GetModuleHandle(dll)
    print(handle)
    GetProcAddress              = kernel32.GetProcAddress
    GetProcAddress.argtypes     = [c_void_p,c_char_p]
    GetProcAddress.restype      = c_void_p
    address = GetProcAddress(handle,function)
    print(address)

我的输出句柄值为140707194077184,地址值为140707194386736,我使用OllyDbg查看msvcrt.dll中wprintf函数的地址为0x73D178A0,但值地址转换为十六进制也比0x73D178A0大得多,希望有人可以帮帮我吗,谢谢

2 个答案:

答案 0 :(得分:2)

没关系回答我的评论,我找到了原因。来自OllyDbg重点是我的):

  

OllyDbg是用于Microsoft ® Windows ® 32位汇编程序级分析调试器。

这意味着它只能只加载(使用) 32位进程(和/或 .dll s)。 wprintf 地址进行确认( 0x 73D178A0 32位,因为它(最多)具有 8 < / strong> 十六进制数字)。

另一方面,在 Python 中,您获得了(很多)较大的指针或地址值(例如 handler = 140707194077184 (< em> 0x 7FF8F256B930 ))不适合 32位范围,因此它是 64位。有关如何运行 Python 架构的更多详细信息,请选中[SO]: How do I determine if my python shell is executing in 32bit or 64bit mode on OS X? (@CristiFati's answer)(即使问题是针对 OSX 的,也涵盖了 Win 也是如此)。

那么,有什么收获呢? [MS.Docs]: File System Redirector使您对 msvcr(t ###)。dll 位置感到困惑:

  • Python 64位)从“%windir%\ System32
  • 加载了它
  • OllyDbg 32位)使您认为它是从同一位置加载的(出于向后兼容的原因),而实际上是从加载的“%windir%\ SysWOW64

使用为 32位 64位构建的工具,您可以并行启动(我使用Dependency Walker),您可以看到它们之间的区别。

答案 1 :(得分:1)

返回值是Windows句柄。该值很大,因为您正在使用64位Python。只要正确声明了ctypes,该值就无关紧要。该代码将在Python 2或3、32位或64位版本上运行:

from __future__ import print_function
import sys
from ctypes import *

print(sys.version)

kernel32 = WinDLL('kernel32')

GetModuleHandle          = kernel32.GetModuleHandleW
GetModuleHandle.argtypes = [c_wchar_p]
GetModuleHandle.restype  = c_void_p
GetProcAddress           = kernel32.GetProcAddress
GetProcAddress.argtypes  = [c_void_p,c_char_p]
GetProcAddress.restype   = c_void_p

handle = GetModuleHandle(u'user32')
address = GetProcAddress(handle,b'MessageBeep')
print(hex(address))
MessageBeep = WINFUNCTYPE(c_int,c_uint)(address)
MessageBeep(0)

已安装两个Python的输出(每次都发出哔声):

C:\>py -2 test.py
2.7.14 (v2.7.14:84471935ed, Sep 16 2017, 20:19:30) [MSC v.1500 32 bit (Intel)]
0x756e56d0

C:\>py -3 test.py
3.7.0 (v3.7.0:1bf9cc5093, Jun 27 2018, 04:59:51) [MSC v.1914 64 bit (AMD64)]
0x7fff6ca29a40