Reversing : The Hacker's Guide to Reverse Engineering

(ff) #1
the program (such as the address of a certain variable) or it could simply be a
code address within the executable (in which case the hardware breakpoint
provides equivalent functionality to a software breakpoint).
Once a breakpoint is hit, users typically step through the code in order to
analyze it. Stepping through code means that each instruction is executed indi-
vidually and that control is returned to the debugger after each program
instruction is executed. Single-stepping is implemented on IA-32 processors
using the processor’s trap flag (TF) in the EFLAGSregister. When the trap flag
is enabled, the processor generates an interrupt after every instruction that is
executed. In this case the interrupt is interrupt number 1, which is the single-
stepinterrupt.

The IsDebuggerPresent API


IsDebuggerPresentis a Windows API that can be used as a trivial tool for
detecting user-mode debuggers such as OllyDbg or WinDbg (when used as a
user-mode debugger). The function accesses the current process’s Process Envi-
ronment Block (PEB) to determine whether a user-mode debugger is attached.
A program can call this API and terminate if it returns TRUE, but such a method
is not very effective against reversers because it is very easy to detect and
bypass. The name of this API leaves very little room for doubt; when it is called,
a reverser will undoubtedly find the call very quickly and eliminate or skip it.
One approach that makes this API somewhat more effective as an antide-
bugging measure is to implement it intrinsically, within the program code.
This way the call will not stand out as being a part of antidebugger logic. Of
course you can’t just implement an API intrinsically—you must actually copy
its code into your program. Luckily, in the case of IsDebuggerPresentthis
isn’t really a problem, because the implementation is trivial; it consists of four
lines of assembly code.
Instead of directly calling IsDebuggerPresent, a program could imple-
ment the following code.

mov eax,fs:[00000018]
mov eax,[eax+0x30]
cmp byte ptr [eax+0x2], 0
je RunProgram
; Inconspicuously terminate program here...

Assuming that the actual termination is done in a reasonably inconspicuous
manner, this approach would be somewhat more effective in detecting user-
mode debuggers, because it is more difficult to detect. One significant disad-
vantage of this approach is that it takes a specific implementation of the
IsDebuggerPresentAPI and assumes that two internal offsets in NT data
structure will not change in future releases of the operating system. First, the

332 Chapter 10

Free download pdf