brintos

brintos / llvm-project-archived public Read only

0
0
Text · 8.3 KiB · d5fb504 Raw
238 lines · python
1# DExTer : Debugging Experience Tester2# ~~~~~~   ~         ~~         ~   ~~3#4# Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.5# See https://llvm.org/LICENSE.txt for license information.6# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception7 8from ctypes import *9from enum import *10from functools import partial11 12from .utils import *13from . import control14from . import symbols15from . import sysobjs16 17 18class DebugAttach(IntFlag):19    DEBUG_ATTACH_DEFAULT = 020    DEBUG_ATTACH_NONINVASIVE = 121    DEBUG_ATTACH_EXISTING = 222    DEBUG_ATTACH_NONINVASIVE_NO_SUSPEND = 423    DEBUG_ATTACH_INVASIVE_NO_INITIAL_BREAK = 824    DEBUG_ATTACH_INVASIVE_RESUME_PROCESS = 0x1025    DEBUG_ATTACH_NONINVASIVE_ALLOW_PARTIAL = 0x2026 27 28# UUID for DebugClient7 interface.29DebugClient7IID = IID(30    0x13586BE3,31    0x542E,32    0x481E,33    IID_Data4_Type(0xB1, 0xF2, 0x84, 0x97, 0xBA, 0x74, 0xF9, 0xA9),34)35 36 37class DEBUG_CREATE_PROCESS_OPTIONS(Structure):38    _fields_ = [39        ("CreateFlags", c_ulong),40        ("EngCreateFlags", c_ulong),41        ("VerifierFlags", c_ulong),42        ("Reserved", c_ulong),43    ]44 45 46class IDebugClient7(Structure):47    pass48 49 50class IDebugClient7Vtbl(Structure):51    wrp = partial(WINFUNCTYPE, c_long, POINTER(IDebugClient7))52    idc_queryinterface = wrp(POINTER(IID), POINTER(c_void_p))53    idc_attachprocess = wrp(c_longlong, c_long, c_long)54    idc_detachprocesses = wrp()55    idc_terminateprocesses = wrp()56    idc_createprocessandattach2 = wrp(57        c_ulonglong, c_char_p, c_void_p, c_ulong, c_char_p, c_char_p, c_ulong, c_ulong58    )59    _fields_ = [60        ("QueryInterface", idc_queryinterface),61        ("AddRef", c_void_p),62        ("Release", c_void_p),63        ("AttachKernel", c_void_p),64        ("GetKernelConnectionOptions", c_void_p),65        ("SetKernelConnectionOptions", c_void_p),66        ("StartProcessServer", c_void_p),67        ("ConnectProcessServer", c_void_p),68        ("DisconnectProcessServer", c_void_p),69        ("GetRunningProcessSystemIds", c_void_p),70        ("GetRunningProcessSystemIdsByExecutableName", c_void_p),71        ("GetRunningProcessDescription", c_void_p),72        ("AttachProcess", idc_attachprocess),73        ("CreateProcess", c_void_p),74        ("CreateProcessAndAttach", c_void_p),75        ("GetProcessOptions", c_void_p),76        ("AddProcessOptions", c_void_p),77        ("RemoveProcessOptions", c_void_p),78        ("SetProcessOptions", c_void_p),79        ("OpenDumpFile", c_void_p),80        ("WriteDumpFile", c_void_p),81        ("ConnectSession", c_void_p),82        ("StartServer", c_void_p),83        ("OutputServers", c_void_p),84        ("TerminateProcesses", idc_terminateprocesses),85        ("DetachProcesses", idc_detachprocesses),86        ("EndSession", c_void_p),87        ("GetExitCode", c_void_p),88        ("DispatchCallbacks", c_void_p),89        ("ExitDispatch", c_void_p),90        ("CreateClient", c_void_p),91        ("GetInputCallbacks", c_void_p),92        ("SetInputCallbacks", c_void_p),93        ("GetOutputCallbacks", c_void_p),94        ("SetOutputCallbacks", c_void_p),95        ("GetOutputMask", c_void_p),96        ("SetOutputMask", c_void_p),97        ("GetOtherOutputMask", c_void_p),98        ("SetOtherOutputMask", c_void_p),99        ("GetOutputWidth", c_void_p),100        ("SetOutputWidth", c_void_p),101        ("GetOutputLinePrefix", c_void_p),102        ("SetOutputLinePrefix", c_void_p),103        ("GetIdentity", c_void_p),104        ("OutputIdentity", c_void_p),105        ("GetEventCallbacks", c_void_p),106        ("SetEventCallbacks", c_void_p),107        ("FlushCallbacks", c_void_p),108        ("WriteDumpFile2", c_void_p),109        ("AddDumpInformationFile", c_void_p),110        ("EndProcessServer", c_void_p),111        ("WaitForProcessServerEnd", c_void_p),112        ("IsKernelDebuggerEnabled", c_void_p),113        ("TerminateCurrentProcess", c_void_p),114        ("DetachCurrentProcess", c_void_p),115        ("AbandonCurrentProcess", c_void_p),116        ("GetRunningProcessSystemIdByExecutableNameWide", c_void_p),117        ("GetRunningProcessDescriptionWide", c_void_p),118        ("CreateProcessWide", c_void_p),119        ("CreateProcessAndAttachWide", c_void_p),120        ("OpenDumpFileWide", c_void_p),121        ("WriteDumpFileWide", c_void_p),122        ("AddDumpInformationFileWide", c_void_p),123        ("GetNumberDumpFiles", c_void_p),124        ("GetDumpFile", c_void_p),125        ("GetDumpFileWide", c_void_p),126        ("AttachKernelWide", c_void_p),127        ("GetKernelConnectionOptionsWide", c_void_p),128        ("SetKernelConnectionOptionsWide", c_void_p),129        ("StartProcessServerWide", c_void_p),130        ("ConnectProcessServerWide", c_void_p),131        ("StartServerWide", c_void_p),132        ("OutputServerWide", c_void_p),133        ("GetOutputCallbacksWide", c_void_p),134        ("SetOutputCallbacksWide", c_void_p),135        ("GetOutputLinePrefixWide", c_void_p),136        ("SetOutputLinePrefixWide", c_void_p),137        ("GetIdentityWide", c_void_p),138        ("OutputIdentityWide", c_void_p),139        ("GetEventCallbacksWide", c_void_p),140        ("SetEventCallbacksWide", c_void_p),141        ("CreateProcess2", c_void_p),142        ("CreateProcess2Wide", c_void_p),143        ("CreateProcessAndAttach2", idc_createprocessandattach2),144        ("CreateProcessAndAttach2Wide", c_void_p),145        ("PushOutputLinePrefix", c_void_p),146        ("PushOutputLinePrefixWide", c_void_p),147        ("PopOutputLinePrefix", c_void_p),148        ("GetNumberInputCallbacks", c_void_p),149        ("GetNumberOutputCallbacks", c_void_p),150        ("GetNumberEventCallbacks", c_void_p),151        ("GetQuitLockString", c_void_p),152        ("SetQuitLockString", c_void_p),153        ("GetQuitLockStringWide", c_void_p),154        ("SetQuitLockStringWide", c_void_p),155        ("SetEventContextCallbacks", c_void_p),156        ("SetClientContext", c_void_p),157    ]158 159 160IDebugClient7._fields_ = [("lpVtbl", POINTER(IDebugClient7Vtbl))]161 162 163class Client(object):164    def __init__(self):165        DbgEng = WinDLL("DbgEng")166        DbgEng.DebugCreate.argtypes = [POINTER(IID), POINTER(POINTER(IDebugClient7))]167        DbgEng.DebugCreate.restype = c_ulong168 169        # Call DebugCreate to create a new debug client170        ptr = POINTER(IDebugClient7)()171        res = DbgEng.DebugCreate(byref(DebugClient7IID), ptr)172        aborter(res, "DebugCreate")173        self.client = ptr.contents174        self.vt = vt = self.client.lpVtbl.contents175 176        def QI(iface, ptr):177            return vt.QueryInterface(self.client, byref(iface), byref(ptr))178 179        # Query for a control object180        ptr = c_void_p()181        res = QI(control.DebugControl7IID, ptr)182        aborter(res, "QueryInterface control")183        self.control_ptr = cast(ptr, POINTER(control.IDebugControl7))184        self.Control = control.Control(self.control_ptr)185 186        # Query for a SystemObjects object187        ptr = c_void_p()188        res = QI(sysobjs.DebugSystemObjects4IID, ptr)189        aborter(res, "QueryInterface sysobjects")190        self.sysobjects_ptr = cast(ptr, POINTER(sysobjs.IDebugSystemObjects4))191        self.SysObjects = sysobjs.SysObjects(self.sysobjects_ptr)192 193        # Query for a Symbols object194        ptr = c_void_p()195        res = QI(symbols.DebugSymbols5IID, ptr)196        aborter(res, "QueryInterface debugsymbosl5")197        self.symbols_ptr = cast(ptr, POINTER(symbols.IDebugSymbols5))198        self.Symbols = symbols.Symbols(self.symbols_ptr)199 200    def AttachProcess(self, pid):201        # Zero process-server id means no process-server.202        res = self.vt.AttachProcess(203            self.client, 0, pid, DebugAttach.DEBUG_ATTACH_DEFAULT204        )205        aborter(res, "AttachProcess")206        return207 208    def DetachProcesses(self):209        res = self.vt.DetachProcesses(self.client)210        aborter(res, "DetachProcesses")211        return212 213    def TerminateProcesses(self):214        res = self.vt.TerminateProcesses(self.client)215        aborter(res, "TerminateProcesses")216        return217 218    def CreateProcessAndAttach2(self, cmdline):219        options = DEBUG_CREATE_PROCESS_OPTIONS()220        options.CreateFlags = 0x2  # DEBUG_ONLY_THIS_PROCESS221        options.EngCreateFlags = 0222        options.VerifierFlags = 0223        options.Reserved = 0224        attach_flags = 0225        res = self.vt.CreateProcessAndAttach2(226            self.client,227            0,228            cmdline.encode("ascii"),229            byref(options),230            sizeof(options),231            None,232            None,233            0,234            attach_flags,235        )236        aborter(res, "CreateProcessAndAttach2")237        return238