Jump to content
Tuts 4 You

1 Screenshot

This is an example for submitting a CrackMe in the Downloads section of the site.

You can download the file and run Debug Blocker x64. Nothing too exciting will happen!

The challenge here would be to patch the debug-blocker function so that it does not spawn a second process.

; ------------------------------------------------------------------
;
;   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

This is where I as the author would post my own solution if I wanted to add one.

This field is optional.


User Feedback

Recommended Comments

There are no comments to display.

×
×
  • Create New...