Anti-debugging 0x04

2 minute read

Introducation

the last week i published IsDebuggerPresent()technique which function available in the kernel32.dll library. This function is often used in malware to complexify the reverse engineering because it will take different paths in the program’s flow when the malware is analyzed in a user-mode debugger such as x32dbg and the most widely used anti-debugging method in Windows, Here i will be going through anothor very commen technique that malware authors use it, CheckRemoteDebuggerPresent() from kernel32.dll.

CheckRemoteDebuggerPresent()

image(1)

Description

  • This Windows API can be used to detect if the calling process is being debugged through any debugger, but also if another process is being debugged.

Syntax

MSDN

BOOL CheckRemoteDebuggerPresent(
  HANDLE hProcess,
  PBOOL  pbDebuggerPresent
);

Debugger

push pbDebuggerPresent_address ---> push the address of a 32 bit variable
push Process__handle           ---> push the handle to a process ( 1 for the calling process)
// call
CheckRemoteDebuggerPresent    ---> call the API
mov eax , pbDebuggerPresent_address ] ---> check the returned result in the variable
test eax,eax
jne _debuggerfound            ----> if not zero, a debugger was found.

C/C++ Code

BOOL bDebuggerPresent;
if (TRUE == CheckRemoteDebuggerPresent(GetCurrentProcess(), &bDebuggerPresent) &&
    TRUE == bDebuggerPresent)
    ExitProcess(-1);

x86 Assembly

lea eax, bDebuggerPresent]
    push eax
    push -1  ; GetCurrentProcess()
    call CheckRemoteDebuggerPresent
    cmp [bDebuggerPresent], 1
    jz being_debugged
    ...
being_debugged:
    push -1
    call ExitProcess

x86 Assembly

  lea rdx, [bDebuggerPresent]
    mov rcx, -1 ; GetCurrentProcess()
    call CheckRemoteDebuggerPresent
    cmp [bDebuggerPresent], 1
    jz being_debugged
    ...
being_debugged:
    mov ecx, -1
    call ExitProcess

return Value

  • If this function return 1 —–> Debugger Found!
  • If this function return 0 —> Debugger is not Found!

    Bypass CheckRemoteDebuggerPresent

    Stage(1)

  • I will put breakpoint in CheckRemoteDebuggerPresent() function
  • Press F9 to run sample image(20)

Stage(2)

  • press f7 to enter in this funtion and bypass the trick.
  • When i press F8 in function to bypass the trick , i find this function NtQueryInformationProcess() which retrieves information about the specified process. Capture.

Stage(3)

  • Look at EAX at register EAX –> 0000000
  • Look at stack in the value being debugged —> FFFFFFFF
  • Compare the two values
  • To bypass this trick must be changedffffffff (being debugged) to 0 because any value is not equal 0 the sample will terminate itself. Capture2

Stage(4)

  • We notice that line XOR EAX , EAX —-> EAX —->0
  • I will click right in line that compare two value —> Assemble—> change CMP to MOV and click assemble image3

Stage(5)

  • Press F8
  • We see call that terminates sample not execute
  • Nice to bypass this trick. image4

References

  • https://anti-debug.checkpoint.com/techniques/debug-flags.html#using-win32-api-checkremotedebuggerpresent
  • https://www.codeproject.com/Articles/29469/Introduction-Into-Windows-Anti-Debugging
  • https://xorl.wordpress.com/2017/12/09/the-checkremotedebuggerpresent-anti-debugging-technique/
  • https://docs.microsoft.com/en-us/windows/win32/api/winternl/nf-winternl-ntqueryinformationprocess