Anti-Reversing Techniques (Part 1)

0xM3H51N
InfoSec Write-ups
Published in
6 min readSep 6, 2022

--

https://www.flaticon.com/free-icons/software-development

Introduction

Anti-Reversing Techniques is very useful to protect your code especially if your business is depending on that code or what ever reason you might have to protect it from reversing or cracking, but in other case, Malware Authors tend to use anti reversing techniques to make the Process of Analyzing a malware or reversing it much harder. The techniques mentioned in this article is not the only techniques used out there, also it can goes from very simple like calling Windows API to complex techniques like writing a VM obfuscator to hide code flow, in this series of articles we will focus on Windows x86 binaries.

let’s begin…

Debugger Detection

One of the main tools used by Malware analyst and Reverse Engineers is a debugger, so what is a debugger?

A Debugger is a software used to test and have control over other software, in other word it makes you see what is happening under the hood like stopping the execution of the software on a single point, viewing the stack and registers etc... .

What malware Authors tend to do in there malwares is to detect if it is under debugger or not, and one of the simplest anti-debugging technique is :

IsDebuggerPresent():

https://docs.microsoft.com/en-us/windows/win32/api/debugapi/nf-debugapi-isdebuggerpresent

From the name of the function it is obviously checks if the calling process is being debugged, to use this function we do not need any arguments:

Code

if we run the executable without the debugger it will continue to the message “No debugger detected”:

but under a debugger it will detect that its being debugged and proceed to ExitProcess() function and terminate -by the way not any debug detection leads to terminating the software, the malware author could change the workflow to deceive the analyst- :

so how the detection happened!? to answer this question first we need to understand what is (TEB) and (PEB):

  • Thread Environment block (TEB): is a data structure that stores information about the current running thread in a process and every thread has it’s own TEB structure, and in Win32 environment the FS register always points at the TEB, while in a Win64 environment it’s the GS register.
  • Process Environment block (PEB): The PEB is a structure that contains data about the process, and when looking at the TEB we will find a pointer to the PEB structure.

for more on this topic this blog article is good one to read:

Anatomy of the Process Environment Block (PEB) (Windows Internals)

https://docs.microsoft.com/en-us/windows/win32/api/winternl/ns-winternl-teb
https://docs.microsoft.com/en-us/windows/win32/api/winternl/ns-winternl-peb

As we can see from the PEB structure that the second byte is the BeingDebugged member which is what the function IsDebuggerPresent checks to determine if the Process is under debugging or not. If it is the value will be 1 and 0 if it’s not. If we follow the call to our function IsDebuggerPresent we will find this:

  • Line1: moving the address of TEB structure to the eax register.
  • Line2: moving the address of PEB structure to the eax register which is TEB address + 30 = PEB address.
  • line3: moving the BeingDebugged member value to eax register.
  • line4: return the eax value to be tested.

After testing the register eax and according to the result we shall proceed to ExitProcess or jump and continue the execution of the software. Now to by pass this anti-debugging technique we change the value of the eax register from 0x1 to 0x0 after returning, or we can change the value of the BeingDebugged member in PEB structure which is the best way to do that, we can go to Memory Map and look for the address of the PEB which is 7EFDE000 and right click then Follow in Dump, or at the entry point of the software you will always find the ebx register points to the PEB structure also Follow in Dump, after that we right click on the value > Binary > Edit or use shortcut ctrl+e and change the value:

x64dbg: Following the PEB to dump
x64dbg: ebx register at the entry point
x64dbg: Editing the value of BeingDebugged member

But calling the IsDebuggerPresent API is very obvious to the analyst, that is why sometimes malware authors will do this check manually for example:

Code

Under debugger our code will look like:

The same bypassing technique also used here.

NtGlobalFlag:

The PEB structure has a member or a field called NtGlobalFlag at (offset x68) in win32 environment and if the process is being debugged it will have the value 0x70 and 0x0 if not.

To by pass this anti-debugging technique, you have to change the value to 0x0 like the past technique:

x64dbg: Editing the value of NtGlobalFlag member
Implementation of Checking the NtGlobalFlag

Note: The value of this member is not changed when a debugger attach to a process

CheckRemoteDebuggerPresent:

This function Checks if the process is being debugged by another process and it takes two arguments as it appear clearly above, what it’s important is that it is a wrapper for ZwQueryInformationProcess :

A license tellshttps://docs.microsoft.com/en-us/windows/win32/procthread/zwqueryinformationprocess

This function will retrieve information about the process if it is under a debugger or not, by specifying the second argument to ProcessDebugPort :

https://docs.microsoft.com/en-us/windows/win32/procthread/zwqueryinformationprocess
x64dbg: Inside the CheckRemoteDebuggerPresent Function

As it appear in the above picture the second argument passed to the ZwQueryInformationProcess is 7 which will retrieve information about the process if it is under a debugger or not. To by pass this technique we need to NOP both of the instruction highlighted in the picture above and the reason is the eax register will be set to 1 with instruction SETNE - sets the byte in the operand to 1 if the Zero Flag is clear, otherwise sets the operand to 0 - then move the value in the eax to where ESI register is pointing to to be compared after returning from this routine:

x64dbg: Inside the CheckRemoteDebuggerPresent Function

After returning from the routine we see a comparison between the value 0 and where the ESP is pointing to, and it appear in low right corner the value after NOP-ing the instruction is 0, in a normal case it would be 1, so after continuing the execution we shall get the message “No debugger detected”:

x64dbg: Comparing the result after returning from CheckRemoteDebuggerPresent

Thanks for reading and hope it was beneficial, see you on (part2) as soon as possible 🙂.

From Infosec Writeups: A lot is coming up in the Infosec every day that it’s hard to keep up with. Join our weekly newsletter to get all the latest Infosec trends in the form of 5 articles, 4 Threads, 3 videos, 2 Github Repos and tools, and 1 job alert for FREE!

--

--