首页
社区
课程
招聘
LoadImageNotifyRoutine回调中获取dll完整路径会蓝屏
发表于: 2016-4-10 10:15 11307

LoadImageNotifyRoutine回调中获取dll完整路径会蓝屏

2016-4-10 10:15
11307
只要在回调函数中有执行过IoQueryFileDosDeviceName或者ObQueryNameString,单步执行完整个回调函数也没问题,但是bc *之后g立马蓝屏。崩溃位置在NtMapViewOfSection

只要注释掉IoQueryFileDosDeviceName再跑就100%不会蓝屏,因此可以确定是这句的问题


PsSetLoadImageNotifyRoutine(LoadImageNotifyCallback);

VOID LoadImageNotifyCallback(PUNICODE_STRING FullImageName, HANDLE ProcessId, PIMAGE_INFO pImageInfo)
{
	PEPROCESS Process;
	USHORT nLength;
	PIMAGE_INFO_EX pImageInfoEx;
	NTSTATUS status;

	if (ProcessId == (HANDLE)0 || ProcessId == (HANDLE)4)
		return;

	if (!FullImageName)
		return;

	if (NT_SUCCESS(PsLookupProcessByProcessId(ProcessId, &Process)))
	{
		//Protectd and not in white list
		if (LoadImageNotify.obEvent != NULL && IsProcessInList(Process, ProtectedProcessHead))
		{
			LoadImageNotify_Callback *buffer = (LoadImageNotify_Callback *)LoadImageNotify.SharedMem;
			buffer->ProcessId = (__int32)ProcessId;
			RtlZeroMemory(buffer->ImagePath, sizeof(buffer->ImagePath));

			if (pImageInfo->ExtendedInfoPresent)
			{
				pImageInfoEx = CONTAINING_RECORD(pImageInfo, IMAGE_INFO_EX, ImageInfo);

				PFILE_OBJECT pFileObject = pImageInfoEx->FileObject;
				POBJECT_NAME_INFORMATION fileNameInfo;

					status = IoQueryFileDosDeviceName(pFileObject, &fileNameInfo);
					if (NT_SUCCESS(status))
					{
						nLength = min(fileNameInfo->Name.Length, sizeof(buffer->ImagePath) - sizeof(WCHAR));
						RtlCopyMemory(buffer->ImagePath, fileNameInfo->Name.Buffer, nLength);
						ExFreePool(fileNameInfo);
					}
			}

			KeSetEvent(LoadImageNotify.obEvent, 0, FALSE);
		}
		ObDereferenceObject(Process);
	}
}

[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)

收藏
免费 0
支持
分享
最新回复 (4)
雪    币: 878
活跃值: (496)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
2
蓝屏的代码是什么?把拷贝路径的那几行也注释看看
2016-4-10 18:57
0
雪    币: 12848
活跃值: (9167)
能力值: ( LV9,RANK:280 )
在线值:
发帖
回帖
粉丝
3
LoadImageNotify_Callback *buffer = (LoadImageNotify_Callback *)LoadImageNotify.SharedMem;
      buffer->ProcessId = (__int32)ProcessId;
      RtlZeroMemory(buffer->ImagePath, sizeof(buffer->ImagePath));

      if (pImageInfo->ExtendedInfoPresent)
      {
        pImageInfoEx = CONTAINING_RECORD(pImageInfo, IMAGE_INFO_EX, ImageInfo);

        PFILE_OBJECT pFileObject = pImageInfoEx->FileObject;
        POBJECT_NAME_INFORMATION fileNameInfo;

          status = IoQueryFileDosDeviceName(pFileObject, &fileNameInfo);
          if (NT_SUCCESS(status))
          {
            nLength = min(fileNameInfo->Name.Length, sizeof(buffer->ImagePath) - sizeof(WCHAR));
            //RtlCopyMemory(buffer->ImagePath, fileNameInfo->Name.Buffer, nLength);
            ExFreePool(fileNameInfo);
          }
      }

      KeSetEvent(LoadImageNotify.obEvent, 0, FALSE);

奇了怪,我把RtlCopyMemory注释掉就不会蓝屏了。。。难道是越界了?

蓝屏时的调用堆栈如下:

fffff880`0712ede8 fffff800`05b6c6d2 : 00000000`00000000 fffffa80`02812630 00000000`00000065 fffff800`05ab5314 : nt!RtlpBreakWithStatusInstruction
fffff880`0712edf0 fffff800`05b6d4be : 00000000`00000003 00000000`00000000 fffff800`05ab1ee0 00000000`0000000a : nt!KiBugCheckDebugBreak+0x12
fffff880`0712ee50 fffff800`05a77004 : 00000000`00000002 00000000`00000000 fffffa80`01cb7a40 fffff800`05af46a2 : nt!KeBugCheck2+0x71e
fffff880`0712f520 fffff800`05a76469 : 00000000`0000000a 00000000`00000000 00000000`00000002 00000000`00000000 : nt!KeBugCheckEx+0x104
fffff880`0712f560 fffff800`05a750e0 : 00000000`00000000 fffffa80`03b5c300 fffff8a0`20206f49 fffff8a0`025104d0 : nt!KiBugCheckDispatch+0x69
fffff880`0712f6a0 fffff800`05a96a83 : 00000000`00000001 00000000`00000000 fffffa80`20206f49 00000000`00000000 : nt!KiPageFault+0x260
fffff880`0712f830 fffff800`05a5392f : 00000000`00000001 00000000`00017000 fffffa80`02812600 00000000`00000000 : nt!IopCompleteRequest+0xae3
fffff880`0712f900 fffff800`05a28ba9 : 00000000`00000000 00000000`00000000 00000000`00000000 00000000`00000000 : nt!KiDeliverApc+0x1d7
fffff880`0712f980 fffff800`05db92da : fffffa80`042a3be0 fffffa80`02812b30 fffff880`0712fb10 fffff880`0712fb08 : nt!KiCheckForKernelApcDelivery+0x25
fffff880`0712f9b0 fffff800`05d8debf : fffffa80`00000004 fffffa80`02812b30 fffff880`0712fb10 00000000`00000021 : nt! ?? ::NNGAKEGL::`string'+0x2a83e
fffff880`0712faa0 fffff800`05a76153 : 00000000`00000900 fffffa80`02812630 00000000`001cdfe8 00000000`00000001 : nt!NtMapViewOfSection+0x2be
fffff880`0712fb70 00000000`7707013a : 00000000`74b95bdd 00000000`74ba37dc 00000000`003446b8 00000000`00000000 : nt!KiSystemServiceCopyEnd+0x13
00000000`001cdfc8 00000000`74b95bdd : 00000000`74ba37dc 00000000`003446b8 00000000`00000000 00000000`00000000 : ntdll!NtMapViewOfSection+0xa
00000000`001cdfd0 00000000`74b8cf87 : 00000000`00000000 00000000`00344878 00000000`7efdb000 00000000`00000060 : wow64!whNtMapViewOfSection+0x1b9
00000000`001ce120 00000000`74b1276d : 00000000`76443f49 00000000`74b80023 00000000`00000000 00000000`003444a0 : wow64!Wow64SystemServiceEx+0xd7
00000000`001ce9e0 00000000`74b8d07e : 00000000`00000000 00000000`74b11920 00000000`001cec70 00000000`77053ae1 : wow64cpu!ServiceNoTurbo+0x24
00000000`001ceaa0 00000000`74b8c549 : 00000000`00000000 00000000`00000000 00000000`74b84ac8 00000000`7ffe0030 : wow64!RunCpuSimulation+0xa
00000000`001ceaf0 00000000`770684c8 : 00000000`00092c00 00000000`00000000 00000000`77153670 00000000`771257a0 : wow64!Wow64LdrpInitialize+0x429
00000000`001cf040 00000000`77067623 : 00000000`00000000 00000000`77069181 00000000`77020000 00000000`00000000 : ntdll!LdrpInitializeProcess+0x17e2
00000000`001cf540 00000000`7705308e : 00000000`001cf600 00000000`00000000 00000000`7efdf000 00000000`00000000 : ntdll! ?? ::FNODOBFM::`string'+0x2bea0
00000000`001cf5b0 00000000`00000000 : 00000000`00000000 00000000`00000000 00000000`00000000 00000000`00000000 : ntdll!LdrInitializeThunk+0xe


TRAP FRAMEl显示

nt!IopCompleteRequest+0xae3:
fffff800`05a96a83 488b09 mov rcx,qword ptr [rcx] ds:00000000`00000000=????????????????


蓝屏代码是IRQL_NOT_LESS_OR_EQUAL

看样子是什么地方出了个空指针?

而且神奇的是我只复制一个字符(bufffer->ImagePath[0] =  fileNameInfo->Name.Buffer[0])就没事,复制260个字符就boom了
2016-4-10 23:56
0
雪    币: 5
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
请问楼主解决这个问题了吗?
我测试结果是IoQueryFileDosDeviceName调用就不行,直接蓝屏。
2016-5-10 13:17
0
雪    币: 3237
活跃值: (1886)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
POBJECT_NAME_INFORMATION fileNameInfo;


fileNameInfo 是指针,并且没有申请内存空间,也就是野指针(个人理解)。

status = IoQueryFileDosDeviceName(pFileObject, &fileNameInfo);

当调用开始,那么本来是要复制 pFileObject 的信息到 结构体指针 fileNameInfo,却遇到了没有内存可以写入.

所以是会发生崩溃的。
2016-5-13 12:31
0
游客
登录 | 注册 方可回帖
返回
//