PythonCtype.windll.kernel32.CreateThread参数值

2024-09-28 21:01:25 发布

您现在位置:Python中文网/ 问答频道 /正文

这可能是一个非常简单的问题,但不知怎么的,我就是不能把我的头围绕着答案,我也找不到任何关于这个主题的好的和相关的文献资料。在

因此,我尝试使用Python的ctypes模块和其中的CreateThread方法来实现PoCctypes.windll.kernel32类(在程序的内存空间中执行外壳代码注入)

根据msdn文档CreateThread,7个参数为:

  • 指向安全属性的指针
  • 初始堆栈大小
  • 指向起始地址的指针
  • 指向任何参数的指针
  • 创建标志
  • 指向接收线程标识符的值的指针

所有使用python调用c风格函数和lib的例子如下:

thread_handle = ctypes.windll.kernel32.CreateThread(ctypes.c_int(0),
                ctypes.c_int(0),
                ctypes.c_int(ptr),
                ctypes.c_int(0),
                ctypes.c_int(0),
                ctypes.pointer(ctypes.c_int(0)))

有人能解释一下为什么最后一个参数被用作ctypes.pointer(c_int0),而另一个空指针的常量值整数0用于其他参数。(例如ctypes.c\u int(0))

更新:这里是一个示例代码,这个实现在网络上随处可见:

createThread function call in python的第786行

注意,在上面链接的脚本行中,注释提到:

^{pr2}$

作者在注释CreateThread函数调用的引用时可能出错。在

假设: 根据Mark在回答中提到的注释,ThreadID和ThreadHandle是不同的,通过传入一个ctypes.pointer(ctypes.c\u int(0))而不仅仅是纯ctypes.c\u int(0)(NULL)意味着在int0位置,将存储线程ID。有人能确认这个假设吗?在


Tags: 答案代码主题参数ctypes线程int指向
1条回答
网友
1楼 · 发布于 2024-09-28 21:01:25

最后一个参数实例化一个C整数(c_int(0))并将其作为指针传递。这与最后一个参数定义松散匹配。它应该是一个DWORD,通常定义为unsigned long(ctypes中的c_ulong)。使用ctypes.byref比创建指针更有效。该参数用于将线程ID作为输出参数返回,因此需要正确的C类型的实例的地址来存储ID

下面是一个工作示例,它用ctypes显式定义每个函数的输入/输出。请注意,ctypeswintypes中有预定义的窗口类型:

import ctypes as c
from ctypes import wintypes as w

LPTHREAD_START_ROUTINE = c.WINFUNCTYPE(w.DWORD,w.LPVOID)
SIZE_T = c.c_size_t

k32 = c.WinDLL('kernel32')
test = c.WinDLL('test')

CreateThread = k32.CreateThread
CreateThread.argtypes = w.LPVOID,SIZE_T,LPTHREAD_START_ROUTINE,w.LPVOID,w.DWORD,w.LPDWORD
CreateThread.restype = w.HANDLE

WaitForSingleObject = k32.WaitForSingleObject
WaitForSingleObject.argtypes = w.HANDLE,w.DWORD
WaitForSingleObject.restype = w.DWORD

sa = None  # No security specified.  None == NULL pointer.
stack = 0  # Use default stack
start = LPTHREAD_START_ROUTINE(test.func)
param = 0x12345
flags = 0 # start thread immediately
tid = w.DWORD()
h = CreateThread(sa,stack,start,param,flags,c.byref(tid))
WaitForSingleObject(h,1000) # wait for the thread to exit.

下面是一个简单的C函数作为线程运行的代码:

^{pr2}$

输出如下:

0000000000012345

相关问题 更多 >