title: is SSDT table writable in windows7?
body: <p>I have written a windows7 device driver which hooks SSDT entry.
  I thought SSDT (Secondary System Descriptor Tables) is write protected. but I tried to overwrite SSDT anyway
  and it was successful without error.
  I was doing this on native machine(not in VM)
  I printed CR0 register to check if WP was cleared before overwrite SSDT.
  the WP bit of CR0 was set...
  how could I overwrite SSDT with out any circumvention?
  I don't understand how this is possible.
  can someone explain this?</p>
  
  <pre><code>NTSTATUS DriverEntry(PDRIVER_OBJECT driverObject, PUNICODE_STRING RegistryPath) {
  
  unsigned int m_cr0=0;
  __asm
    {
            push eax
            mov eax, CR0
            mov m_cr0, eax;
            pop eax
    }
  
  DbgPrint("CR0 : %08X\n", m_cr0);
  driverObject-&gt;DriverUnload = Unload_driver;
  DbgPrint("Hooking API! SSDT:%08X\n", (unsigned int)((void*)&amp;KeServiceDescriptorTable));
  
  Hooking();
  
  return(STATUS_SUCCESS);
  </code></pre>
  
  <p>}</p>
  
  <pre><code>#define SYSTEMSERVICE(_name) KeServiceDescriptorTable.ServiceTable[*(DWORD *) ((unsigned char *)_name + 1)]
  
  
  void Hooking(void){
  
  DbgPrint("Hooking API! ZwCreateFile : %08X, index : %d\n", ZwCreateFile, *(DWORD *) ((unsigned char *)ZwCreateFile + 1) );
  DbgPrint("Hooking API! FakeZwCreateFile : %08X\n", FakeZwCreateFile);
  
  DbgPrint("Hooking API! ZwQueryDirectoryFile : %08X, index : %d\n", ZwQueryDirectoryFile, *(DWORD *) ((unsigned char *)ZwQueryDirectoryFile + 1) );
  DbgPrint("Hooking API! FakeZwQueryDirectoryFile : %08X\n", FakeZwQueryDirectoryFile);
  
  DbgPrint("Hooking API! ZwQueryVolumeInformationFile : %08X, index : %d\n", ZwQueryVolumeInformationFile, *(DWORD *) ((unsigned char *)ZwQueryVolumeInformationFile + 1) );
  DbgPrint("Hooking API! FakeZwQueryVolumeInformationFile : %08X\n", FakeZwQueryVolumeInformationFile);
  
  //cli, sti - disable/enable interruptions
  _asm{cli}
  // hook CreateFile
  OrigZwCreateFile = (ZWCREATEFILE) (SYSTEMSERVICE(ZwCreateFile));
  (ZWCREATEFILE) (SYSTEMSERVICE(ZwCreateFile)) = FakeZwCreateFile;
  
  // hook QueryDirectoryFile
  OrigZwQueryDirectoryFile = (ZWQUERYDIRECTORYFILE) (SYSTEMSERVICE(ZwQueryDirectoryFile));
  (ZWQUERYDIRECTORYFILE) (SYSTEMSERVICE(ZwQueryDirectoryFile)) = FakeZwQueryDirectoryFile;
  
  // hook QueryVolumeInformationFile
  OrigZwQueryVolumeInformationFile = (ZWQUERYVOLUMEINFORMATIONFILE) (SYSTEMSERVICE(ZwQueryVolumeInformationFile));
  (ZWQUERYVOLUMEINFORMATIONFILE) (SYSTEMSERVICE(ZwQueryVolumeInformationFile)) = FakeZwQueryVolumeInformationFile;
  _asm{sti}
  </code></pre>
  
  <p>}</p>
  
  <p>This is my driver entry code and SSDT hooking code.
  I just dumped CR0 register value and changed the SSDT entry for
  ZwCreateFile, ZwQueryDirectoryFile, ZwQueryVolumeInformationFile</p>
  
  <p><img src="https://i.stack.imgur.com/MrZWL.png" alt="Debug View"></p>
  
  <p>This is the screen capture of Debug View (which shows the DbgPrint messages)
  CR0 is '8001003B' which tells me the 16th bit(WP) is set.
  but SSDT hook works fine. the system API for CreateFile, QueryDirectoryFile...
  are changed for my own taste.</p>
  
  <p>The operating system was Windows7 professional K, 32bit.
  it is running on the actual machine(not in VM)</p>