Files
2026-10-10 21:58:27 +08:00

183 lines
8.0 KiB
Plaintext
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
from stdint import *
from win32.win32base import HANDLE, LPCSTR, LPCWSTR
import win32.win32base
define PROCESS_TERMINATE = 0x0001
define PROCESS_CREATE_THREAD = 0x0002
define PROCESS_VM_OPERATION = 0x0008
define PROCESS_VM_READ = 0x0010
define PROCESS_VM_WRITE = 0x0020
define PROCESS_QUERY_INFORMATION = 0x0400
define PROCESS_ALL_ACCESS = 0x001FFFFF
define THREAD_TERMINATE = 0x0001
define THREAD_SUSPEND_RESUME = 0x0002
define THREAD_GET_CONTEXT = 0x0008
define THREAD_SET_CONTEXT = 0x0010
define THREAD_QUERY_INFORMATION = 0x0040
define THREAD_ALL_ACCESS = 0x001FFFFF
define CREATE_SUSPENDED = 0x00000004
define CREATE_NEW_CONSOLE = 0x00000010
define CREATE_NEW_PROCESS_GROUP = 0x00000200
define CREATE_NO_WINDOW = 0x08000000
define DETACHED_PROCESS = 0x00000008
define STARTF_USESHOWWINDOW = 0x00000001
define STARTF_USESTDHANDLES = 0x00000100
define SW_HIDE = 0
define SW_SHOW = 5
define SW_MINIMIZE = 6
define NORMAL_PRIORITY_CLASS = 0x00000020
define IDLE_PRIORITY_CLASS = 0x00000040
define HIGH_PRIORITY_CLASS = 0x00000080
define REALTIME_PRIORITY_CLASS = 0x00000100
define BELOW_NORMAL_PRIORITY_CLASS = 0x00004000
define ABOVE_NORMAL_PRIORITY_CLASS = 0x00008000
define STILL_ACTIVE = 259
struct STARTUPINFOA:
cb: DWORD
lpReserved: CHARPTR
lpDesktop: CHARPTR
lpTitle: CHARPTR
dwX: DWORD
dwY: DWORD
dwXSize: DWORD
dwYSize: DWORD
dwXCountChars: DWORD
dwYCountChars: DWORD
dwFillAttribute: DWORD
dwFlags: DWORD
wShowWindow: WORD
cbReserved2: WORD
lpReserved2: VOIDPTR
hStdInput: HANDLE
hStdOutput: HANDLE
hStdError: HANDLE
struct STARTUPINFOW:
cb: DWORD
lpReserved: WCHARPTR
lpDesktop: WCHARPTR
lpTitle: WCHARPTR
dwX: DWORD
dwY: DWORD
dwXSize: DWORD
dwYSize: DWORD
dwXCountChars: DWORD
dwYCountChars: DWORD
dwFillAttribute: DWORD
dwFlags: DWORD
wShowWindow: WORD
cbReserved2: WORD
lpReserved2: VOIDPTR
hStdInput: HANDLE
hStdOutput: HANDLE
hStdError: HANDLE
struct PROCESS_INFORMATION:
hProcess: HANDLE
hThread: HANDLE
dwProcessId: DWORD
dwThreadId: DWORD
extern def CreateProcessA(lpApplicationName: LPCSTR, lpCommandLine: CHARPTR, lpProcessAttributes: win32.win32base.SECURITY_ATTRIBUTES*, lpThreadAttributes: win32.win32base.SECURITY_ATTRIBUTES*, bInheritHandles: BOOL, dwCreationFlags: ULONG, lpEnvironment: VOIDPTR, lpCurrentDirectory: LPCSTR, lpStartupInfo: STARTUPINFOA*, lpProcessInformation: PROCESS_INFORMATION*) -> BOOL
extern def CreateProcessW(lpApplicationName: LPCWSTR, lpCommandLine: WCHARPTR, lpProcessAttributes: win32.win32base.SECURITY_ATTRIBUTES*, lpThreadAttributes: win32.win32base.SECURITY_ATTRIBUTES*, bInheritHandles: BOOL, dwCreationFlags: ULONG, lpEnvironment: VOIDPTR, lpCurrentDirectory: LPCWSTR, lpStartupInfo: STARTUPINFOW*, lpProcessInformation: PROCESS_INFORMATION*) -> BOOL
extern def TerminateProcess(hProcess: HANDLE, uExitCode: UINT) -> BOOL
extern def GetExitCodeProcess(hProcess: HANDLE, lpExitCode: ULONG*) -> BOOL
extern def GetExitCodeThread(hThread: HANDLE, lpExitCode: ULONG*) -> BOOL
extern def OpenProcess(dwDesiredAccess: ULONG, bInheritHandle: BOOL, dwProcessId: ULONG) -> HANDLE
extern def GetCurrentProcess() -> HANDLE
extern def GetCurrentProcessId() -> ULONG
extern def CreateThread(lpThreadAttributes: win32.win32base.SECURITY_ATTRIBUTES*, dwStackSize: sizet, lpStartAddress: VOIDPTR, lpParameter: VOIDPTR, dwCreationFlags: ULONG, lpThreadId: ULONG*) -> HANDLE
extern def OpenThread(dwDesiredAccess: ULONG, bInheritHandle: BOOL, dwThreadId: ULONG) -> HANDLE
extern def SuspendThread(hThread: HANDLE) -> ULONG
extern def ResumeThread(hThread: HANDLE) -> ULONG
extern def TerminateThread(hThread: HANDLE, dwExitCode: ULONG) -> BOOL
extern def GetCurrentThread() -> HANDLE
extern def GetCurrentThreadId() -> ULONG
extern def GetThreadId(hThread: HANDLE) -> ULONG
extern def GetProcessId(hProcess: HANDLE) -> ULONG
extern def SetThreadPriority(hThread: HANDLE, nPriority: INT) -> BOOL
extern def GetThreadPriority(hThread: HANDLE) -> INT
extern def ExitProcess(uExitCode: UINT) -> VOID
extern def ExitThread(dwExitCode: ULONG) -> VOID
extern def TlsAlloc() -> ULONG
extern def TlsFree(dwTlsIndex: ULONG) -> BOOL
extern def TlsGetValue(dwTlsIndex: ULONG) -> VOIDPTR
extern def TlsSetValue(dwTlsIndex: ULONG, lpTlsValue: VOIDPTR) -> BOOL
# =============================================================================
# x86-64 CONTEXT (winnt.h DECLSPEC_ALIGN(16)); after SuspendThread, GetThreadContext reads RIP/RSP/RBP for stack walking.
# Fields/offsets must match winnt.h AMD64 exactly and must not be trimmed: GetThreadContext(CONTEXT_FULL) and StackWalk64 write sizeof(CONTEXT)=0x4D0=1232 bytes, so LastBranchToRip/LastBranchFromRip (0x4B0/0x4B8) are required. Allocate 16-byte aligned (stdlib.malloc/calloc), never a stack local.
# =============================================================================
define CONTEXT_AMD64 = 0x00100000
define CONTEXT_CONTROL = 0x00100001
define CONTEXT_INTEGER = 0x00100002
define CONTEXT_SEGMENTS = 0x00100004
define CONTEXT_FLOATING_POINT = 0x00100008
define CONTEXT_DEBUG_REGISTERS = 0x00100010
define CONTEXT_FULL = 0x0010000B
struct CONTEXT:
P1Home: ULONGLONG # 0x000
P2Home: ULONGLONG # 0x008
P3Home: ULONGLONG # 0x010
P4Home: ULONGLONG # 0x018
P5Home: ULONGLONG # 0x020
P6Home: ULONGLONG # 0x028
ContextFlags: DWORD # 0x030
MxCsr: DWORD # 0x034
SegCs: WORD # 0x038
SegDs: WORD # 0x03A
SegEs: WORD # 0x03C
SegFs: WORD # 0x03E
SegGs: WORD # 0x040
SegSs: WORD # 0x042
EFlags: DWORD # 0x044
Dr0: ULONGLONG # 0x048
Dr1: ULONGLONG # 0x050
Dr2: ULONGLONG # 0x058
Dr3: ULONGLONG # 0x060
Dr6: ULONGLONG # 0x068
Dr7: ULONGLONG # 0x070
Rax: ULONGLONG # 0x078
Rcx: ULONGLONG # 0x080
Rdx: ULONGLONG # 0x088
Rbx: ULONGLONG # 0x090
Rsp: ULONGLONG # 0x098
Rbp: ULONGLONG # 0x0A0
Rsi: ULONGLONG # 0x0A8
Rdi: ULONGLONG # 0x0B0
R8: ULONGLONG # 0x0B8
R9: ULONGLONG # 0x0C0
R10: ULONGLONG # 0x0C8
R11: ULONGLONG # 0x0D0
R12: ULONGLONG # 0x0D8
R13: ULONGLONG # 0x0E0
R14: ULONGLONG # 0x0E8
R15: ULONGLONG # 0x0F0
Rip: ULONGLONG # 0x0F8
FltSave: [512]uint8 # 0x100(XMM_SAVE_AREA32)
VectorRegister: [416]uint8 # 0x300(M128A[26])
VectorControl: ULONGLONG # 0x4A0
DebugControl: ULONGLONG # 0x4A8
LastBranchToRip: ULONGLONG # 0x4B0
LastBranchFromRip: ULONGLONG # 0x4B8
LastExceptionToRip: ULONGLONG # 0x4C0
LastExceptionFromRip: ULONGLONG # 0x4C8
# Get thread context (processthreadsapi.h). hThread needs THREAD_GET_CONTEXT; ContextFlags must be set to CONTEXT_AMD64 | ... first (x64; CONTEXT_FULL here).
# Returns 0 on failure (see GetLastError).
extern def GetThreadContext(hThread: HANDLE, lpContext: CONTEXT*) -> BOOL
# LPTOP_LEVEL_EXCEPTION_FILTER SetUnhandledExceptionFilter(LPTOP_LEVEL_EXCEPTION_FILTER);
# SetUnhandledExceptionFilter registers a process-level unhandled-exception filter (errhandlingapi.h/kernel32); the callback runs on the faulting thread and returns EXCEPTION_CONTINUE_SEARCH(0) to use the default handler (does not swallow).
# Callback: LONG CALLBACK Filter(_EXCEPTION_POINTERS*): ExceptionRecord@0x00, ContextRecord@0x08 (EXCEPTION_RECORD=0x98). First arg declared as rawptr; return ignored (previous filter). See traceback.vp Install/DumpCrashThread.
extern def SetUnhandledExceptionFilter(TopLevelExceptionFilter: rawptr) -> rawptr