import t from stdint import * from w32.win32base import * 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 class 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 class 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 class PROCESS_INFORMATION(): hProcess: HANDLE hThread: HANDLE dwProcessId: DWORD dwThreadId: DWORD extern def CreateProcessA(lpApplicationName: LPCSTR, lpCommandLine: CHARPTR, lpProcessAttributes: SECURITY_ATTRIBUTES*, lpThreadAttributes: SECURITY_ATTRIBUTES*, bInheritHandles: BOOL, dwCreationFlags: ULONG, lpEnvironment: VOIDPTR, lpCurrentDirectory: LPCSTR, lpStartupInfo: STARTUPINFOA*, lpProcessInformation: PROCESS_INFORMATION*) -> BOOL extern def CreateProcessW(lpApplicationName: LPCWSTR, lpCommandLine: WCHARPTR, lpProcessAttributes: SECURITY_ATTRIBUTES*, lpThreadAttributes: 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: 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 class 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: t.CArray[uint8, 512] # 0x100(XMM_SAVE_AREA32) VectorRegister: t.CArray[uint8, 416] # 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 t.CPtr; return ignored (previous filter). See traceback.vp Install/DumpCrashThread. extern def SetUnhandledExceptionFilter(TopLevelExceptionFilter: t.CPtr) -> t.CPtr