Jump to content
Tuts 4 You

Anti-Debugging

Techniques for detecting, preventing and circumventing debugging practices...

13 files

  1. Windows Anti-Debug Reference

    This paper classifies and presents several anti-debugging techniques used on Windows NT-based operating systems.

    Anti-debugging techniques are ways for a program to detect if it runs under control of a debugger. They are used by commercial executable protectors, packers and malicious software, to prevent or slow-down the process of reverse-engineering.
    We'll suppose the program is analyzed under a ring3 debugger, such as OllyDbg on Windows platforms. The paper is aimed towards reverse-engineers and malware analysts.
    Note that we will talk purely about generic anti-debugging and anti-tracing techniques. Specific debugger detection, such as window or processes enumeration, registry scanning, etc. will not be addressed here.

    510 downloads

    0 comments

    Updated

  2. The Ultimate Anti-Debugging Reference

    A debugger is probably the most commonly-used tool when reverse-engineering (a disassembler tool such as the Interactive DisAssembler (IDA) being the next most common). As a result, anti-debugging tricks are probably the most common feature of code intended to interfere with reverse-engineering (and anti-disassembly constructs being the next most common). These tricks can simply detect the presence of the debugger, disable the debugger, escape from the control of the debugger, or even exploit a vulnerability in the debugger. The presence of a debugger can be inferred indirectly, or a specific debugger can be detected. Disabling or escaping from the control of the debugger can be achieved in both generic and specific ways. Exploiting a vulnerability, however, is achieved against specific debuggers. Of course, the debugger does not need to be present in order for the exploit to be attempted.
    Typically, when a debugger loads, the debuggee's environment is changed by the operating system, to allow the debugger to interact with the debuggee (one exception to this is the Obsidian debugger). Some of these changes are more obvious than others, and affect the operation of the debuggee in different ways. The environment can also be changed in different ways, depending on whether a debugger was used to create a process, or if the debugger attaches to process that is running already.
    What follows is a selection of the known techniques used to detect the presence of a debugger, and in some cases, the defences against them.
    Note: This text contains a number of code snippets in both 32-bit and 64-bit versions. For simplicity, the 64-bit versions assume that all stack and heap pointers, and all handles, fit in 32 bits. They also rely on the fact that the PEB is always located in low memory.

    498 downloads

    0 comments

    Updated

  3. The Superdiversifier: Peephole Individualization for Software Protection

    We present a new approach to individualize programs at the machine and byte-code levels. Our superdiversification methodology is based on the compiler technique of superoptimization, which performs a brute-force search over all possible short instruction sequences to find minimum-size implementations of desired functions. Superdiversification also searches for equivalent code sequences, but we guide the search by restricting the allowed instructions and operands to control the types of generated code. Our goal is not necessarily the shortest or most optimal code sequence, but an individualized sequence identified by a secret key or other means, as determined by user-specified criteria. Also, our search is not limited to commodity instruction sets, but can work over arbitrary byte-codes designed for software randomization and protection. Applications include patch obfuscation to complicate reverse engineering and exploit creation, as well as binary diversification to frustrate malicious code tampering. We believe that this approach can serve as a useful element of a comprehensive software-protection system.

    158 downloads

    0 comments

    Updated

  4. The Art of Unpacking

    Unpacking is an art-it is a mental challenge and is one of the most exciting mind games in the reverse engineering field. In some cases, the reverser needs to know the internals of the operating system in order to identify or solve very difficult ant-reversing tricks employed by packers/protectors, patience and cleverness are also major factors in a successful unpack. This challenge involves researchers creating the packers and on the other side, the researchers that are determined to bypass these protections.
    The main purpose of this paper is to present anti-reversing techniques employed be executable packers/protectors and also discuss techniques and publicly available tools that can be used to bypass or disable this protections. This information will allow researchers, especially, malcode analysts to identify these techniques when utilized by packed malicious code, and then be able decide the next move when these anti-reversing techniques impede successful analysis. As a secondary purpose, the information presented can also be used by researchers that are planning to add some level of protection in their software by slowing down reversers from analyzing their protected code, but of course, nothing will stop a skilled, informed, and determined reverser.

    376 downloads

    0 comments

    Updated

  5. Software Protection Against Reverse Engineering Tools

    Advances in technology have led to the use of simple to use automated debugging tools which can be extremely helpful in troubleshooting problems in code. However, a malicious attacker can use these same tools. Securely designing software and keeping it secure has become extremely difficult. These same easy to use debuggers can be used to bypass security built into software. While the detection of an altered executable file is possible, it is not as easy to prevent alteration in the first place. One way to prevent alteration is through code obfuscation or hiding the true function of software so as to make alteration difficult. This research executes blocks of code in parallel from within a hidden function to obscure functionality.
    This method is tested on six programs; a DOS version of the UNIX grep utility and five computational functions: Fast Fourier Transfer, Successive Over-Relaxation, Sparse matrix-multiply, Monte Carlo integration, and dense LU factorization. It tests the impact of using four, eight, and twelve parallel threads of execution to obscure functionality.
    The concept is effective, but is limited due to the cost associated with using threads. The computational functions make millions of calls to the hidden function. The average cost per thread for these five functions turns out to be 7.04906 x 10-6 seconds. The grep function does not make millions of calls and is therefore more feasible. Care must be taken to ensure the compiler does not remove parallel threads if optimization is used.

    257 downloads

    0 comments

    Updated

  6. OllyDbg Detection Tricks

    The year is 2004. The ring-3 debuggers are used often and often. Since they offer Windows GUI they are more handy instead of the ring-0 debuggers (like SoftIce). In this essay I will talk (write) about the detection of one of the best ring-3 debuggers - OllyDbg. Many have heard of the IsDebbugerPresent and of the fs:[20] detecting tricks, but what about some other new ones? Here I will present you some of my own detecting tricks. I will give you the general explanation so you would be able to use your fantasy to improve it yourself.

    238 downloads

    0 comments

    Updated

  7. Improving the HideDebugger Function

    Improving of the HideDebuger function with sources and a detailed drill down into Windows internals anti-debugging function.

    208 downloads

    0 comments

    Updated

  8. EventPairHandle as AntiDebug Trick

    An EventPair Object is an Event constructed by two _KEVENT structures which are conventionally named High and Low. EventPairs are used for synchronization in Quick LPC, they allow the called thread to continue the current quantum, reducing scheduling overhead and latency. Now by looking to the basic operation that a debugger need to accomplish, we can see that these tasks are conceptuall simple, when the target is normally running, the debugger is sleeping, but when certain events occur Dbg Wakes Up. Became clear that there is a strict relation between generic Event Objects and Debuggers cause they have to create a custom Event called DebugEvent able to handle exceptions. Due to the presence of Event owned by the Debugger, every information relative to the Events of a normal process differs from a debugged process.

    145 downloads

    0 comments

    Updated

  9. Defeating Anti-Debugs in OllyDbg

    This video tutorial is not for complete unpacking... just some tricks for kill antidebugs in HyperUnpackMe2 and run it in OllyDBG just for fun...

    281 downloads

    0 comments

    Updated

  10. Counter-Measures Cheat Sheet (Anti-Debug)

    A printable cheat sheet of anti-debugging techniques:
    Generics
    BeingDebugged: PEB.BeingDebugged db [fs:[30] + 2] == 1 IsDbgPresent: BeingDebugged check, via IsDebuggerPresent NtGlobalFlag: PEB.NtGlobalFlag dd [fs:[30] + 68] has 70 set HeapFlags: Heap.Flags dd [[fs:[30] + 18] + C] == 2 ForceFlags: Heap.ForceFlags dd [[fs:[30] + 18] + 10] is not null msvcrt!trigo: msvcrt!CIasin(invalid) => al = NtGlobalFlag ? a8 : 98 deletefiber: DeleteFiber(invalid) => LastError = ForceFlags ? 80000003 : 57 gs: GS is reset, on thread switch pop ss: debuggers can't step right after pop SS => TF set in EFlags, 100 via pushf smsw: operand = just after FPU ? 80010031 : 8001003b int 2c/2e: slides over next instruction + sets EDX to next EIP, but incorrect if stepped int 2d: triggers BREAKPOINT exception if not under a debugger InvalidHandle: CloseHandle(invalid) ! INVALID HANDLE exception if debugger is present ChkRemoteDbg: CheckRemoteDebuggerPresent(GetCurrentProcess(),;&result) = 1 : 0 NtQueryInfo: NtQueryInformationProcess(-1,ProcessDebugPort =7, var, ...) => [var] = present ?-1:0 HideThread: NtSetInformationThread(-2,ThreadhideFromDebugger= 11, -1, 0) => not responding csr: OpenProcess(..., 0,CsrGetProcessId()) => no error if SeDebugPrivilege acquired Timing: comparison of two RDTSC, inlined GetTickCount, GS resets, ... Timing API: comparison of two APIs like GetTickCount, GetSystemTime, QueryPerformanceCounter, ... Exceptions tricks (in the exception handler):
    jmp: change resume address via Context.regEIP (Context+B8) step: step next instruction and re-trigger via setting TF in Context.EFlags (Context+C0) hwbp: set or detects hardware breakpoint via Context.dr* (Context+04/+18) higher: overwrite higher handler and trigger exception ([esp+18]) return: overwrite return address in stack ! context re-loading is skipped ([esp+24]) Ollydbg (1.1) specific:
    esi: esi = -1 on startup under ollydbg, not in general FPU: Display FFFFFFFF FFFFFFFF C0/40 3D as float => crash OdbgStr: OutputDebugStringA("%s%s") => crash VmWare specific:
    backdoor: in 'VMXh', 'VX' => exception if not present, else modifed eax and ebx sidt: [operand + 5] == e8 or ff if present sldt: result != 0 if present str: result == 4000h if present Reminders:
    TF is used by a debugger for stepping: set TF, an exception will be triggered after next execution is stepped TEB is at fs:[18] the PEB is accessible directly (fs:[30]) or via TEB.EnvironmentPointer ([fs:[18] + 30]) LastError is accessible via TEB.LastErrorValue ([fs:[18] + 34]) => GetLastError is inlinable GetCurrentProcess = FFFFFFFF (constant value) GetCurrentThread = -2 (constant value) CsrGetProcessId= dword[7C980380] => (inlineable) GetTickCount = dword [7FFE0000] * dword[7FFE0004]) >> 24 => inlineable  

    193 downloads

    0 comments

    Updated

  11. Anti-Unpacker Tricks

    Anti-unpacking tricks can come in different forms, depending on what kind of unpacker they want to attack. The unpacker can be in the form of a memory-dumper, a debugger, an emulator, a code-buffer, or a W-X interceptor. It can be a tool in a virtual machine. There are corresponding tricks for each of these, and they will be discussed separately.
    - A memory-dumper dumps the process memory of the running process, without regard to the code inside it.
    - A debugger attaches to the process, allowing single-stepping, or the placing of breakpoints at key locations, in order to stop execution at the right place. The process can then be dumped with more precision than a memory-dumper alone.
    - An emulator, as used within this paper, is a purely software-based environment, most commonly used by anti-malware software. It places the file to execute inside the environment and watches the execution for particular events of interest.
    - A code-buffer is similar to, but different from, a debugger. It also attaches to a process, but instead of executing instructions in-place, it copies each instruction into a private buffer and executes it from there. It allows fine- grained control over execution as a result. It is also more transparent than a debugger, and faster than an emulator.
    - A W-X interceptor uses page-level tricks to watch for write-then-execute sequences. Typically, an executable region is marked as read-only and executable, and everything else is marked as read-only and non-executable (or simply non-present, depending on the hardware capabilities). Then the code is allowed to execute freely. The interceptor intercepts exceptions that are triggered by writes to read-only pages, or execution from non-executable or non-present pages. If the hardware supports it, a read-only page will be replaced by a writable but non-executable page, and the write will be allowed to continue. Otherwise, the single-step exception will be used to allow the write to complete, after which the page will be restored to its non-present state. In either case, the page address is kept in a list. In the event of exceptions triggered by execution of non-executable or non-present pages, the page address is compared to the entries in that list. A match indicates the execution of newly-written code, and is a possible host entrypoint.

    273 downloads

    0 comments

    Updated

  12. Anti-Debugging - A Developers View

    Anti-debugging is the implementation of one or more techniques within computer code that hinders attempts at reverse engineering or debugging a target binary. Within this paper we will present a number of the known methods of anti-debugging in a fashion that is easy to implement for a developer of moderate expertise. We will include source code, whenever possible, with a line by line explanation of how the anti-debugging technique operates. The goal of the paper is to educate development teams on anti-debugging methods and to ease the burden of implementation.

    214 downloads

    0 comments

    Updated

  13. Anti-Reverse Engineering Guide

    An individual reading this should have a solid understanding of ASM, how computers handle memory, the Win32 Debugging API, and at least some knowledge of Windows internals. This code most likely will not work on any *nix platform due to the fundamental differences of the Operating Systems. Any other knowledge in the field of reverse engineering is also a plus. One great thing about learning and implementing anti-debugging is that you also develop your reversing skills, which is a great plus to anyone interested in the field. Along with the other mentioned subjects, an interested reader should also be familiar with the tools used for binary application reversing such as OllyDBG, WinDBG, SoftICE, IDA Pro, and others.

    703 downloads

    0 comments

    Updated


×
×
  • Create New...