BSOD on Copying file name

Hi All,
I don’t know why this happens. The source buffer is fine, I can see it in memory and it contains the file name, with length.
The target buffer is from Windows, and it contains length enough to copy the file name.

N bytes of memory was allocated and more than N bytes are being referenced.
This cannot be protected by try-except.
When possible, the guilty driver’s name (Unicode string) is printed on
the bugcheck screen and saved in KiBugCheckDriver.
Arg1: 9ecfd000, memory referenced
Arg2: 00000001, value 0 = read operation, 1 = write operation
Arg3: 8fd7eaa9, if non-zero, the address which referenced memory.
Arg4: 00000000, (reserved)

Debugging Details:

WRITE_ADDRESS: 9ecfd000 Special pool

mydriver!CopyAndFlipUnicode+49 [c:\users\driver\unicode.c @ 12]
8fd7eaa9 66891441 mov word ptr [ecx+eax*2],dx


IMAGE_NAME: mydriver.sys


MODULE_NAME: mydriver

FAULTING_MODULE: 8fd7c000 mydriver



PROCESS_NAME: explorer.exe


TRAP_FRAME: 95f3ba7c – (.trap 0xffffffff95f3ba7c)
ErrCode = 00000002
eax=00000002 ebx=89528a78 ecx=9ecfcffc edx=0000006f esi=9eccae00 edi=8db3f288
eip=8fd7eaa9 esp=95f3baf0 ebp=95f3baf4 iopl=0 nv up ei ng nz ac po cy
cs=0008 ss=0010 ds=0023 es=0023 fs=0030 gs=0000 efl=00010293
8fd7eaa9 66891441 mov word ptr [ecx+eax*2],dx ds:0023:9ecfd000=???
Resetting default scope

LAST_CONTROL_TRANSFER: from 828d8559 to 8285ecf0

95f3b5dc 828d8559 00000003 61850f60 00000065 nt!RtlpBreakWithStatusInstruction
95f3b62c 828d9055 00000003 8965fc50 0000001f nt!KiBugCheckDebugBreak+0x1c
95f3b9f0 82864d87 00000050 9ecfd000 00000001 nt!KeBugCheck2+0x68b
95f3ba64 8283ea48 00000001 9ecfd000 00000000 nt!MmAccessFault+0xbf
95f3ba64 8fd7eaa9 00000001 9ecfd000 00000000 nt!KiTrap0E+0xdc
95f3baf4 8fd87fc0 9ecfcffc 97404584 00000004 mydriver!CopyAndFlipUnicode+0x49 [c:\users\driver\unicode.c @ 12]
95f3bb10 8fd8811f 89528b30 a03fcfe0 9ecfcff8 mydriver!CatalogFolderToNameInformation+0x150 [c:\users\driver\fileinfo.c @ 170]
95f3bb2c 8fd8848c 89528b30 a03fcfe0 9ecfcf98 mydriver!CatalogFolderToAllInformation+0x11f [c:\users\driver\fileinfo.c @ 233]
95f3bbc4 8fd8cf46 9ec3cfd8 00000005 89528a78 mydriver!mydriverQueryInformation+0x30c [c:\users\driver\fileinfo.c @ 363]
95f3bbe0 8fd8d3d8 9ec3cfd8 1a2a0ce5 8db3f288 mydriver!mydriverDispatchRequest+0xa6 [c:\users\driver\irp.c @ 1113]
95f3bc24 82b2b6c3 89528a78 9eccae00 9eccae00 mydriver!IRPDispatcher+0x138 [c:\users\driver\irp.c @ 1278]
95f3bc48 82834fc9 00000000 00000000 89528a78 nt!IovCallDriver+0x258
95f3bc5c 82a20f53 61850454 00000f40 074ad69c nt!IofCallDriver+0x1b
95f3bd18 8283b85a 01d86b60 074ad6a8 004ad6fc nt!NtQueryInformationFile+0x779
95f3bd18 773d70a6 01d86b60 074ad6a8 004ad6fc nt!KiFastCallEntry+0x12a
074ad67c 773d6024 7578b167 00000f40 074ad6a8 ntdll!KiIntSystemCall+0x6
074ad680 7578b167 00000f40 074ad6a8 074ad6fc ntdll!ZwQueryInformationFile+0xc
074ad768 75b80821 00000f40 074ad78c 074adcc8 KERNELBASE!GetFileInformationByHandle+0x84
WARNING: Stack unwind information not available. Following frames may be wrong.
074ad7c4 75b8135f 074adcc8 074ad7e4 074ad7e8 SHELL32!ExtractIconExW+0x177c
074ada54 75abf84c 074adcc8 074adf3c 00000000 SHELL32!ExtractIconExW+0x22ba
074aded4 75b80e7a 03f7fc40 00000000 00000001 SHELL32!SHGetPathFromIDListEx+0xb33
074adee8 75b79779 05ad87b4 03f7fc40 074ae000 SHELL32!ExtractIconExW+0x1dd5
074adf0c 75b7a58f 03f9a95c 00000001 02a0fee8 SHELL32!Ordinal894+0x1c9
074adf9c 75b7a4b1 03f9a95c 03effcb0 074adfc8 SHELL32!Ordinal894+0xfdf
074adfd4 75b79c65 03f9a95c 074ae000 00000001 SHELL32!Ordinal894+0xf01
074ae044 75b798cf 02a0fee8 03f9a95c 76836f41 SHELL32!Ordinal894+0x6b5
074ae06c 75b7b580 03f9a95c 03e9e618 00000000 SHELL32!Ordinal894+0x31f
074ae2b8 75b79fe7 00000dec 059f1810 02a07f44 SHELL32!SHAddToRecentDocs+0x55a
074af75c 75b79eb7 02a07e34 02a07e10 02a07f44 SHELL32!Ordinal894+0xa37
074af7c0 75ac835e 059c86c8 01000000 80000000 SHELL32!Ordinal894+0x907
074af7e0 75b0635b 059c86dc 7fffffff 05aed340 SHELL32!SHDefExtractIconW+0x1488
074af7fc 75b08be3 074af838 00000000 05af2778 SHELL32!Ordinal767+0x433
074af844 75b08d17 074af85c 7679b2b1 05aed340 SHELL32!DAD_SetDragImage+0x732
074af84c 7679b2b1 05aed340 059c0800 074af8d0 SHELL32!DAD_SetDragImage+0x866
074af85c 773bd897 05af2778 700b53ae 00280ea8 SHLWAPI!PathBuildRootW+0x4c
074af8d0 773c0846 05af2778 059c0800 700b514e ntdll!RtlpTpWorkCallback+0x11d
074afa30 772fed6c 00280ea0 074afa7c 773f377b ntdll!TppWorkerThread+0x572
074afa3c 773f377b 00280ea0 700b5102 00000000 kernel32!BaseThreadInitThunk+0xe
074afa7c 773f374e 773c03e9 00280ea0 00000000 ntdll!__RtlUserThreadStart+0x70
074afa94 00000000 773c03e9 00280ea0 00000000 ntdll!_RtlUserThreadStart+0x1b


mydriver!CopyAndFlipUnicode+49 [c:\users\driver\unicode.c @ 12]
8fd7eaa9 66891441 mov word ptr [ecx+eax*2],dx

8: if (Count > MaxCount) Count = MaxCount;
10: for (i = 0 ; i < Count; i++)
11: {

12: Dest[i] = be16_to_cpu(Src[i]);
13: }
15: }


SYMBOL_NAME: mydriver!CopyAndFlipUnicode+49


FAILURE_BUCKET_ID: 0xD6_VRF_mydriver!CopyAndFlipUnicode+49

BUCKET_ID: 0xD6_VRF_mydriver!CopyAndFlipUnicode+49

Followup: MachineOwner

Well, the faulting instruction is mov word ptr [ecx+eax*2],dx. ECX is 9ecfcffc and EAX is 00000002 so ECX+EAX*2 is 0x9ECFD000. This is at the end of a page and when running with Special Pool enabled you’ll often see this kind of allocations, where the buffer is set at the end of a page to detect a buffer overrun. So is it possible that Dest in this case is only 4 bytes long and Src is longer than that ?


> 8fd7eaa9 66891441 mov word ptr [ecx+eax*2],dx ds:0023:9ecfd000=???

You have copied too far behind the end of string, so you got
to the next page, which is invalid. That’s why your driver BSOD’ed.

Please, read some basics about kernel mode, like the UNICODE_STRING
structure. Keep in mind that it doesn’t have to be zero terminated
and its length is in bytes, not in chars.


I’m not quite sure where you’re copying the file name from. However, keep in mind that FileObject->FileName is only valid during PreCreate.


Fernando Roberto da Silva
DriverEntry Kernel Development

Dest[i] = be16_to_cpu(Src[i]);
This is the actual copying of buffer.

My source is BE, and destination is LE. So simply copying the converted item one by one from the source to target till the length of source.

My source is available in a struct FileObject->FsContext with me. So there is no point it has less memory or anything else.

Let’s discuss about the destination. The destination came from Windows, I get the IRP_MJ_QUERY_INFORMATION with class FileAllInformation.

I have checked the size of the input buffer, which is 64 bytes, and I copied everything. For file name I am left with last 8 bytes, and my file (source) is 4 bytes only.

So FILE_NAME_INFORMATION can contain 4 bytes of data and 4 bytes for the size.

Now I don’t understand how I copied too far. Even if I copy the more than 4 bytes (for a valid source string) it never BSODed on copying name.

I’m not sure what is the point of the discussion. As everybody pointed out, the problem is you’re writing past the end of the buffer. This might appear to work without driver verifier but it’s probably just corrupting memory.

You need to make sure there is enough room in the buffer.

Please note that FILE_ALL_INFORMATION is a variable-sized structure and there is a protocol on how to report the required size to the caller if the size you’re called with is not enough.