- 注册时间
- 2011-3-6
- 最后登录
- 1970-1-1
该用户从未签到
|
在我的上一篇文章中讲到
51604788
枚举窗口 使用EnumWinodws是调用内核中NtUserBuildHwndList 这个函数最后2个参数必须是R3的地址
不然会返回0xC0000008错误,并且如果使用控制台窗口测试,这时ETHREAD下的win32Thread是NULL 也会返回0xC0000008错误
去实现的时候,返回成功了,但只传回线程的窗口HWND
然后去看了看win32k.sys的这个函数
下面是我修改了好的IDA F5这个函数
- // typedef NTSTATUS (__fastcall *PFN_NTUSERBULIDHWNDLIST)(
- // __int64 hDesktop,
- // __int64 hWndParent,
- // BOOLEAN bChildren,
- // unsigned int dwThreadId,
- // unsigned int lParam,
- // OUT PVOID pWnd,
- // OUT PVOID pBufSize);
- /*参考链接:
- http://read.pudn.com/downloads3/sourcecode/windows/248345/win2k/private/ntos/w32/ntuser/kernel/enumwin.c__.htm (win2k\private\ntos\w32\ntuser\kernel\enumwin.c)
- http://svn.netlabs.org/repos/odin32/trunk/include/win/win.h
- https://www.reactos.org/wiki/Techwiki:Win32k/WND
- https://www.reactos.org/wiki/Techwiki:Win32k/THREADINFO
- http://bbs.pediy.com/showthread.php?t=100983
- http://www.mengwuji.net/thread-99-1-1.html
- http://bbs.pediy.com/showthread.php?t=131950
- */
- __int64 __fastcall NtUserBuildHwndList(__int64 hDesktop, __int64 hWndParent, BOOL bChildren, unsigned int dwThreadId, unsigned int MaxNum_user, PVOID pWnd_User, unsigned __int64 pBuffSize_User)
- {
- int m_ThreadId; // ebx@1
- BOOL m_bChildren; // er14@1
- __int64 m_hWndParent; // rdi@1
- __int64 m_hDesktop; // rsi@1
- __int64 m_m_pBwl; // r12@1
- UINT flags; // er13@1
- __int64 v13; // rax@1
- __int64 v14; // rdx@1
- tagWND *m_tagWnd; // rax@4
- NTSTATUS status; // ebx@5
- tagTHREADINFO *m_pti; // rax@8
- tagTHREADINFO *m_m_pti; // rdi@8
- tagDESKTOP *m_rpdesk; // rax@9
- tagDESKTOP *m_p_desk_top; // rsi@16
- tagTHREADINFO *v21; // rax@16
- tagWND *m_top_wnd; // rax@22
- __int64 m_pBwl; // rax@27
- unsigned int m_max_hwnd; // edi@29
- __int64 m_max_num_user; // rbx@29
- unsigned __int64 m_p_buff_size_user; // r13@31
- unsigned __int64 m_m_p_buff_size_user; // rdx@31
- int v29; // [sp+48h] [bp-40h]@16
- tagTHREADINFO *v30; // [sp+50h] [bp-38h]@16
- tagDESKTOP *v31; // [sp+58h] [bp-30h]@16
- int v32; // [sp+60h] [bp-28h]@16
- int v33; // [sp+64h] [bp-24h]@16
- PVOID Object; // [sp+98h] [bp+10h]@14
- m_ThreadId = dwThreadId;
- m_bChildren = bChildren;
- m_hWndParent = hWndParent;
- m_hDesktop = hDesktop;
- m_m_pBwl = 0i64;
- flags = 2;
- LODWORD(v13) = ExEnterPriorityRegionAndAcquireResourceExclusive(gpresUser);
- gptiCurrent = v13;
- gbValidateHandleForIL = 0;
- if ( *(_BYTE *)gpsi & 4 )
- flags = 10;
- if ( m_hWndParent )
- {
- LODWORD(m_tagWnd) = ValidateHwnd(m_hWndParent);
- if ( !m_tagWnd )
- {
- status = 0xC0000008;
- goto LABEL_41;
- }
- }
- else
- {
- m_tagWnd = 0i64;
- }
- if ( m_ThreadId )
- {
- m_pti = (tagTHREADINFO *)PtiFromThreadId(m_ThreadId);
- m_m_pti = m_pti;
- if ( !m_pti || (m_rpdesk = m_pti->rpdesk) == 0i64 )
- {
- status = 0xC0000008;
- UserSetLastError(0x57);
- goto LABEL_41;
- }
- m_tagWnd = m_rpdesk->pDeskInfo->spwnd->spwndChild;
- }
- else
- {
- m_m_pti = 0i64;
- }
- if ( !m_hDesktop )
- {
- m_p_desk_top = 0i64;
- Object = 0i64;
- goto LABEL_20;
- }
- LOBYTE(v14) = 1;
- if ( (int)ValidateHdesk((void *)m_hDesktop, v14, 1i64, &Object) < 0 )
- {
- status = 0xC0000008;
- goto LABEL_41;
- }
- v32 = 0;
- v33 = 0;
- m_p_desk_top = (tagDESKTOP *)Object;
- v31 = (tagDESKTOP *)Object;
- v29 = 1;
- LODWORD(v21) = PsGetCurrentProcess();
- v30 = v21;
- status = MapDesktop(&v29);
- if ( status >= 0 )
- {
- m_tagWnd = m_p_desk_top->pDeskInfo->spwnd->spwndChild;
- LABEL_20:
- if ( m_tagWnd )
- {
- if ( m_bChildren )
- {
- flags |= 1u;
- m_tagWnd = m_tagWnd->spwndChild;
- }
- }
- else if ( !m_p_desk_top )
- {
- m_top_wnd = (tagWND *)GetThreadDesktopWindow((__int64)m_m_pti);// /*0x060*/ struct _tagWND* spwndChild;
- if ( !m_top_wnd )
- {
- status = 0xC0000008;
- UserSetLastError(0x57);
- goto LABEL_41;
- }
- m_tagWnd = m_top_wnd->spwndChild; // /*0x060*/ struct _tagWND* spwndChild;
- }
- m_pBwl = BuildHwndList(m_tagWnd, flags, m_m_pti);
- m_m_pBwl = m_pBwl; // _BWL 这个结构符号里找不到
- /*
- ROS 中2k xp中定义如下:
- typedef struct _BWL
- {
- struct _BWL *pbwlNext;
- HWND *phwndNext;
- HWND *phwndMax;
- PTHREADINFO ptiOwner;
- HWND rghwnd[1];
- } BWL, *PBWL;
- */
- if ( m_pBwl )
- {
- m_max_hwnd = (unsigned __int64)((*(_QWORD *)(m_pBwl + 8) - m_pBwl - 0x20) >> 3) + 1;
- m_max_num_user = MaxNum_user;
- if ( MaxNum_user > 0x1FFFFFFF )
- ExRaiseAccessViolation();
- ProbeForWrite(pWnd_User, 8 * m_max_num_user, 4u);
- m_p_buff_size_user = pBuffSize_User;
- m_m_p_buff_size_user = pBuffSize_User;
- if ( pBuffSize_User >= (unsigned __int64)W32UserProbeAddress )
- m_m_p_buff_size_user = (unsigned __int64)W32UserProbeAddress;
- *(_DWORD *)m_m_p_buff_size_user = *(_DWORD *)m_m_p_buff_size_user;
- if ( m_max_hwnd > (unsigned int)m_max_num_user )
- {
- status = 0xC0000023;
- }
- else
- {
- memmove(pWnd_User, (const void *)(m_m_pBwl + 0x20), 8i64 * m_max_hwnd);
- status = 0;
- }
- *(_DWORD *)m_p_buff_size_user = m_max_hwnd;
- }
- else
- {
- status = 0xC0000008;
- UserSetLastError(8);
- }
- goto LABEL_37;
- }
- UserSetLastError(6);
- LABEL_37:
- if ( m_m_pBwl )
- FreeHwndList(m_m_pBwl);
- if ( m_p_desk_top )
- ObfDereferenceObject(m_p_desk_top);
- LABEL_41:
- UserSessionSwitchLeaveCrit();
- return (unsigned int)status;
- }
复制代码 可以看到 最后两个参数必须是R3的地址
否则返回0xC0000008错误,还有一点是如果这个线程的win32Thread是NULL的话也会返回0xC0000008错误(在控制台程序中出现)
修改后的代码,很明显可以知道如果dwThreadId是NULL的话就是枚举所有HWND
以下代码在win7 x64下测试通过
代码没有查询窗口的进程是谁
要查询的话只要调用
NtUserQueryWindow 即可得到
例如NtUserQueryWindow(hWnd,0);
R0:- #include <ntddk.h>
- #define DEVICE_NAME L"\\device\\DjWow"
- #define LINK_NAME L"\\dosdevices\\DjWow" //\\??\\xxxx
- #define IOCTRL_BASE 0x800
-
- #define IOCTL_CODE(i) \
- CTL_CODE(FILE_DEVICE_UNKNOWN, IOCTRL_BASE+i, METHOD_BUFFERED,FILE_ANY_ACCESS)
-
- #define CTL_HELLO IOCTL_CODE(0)
- #define CTL_ULONG IOCTL_CODE(1)
- #define CTL_WCHAR IOCTL_CODE(2)
- #define CTL_CALLLIST IOCTL_CODE(3)
- VOID testGetWndList(unsigned int ThreadId,PVOID OutputBuffer,ULONG BufferSize,PVOID Outbuflenbuf);
- typedef NTSTATUS (__fastcall *PFN_NTUSERBULIDHWNDLIST)(
- __int64 hDesktop,
- __int64 hWndParent,
- BOOLEAN bChildren,
- unsigned int dwThreadId,
- unsigned int lParam,
- OUT PVOID pWnd,
- OUT PVOID pBufSize);
- //硬编码了
- PFN_NTUSERBULIDHWNDLIST g_NtUserBuildHwndList = (PFN_NTUSERBULIDHWNDLIST)0xfffff96000084630;
- NTSTATUS DispatchCommon(PDEVICE_OBJECT pDeviceObject, PIRP pIrp)
- {
- pIrp->IoStatus.Status = STATUS_SUCCESS;
- pIrp->IoStatus.Information = 0;
- UNREFERENCED_PARAMETER(pDeviceObject);
- IoCompleteRequest(pIrp, IO_NO_INCREMENT);
- return STATUS_SUCCESS;
- }
- NTSTATUS DispatchCreate(PDEVICE_OBJECT pDeviceObject, PIRP pIrp)
- {
- pIrp->IoStatus.Status = STATUS_SUCCESS;
- pIrp->IoStatus.Information = 0;
- UNREFERENCED_PARAMETER(pDeviceObject);
- IoCompleteRequest(pIrp, IO_NO_INCREMENT);
- return STATUS_SUCCESS;
- }
- NTSTATUS DispatchClose(PDEVICE_OBJECT pDeviceObject, PIRP pIrp)
- {
- pIrp->IoStatus.Status = STATUS_SUCCESS;
- pIrp->IoStatus.Information = 0;
- UNREFERENCED_PARAMETER(pDeviceObject);
- IoCompleteRequest(pIrp, IO_NO_INCREMENT);
- return STATUS_SUCCESS;
- }
- NTSTATUS DispatchClear(PDEVICE_OBJECT pDeviceObject, PIRP pIrp)
- {
- pIrp->IoStatus.Status = STATUS_SUCCESS;
- pIrp->IoStatus.Information = 0;
- UNREFERENCED_PARAMETER(pDeviceObject);
- IoCompleteRequest(pIrp, IO_NO_INCREMENT);
- return STATUS_SUCCESS;
- }
- NTSTATUS DispatchRead(PDEVICE_OBJECT pDeviceObject, PIRP pIrp)
- {
- PVOID pBuff = 0;
- ULONG pBuffLen = 0;
- ULONG pStackLen = 0;
- PIO_STACK_LOCATION pStack = 0;
- ULONG uMin = 0;
- UNREFERENCED_PARAMETER(pDeviceObject);
- pBuff = pIrp->AssociatedIrp.SystemBuffer;
- pStack = IoGetCurrentIrpStackLocation(pIrp);
- pStackLen = pStack->Parameters.Read.Length;
- pBuffLen = (wcslen(L"hello world") + 1) * sizeof(WCHAR);
- uMin = pBuffLen < pStackLen ? pBuffLen:pStackLen;
- RtlCopyMemory(pBuff, L"hello wolrd", uMin);
- pIrp->IoStatus.Status = STATUS_SUCCESS;
- pIrp->IoStatus.Information = uMin;
- IoCompleteRequest(pIrp, IO_NO_INCREMENT);
- return STATUS_SUCCESS;
- }
- NTSTATUS DispatchWrite(PDEVICE_OBJECT pDeviceObject, PIRP pIrp)
- {
- PVOID pWriteBuff = 0;
- PVOID pBuff = 0;
- ULONG uWriteBuffLen = 0;
- PIO_STACK_LOCATION pStack = 0;
- UNREFERENCED_PARAMETER(pDeviceObject);
- pWriteBuff = pIrp->AssociatedIrp.SystemBuffer;
- pStack = IoGetCurrentIrpStackLocation(pIrp);
- uWriteBuffLen = pStack->Parameters.Write.Length;
- pBuff = ExAllocatePoolWithTag(PagedPool, uWriteBuffLen,'TSET');
- if(pBuff == NULL)
- {
- pIrp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES;
- pIrp->IoStatus.Information = 0;
- return STATUS_INSUFFICIENT_RESOURCES;
- }
- RtlZeroMemory(pBuff, uWriteBuffLen);
- RtlCopyMemory(pBuff,pWriteBuff, uWriteBuffLen);
- ExFreePool(pBuff);
- pBuff = 0;
- IoCompleteRequest(pIrp, IO_NO_INCREMENT);
- pIrp->IoStatus.Status = STATUS_SUCCESS;
- pIrp->IoStatus.Information = uWriteBuffLen;
- return STATUS_SUCCESS;
- }
- NTSTATUS DispatchIoctrl(PDEVICE_OBJECT pDeviceObject, PIRP pIrp)
- {
- PIO_STACK_LOCATION pStack = 0;
- PVOID pBuff = 0;
- ULONG uOutLen = 0;
- ULONG uInLen = 0;
- ULONG uCtlCode = 0;
- ULONG_PTR *Context;
- PVOID64 outbuflenbuf;
- PVOID64 OutBuf;
- unsigned int ThreadId;
- UNREFERENCED_PARAMETER(pDeviceObject);
- pStack = IoGetCurrentIrpStackLocation(pIrp);
- uOutLen = pStack->Parameters.DeviceIoControl.OutputBufferLength;
- uInLen = pStack->Parameters.DeviceIoControl.InputBufferLength;
- pBuff = pIrp->AssociatedIrp.SystemBuffer;
- uCtlCode = pStack->Parameters.DeviceIoControl.IoControlCode;
- switch (uCtlCode)
- {
- case CTL_HELLO:
- DbgPrint("hello!\n");
- break;
- case CTL_ULONG:
- {
- DbgPrint("pid:%d\n",*(ULONG*)pBuff);
- RtlCopyMemory(pBuff,L"ok",uOutLen);
- break;
- }
- case CTL_WCHAR:
- DbgPrint("%ws",pBuff);
- break;
- case CTL_CALLLIST:
- {
- Context = (ULONG_PTR*)pBuff;
- ThreadId = (unsigned int)Context[0];
- OutBuf = (PVOID)Context[1];
- uOutLen = Context[2];
- outbuflenbuf = (PVOID)Context[3];
- DbgPrint("[Drv]Thread Id is %d OutpubBuffer=0x%08LLX BufLen=0x%X outbuflenbuf = 0x%08LLX\n",ThreadId,OutBuf,uOutLen,outbuflenbuf);
- testGetWndList(ThreadId,OutBuf,uOutLen,outbuflenbuf);
- break;
- }
- default:
- DbgPrint("UNKNUW CTLCODE!\n");
- break;
- }
- pIrp->IoStatus.Status = STATUS_SUCCESS;
- pIrp->IoStatus.Information = uOutLen;
- IoCompleteRequest(pIrp, IO_NO_INCREMENT);
- return STATUS_SUCCESS;
- }
- /*
- 参考:
- http://bbs.pediy.com/showthread.php?t=100983
- http://www.mengwuji.net/thread-99-1-1.html
- http://bbs.pediy.com/showthread.php?t=131950
- I:\IDA分析\win7 x64\win32k.sys / win32k.i64
- */
- VOID testGetWndList(unsigned int ThreadId,PVOID64 OutputBuffer,ULONG BufferSize,PVOID64 Outbuflenbuf)
- {
- //ULONG_PTR *HwnBuf=NULL;
- ULONG BufSize=0;
- ULONG MaxNum = 0x1000;
- NTSTATUS status;
- int i = 0;
- __int64 hwnd = 0;
- __int64 *hwndtable = NULL;
-
- BufSize = BufferSize;
- MaxNum = BufferSize/sizeof(ULONG_PTR);
- //HwnBuf = (ULONG_PTR*)OutputBuffer;
- DbgPrint("MAXNUM:0x%x",MaxNum);
- DbgPrint("准备调用NtUserBuildHwndList...\n");
-
-
- status = g_NtUserBuildHwndList(0,
- 0,
- FALSE,
- NULL,//ThreadId,
- MaxNum,//MaxNum
- OutputBuffer,
- Outbuflenbuf);
-
- hwndtable = (__int64*)OutputBuffer;
- DbgPrint("%d\n",*(ULONG_PTR*)Outbuflenbuf);
- /*
- 0 d fffff960`00084862 e 1 0001 (0001) win32k!NtUserBuildHwndList+0x232
- 1 e fffff960`000847fb e 1 0001 (0001) win32k!NtUserBuildHwndList+0x1cb
- 3 e fffff960`00084804 e 1 0001 (0001) win32k!NtUserBuildHwndList+0x1d4
- */
- for (i = 0; i < *(ULONG_PTR*)Outbuflenbuf; i++)
- {
- __try
- {
- hwnd = hwndtable[i];
- DbgPrint("0x%llx\n",hwnd);
- }
- __except(1)
- {
- DbgPrint("except!\n");
- }
- }
- DbgPrint("count:%d\n",i);
- DbgPrint("NtUserBuildHwndList Returned status = 0x%08X \n",status);
- }
- VOID DriverUnload(PDRIVER_OBJECT pDriverObject)
- {
- UNICODE_STRING strLinkName ={0};
- RtlInitUnicodeString(&strLinkName,LINK_NAME);
- IoDeleteSymbolicLink(&strLinkName);
- if(pDriverObject->DeviceObject)
- {
- IoDeleteDevice(pDriverObject->DeviceObject);
- }
-
- DbgPrint("DriverUnload");
- return;
- }
- NTSTATUS DriverEntry(PDRIVER_OBJECT pDriverObject, PUNICODE_STRING pRegPath)
- {
- UNICODE_STRING strDeviceName = {0};
- UNICODE_STRING strLinkName = {0};
- NTSTATUS status = 0;
- PDEVICE_OBJECT pDeviceObject = 0;
- ULONG i = 0;
- DbgPrint("[DJWOW]DriverEntry!\n");
- UNREFERENCED_PARAMETER(pRegPath);
- RtlInitUnicodeString(&strDeviceName, DEVICE_NAME);
- RtlInitUnicodeString(&strLinkName, LINK_NAME);
- status = IoCreateDevice(pDriverObject, 0, &strDeviceName, FILE_DEVICE_UNKNOWN, 0, FALSE, &pDeviceObject);
- if(!NT_SUCCESS(status))
- {
- DbgPrint("CretaDevice Faild:0x%x\n",status);
- return status;
- }
- pDeviceObject->Flags |= DO_BUFFERED_IO;
- status = IoCreateSymbolicLink(&strLinkName,&strDeviceName);
- if(!NT_SUCCESS(status))
- {
- IoDeleteDevice(pDeviceObject);
- DbgPrint("IoCreateSymbolicdLink Faild:0x%x\n",status);
- return status;
- }
- for (i = 0; i < IRP_MJ_MAXIMUM_FUNCTION + 1; i++)
- {
- pDriverObject->MajorFunction[i] = DispatchCommon;
- }
- pDriverObject->MajorFunction[IRP_MJ_CREATE] = DispatchCreate;
- pDriverObject->MajorFunction[IRP_MJ_READ] = DispatchRead;
- pDriverObject->MajorFunction[IRP_MJ_WRITE] = DispatchWrite;
- pDriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = DispatchIoctrl;
- pDriverObject->MajorFunction[IRP_MJ_CLOSE] = DispatchClose;
- pDriverObject->MajorFunction[IRP_MJ_CLEANUP] = DispatchClear;
- pDriverObject->DriverUnload = DriverUnload;
- return STATUS_SUCCESS;
- }
复制代码
R3(也需要是x64):
- int CMFC_EXEDlg::SendDeviceIoControl(void)
- {
- DWORD byteRetned=0;
- DWORD retValue;
- char buffer[300] = {0};
- char wndbuffer[0x1000] = {0};
- HWND* tmp = 0;
-
- ULONG_PTR IoContext[4]={0};//ThreadId,Outputbuffer,outbuflen
- DWORD dwThreadId = GetCurrentThreadId();
- CString str;
- /*sprintf(buffer,"[Client]Current TheadId = %d\n",dwThreadId);
- OutputDebugStringA(buffer);*/
- //printf("[Client]Current TheadId = %d\n",dwThreadId);
- str.Format(L"%d",dwThreadId);
- m_edit_string = str;
- UpdateData(FALSE);
- /*sprintf(buffer,"[Client]WndList Buffer = 0x%08X\n",wndbuffer);
- OutputDebugStringA(buffer);*/
- //printf("[Client]WndList Buffer = 0x%08X\n",wndbuffer);
- str.Format(L"0x%08x\r\n",wndbuffer);
- m_edit_string += str;
- HANDLE hDevice = CreateFileA( "\\\\.\\DjWow",
- GENERIC_READ | GENERIC_WRITE,
- 0,
- NULL,
- OPEN_EXISTING,
- FILE_ATTRIBUTE_NORMAL,
- NULL
- );
- if ( hDevice == ((HANDLE)0xFFFFFFFF) )
- {
- OutputDebugStringA("[Client]Open SymbolLink Failed!\n");
- return 0;
- }
- //填充buffer
- IoContext[0] = dwThreadId;
- IoContext[1] = (ULONG_PTR)wndbuffer;
- IoContext[2] = 0x1000;
- IoContext[3] = (ULONG_PTR)&IoContext[2];
- retValue=DeviceIoControl(hDevice,
- CTL_CALLLIST,
- IoContext,
- sizeof(ULONG_PTR)*4,
- wndbuffer,
- 0x1000,
- &byteRetned,
- NULL);
- CloseHandle(hDevice);
- /*sprintf(buffer,"[Client]return value=%d\n",retValue);
- OutputDebugStringA(buffer);*/
- //printf("[Client]return value=%d\n",retValue);
- m_edit_string += "\r\nok!";
- //str.Format(L"%s",wndbuffer);
- //m_edit_string += L"\r\n" + str;
- tmp = (HWND*)wndbuffer;
- int i = 0;
- while (i < 100)
- {
- GetWindowTextA(tmp[i],buffer,MAX_PATH-1);
- str.Format(L"%s",buffer);
- m_edit_string += L"\r\n" + str;
- UpdateData(FALSE);
- i++;
- }
- UpdateData(FALSE);
- return 1;
- }
复制代码 为什么不用EnumWindows呢?
我就闲着无聊.....
|
|