Teddy Rogers Posted June 1, 2020 Posted June 1, 2020 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
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now