在Windows上,Python(2)的标准库例程subprocess.Popen
允许您为CreateProcess
指定任意标志,并且您可以访问进程句柄对于Popen
返回的对象新创建的进程。但是,在Popen
返回之前,库将关闭新创建的进程的初始线程的线程句柄。
现在,我需要在创建标志中创建一个挂起的进程(CREATE_SUSPENDED
),这样我就可以在它有机会执行任何代码之前对其进行操作(具体来说,将其附加到作业对象)。但是,这意味着我需要线程句柄才能从暂停中释放进程(使用ResumeThread
)。我能找到恢复线程句柄的唯一方法是使用"工具帮助"库遍历整个系统上的所有线程(例如,请参阅this question and answer)。这个有效,但我不喜欢它。具体来说,我担心每次需要创建进程时都会对系统上的所有线程进行快照,这样做太贵了。 (较大的应用程序是一个测试套件,使用隔离进程;它以几十到几百秒的速率创建和销毁进程。)
所以,问题是:是否有一种更有效的方式来恢复由CREATE_SUSPENDED
暂停的进程的执行,如果您拥有的是进程句柄和设施Python 2标准库(包括ctypes,但不是 winapi附加组件)? Vista和更高技术是可以接受的,但XP兼容性是首选。
答案 0 :(得分:1)
我找到了更快的方法;遗憾的是,它依赖于未记录的API NtResumeProcess
。这听起来确实如此 - 采用进程句柄并将等效的ResumeThread
应用于进程中的每个线程。使用它的Python / ctypes代码看起来像
import ctypes
from ctypes.wintypes import HANDLE, LONG, ULONG
ntdll = ctypes.WinDLL("ntdll.dll")
RtlNtStatusToDosError = ntdll.RtlNtStatusToDosError
NtResumeProcess = ntdll.NtResumeProcess
def errcheck_ntstatus(status, *etc):
if status < 0: raise ctypes.WinError(RtlNtStatusToDosError(status))
return status
RtlNtStatusToDosError.argtypes = (LONG,)
RtlNtStatusToDosError.restype = ULONG
# RtlNtStatusToDosError cannot fail
NtResumeProcess.argtypes = (HANDLE,)
NtResumeProcess.restype = LONG
NtResumeProcess.errcheck = errcheck_ntstatus
def resume_subprocess(proc):
NtResumeProcess(int(proc._handle))
在使用其他空闲的Windows 7虚拟机上,使用此技术测量的流程设置开销比使用Toolhelp少大约20%。正如预期的那样,根据Toolhelp的工作原理,系统中存在的线程越多,性能增量就越大 - 无论它们是否与相关程序有任何关系。
鉴于NtResumeProcess
及其对应NtSuspendProcess
的明显的一般效用,我想知道为什么他们从未被记录并给出了kernel32包装器。它们被少数核心系统DLL和EXE使用,所有这些都是AFAICT,是Windows错误报告机制的一部分(faultrep.dll
,werui.dll
,werfault.exe
,dwwin.exe
等等,并且似乎没有重新公开文档名称下的功能。这些函数似乎不太可能更改它们的语义而不改变它们的名字,但是一个防御性编码的程序应该准备好让它们消失(我想回到工具帮助)。
答案 1 :(得分:-2)
我在这里张贴这个,因为我找到了解决这个问题的东西。我自己正在研究这个问题,我相信我已经找到了解决方案。
我不能给你一个摘录或摘要,因为它太多了,我发现它只是两个小时前。我在这里发布这个给所有其他人,像我一样,寻求一种方法来“轻松”在Windows中生成一个正确的子进程,但是想要执行 cuckoo 。 ;)
整个第二章很重要,但细节从第12页开始。
我希望它能帮助别人,希望能帮助我。
编辑:
我想我可以添加更多内容。根据我收集的内容,本文档解释了如何生成一个永不执行的睡眠过程。这样我们就可以正常运行Windows进程。然后它解释了通过使用win32api函数VirtualAllocEx
和WriteProcessMemory
,我们可以轻松地分配可执行页面并将机器代码注入其他进程。
然后 - 我认为最好的部分 - 可以更改进程的寄存器,允许程序员将指令指针更改为指向 cuckoo !
惊人!