                Dream Of Every Reverser
                
                                deroko of ARTeam
                                
Theory and coding

 To make working r0 memory tracer some rules must be defined.
 
 - r3 memory is pagable
 - no way to lock that memory
 - SwapContext hook is required
 
Ring0 memory is pagable, and as I know there is no way to lock it in physical
memory such that virtual address always = physical locked address. I have
tried with MmProbeAndLockPages but according to Microsoft Description [1], it
locks only physicl pages in memory but it doesn't assure that when translation
ocurrs VirtualMemory will be resolved as locked Physical Pages. That's why MS
states that even MmIsAddressValid can return false on such locked pages. For
the record MmIsAddressValid checks P bit in PDE/PTE for certain address. 

When memory is pagable, there are two ways to control access to it.

- when P bit is 0 and page is paged out then page fault will be raised and OS
  should bring this page back : we log action thanks to ErrorCode and call
  default handler
- when page is present in physical memory then U/S bit in PTE can be used to
  track user access to this memory. Of cours, thx to error code we know what
  happened (r/w and using eip determine if it is execution).
  
When there is r/w on a given range, set TF and execute instruction and after
instruction is executed change permisson on range again (eg. set mbreak). If
we are also monitoring RW TF is a must have, as TLB tracing nooks RW break until
SwapContext (eg. mov cr3, NewPageTable isn't executed or in simpler words TLB
isn't flushed).

Hook of SwapContext is needed to clear and set permissions on page when traced
process is about to execute or execution is changed to new process. Due to 
execution of new process it is possible that traced memory will be paged out
in r3, so when this process is about to execute again we have to clear U bit
on this new pages. We must not assume that this pages won't be paged out, this
is pagable memory and everything has to be considered!!! It is even possible
that memory which was paged out will be paged in while we are not executing
our traced process -> NtReadVirtualMemory is good example.

PAE memory access special case:

In my tests there was something quite odd. While running tests on system w/o
PAE pages which had PAGE_xxxxWRTIE set, had W bit set in PTE, on PAE this
wasn't the case. On PAE system even if page has PAGE_xxxxWRITE set it doesn't
have W bit set. Instead windows uses high bits of PAE. You may see this 
special case handling in : PaeSpecialCase procedure. So even if page is in
memory (P set) and if write occurs, we still have to pass execution to
KiTrap0E. I ASSUME that windows uses this reserved bits to apply memory
access w/o need to page out paged in page on which protection is changed.
Just assumption, don't trust me on this one as I din't have will to 
investigate it :)

That's all about this tracing concept...

Limitation in this public version:
1. no r3/r0 communication
2. no mp support (read source, you will see code that needs to be added
                  for MP support)
3. due to hook in SwapContext Kaspersky AV is not supported, and never
   will be, untill they stop hooking it :)

                                                deroko of ARTeam


[1] http://www.microsoft.com/whdc/Driver/tips/MmProbe.mspx


