使用 Python ctypes 在调试中创建进程

问题描述 投票:0回答:1

以下代码应该在调试模式下启动一个新进程

calc.exe
。但是,它失败并显示代码 2 或
ERROR_FILE_NOT_FOUND
。然而,这个文件
calc.exe
确实存在于系统中。这段代码可能有什么问题?路径是否存在可以改进的问题,以便可以正常工作?

from ctypes import *
kernel32 = windll.kernel32

WORD      = c_ushort
DWORD     = c_ulong
LPBYTE    = POINTER(c_ubyte)
LPTSTR    = POINTER(c_char)
HANDLE    = c_void_p

class STARTUPINFO(Structure):
    _fields_ = [
        ("cb",            DWORD),
        ("lpReserved",    LPTSTR),
        ("lpDesktop",     LPTSTR),
        ("lpTitle",       LPTSTR),
        ("dwX",           DWORD),
        ("dwY",           DWORD),
        ("dwXSize",       DWORD),
        ("dwYSize",       DWORD),
        ("dwXCountChars", DWORD),
        ("dwYCountChars", DWORD),
        ("dwFillAttribute",DWORD),
        ("dwFlags",       DWORD),
        ("wShowWindow",   WORD),
        ("cbReserved2",   WORD),
        ("lpReserved2",   LPBYTE),
        ("hStdInput",     HANDLE),
        ("hStdOutput",    HANDLE),
        ("hStdError",     HANDLE),
    ]

class PROCESS_INFORMATION(Structure):
    _fields_ = [
        ("hProcess",    HANDLE),
        ("hThread",     HANDLE),
        ("dwProcessId", DWORD),
        ("dwThreadId",  DWORD),
    ]

DEBUG_PROCESS = 0x00000001
creation_flags = DEBUG_PROCESS

startupinfo         = STARTUPINFO()
startupinfo.dwFlags     = 0x1
startupinfo.wShowWindow = 0x0
startupinfo.cb = sizeof(startupinfo)

process_information = PROCESS_INFORMATION()

result = kernel32.CreateProcessA("C:\\Windows\\System32\\calc.exe",
                        None,
                        None,
                        None,
                        None,
                        creation_flags,
                        None,
                        None,
                        byref(startupinfo),
                        byref(process_information)
)

print(result)
print(kernel32.GetLastError())
python python-3.x windows ctypes kernel32
1个回答
0
投票

有很多错误的地方:

code00.py

#!/usr/bin/env python

import ctypes as cts
import sys
from ctypes import wintypes as wts


class STARTUPINFOA(cts.Structure):
    _fields_ = (
        ("cb", wts.DWORD),
        ("lpReserved", wts.LPSTR),
        ("lpDesktop", wts.LPSTR),
        ("lpTitle", wts.LPSTR),
        ("dwX", wts.DWORD),
        ("dwY", wts.DWORD),
        ("dwXSize", wts.DWORD),
        ("dwYSize", wts.DWORD),
        ("dwXCountChars", wts.DWORD),
        ("dwYCountChars", wts.DWORD),
        ("dwFillAttribute", wts.DWORD),
        ("dwFlags", wts.DWORD),
        ("wShowWindow", wts.WORD),
        ("cbReserved2", wts.WORD),
        ("lpReserved2", wts.LPBYTE),
        ("hStdInput", wts.HANDLE),
        ("hStdOutput", wts.HANDLE),
        ("hStdError", wts.HANDLE),
    )
LPSTARTUPINFOA = cts.POINTER(STARTUPINFOA)

class PROCESS_INFORMATION(cts.Structure):
    _fields_ = (
        ("hProcess", wts.HANDLE),
        ("hThread", wts.HANDLE),
        ("dwProcessId", wts.DWORD),
        ("dwThreadId", wts.DWORD),
    )
LPPROCESS_INFORMATION = cts.POINTER(PROCESS_INFORMATION)

LPSECURITY_ATTRIBUTES = cts.c_void_p

DEBUG_PROCESS = 0x00000001


def main(*argv):
    kernel32 = cts.windll.kernel32

    GetLastError = kernel32.GetLastError
    GetLastError.argtypes = ()
    GetLastError.restype = wts.DWORD

    CreateProcessA = kernel32.CreateProcessA
    CreateProcessA.argtypes = (
        wts.LPCSTR, wts.LPSTR, LPSECURITY_ATTRIBUTES, LPSECURITY_ATTRIBUTES,
        wts.BOOL, wts.DWORD, wts.LPVOID, wts.LPCSTR, LPSTARTUPINFOA, LPPROCESS_INFORMATION
    )
    CreateProcessA.restype = wts.BOOL


    creation_flags = DEBUG_PROCESS
    creation_flags = 0  # Not automatically killed when Python terminates

    startupinfo = STARTUPINFOA()
    startupinfo.dwFlags = 0x1
    startupinfo.wShowWindow = 0x0
    startupinfo.cb = cts.sizeof(STARTUPINFOA)

    process_information = PROCESS_INFORMATION()

    result = kernel32.CreateProcessA(
        b"C:\\Windows\\System32\\calc.exe",
        None,
        None,
        None,
        False,
        creation_flags,
        None,
        None,
        cts.byref(startupinfo),
        cts.byref(process_information)
    )

    print(f"CreateProcessA returned {result}")
    if not result:
        print(f"  Error: {GetLastError()}")
    else:
        print(f"  Created process (PId: {process_information.dwProcessId},"
              f" TId: {process_information.dwThreadId})")


if __name__ == "__main__":
    print(
        "Python {:s} {:03d}bit on {:s}\n".format(
            " ".join(elem.strip() for elem in sys.version.split("\n")),
            64 if sys.maxsize > 0x100000000 else 32,
            sys.platform,
        )
    )
    rc = main(*sys.argv[1:])
    print("\nDone.\n")
    sys.exit(rc)

输出

(py_pc064_03.10_test0) [cfati@CFATI-5510-0:e:\Work\Dev\StackExchange\StackOverflow\q078680399]> sopr.bat
### Set shorter prompt to better fit when pasted in StackOverflow (or other) pages ###

[prompt]> python ./code00.py
Python 3.10.11 (tags/v3.10.11:7d4cc5a, Apr  5 2023, 00:38:17) [MSC v.1929 64 bit (AMD64)] 064bit on win32

CreateProcessA returned 1
  Created process (PId: 32444, TId: 22832)

Done.


[prompt]> :: Calculator window is pops up

作为 CTypes 的替代方案,您可以尝试 [GitHub]:mhammond/pywin32 - Python for Windows (pywin32) Extensions,它是 WinAPIPython 包装器(并且包含大量 Python 的样板代码) 程序员不必编写)。文档 (WiP) 可在 [GitHub.MHammond]:Python for Win32 扩展帮助(或 [ME.TimGolden]:Python for Win32 扩展帮助)找到。

© www.soinside.com 2019 - 2024. All rights reserved.