Uninformed: Informative Information for the Uninformed

Vol 7» 2007.May

Previous Work

The ideas described in this paper benefit greatly from the concepts demonstrated in previous works. The memory mirroring concept described in 2.2 draws heavily from the PaX team's work relating to their VMA mirroring and software-based non-executable page implementations[9]. Oded Horovitz provided an implementation of the paging approach for Windows and applied it to application security[5]. In addition, there have been other examples that use concepts similar to those described by PaX to achieve additional results, such as OllyBone, ShadowWalker, and others[11,10]. The use of DBI in 2.1 for memory analysis is facilitated by the excellent work that has gone into DynamoRIO, Valgrind, and indeed all other DBI frameworks[4,12].

It should be noted that if one is strictly interested in monitoring writes to a memory region, Windows provides a built-in feature known as a write watch. When allocating a region with VirtualAlloc, the MEM_WRITE_WATCH flag can be set. This flag tells the kernel to track writes that occur to the region. These writes can be queried at a later point in time using GetWriteWatch[7].

It is also possible to use guard pages and other forms of page protection, such as PAGE_NOACCESS, to intercept memory access to a page in user-mode. Pedram Amini's PyDbg supports the concept of memory breakpoints which are implemented using guard pages[2]. This type of approach has two limitations that are worth noting. The first limitation involves an inability to pass addresses to kernel-mode that have had a memory breakpoint set on them (either guard page or PAGE_NOACCESS). If this occurs it can lead to unexpected behavior, such as by causing a system call to fail when referencing the user-mode address. This would not trigger an exception in user-mode. Instead, the system call would simply return STATUS_ACCESS_VIOLATION. As a result, an application might crash or otherwise behave improperly. The second limitation is that there may be consequences in multi-threaded environments where memory accesses are missed.