Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

bsod after writeprocessmemory using triggercopyonwrite #24

Open
Tai7sy opened this issue Jul 1, 2020 · 6 comments
Open

bsod after writeprocessmemory using triggercopyonwrite #24

Tai7sy opened this issue Jul 1, 2020 · 6 comments
Labels
bug Something isn't working

Comments

@Tai7sy
Copy link
Contributor

Tai7sy commented Jul 1, 2020

after the target process terminated, there will still be a pfn left on system,
and bsod when produrce of memory management try to scan all pfn and find a useless pfn.

@Tai7sy
Copy link
Contributor Author

Tai7sy commented Jul 1, 2020

and bsod when produrce of memory management try to scan all pfn and find a useless pfn.

it will take a few minutes or hours

@HoShiMin
Copy link
Owner

HoShiMin commented Jul 2, 2020

Well, could you check it again with this release? https://github.com/HoShiMin/Kernel-Bridge/releases/tag/v1.19.2

@HoShiMin HoShiMin added the bug Something isn't working label Jul 2, 2020
@Tai7sy
Copy link
Contributor Author

Tai7sy commented Jul 3, 2020

EDIT
still bsod, detail information:

*******************************************************************************
*                                                                             *
*                        Bugcheck Analysis                                    *
*                                                                             *
*******************************************************************************

MEMORY_MANAGEMENT (1a)
    # Any other values for parameter 1 must be individually examined.
Arguments:
Arg1: 0000000000009696, The subtype of the bugcheck.
Arg2: fffff10000ff5310
Arg3: 0000000000000000
Arg4: 0000000000000000

Debugging Details:
------------------

SYMSRV:  BYINDEX: 0x4
         c:\symbols*https://msdl.microsoft.com/download/symbols
         mssmbios.pdb
         6AEB55D4626165B2915516C094CDA9681
SYMSRV:  PATH: c:\symbols\mssmbios.pdb\6AEB55D4626165B2915516C094CDA9681\mssmbios.pdb
SYMSRV:  RESULT: 0x00000000
DBGHELP: mssmbios - public symbols  
        c:\symbols\mssmbios.pdb\6AEB55D4626165B2915516C094CDA9681\mssmbios.pdb
SYMSRV:  BYINDEX: 0x5
         C:\Symbols*https://msdl.microsoft.com/download/symbols
         ntkrnlmp.exe
         438FFEC3a6e000
SYMSRV:  PATH: C:\Symbols\ntkrnlmp.exe\438FFEC3a6e000\ntkrnlmp.exe
SYMSRV:  RESULT: 0x00000000
DBGHELP: C:\Symbols\ntkrnlmp.exe\438FFEC3a6e000\ntkrnlmp.exe - OK
SYMSRV:  BYINDEX: 0x6
         c:\symbols*https://msdl.microsoft.com/download/symbols
         win32k.sys
         764F350B8b000
SYMSRV:  PATH: c:\symbols\win32k.sys\764F350B8b000\win32k.sys
SYMSRV:  RESULT: 0x00000000
DBGHELP: c:\symbols\win32k.sys\764F350B8b000\win32k.sys - OK
DBGENG:  Partial symbol load found image c:\symbols\win32k.sys\764F350B8b000\win32k.sys.
SYMSRV:  BYINDEX: 0x7
         c:\symbols*https://msdl.microsoft.com/download/symbols
         win32k.pdb
         0DA3A0E818F8C214FF51F7C871067A401
SYMSRV:  PATH: c:\symbols\win32k.pdb\0DA3A0E818F8C214FF51F7C871067A401\win32k.pdb
SYMSRV:  RESULT: 0x00000000
DBGHELP: win32k - public symbols  
        c:\symbols\win32k.pdb\0DA3A0E818F8C214FF51F7C871067A401\win32k.pdb

KEY_VALUES_STRING: 1

    Key  : Analysis.CPU.Sec
    Value: 2

    Key  : Analysis.DebugAnalysisProvider.CPP
    Value: Create: 8007007e on windywhli-PC1

    Key  : Analysis.DebugData
    Value: CreateObject

    Key  : Analysis.DebugModel
    Value: CreateObject

    Key  : Analysis.Elapsed.Sec
    Value: 4

    Key  : Analysis.Memory.CommitPeak.Mb
    Value: 66

    Key  : Analysis.System
    Value: CreateObject


ADDITIONAL_XML: 1

BUGCHECK_CODE:  1a

BUGCHECK_P1: 9696

BUGCHECK_P2: fffff10000ff5310

BUGCHECK_P3: 0

BUGCHECK_P4: 0

PROCESS_NAME:  System

STACK_TEXT:  
fffffb03`83b61ea8 fffff807`40141d72 : 00000000`00009696 00000000`00000003 fffffb03`83b62010 fffff807`4000c380 : nt!DbgBreakPointWithStatus
fffffb03`83b61eb0 fffff807`401414f7 : 00000000`00000003 fffffb03`83b62010 fffff807`40078660 00000000`0000001a : nt!KiBugCheckDebugBreak+0x12
fffffb03`83b61f10 fffff807`40064837 : 00000000`00000000 00000000`00000002 fffff100`017d9000 00000000`00000002 : nt!KeBugCheck2+0x957
fffffb03`83b62630 fffff807`400aaf74 : 00000000`0000001a 00000000`00009696 fffff100`00ff5310 00000000`00000000 : nt!KeBugCheckEx+0x107
fffffb03`83b62670 fffff807`3fffa1db : 00000000`0001dc4e 20000000`0001dc4f fffffb03`83b62730 ffffc987`098fd308 : nt!MiGetTopLevelPfn+0x18b264
fffffb03`83b62700 fffff807`3fff9b54 : ffffc987`04250028 ffffc987`04250028 00000000`0001dc4f 00000000`002dd500 : nt!MiStoreCheckCandidatePage+0xd7
fffffb03`83b62760 fffff807`3fffc1c8 : ffffc987`07518050 fffffb03`00000001 fffff100`0001dc4f 00000000`00000000 : nt!MiStoreWriteModifiedPages+0x244
fffffb03`83b628b0 fffff807`400343d9 : ffffc987`07518050 00000000`00019e5f fffffb03`00000100 00000000`00000100 : nt!MiGatherPagefilePages+0x478
fffffb03`83b629c0 fffff807`3feeea45 : ffffc987`079020c0 ffffc987`079020c0 fffff807`40034180 fffff807`402eea00 : nt!MiModifiedPageWriter+0x259
fffffb03`83b62c10 fffff807`4006bb8c : fffff807`3f0a2180 ffffc987`079020c0 fffff807`3feee9f0 00000000`00000000 : nt!PspSystemThreadStartup+0x55
fffffb03`83b62c60 00000000`00000000 : fffffb03`83b63000 fffffb03`83b5d000 00000000`00000000 00000000`00000000 : nt!KiStartSystemThread+0x1c


SYMBOL_NAME:  nt!MiGetTopLevelPfn+18b264

MODULE_NAME: nt

STACK_COMMAND:  .thread ; .cxr ; kb

IMAGE_NAME:  memory_corruption

BUCKET_ID_FUNC_OFFSET:  18b264

FAILURE_BUCKET_ID:  0x1a_9696_nt!MiGetTopLevelPfn

OS_VERSION:  10.0.17763.1

BUILDLAB_STR:  rs5_release

OSPLATFORM_TYPE:  x64

OSNAME:  Windows 10

FAILURE_ID_HASH:  {d4280011-e8e7-b961-d005-2ab957e4b051}

Followup:     MachineOwner
---------

MEMORY_MANAGEMENT Parameters
0x9696: A PFN (parameter 2) was encountered with a corrupted linkage no longer connected to its top level process. This indicates corruption in the PFN structures.

@Tai7sy
Copy link
Contributor Author

Tai7sy commented Jul 11, 2020

This case maybe helpful:

Call TriggerCopyOnWrite with invalid address(such as MessageBoxA ~ MessageBoxA+4096), the function will return false. but when exit the target process, the system will BSOD immediately,
the stack information is the same as above.

@HoShiMin
Copy link
Owner

HoShiMin commented Jul 11, 2020

@Tai7sy, in fact there are no ways to trigger CoW safely...
I have a similar trace:

ffff8e8b`4752b918 fffff803`2b31df72     : ffff8e8b`4752ba80 fffff803`2b16aa70 00000000`00000000 00000000`00000000 : nt!DbgBreakPointWithStatus
ffff8e8b`4752b920 fffff803`2b31d556     : 00000000`00000003 ffff8e8b`4752ba80 fffff803`2b1f2950 00000000`0000001a : nt!KiBugCheckDebugBreak+0x12
ffff8e8b`4752b980 fffff803`2b1ddb27     : 00000000`00000000 00000000`00000000 ffff9300`0091ec90 00000000`00000000 : nt!KeBugCheck2+0x946
ffff8e8b`4752c090 fffff803`2b2250eb     : 00000000`0000001a 00000000`00009696 ffff9300`00a50360 00000000`00000000 : nt!KeBugCheckEx+0x107
ffff8e8b`4752c0d0 fffff803`2b15415f     : 00000000`00000020 ffff9300`00a50360 00000000`00000000 ffff8e8b`4752c248 : nt!MiGetTopLevelPfn+0x1c664b
ffff8e8b`4752c160 fffff803`2b5171e6     : ffffe50f`9989f080 ffff8e8b`4752c269 ffff9300`00a50360 00000000`00000000 : nt!MiCapturePfnVm+0xdf
ffff8e8b`4752c1b0 fffff803`2b517a5d     : 00000000`00000080 00000000`00000000 00000000`00000000 ffff9300`047fffd0 : nt!MiProcessCrcList+0x226
ffff8e8b`4752c2d0 fffff803`2b516d60     : 00000000`00000000 00000000`00000000 ffff8e8b`4752c4f0 00000000`00000000 : nt!MiCombineAllPhysicalMemory+0x30d
ffff8e8b`4752c3f0 fffff803`2b437c1a     : 00000000`00000000 00000000`00000000 ffffe50f`9989f080 fffff803`2b1e4f37 : nt!MiCombineIdenticalPages+0x214
ffff8e8b`4752c660 fffff803`2b1ef375     : ffffe50f`99890000 00000000`00000000 ffff8e8b`4752cb80 00000000`00000000 : nt!NtSetSystemInformation+0x59a
ffff8e8b`4752cb00 00007ff9`9df6e2c4     : 00007ff9`91acda20 000000c6`089fd3b0 000000c6`08cffe69 00000000`00000000 : nt!KiSystemServiceCopyEnd+0x25
000000c6`08cffde8 00007ff9`91acda20     : 000000c6`089fd3b0 000000c6`08cffe69 00000000`00000000 00000000`00000000 : ntdll!NtSetSystemInformation+0x14
000000c6`08cffdf0 00007ff9`9bf56fd4     : 00000000`00000000 00000000`00000000 00000000`00000000 00000000`00000000 : sysmain!PfsCombineWorker+0x1b0
000000c6`08cffed0 00007ff9`9df1cec1     : 00000000`00000000 00000000`00000000 00000000`00000000 00000000`00000000 : KERNEL32!BaseThreadInitThunk+0x14
000000c6`08cfff00 00000000`00000000     : 00000000`00000000 00000000`00000000 00000000`00000000 00000000`00000000 : ntdll!RtlUserThreadStart+0x21

...and I have no idea how to fix it.

We can use ZwProtectVirtualMemory to make a page writeable, then perform write and revert rights back, but there is no ZwProtectVirtualMemory in Windows 7's exports (and it's unsafe to find it by signatures - I want solve it without questionable code).

What else could we do?

@Tai7sy
Copy link
Contributor Author

Tai7sy commented Jul 12, 2020

When set a breakpoint on MiCopyOnWrite(using hook), and calling r3 api WriteProcessMemory, trace:

 # Child-SP          RetAddr               Call Site
00 fffffb03`83b37fc0 fffff807`3ff75af1     XXX!DetourMiCopyOnWrite+0x8f [Hook.cpp @ 2053] 
01 fffffb03`83b38070 fffff807`3ff79d13     nt!MiValidFault+0x2c1
02 fffffb03`83b380e0 fffff807`3ff791ef     nt!MiUserFault+0x6c3
03 fffffb03`83b381d0 fffff807`40072183     nt!MmAccessFault+0x13f
04 fffffb03`83b38370 fffff807`40076d89     nt!KiPageFault+0x343
05 fffffb03`83b38508 fffff807`404ad3fd     nt!memcpy+0x49
06 fffffb03`83b38510 fffff807`40532737     nt!MmCopyVirtualMemory+0x56d
07 fffffb03`83b389d0 fffff807`4053259b     nt!MiReadWriteVirtualMemory+0x157
08 fffffb03`83b38a50 fffff807`40075885     nt!NtWriteVirtualMemory+0x1b
09 fffffb03`83b38a90 00007ffa`cf3afdd4     nt!KiSystemServiceCopyEnd+0x25
0a 00000000`0009e5b8 00000000`0000000f     0x00007ffa`cf3afdd4
0b 00000000`0009e5c0 00000000`00000000     0xf

Pte::TriggerCopyOnWrite trace:

 # Child-SP          RetAddr               Call Site
00 fffffb03`83b38390 fffff807`3ff75af1     XXX!DetourMiCopyOnWrite+0x8f [Hook.cpp @ 2053] 
01 fffffb03`83b38440 fffff807`3ff79d13     nt!MiValidFault+0x2c1
02 fffffb03`83b384b0 fffff807`3ff791ef     nt!MiUserFault+0x6c3
03 fffffb03`83b385a0 fffff807`40072183     nt!MmAccessFault+0x13f
04 fffffb03`83b38740 fffff807`45bec115     nt!KiPageFault+0x343
05 fffffb03`83b388d0 fffff807`45bf558d     XXX!Pte::TriggerCopyOnWrite+0x355 [PteUtils.cpp @ 212] 
06 fffffb03`83b38980 fffff807`45bf350a     ...
08 fffffb03`83b38a90 00007ffa`cf3b1e84     nt!KiSystemServiceCopyEnd+0x25
09 00000000`0009e5b8 00000000`0000000f     0x00007ffa`cf3b1e84
0a 00000000`0009e5c0 00000000`00000000     0xf

There is also no difference in the second paramter of MiCopyOnWrite.

kd> ?? PteInfo
struct Pte::PAGE_TABLES_INFO
   +0x000 Pml4e            : 0xfffff67b`3d9ec000 PML4E
   +0x008 Pdpe             : 0xfffff67b`3d800000 PDPE
   +0x010 Pde              : 0xfffff67b`00000010 PDE
   +0x018 Pte              : 0xfffff600`00002008 PTE
   +0x020 Type             : 5 ( pt64Page4Kb )
kd> dx -id 0,0,ffffc9870624b340 -r1 ((Re_Kernel!PTE *)0xfffff60000002008)
((Re_Kernel!PTE *)0xfffff60000002008)                 : 0xfffff60000002008 [Type: PTE *]
    [+0x000] x32              [Type: PTE::<unnamed-type-x32>]
    [+0x000] x64              [Type: PTE::<unnamed-type-x64>]
kd> dx -id 0,0,ffffc9870624b340 -r1 (*((Re_Kernel!PTE::<unnamed-type-x64> *)0xfffff60000002008))
(*((Re_Kernel!PTE::<unnamed-type-x64> *)0xfffff60000002008))                 [Type: PTE::<unnamed-type-x64>]
    [+0x000] Value            : 0x1000000642ad825 [Type: unsigned __int64]
    [+0x000] Page4Kb          [Type: PTE::<unnamed-type-x64>::<unnamed-type-Page4Kb>]
kd> dx -id 0,0,ffffc9870624b340 -r1 (*((Re_Kernel!PTE::<unnamed-type-x64>::<unnamed-type-Page4Kb> *)0xfffff60000002008))
(*((Re_Kernel!PTE::<unnamed-type-x64>::<unnamed-type-Page4Kb> *)0xfffff60000002008))                 [Type: PTE::<unnamed-type-x64>::<unnamed-type-Page4Kb>]
    [+0x000 ( 0: 0)] P                : 0x1 [Type: unsigned __int64]
    [+0x000 ( 1: 1)] RW               : 0x0 [Type: unsigned __int64]
    [+0x000 ( 2: 2)] US               : 0x1 [Type: unsigned __int64]
    [+0x000 ( 3: 3)] PWT              : 0x0 [Type: unsigned __int64]
    [+0x000 ( 4: 4)] PCD              : 0x0 [Type: unsigned __int64]
    [+0x000 ( 5: 5)] A                : 0x1 [Type: unsigned __int64]
    [+0x000 ( 6: 6)] D                : 0x0 [Type: unsigned __int64]
    [+0x000 ( 7: 7)] PAT              : 0x0 [Type: unsigned __int64]
    [+0x000 ( 8: 8)] G                : 0x0 [Type: unsigned __int64]
    [+0x000 (11: 9)] AVL              : 0x4 [Type: unsigned __int64]
    [+0x000 (51:12)] PhysicalPageFrameNumber : 0x642ad [Type: unsigned __int64]
    [+0x000 (62:52)] Available        : 0x10 [Type: unsigned __int64]
    [+0x000 (63:63)] NX               : 0x0 [Type: unsigned __int64]

The call to MiCopyOnWrite is no different. So I think the problem is that we have to set some other flags(PTE/PFN?) to let the system release it when it needs to.

ALso, using ZwProtectVirtualMemory will cause some other problems.
for example, it maybe failed when the target region created with SEC_NOCHANGE

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants