Today’s post revisits the concept of memory access breakpoints. Before I started this series, I wrote a post showing a proof of concept technique for setting a memory breakpoint on a wide range of memory using SDbgExt’s !vprotect command, PAGE_GUARD pages, and WinDbg. However, there’s more to be said about memory access breakpoints than meets the eye.
As I have mentioned in the previous post, hardware breakpoints on Intel x86/x64 CPUs can be configured to fire on reads or writes to a specific memory location, whose size cannot exceed the size of the system word*. DBX, on the other hand, allows access breakpoints on memory ranges of arbitrary size. Furthermore, DBX allows you to configure the breakpoint to fire before or after the memory access has taken place, as opposed to hardware breakpoints that are always fired after the event has occurred.
Below is an example of using DBX’s memory access breakpoints:
(dbx) list
28 getchar();
29 ms2.next = &ms2;
30 getchar();
31 ms.y = 14;
32 ms1.y = 13;
33 getchar();
(dbx) stop access wb &ms
(3) stop access wb &ms, 12
(dbx) cont
watchpoint wb &ms (0x8068f04[12]) at line 31 in file "stl.cc"
31 ms.y = 14;
(dbx) print ms.y
ms.y = 0
...
(dbx) list
26 getchar();
27 a.arr[678] = 'a';
28 getchar();
(dbx) stop access w &a
(3) stop access wa &a, 1000
(dbx) cont
watchpoint wa &a (0x8047846[1000]) at line 27 in file "stl.cc"
27 a.arr[678] = 'a';
(dbx) print a.arr[678]
a.arr[678] = 'a'
There are two things worth noting here: first, there is no need to specify the size of anything—DBX deduces size information from the variable itself; second, the memory breakpoint indeed works for a range that is larger than what hardware breakpoints allow.
Read more: All Your Base Are Belong To Us
0 comments:
Post a Comment