A forum for reverse engineering, OS internals and malware analysis 

Forum for discussion about kernel-mode development.
 #26434  by openav
 Tue Aug 04, 2015 5:05 pm
Hello,

I'am working on a small antivirus driver. I'am using PsSetLoadImageNotifyRoutine to change the entry point of the loaded image.

To do this I have to disable the write protection. I got this code from https://github.com/Cr4sh/DrvHide-PoC/bl ... common.cpp:
Code: Select all
void __stdcall ClearWp(PVOID Param)
{
#ifdef _X86_
    __asm
    {              
        mov     eax,cr0             
        and     eax,not 000010000h
        mov     cr0,eax
    }
#else
    // clear wp-bit in cr0 register
    _clear_wp();
#endif // _X_86_
}
//--------------------------------------------------------------------------------------
void __stdcall SetWp(PVOID Param)
{
#ifdef _X86_
    __asm
    {
        mov     eax,cr0
        or      eax,000010000h
        mov     cr0,eax
    }
#else
    // set wp-bit in cr0 register
    _set_wp();
#endif // _X_86_
}
When compiling on x64 the _set_wp/_clear_wp functions are not found. Where can I find this functions?

Thank you.
 #26436  by EP_X0FF
 Tue Aug 04, 2015 6:03 pm
Write code with __writecr0 intrinsic.
 #26438  by Vrtule
 Tue Aug 04, 2015 6:51 pm
Alternatively, you probably can map a memory you wish to change into another location and with read/write permissions.

1) User IoCreateMdl to describe the target buffer as a MDL,
2) Lock the buffer by MmProbeAndLockpages(..., IoWriteAccess),
3) Map to another place with MmMapLockedPagesSpecifyCache (is the target buffer already resides in kernel memory, you have to map to a place residing in "user memory" (e.g. in System process' address space),
4) do what you need,
5) unmap everything (MmUnmapLockedPages, MmUnlockpages, IoFreeMdl).
 #26439  by openav
 Tue Aug 04, 2015 7:00 pm
Thank you for your fast answers. I implemented it with __writecr0 and it worked fine!

I will test the alternative way later.

Thank you!
 #26441  by Vrtule
 Tue Aug 04, 2015 11:04 pm
And be aware of the copy-on-write optimization (especially on DLL images).
 #26447  by Brock
 Wed Aug 05, 2015 11:26 pm
Maybe my implementation can help you as well if you need it
Code: Select all
#define CR0_WP 0x10000

VOID DisableWriteProtection(BOOLEAN Disable)
{
if (Disable)
{
#ifdef _WIN64

_disable();                         /* Clear interrupts intrinsic for x64 */

#else

__asm
{
  cli                               /* Clear interrupts inline asm for x86 */
}
#endif

__writecr0(__readcr0() & ~CR0_WP);  /* Set cr0 bit 16 (WP-bit) to 0 */
}
else
{
__writecr0(__readcr0() | CR0_WP);   /* Set cr0 bit 16 (WP-bit) to 1 */

#ifdef _WIN64

_enable();                          /* Restore interrupts intrinsic for x64 */

#else

__asm
{
  sti                               /* Restore interrupts inline asm for x86 */
}
#endif
}
}

// Call it like this:

DisableWriteProtection(TRUE);
// Do Work
DisableWriteProtection(FALSE);

Intrinsics are definitely the best for this as already mentioned and MDLs are another good option like Vrtule mentioned.
 #26453  by Cr4sh
 Thu Aug 06, 2015 7:11 pm
On SMP enabled systems you also need to be sure that WP clear and WP set routines will be run on the same CPU, it's very common mistake, add KeSetAffinityThread() call to your code.
 #26479  by breaker09
 Sun Aug 09, 2015 12:24 pm
I am trying to modify the memory of ntdll.dll .text section from kernelmode. This code worked fine for me in Windows 8.1, but it's causing a crash now in Windows 10:
Code: Select all
_disable();
ULONG64 cr0 = __readcr0();
__writecr0(cr0 & ~(1 << 16));
memcpy(pntdll_addr, patch, sizeof(patch));
__writecr0(cr0);
_enable();
I've also now tried to add KeSetAffinityThread now, as suggested, so that my code looks like this:
Code: Select all
KAFFINITY cpuBitMap = KeQueryActiveProcessors();
PKTHREAD   pKThread = KeGetCurrentThread();
KeSetAffinityThread(pKThread, 0);

_disable();
ULONG64 cr0 = __readcr0();
__writecr0(cr0 & ~(1 << 16));
memcpy(pntdll_addr, patch, sizeof(patch));
__writecr0(cr0);
_enable();

KeSetAffinityThread(pKThread, cpuBitMap);
But I am still not able to write to the code section without a crash. :(

Am I using KeSetAffinityThread correctly there?
Or did something change in Windows 10 now?