183 lines
8.0 KiB
Plaintext
183 lines
8.0 KiB
Plaintext
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
|