Most debuggers are capable of displaying a stack trace. A stack trace is an
analysis of the contents of the stack at any given time, in this case the time of the crash, to
break the stack down into the frames associated with each function call that preceded
the point of the crash. A valid stack trace can indicate the sequence of function calls that
led to the crash, and thus the execution path that must be followed to reproduce the
crash. An example stack trace for a simple program is shown next:
Breakpoint 1, 0x00401056 in three_deep ()
(gdb) bt
#0 0x00401056 in three_deep ()
#1 0x0040108f in two_deep ()
#2 0x004010b5 in one_deep ()
#3 0x004010ec in main ()
This trace was generated using gdb??™s bt (backtrace) command. OllyDbg offers nearly
identical capability with its Call Stack display, as shown in Figure 18-2.
Unfortunately, when a vulnerability involves stack corruption, as occurs with stackbased
buffer overflows, a debugger will most likely be unable to construct a proper stack
trace. This is because saved return addresses and frame pointers are often corrupted,
making it impossible to determine the location from which a function was called.
Figure 18-1 OllyDbg register display
Chapter 18: From Vulnerability to Exploit
463
PART IV
The second case to consider when analyzing eip is whether eip points to a completely
unexpected location such as the stack or the heap, or better yet, whether the contents of
eip resemble our user-supplied input.
Pages:
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808