Page 1 of 2

Anti-piracy tip: Prevent debugging (Windows)

Posted: Sun Apr 22, 2018 9:26 am
by firace
A nice trick to keep an attacker from attaching a user-mode debugger (such as Olly or x86dbg) to your program, by having 2 instances debugging each other.

Note: This is just a quick demo, use it as a starting point. :)

Code: Select all


Global target 
ParentPID =  Val(ProgramParameter())

If ParentPID = 0
  hprocess=RunProgram(ProgramFilename(), Str(GetCurrentProcessId_()), "", #PB_Program_Open); 
  ChildPID=ProgramID(hProcess)
EndIf

If ParentPID <> 0 : target = ParentPID : Else : target = ChildPID : EndIf

Procedure debug_other(*a)
  Delay(500)
  result=DebugActiveProcess_(target)  
  
  Repeat
    WaitForDebugEvent_(@lpep.Debug_event,900)
    ContinueDebugEvent_(lpep.debug_event\dwProcessId,lpep.debug_event\dwThreadId,#DBG_CONTINUE);
  ForEver
EndProcedure

CreateThread(@debug_other(),1)

If ParentPID = 0 : parentflag$ = "I'M THE PARENT" :   Else : parentflag$ = "I'M THE CHILD" : height + 100 : EndIf

OpenWindow(0, 100, 100 + height, 340, 60, "Me: " + GetCurrentProcessId_() + " -- My target: " + target + " -- " + parentflag$)

Repeat : Until WaitWindowEvent() = #PB_Event_CloseWindow

Result (Olly screenshot):

Image

Re: Anti-piracy tip: Prevent debugging (Windows)

Posted: Sun Apr 22, 2018 11:42 am
by Dude
Hmm, don't get too excited; OllyDbg had no problem here:

Image

Re: Anti-piracy tip: Prevent debugging (Windows)

Posted: Sun Apr 22, 2018 1:43 pm
by firace
Dude wrote:Hmm, don't get too excited; OllyDbg had no problem here:

Strange. Windows version, PB version, Olly version?

Re: Anti-piracy tip: Prevent debugging (Windows)

Posted: Sun Apr 22, 2018 1:52 pm
by Dude
firace wrote:Windows version, PB version, Olly version?
Windows 7 Ultimate (64-bit), PureBasic v5.62 (32-bit), OllyDbg v2.01 (32-bit).

Re: Anti-piracy tip: Prevent debugging (Windows)

Posted: Mon Apr 23, 2018 10:08 am
by ar-s
A small tip is to kill olly.exe process when it's detected. It's not a big protection, but that could stop noobs.

Re: Anti-piracy tip: Prevent debugging (Windows)

Posted: Mon Apr 23, 2018 10:43 am
by Dude
ar-s wrote:A small tip is to kill olly.exe process when it's detected.
Yes, but OllyDbg can launch your exes in "paused" mode (Ctrl+11), which can then be stepped through at will (F7). The cracker can then find the point in your app where the process detection exists, and remove it.

Re: Anti-piracy tip: Prevent debugging (Windows)

Posted: Mon Apr 23, 2018 11:28 am
by HanPBF
Tool "PELock" protects Your exe against debuggers.

Re: Anti-piracy tip: Prevent debugging (Windows)

Posted: Tue Apr 24, 2018 9:02 pm
by CELTIC88

Re: Anti-piracy tip: Prevent debugging (Windows)

Posted: Tue May 15, 2018 11:53 pm
by Opcode
You can call IsDebuggerPresent but it's easy to spot the function in the code. Using the process environment block to pull the return value is less suspicious.

Code: Select all

Procedure CheckForDebugger(Parameter.i)
  
  Protected.i IsDebuggerPresent = 0
 
  Repeat
   
    !mov eax, [fs:0x30]
    !mov al, [eax+2]
    !mov [p.v_IsDebuggerPresent], al
    
    If IsDebuggerPresent <> 0
      PrintN("Debugger Detected!")
      ExitProcess_(0)
    EndIf
    
    Delay(10)
   
  ForEver
 
EndProcedure

OpenConsole("Attach To Me")
CreateThread(@CheckForDebugger(), 0)

Repeat
  PrintN("Hai!")
  Delay(1000)
ForEver
There are better ways for detecting a debugger but this is just a simple way of many.

Re: Anti-piracy tip: Prevent debugging (Windows)

Posted: Wed May 16, 2018 1:03 am
by Dude
Opcode wrote:You can call IsDebuggerPresent but it's easy to spot the function in the code. Using the process environment block to pull the return value is less suspicious.

Code: Select all

OpenConsole()

Procedure CheckForDebugger(Parameter.i)
  
  Repeat
    
    !mov eax, [fs:0x30] 
    !mov al, [eax+2] 
    !test al, al 
    !jne ll_checkfordebugger_debuggerdetected
    !jmp ll_checkfordebugger_nodebuggerdetected
    
    DebuggerDetected:
    PrintN("Debugger Detected!")
    ExitProcess_(0)
    
    NoDebuggerDetected:
    Delay(10) ; Lets not hammer the CPU
    
  ForEver
  
EndProcedure

CreateThread(@CheckForDebugger(), 0)

Repeat
  PrintN("Hai!")
  Delay(1000)
ForEver
There are better ways for detecting a debugger but this is just a simple way of many.
Good example, Opcode -- it successfully detects OllyDbg here. I'll use that in my app. Another simple test is just to search all windows that have (say) "OllyDbg" in their title. I did that with an old app I wrote in Visual Basic many years ago, and my app simply wouldn't run if such a window was found. No error message or anything; just a silent quit. To the honest user this was never a problem because the app always ran; it was only crackers who suffered it and they should be smart enough to work out why. ;)

Re: Anti-piracy tip: Prevent debugging (Windows)

Posted: Sat May 26, 2018 8:56 am
by Opcode
Dude wrote:
Opcode wrote:You can call IsDebuggerPresent but it's easy to spot the function in the code. Using the process environment block to pull the return value is less suspicious.

Code: Select all

OpenConsole()

Procedure CheckForDebugger(Parameter.i)
  
  Repeat
    
    !mov eax, [fs:0x30] 
    !mov al, [eax+2] 
    !test al, al 
    !jne ll_checkfordebugger_debuggerdetected
    !jmp ll_checkfordebugger_nodebuggerdetected
    
    DebuggerDetected:
    PrintN("Debugger Detected!")
    ExitProcess_(0)
    
    NoDebuggerDetected:
    Delay(10) ; Lets not hammer the CPU
    
  ForEver
  
EndProcedure

CreateThread(@CheckForDebugger(), 0)

Repeat
  PrintN("Hai!")
  Delay(1000)
ForEver
There are better ways for detecting a debugger but this is just a simple way of many.
Good example, Opcode -- it successfully detects OllyDbg here. I'll use that in my app. Another simple test is just to search all windows that have (say) "OllyDbg" in their title. I did that with an old app I wrote in Visual Basic many years ago, and my app simply wouldn't run if such a window was found. No error message or anything; just a silent quit. To the honest user this was never a problem because the app always ran; it was only crackers who suffered it and they should be smart enough to work out why. ;)
Updated the code in original post to make more sense with PB, if that's of any help.

Re: Anti-piracy tip: Prevent debugging (Windows)

Posted: Sat May 26, 2018 5:42 pm
by CELTIC88
you can use this method

Code: Select all

;IncludeFile "c:\dasm.pb"

DisableDebugger
EnableASM
Procedure anti_debugging()
  ;origin code https://github.com/invictus1306/Anti-debugging-techniques/blob/master/anti-debugging.asm
  ;NtGlobalFlag - PEB!NtGlobalFlags
  XOR eax, eax
  !MOV eax, [fs:eax+0x30]
  MOV eax, [eax+0x68]
  AND eax, 0x70
  !DB 0xeb, 0x01
  !DB 0xff, 0x85, 0xC0 ;junk byte - test eax, eax
  JNE @Detected
  
  ;obfuscation
  !DB 0xeb, 0x02
  !DB	0xcc, 0xfe, 0xeb, 0x00
  
  ;IsDebuggerPresent first - kernel32!IsDebuggerPresent
  IsDebuggerPresent_()
  CALL @eip_manipulate ; change eip (point to next instruction)
  MOV eax, 0x10
  CMP eax, 1
  JE @Detected
  
  ;IsDebuggerPresent second - PEB!IsDebugged
  XOR eax, eax
  !MOV eax,  [fs:0x18]
  !MOV eax, DWORD [ds:eax+0x30]
  !MOVZX eax, BYTE [ds:eax+0x2]
  TEST eax, eax
  JNE @Detected
  
  ;FindWindows for ollydbg
  FindWindow_("OLLYDBG",0)
  TEST eax, eax
  JNE @Detected
  
  ;software breakpoint detection into MessageBox API
  CLD
  MOV edi, @Detected
  MOV ecx, 0x13
  MOV al,0xcc
  REPNE SCASB
  JZ @Detected
  
  ;hardware breakpoint detection
  PUSH HwBpHandler
  !PUSH dword [fs:0]
  !MOV DWORD [fs:0], esp
  XOR eax, eax
  DIV eax
  !POP DWORD [fs:0]
  NOP
  NOP
  NOP
  ADD esp, 8
  TEST eax, eax
  JNE @Detected
  
  ;get write permissions for self-modifying code
  XOR esi, esi
  XOR ecx, ecx
  MOV esi,  @encrypted_code
  PUSH esp
  PUSH esp
  PUSH #PAGE_EXECUTE_READWRITE
  PUSH 0x4
  PUSH esi
  CALL _VirtualProtect@16
  POP eax
  
  ;self-modifying code
  MOV eax, 0x1234   ;key
  MOV ecx, @encrypted_code
  
  !@loop_decryption:
  XOR [ecx], al ;very simple algorithm
  INC ecx
  CMP ecx, @encrypted_code + 0x4
  JNE @loop_decryption
  
  !@encrypted_code:
  DB 0x5e, 0x4  ;push 30h
  DB 0xdf, 0x34 ;jmp at next instruction 
  POP eax
  
  JMP skiip
  !@Detected:
  MOV eax, 1
  ProcedureReturn
  !skiip:
  XOR eax, eax    
  RET
  
  !@eip_manipulate:
  ADD dword [esp], 5
  RET
  
  !HwBpHandler:
  XOR eax, eax
  MOV eax, [esp + 0xc]     ; This is a CONTEXT structure on the stack
  CMP DWORD [eax + 0x4], 0 ; Dr0
  JNE bpFound
  CMP DWORD [eax + 0x8], 0 ; Dr1
  JNE bpFound
  CMP DWORD [eax + 0xc], 0 ; Dr2
  JNE bpFound
  CMP DWORD [eax + 0x10], 0 ; Dr3
  JNE bpFound
  JMP retFromException
  
  !bpFound:
  MOV DWORD [eax + 0xb0], -1 ; HW bp found
  
  !retFromException:
  ADD DWORD [eax + 0xb8], 6
  XOR eax, eax
  RET
  
  ;force the compiler to add this function
  VirtualProtect_(0,0,0,0)
EndProcedure
EnableDebugger
DisableASM


If anti_debugging() 
  MessageRequester(":(","Debugger detectd!")
Else
  MessageRequester(":)","Perfect!")
EndIf


but do not really protect your application :(

Image

patch.1337

Code: Select all

>test22.exe
000010B1:0F->90
000010B2:85->90
000010B3:B0->90
000010B4:00->90
000010B5:00->90
000010B6:00->90
000010CF:0F->90
000010D0:84->90
000010D1:92->90
000010D2:00->90
000010D3:00->90
000010D4:00->90
000010E6:75->90
000010E7:7F->90
000010FA:75->90
000010FB:6B->90

Re: Anti-piracy tip: Prevent debugging (Windows)

Posted: Sat Sep 07, 2019 9:30 am
by Opcode
Here's another method to add to the collection. Easy to implement, easy to bypass. Still something though.

Code: Select all

Procedure PatchDbgUiRemoteBreakin()
  
  Protected.l DbgAddr, oProtect
  
  DbgAddr = GetProcAddress_(GetModuleHandle_("ntdll.dll"), "DbgUiRemoteBreakin")
  
  VirtualProtect_(DbgAddr, 6, #PAGE_EXECUTE_READWRITE, @oProtect)
  
  PokeB(DbgAddr + 0, $68)
  PokeL(DbgAddr + 1, GetProcAddress_(GetModuleHandle_("kernel32.dll"), "ExitProcess"))
  PokeB(DbgAddr + 5, $C3)
  
  VirtualProtect_(DbgAddr, 6, oProtect, @oProtect)
  
EndProcedure

Re: Anti-piracy tip: Prevent debugging (Windows)

Posted: Sat Sep 07, 2019 10:15 am
by BarryG
Opcode wrote:Here's another method to add to the collection. Easy to implement, easy to bypass. Still something though.

Code: Select all

Procedure PatchDbgUiRemoteBreakin()
  
  Protected.l DbgAddr, oProtect
  
  DbgAddr = GetProcAddress_(GetModuleHandle_("ntdll.dll"), "DbgUiRemoteBreakin")
  
  VirtualProtect_(DbgAddr, 6, #PAGE_EXECUTE_READWRITE, @oProtect)
  
  PokeB(DbgAddr + 0, $68)
  PokeL(DbgAddr + 1, GetProcAddress_(GetModuleHandle_("kernel32.dll"), "ExitProcess"))
  PokeB(DbgAddr + 5, $C3)
  
  VirtualProtect_(DbgAddr, 6, oProtect, @oProtect)
  
EndProcedure
What does this do? And do you just call that procedure alone to protect your exe?

Re: Anti-piracy tip: Prevent debugging (Windows)

Posted: Sat Sep 07, 2019 10:32 am
by Everything
BarryG wrote:What does this do? And do you just call that procedure alone to protect your exe?
It's old useless antidebug trick which "patch" function address usually called by debuggers with 'ExitProcess' address :)