A forum for reverse engineering, OS internals and malware analysis 

Forum for discussion about kernel-mode development.
 #23589  by Vrtule
 Mon Aug 11, 2014 6:06 pm
Hello,

if you need to make changes to win32k.sys in memory (or just to read it) multiple times, you can map it into System process address space (via a MDL) so you won't need a GUI thread anymore. It might be possible to use another MDL to map the memory to the kernel area (shared in all address space). I am not sure how much safe this approach is however.
 #23593  by myid
 Tue Aug 12, 2014 12:29 am
Vrtule wrote:Hello,

if you need to make changes to win32k.sys in memory (or just to read it) multiple times, you can map it into System process address space (via a MDL) so you won't need a GUI thread anymore. It might be possible to use another MDL to map the memory to the kernel area (shared in all address space). I am not sure how much safe this approach is however.
Thanks a lot. I will try to do that. :lol:
 #23601  by Vrtule
 Tue Aug 12, 2014 10:11 pm
The following routine maps a given part of kernel memory (e.g. a win32k.sys) as writable to address space of the System process. For win32k.sys, the routine must be called in the context of a GUI process.
Code: Select all
NTSTATUS MapWin32kPartWritable(PVOID Address, SIZE_T Size, PMDL *Mdl, PVOID *UserAddress)
{
   PMDL tmpMdl = NULL;
   KAPC_STATE apcState;
   NTSTATUS status = STATUS_UNSUCCESSFUL;
   PVOID tmpUserAddress = NULL;

   tmpMdl = IoAllocateMdl(Address, (ULONG)Size, FALSE, FALSE, NULL);
   if (tmpMdl != NULL) {
      MmProbeAndLockPages(tmpMdl, KernelMode, IoReadAccess);
      KeStackAttachProcess(PsInitialSystemProcess, &apcState);
      tmpUserAddress = MmMapLockedPagesSpecifyCache(tmpMdl, UserMode, MmCached, NULL, FALSE, NormalPagePriority);
      KeUnstackDetachProcess(&apcState);
      if (tmpUserAddress != NULL) {
         *Mdl = tmpMdl;
         *UserAddress = tmpUserAddress;
         status = STATUS_SUCCESS;
      }

      if (tmpUserAddress == NULL) {
         IoFreeMdl(tmpMdl);
         status = STATUS_UNSUCCESSFUL;
      }
   } else {
      status = STATUS_INSUFFICIENT_RESOURCES;
   }

   return status;
}
To find a GUI process, you can get the list of active processes (ZwQuerySystemInformation), get their EPROCESS structures (PsLookupProcessByProcessId) and look at the w32Process substructure (PsGetProcessWin32Process). The process is a GUI process if the w32Process is non-NULL (PsGetProcessWin32Process returns a non-NULL value).

EDIT: Nt --> Zw
 #23608  by myid
 Wed Aug 13, 2014 5:24 pm
Vrtule wrote:The following routine maps a given part of kernel memory (e.g. a win32k.sys) as writable to address space of the System process. For win32k.sys, the routine must be called in the context of a GUI process.
Code: Select all
NTSTATUS MapWin32kPartWritable(PVOID Address, SIZE_T Size, PMDL *Mdl, PVOID *UserAddress)
{
   PMDL tmpMdl = NULL;
   KAPC_STATE apcState;
   NTSTATUS status = STATUS_UNSUCCESSFUL;
   PVOID tmpUserAddress = NULL;

   tmpMdl = IoAllocateMdl(Address, (ULONG)Size, FALSE, FALSE, NULL);
   if (tmpMdl != NULL) {
      MmProbeAndLockPages(tmpMdl, KernelMode, IoReadAccess);
      KeStackAttachProcess(PsInitialSystemProcess, &apcState);
      tmpUserAddress = MmMapLockedPagesSpecifyCache(tmpMdl, UserMode, MmCached, NULL, FALSE, NormalPagePriority);
      KeUnstackDetachProcess(&apcState);
      if (tmpUserAddress != NULL) {
         *Mdl = tmpMdl;
         *UserAddress = tmpUserAddress;
         status = STATUS_SUCCESS;
      }

      if (tmpUserAddress == NULL) {
         IoFreeMdl(tmpMdl);
         status = STATUS_UNSUCCESSFUL;
      }
   } else {
      status = STATUS_INSUFFICIENT_RESOURCES;
   }

   return status;
}
To find a GUI process, you can get the list of active processes (ZwQuerySystemInformation), get their EPROCESS structures (PsLookupProcessByProcessId) and look at the w32Process substructure (PsGetProcessWin32Process). The process is a GUI process if the w32Process is non-NULL (PsGetProcessWin32Process returns a non-NULL value).

EDIT: Nt --> Zw
Thank you very much! I have solved this problem now!