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.
Recommended Comments
There are no comments to display.