wbenny / injdrv

proof-of-concept Windows Driver for injecting DLL into user-mode processes using APC
MIT License
1.1k stars 276 forks source link

BSOD on Windows 10 #13

Open rgutherz opened 5 years ago

rgutherz commented 5 years ago

Hi, I got BSOD on Windows 10.

SYSTEM_SERVICE_EXCEPTION (3b) An exception happened while executing a system service routine. Arguments: Arg1: 00000000c0000005, Exception code that caused the bugcheck Arg2: fffff802bc932524, Address of the instruction which caused the bugcheck Arg3: ffffe08f1ba66ae0, Address of the context record for the exception that caused the bugcheck Arg4: 0000000000000000, zero.

FAULTING_IP: injdrv+2524 fffff802`bc932524 48394110 cmp qword ptr [rcx+10h],rax

MODULE_NAME: injdrv

IMAGE_NAME: injdrv.sys

This is the callstack: 0: kd> kp

Child-SP RetAddr Call Site 00 ffffe08f1ba66208 fffff802bd45b669 nt!KeBugCheckEx 01 ffffe08f1ba66210 fffff802bd45abbc nt!KiBugCheckDispatch+0x69 02 ffffe08f1ba66350 fffff802bd4533ad nt!KiSystemServiceHandler+0x7c 03 ffffe08f1ba66390 fffff802bd35b126 nt!RtlpExecuteHandlerForException+0xd 04 ffffe08f1ba663c0 fffff802bd35cc23 nt!RtlDispatchException+0x416 05 ffffe08f1ba66ab0 fffff802bd45b742 nt!KiDispatchException+0x1f3 06 ffffe08f1ba67160 fffff802bd4582c5 nt!KiExceptionDispatch+0xc2 07 ffffe08f1ba67340 fffff802bc932524 nt!KiPageFault+0x405 ** WARNING: Unable to verify timestamp for injdrv.sys 08 ffffe08f1ba674d0 fffff802bc9327f3 injdrv!InjFindInjectionInfo(void ProcessId = 0x00000000000020ac)+0x34 [c:\working\injdrv\injlib.c @ 1093] 09 ffffe08f1ba674f0 fffff802bd7f2efe injdrv!InjLoadImageNotifyRoutine(struct _UNICODE_STRING FullImageName = 0xffff91889adea688 "\Windows\System32\msvcrt.dll", void ProcessId = 0x00000000000020ac, struct _IMAGE_INFO * ImageInfo = 0xffffe08f1ba676c0)+0x23 [c:\working\injdrv\injlib.c @ 1340] 0a ffffe08f1ba675b0 fffff802bd7f19f4 nt!PsCallImageNotifyRoutines+0x12e 0b ffffe08f1ba67610 fffff802bd7a1721 nt!MiMapViewOfImageSection+0x734 0c ffffe08f1ba67790 fffff802bd7a0e7b nt!MiMapViewOfSection+0x3c1 0d ffffe08f1ba678e0 fffff802bd45b143 nt!NtMapViewOfSection+0x12b 0e ffffe08f1ba67a10 00007ff9f867aea4 nt!KiSystemServiceCopyEnd+0x13 0f 00000070e8c7e6e8 0000000000000000 0x00007ff9`f867aea4

Checking the source code I found that it is in: PINJ_INJECTION_INFO NTAPI InjFindInjectionInfo( In HANDLE ProcessId ) { PLIST_ENTRY NextEntry = InjInfoListHead.Flink;

while (NextEntry != &InjInfoListHead) { PINJ_INJECTION_INFO InjectionInfo = CONTAINING_RECORD(NextEntry, INJ_INJECTION_INFO, ListEntry);

if (InjectionInfo->ProcessId == ProcessId) { return InjectionInfo; }

NextEntry = NextEntry->Flink; }

return NULL; }

It only happened once. What could be the cause of the problem? Maybe the page fault while in the function for memory that should not be paged?

rgutherz commented 5 years ago

Looks like an access violation exception in the line if (InjectionInfo->ProcessId == ProcessId) The InjectionInfo is invalid

wbenny commented 5 years ago

Uh, yeah... looks like I missed locking of the InjInfoListHead.

rgutherz commented 5 years ago

Yes, that what I though. Can you send an updated code with the lock?

rgutherz commented 5 years ago

I also got BSOD when unloading the driver. Looks like the driver is not handling correctly the unload and there are still pending APC calls.

STACK_TEXT:
fffff88022aea5b8 fffff800045b67b2 : 0000000000000050 fffff88005401f90 0000000000000008 fffff88022aea710 : nt!KeBugCheckEx fffff88022aea5c0 fffff800044e8ddc : 0000000000000008 fffff88005401f90 fffff88022aea800 fffffa8015ef08e0 : nt!MmAccessFault+0x2322 fffff88022aea710 fffff88005401f90 : fffff8000448d6d4 fffff8a001b777a0 00000000c0000034 fffff8a001b77770 : nt!KiPageFault+0x35c fffff88022aea8a8 fffff8000448d6d4 : fffff8a001b777a0 00000000c0000034 fffff8a001b77770 fffff8a001b77701 : +0x1f90 fffff88022aea8b0 fffff80004462eee : 00000000000fe6b0 0000000000000000 fffffffffffc0000 0000000000000072 : nt!KiDeliverApc+0x2e4 fffff88022aea930 fffff800044e2787 : 00000000000fe670 00000000c0000008 fffff88022aea9a0 fffff88022aeaa30 : nt!KiContinueEx+0xfa fffff88022aea9a0 fffff800044ead53 : fffffa8015ef08e0 00000000742e7f3d 000000007efdb001 00000000c0000034 : nt!NtContinue+0x87 fffff88022aeaae0 0000000077609cba : 0000000000000000 0000000000000000 0000000000000000 0000000000000000 : nt!KiSystemServiceCopyEnd+0x13 00000000000fdc38 0000000000000000 : 0000000000000000 0000000000000000 0000000000000000 0000000000000000 : 0x77609cba

rgutherz commented 5 years ago

FAULTING_IP: injdrv.sys+1f90 fffff880`05401f90 ?? ???

wbenny commented 5 years ago

It appears that unloading driver that queues APCs is generally dangerous. It's possible to workaround this issue for KernelMode APCs, but it's more difficult with UserMode APCs.

I discussed this on twitter yesterday, you can check the discussion here: https://twitter.com/PetrBenes/status/1176810311657164805

You can take some ideas from there, but I unfortunatelly have no time currently to take care of this repo.