This program resulted from failed attempt to 'fix' architectural inconsistencies of the Windows 95 Win32 memory model, sometimes referred to as the Dangerous Memory Model (DMM). The program reveals a large amount of interesting run-time information about other programs taking advantage of the DMM. It's been enough said about the DMM and I myself touched on the subject quite a bit sich as in my chapter on Regspy95 in 'Inside the Windows 95 Registry'. To reiterate, the problem (at least potential) of this model is that with the current architecture (and as DMMSPY unambiguosly shows, it's still the same in the Beta 2 of Memphis), while Win32 programs are physically isolated from each other, the system components are quite within their reach.
DMMSPY is a combination of the Win32 GUI application and a VxD. The programs spies upon and records, down to the machine instruction level, any attempt by Ring 3 applications, whether Win16 or Win32, to access any part of memory outside their conventional user-mode memory areas through the common Win32 data selector. Figure 1 depicts the top-level Windows 95 memory layout. The bottommost 4 MByte area called MS-DOS Memory Arena is where the current Virtual Machine is mapped. Changing each other, Win32 programs get mapped into the Private Memory Arena. The next part, Shared Memory Arena is for Win16 applications and DLLs, and for the Win32 system DLLs like Kernel32, User32 , and so on. Finally, the upper 1 GByte part is where the VMM and VxDs are loaded.
Fig. 1 Windows 95 top-level memory map
In theory, there is no need for regular user-mode code to directly access anything in MS-DOS and System Memory arenas. Theory notwithstanding, DmmSpy watches for and finds quite many such accesses. Here is a sample screen shot (approx. 50K bytes worth of download) taken immediately after DmmSpy has started. To start spying, pick 'System Arena' or 'DOS Arena' option from the 'Spying on...' menu. DmmSpy doesn't spy on accesses to both arenas at the same time simply because I was unable to figure out how this could be done. When you feel enough is enough, click on 'Stop Spying'. DmmSpy then shows disassembled machine instructions that made 'unlawful' memory accesses along with the names of Ring 3 programs or DLLs these instructions belong to. In addition, it shows run-time memory and CPU register values for the instructions, and the addresses of memory cells whitin System or MS-DOS arenas that had been touched. As you can see from this output, the vast majority of accesses to the DOS and System memory arenas come from 2 built-in Ring 3 Windows components: 32-bit KERNEL32.DLL and 16-bit KRNL386..EXE. It's up to you to decide whether this has any significant meaning.
DmmSpy and its companion DMM.VXD are complex.software realization of a quite simple idea. Win32 flat memory model is implemented in the same manner as it is for VxDs. That is, all Win32 modules, applications and DLLs receive the same pair of code and data selectors that cover the entire 4 GBytes of the virtual address space. These selectors are transparently mapped to the linear address space, so that, for example, the virtual address 25 is mapped to the linear address 25. Actually, Win32 data selector is not so 'flat'. Because this is an expand-down selector, it effectively cuts off a small chunk of memory (about 64K on my machine) at the very beginning of MS-DOS memory arena. This arrangement automates trapping of null-pointers by the system's fault handler. DmmSpy changes this arrangement by remapping the Win32 data selector in one of two ways: either the System Arena or the entire MS-DOS arena get moved out of selector's coverage area by this remapping. As a result, memory accesses to the excluded areas through the Win32 data selector will generate either the GPF (General Protection Fault) or the Stack Fault. DMM.VXD installs trap handlers for both of these..
In Windows 95, faults occur for a broad variety of reasons and we are only interested in one. To determine whether and how it should handle a particular fault, DMM.VXD has a buit-in run-time disassembler which takes faulty instructions apart and analyzes the operand parts looking for our case. Everything else is filtered out by simply passing control down to the chain of fault handlers. Because DmmSpy has to be a non-intrusive observer, the next step is to emulate the instruction that generated the fault. This is done by built-in opcode interpreter in the manner similar to Simulate_Push family of VMM services. Finally, DMM.VXD records the instruction and the pertinent run-time information in queue and signals an event for DmmSpy to pick up. When the time comes to put this information in view, DmmSpy has an interface to that queue, this avoids recursion and the Heisenberg effect.
This page has been visited times since Mar-24-1998