Jump to content
Tuts 4 You

PureBasic Adventures - DebugBlocker()


Teddy Rogers

Recommended Posts

Teddy Rogers

This is a repost from the "PureBasic Adventures" blog...

Here is a simple example in PureBasic code for using a self-debugger, commonly referred to as Debug Blocker. Compile (or run one of the attached executables in the archive) and click on the "CLICK ME!" button to create a duplicate process being self-debugged. Any queries about the code please comment below...

; ------------------------------------------------------------------
;
;   PureBasic DebugBlocker() function, creates a copy of the currently running
;   process as a child and attaches to it for self-debugging. This method is
;   commonly referred to as "self-debugging" or "Debug Blocker" and is used
;   to protect the parent (now child) process from being debugged. Only one
;   Ring-3 debugger can be attached to a process in Windows OS.
;   
;   Return Values:
;
;   This function does not return a value.
;
;   Remarks:
;
;   Debugging events and actions are handled within the function.
;
;   By Teddy Rogers / PureBasic 5.24 LTS
;
; ------------------------------------------------------------------

Declare DebugBlocker()

If OpenWindow(1, #Null, #Null, 300, 60, "Self-debugging Example", #PB_Window_ScreenCentered | #PB_Window_SystemMenu)
  ButtonGadget(1, 5, 5, 290, 50, "CLICK ME!", #PB_Button_MultiLine)
  
  Repeat
    MyEvent = WaitWindowEvent()
    
    Select MyEvent
      Case #PB_Event_Gadget
        Select EventGadget()
          Case 1
            DebugBlocker()
        EndSelect
    EndSelect
    
  Until MyEvent = #PB_Event_CloseWindow    
EndIf

; A very simple example of self-debugging (Debug-Blocker)...

Procedure DebugBlocker()
  Protected ghMutex, EXIT_PROCESS_DEBUG_EVENT

  ; Create a mutex object, we can use it as an identity to limit the number of spawned processes to be self-debugged...
  
  ghMutex = CreateMutex_(#Null, #True, "Blocker_Mutex")
  
  If ghMutex = #Null Or GetLastError_() = #ERROR_ALREADY_EXISTS             ; If return handle is the existing object GetLastError returns ERROR_ALREADY_EXISTS.
    CloseHandle_(ghMutex)
    MessageBox_(WindowID(1), "Self-debugging already in progress...", "Error", #MB_ICONERROR | #MB_TOPMOST | #MB_SETFOREGROUND)
    ProcedureReturn
  EndIf
  
  ; Find out who we are and create a duplicate process of ourselves...
  
  GetStartupInfo_(lpStartupInfo.STARTUPINFO)
  If CreateProcess_(#Null, GetCommandLine_(), #Null, #Null, #False, #DEBUG_PROCESS, #Null, #Null, @lpStartupInfo, @lpProcessInformation.PROCESS_INFORMATION)
    
    ; Infinitely wait for the debugging event EXIT_PROCESS_DEBUG_EVENT in our new process...
    
    Repeat
      If WaitForDebugEvent_(@myDebug.DEBUG_EVENT, -1)
        If PeekB(@myDebug\dwDebugEventCode) = #EXIT_PROCESS_DEBUG_EVENT
          EXIT_PROCESS_DEBUG_EVENT = #True
        EndIf
      EndIf
      
      ; Continue debugging the process...
      
      If Not ContinueDebugEvent_(myDebug\dwProcessId, myDebug\dwThreadId, #DBG_CONTINUE)
        MessageBox_(WindowID(1), "Debugging error!", "Error", #MB_ICONERROR | #MB_TOPMOST | #MB_SETFOREGROUND)
      EndIf
    Until EXIT_PROCESS_DEBUG_EVENT
    
    ; Tidy up process handles identified in the PROCESS_INFORMATION structure...
    
    CloseHandle_(lpProcessInformation\hProcess)
    CloseHandle_(lpProcessInformation\hThread)
    
  EndIf
  
  ReleaseMutex_(ghMutex)
  CloseHandle_(ghMutex)                                                     ; Destroy the created Blocker_Mutex
  
EndProcedure

Ted.

Debug Blocker.zip

Link to comment

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...