Nearly every attack on a software application begins with reverse engineering its code to understand how it works and find flaws to exploit. Once the inner workings of the target application are understood, attackers can tamper with the code, circumvent security restrictions, change app behavior, and steal secret keys and sensitive data—which is why reverse engineering is one of the OWASP top 10 application risks. One of the first steps of reverse engineering is running the application through a debugger.
What are debuggers?
Debuggers allow developers to test their programs under controlled conditions to see how the underlying code reacts. They perform an essential service in allowing developers to check their code for bugs that could stop the app or program from performing as intended or unintentionally provide access to locally stored data or servers.
Unfortunately, while debuggers are not intended to be used for malicious purposes, the debugging process allows attackers to observe an application in action under different conditions and is the basis of most program hacking operations.
Why anti-debugging techniques are important
Since debugging is such a major part of hacking, application protection solutions must deploy anti-debugging techniques to keep programs safe.
As we’ve looked at before, these anti-debugging techniques enable applications to self-protect even when they are outside of a secure development environment. There are several different strategies employed to enable an app to detect the presence of a debugger being used. Here, we’ll look at some of the most important.
Nine anti-debugging techniques for application security
1. Using system API calls
As debugging is common for developers, many systems provide APIs to use in the debugging process. One of the simplest anti-debugging techniques is to employ these API calls to find out whether or not a debugger is being used. For example, the Windows debugging API provides the function KERNEL32.IsDebuggerPresent. As simple as they are to use, API calls are unfortunately also among the easiest anti-debugging techniques to circumvent.
2. Detecting modifications in the code
One of the primary debugging techniques relies on modifying the original code by inserting and removing instructions from code strings. That means that an app can be programmed to correlate these actions with the presence of a debugger and subsequently execute defensive measures. Although this can be difficult to accomplish successfully, it is among the most effective anti-debugging techniques. It is one of the key features of our application shielding solution, whiteCryption Code Protection.
3. Using exceptions in code
Debuggers are designed to handle certain exceptions in code. This means that during the debugging process, it’s possible to recognize that a debugger is present because of the exceptions that aren’t executed. It is a relatively complex process but still well within the remit of a quality cybersecurity professional.
During an application’s runtime, a new process can be created that will try to attach itself as a debugger of the original parent process. However, if another debugger is already attached, this process will fail, thus alerting the application to the presence of a debugger. The action can be slower due to the necessity of starting a new process but is among the most potent anti-debugging techniques. Self-debugging is among the variety of strategies that our Code Protection solution offers to detect and prevent debugging.
5. Exploiting bugs in popular debuggers
As a perfect illustration that creating a bug-less program or application is nearly impossible, some of the most widely-used debuggers have flaws that cause them to crash or behave other than intended. By introducing instructions or data values known to cause these problems, the debugger can be revealed and nullified. This anti-debugging technique can be simple to execute for those with knowledge of common debuggers and is also a feature of Code Protection’s anti-debugging defenses.
6. Hardware breakpoint detection
Hardware may contain specific debug registers to assist developers in debugging and testing code. As part of a security solution, such as Code Protection, the use of these hardware breakpoints can be read and detected, alerting the application to a debugger’s presence.
7. Detecting the libraries commonly used by debuggers
As certain libraries are used by some debugging and instrumentation tools, the application may call for their use. If they are attached, it indicates the presence of a debugger.
8. Timing-based detection
As the debugging process interrupts a program’s execution, the latency between expected execution time and the actual one can be used to identify an attached debugger. This anti-debugging technique can be rendered less effective if the code is being executed across a range of different devices where such differences in timing would be normal.
9. Diversifying anti-debugging techniques
When used individually, each anti-debugging technique can be overcome with time and knowledge. By mixing up and diversifying the anti-debugging techniques that are used and spreading them across the code, the task of reverse-engineering the application becomes significantly more difficult. This is a core feature of how Code Protection’s anti-debugging defense works with various anti-debug checks being inserted at random places in code so that a hacker is not presented with a uniform or linear challenge.
Stop attacks at the source
Stopping programs and applications from being hacked or injected with malware is a constant struggle for software developers and publishers. As the basis for these hacks is usually reverse-engineering, stopping these attacks at source is one of the most important security battles to win.
Intertrust’s focus on robust application protection has seen us create one of the most effective solutions on the market. whiteCryption Code Protection provides an extremely effective package of diversified anti-debugging techniques and multiple other application shielding strategies to secure the entire code base against reverse engineering and tampering, making it extremely difficult and time-consuming for attackers to hack any application under our protection.
About Juris Olekss
A seasoned security professional, Juris has spent more than 17 years in the IT and security industries, with the majority dedicated to software security. Juris currently serves as a Senior Technical Writer for Intertrust’s whiteCryption application shielding solutions.