win10 tagWnd部分成员逆向(窗口隐藏,窗口保护)
Posted zhuhuibeishadiao
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了win10 tagWnd部分成员逆向(窗口隐藏,窗口保护)相关的知识,希望对你有一定的参考价值。
题外话:窗口隐藏:效果就是spy++ 彗星小助手发现不了窗口,但是窗口确实存在.(副作用:不透明窗口,鼠标不穿透窗口白屏或无反应,进程退出蓝屏(如果恢复了就不会))
一大波黑产在路上了???
怎么隐藏呢?
跟断链一致,前一个的下一个等于当前的下一个,后一个的前一个等于当前的前一个.已经说的很明白了!
另外在17763及以上,在你内核修改是木有效果的哦.具体可以自己研究一下应用层的tagWnd结构,然后,如果你稍微有点基础,就知道怎么搞了:)
拒绝黑产,拒绝伸手党.
简介:tagWnd在win7是公开的 在windbg中输入dt tagWnd是可以看到完整结构体的.
So,这个就不讨论win7了.虽然win10 win32k大改了,但是还是参考的.
先看下win7的tagWnd结构体:
typedef struct _tagWND // 170 elements, 0x128 bytes (sizeof)
/*0x000*/ struct _THRDESKHEAD head; // 5 elements, 0x28 bytes (sizeof)
union // 2 elements, 0x4 bytes (sizeof)
/*0x028*/ ULONG32 state;
struct // 32 elements, 0x4 bytes (sizeof)
/*0x028*/ INT32 bHasMeun : 1; // 0 BitPosition
/*0x028*/ INT32 bHasVerticalScrollbar : 1; // 1 BitPosition
/*0x028*/ INT32 bHasHorizontalScrollbar : 1; // 2 BitPosition
/*0x028*/ INT32 bHasCaption : 1; // 3 BitPosition
/*0x028*/ INT32 bSendSizeMoveMsgs : 1; // 4 BitPosition
/*0x028*/ INT32 bMsgBox : 1; // 5 BitPosition
/*0x028*/ INT32 bActiveFrame : 1; // 6 BitPosition
/*0x028*/ INT32 bHasSPB : 1; // 7 BitPosition
/*0x028*/ INT32 bNoNCPaint : 1; // 8 BitPosition
/*0x028*/ INT32 bSendEraseBackground : 1; // 9 BitPosition
/*0x028*/ INT32 bEraseBackground : 1; // 10 BitPosition
/*0x028*/ INT32 bSendNCPaint : 1; // 11 BitPosition
/*0x028*/ INT32 bInternalPaint : 1; // 12 BitPosition
/*0x028*/ INT32 bUpdateDirty : 1; // 13 BitPosition
/*0x028*/ INT32 bHiddenPopup : 1; // 14 BitPosition
/*0x028*/ INT32 bForceMenuDraw : 1; // 15 BitPosition
/*0x028*/ INT32 bDialogWindow : 1; // 16 BitPosition
/*0x028*/ INT32 bHasCreatestructName : 1; // 17 BitPosition
/*0x028*/ INT32 bServerSideWindowProc : 1; // 18 BitPosition
/*0x028*/ INT32 bAnsiWindowProc : 1; // 19 BitPosition
/*0x028*/ INT32 bBeingActivated : 1; // 20 BitPosition
/*0x028*/ INT32 bHasPalette : 1; // 21 BitPosition
/*0x028*/ INT32 bPaintNotProcessed : 1; // 22 BitPosition
/*0x028*/ INT32 bSyncPaintPending : 1; // 23 BitPosition
/*0x028*/ INT32 bRecievedQuerySuspendMsg : 1; // 24 BitPosition
/*0x028*/ INT32 bRecievedSuspendMsg : 1; // 25 BitPosition
/*0x028*/ INT32 bToggleTopmost : 1; // 26 BitPosition
/*0x028*/ INT32 bRedrawIfHung : 1; // 27 BitPosition
/*0x028*/ INT32 bRedrawFrameIfHung : 1; // 28 BitPosition
/*0x028*/ INT32 bAnsiCreator : 1; // 29 BitPosition
/*0x028*/ INT32 bMaximizesToMonitor : 1; // 30 BitPosition
/*0x028*/ INT32 bDestroyed : 1; // 31 BitPosition
;
;
union // 2 elements, 0x4 bytes (sizeof)
/*0x02C*/ ULONG32 state2;
struct // 30 elements, 0x4 bytes (sizeof)
/*0x02C*/ INT32 bWMPaintSent : 1; // 0 BitPosition
/*0x02C*/ INT32 bEndPaintInvalidate : 1; // 1 BitPosition
/*0x02C*/ INT32 bStartPaint : 1; // 2 BitPosition
/*0x02C*/ INT32 bOldUI : 1; // 3 BitPosition
/*0x02C*/ INT32 bHasClientEdge : 1; // 4 BitPosition
/*0x02C*/ INT32 bBottomMost : 1; // 5 BitPosition
/*0x02C*/ INT32 bFullScreen : 1; // 6 BitPosition
/*0x02C*/ INT32 bInDestroy : 1; // 7 BitPosition
/*0x02C*/ INT32 bWin31Compat : 1; // 8 BitPosition
/*0x02C*/ INT32 bWin40Compat : 1; // 9 BitPosition
/*0x02C*/ INT32 bWin50Compat : 1; // 10 BitPosition
/*0x02C*/ INT32 bMaximizeMonitorRegion : 1; // 11 BitPosition
/*0x02C*/ INT32 bCloseButtonDown : 1; // 12 BitPosition
/*0x02C*/ INT32 bMaximizeButtonDown : 1; // 13 BitPosition
/*0x02C*/ INT32 bMinimizeButtonDown : 1; // 14 BitPosition
/*0x02C*/ INT32 bHelpButtonDown : 1; // 15 BitPosition
/*0x02C*/ INT32 bScrollBarLineUpBtnDown : 1; // 16 BitPosition
/*0x02C*/ INT32 bScrollBarPageUpBtnDown : 1; // 17 BitPosition
/*0x02C*/ INT32 bScrollBarPageDownBtnDown : 1; // 18 BitPosition
/*0x02C*/ INT32 bScrollBarLineDownBtnDown : 1; // 19 BitPosition
/*0x02C*/ INT32 bAnyScrollButtonDown : 1; // 20 BitPosition
/*0x02C*/ INT32 bScrollBarVerticalTracking : 1; // 21 BitPosition
/*0x02C*/ INT32 bForceNCPaint : 1; // 22 BitPosition
/*0x02C*/ INT32 bForceFullNCPaintClipRgn : 1; // 23 BitPosition
/*0x02C*/ INT32 FullScreenMode : 3; // 24 BitPosition
/*0x02C*/ INT32 bCaptionTextTruncated : 1; // 27 BitPosition
/*0x02C*/ INT32 bNoMinmaxAnimatedRects : 1; // 28 BitPosition
/*0x02C*/ INT32 bSmallIconFromWMQueryDrag : 1; // 29 BitPosition
/*0x02C*/ INT32 bShellHookRegistered : 1; // 30 BitPosition
/*0x02C*/ INT32 bWMCreateMsgProcessed : 1; // 31 BitPosition
;
;
union // 2 elements, 0x4 bytes (sizeof)
/*0x030*/ ULONG32 ExStyle;
struct // 32 elements, 0x4 bytes (sizeof)
/*0x030*/ INT32 bWS_EX_DLGMODALFRAME : 1; // 0 BitPosition
/*0x030*/ INT32 bUnused1 : 1; // 1 BitPosition
/*0x030*/ INT32 bWS_EX_NOPARENTNOTIFY : 1; // 2 BitPosition
/*0x030*/ INT32 bWS_EX_TOPMOST : 1; // 3 BitPosition
/*0x030*/ INT32 bWS_EX_ACCEPTFILE : 1; // 4 BitPosition
/*0x030*/ INT32 bWS_EX_TRANSPARENT : 1; // 5 BitPosition
/*0x030*/ INT32 bWS_EX_MDICHILD : 1; // 6 BitPosition
/*0x030*/ INT32 bWS_EX_TOOLWINDOW : 1; // 7 BitPosition
/*0x030*/ INT32 bWS_EX_WINDOWEDGE : 1; // 8 BitPosition
/*0x030*/ INT32 bWS_EX_CLIENTEDGE : 1; // 9 BitPosition
/*0x030*/ INT32 bWS_EX_CONTEXTHELP : 1; // 10 BitPosition
/*0x030*/ INT32 bMakeVisibleWhenUnghosted : 1; // 11 BitPosition
/*0x030*/ INT32 bWS_EX_RIGHT : 1; // 12 BitPosition
/*0x030*/ INT32 bWS_EX_RTLREADING : 1; // 13 BitPosition
/*0x030*/ INT32 bWS_EX_LEFTSCROLLBAR : 1; // 14 BitPosition
/*0x030*/ INT32 bUnused2 : 1; // 15 BitPosition
/*0x030*/ INT32 bWS_EX_CONTROLPARENT : 1; // 16 BitPosition
/*0x030*/ INT32 bWS_EX_STATICEDGE : 1; // 17 BitPosition
/*0x030*/ INT32 bWS_EX_APPWINDOW : 1; // 18 BitPosition
/*0x030*/ INT32 bWS_EX_LAYERED : 1; // 19 BitPosition
/*0x030*/ INT32 bWS_EX_NOINHERITLAYOUT : 1; // 20 BitPosition
/*0x030*/ INT32 bUnused3 : 1; // 21 BitPosition
/*0x030*/ INT32 bWS_EX_LAYOUTRTL : 1; // 22 BitPosition
/*0x030*/ INT32 bWS_EX_NOPADDEDBORDER : 1; // 23 BitPosition
/*0x030*/ INT32 bUnused4 : 1; // 24 BitPosition
/*0x030*/ INT32 bWS_EX_COMPOSITED : 1; // 25 BitPosition
/*0x030*/ INT32 bUIStateActive : 1; // 26 BitPosition
/*0x030*/ INT32 bWS_EX_NOACTIVATE : 1; // 27 BitPosition
/*0x030*/ INT32 bWS_EX_COMPOSITEDCompositing : 1; // 28 BitPosition
/*0x030*/ INT32 bRedirected : 1; // 29 BitPosition
/*0x030*/ INT32 bUIStateKbdAccelHidden : 1; // 30 BitPosition
/*0x030*/ INT32 bUIStateFocusRectHidden : 1; // 31 BitPosition
;
;
union // 2 elements, 0x4 bytes (sizeof)
/*0x034*/ ULONG32 style;
struct // 31 elements, 0x4 bytes (sizeof)
/*0x034*/ INT32 bReserved1 : 16; // 0 BitPosition
/*0x034*/ INT32 bWS_MAXIMIZEBOX : 1; // 16 BitPosition
/*0x034*/ INT32 bReserved2 : 16; // 0 BitPosition
/*0x034*/ INT32 bWS_TABSTOP : 1; // 16 BitPosition
/*0x034*/ INT32 bReserved3 : 16; // 0 BitPosition
/*0x034*/ INT32 bUnused5 : 1; // 16 BitPosition
/*0x034*/ INT32 bWS_MINIMIZEBOX : 1; // 17 BitPosition
/*0x034*/ INT32 bReserved4 : 16; // 0 BitPosition
/*0x034*/ INT32 bUnused6 : 1; // 16 BitPosition
/*0x034*/ INT32 bWS_GROUP : 1; // 17 BitPosition
/*0x034*/ INT32 bReserved5 : 16; // 0 BitPosition
/*0x034*/ INT32 bUnused7 : 2; // 16 BitPosition
/*0x034*/ INT32 bWS_THICKFRAME : 1; // 18 BitPosition
/*0x034*/ INT32 bReserved6 : 16; // 0 BitPosition
/*0x034*/ INT32 bUnused8 : 2; // 16 BitPosition
/*0x034*/ INT32 bWS_SIZEBOX : 1; // 18 BitPosition
/*0x034*/ INT32 bReserved7 : 16; // 0 BitPosition
/*0x034*/ INT32 bUnused9 : 3; // 16 BitPosition
/*0x034*/ INT32 bWS_SYSMENU : 1; // 19 BitPosition
/*0x034*/ INT32 bWS_HSCROLL : 1; // 20 BitPosition
/*0x034*/ INT32 bWS_VSCROLL : 1; // 21 BitPosition
/*0x034*/ INT32 bWS_DLGFRAME : 1; // 22 BitPosition
/*0x034*/ INT32 bWS_BORDER : 1; // 23 BitPosition
/*0x034*/ INT32 bMaximized : 1; // 24 BitPosition
/*0x034*/ INT32 bWS_CLIPCHILDREN : 1; // 25 BitPosition
/*0x034*/ INT32 bWS_CLIPSIBLINGS : 1; // 26 BitPosition
/*0x034*/ INT32 bDisabled : 1; // 27 BitPosition
/*0x034*/ INT32 bVisible : 1; // 28 BitPosition
/*0x034*/ INT32 bMinimized : 1; // 29 BitPosition
/*0x034*/ INT32 bWS_CHILD : 1; // 30 BitPosition
/*0x034*/ INT32 bWS_POPUP : 1; // 31 BitPosition
;
;
/*0x038*/ VOID* hModule;
/*0x040*/ UINT16 hMod16;
/*0x042*/ UINT16 fnid;
/*0x044*/ UINT8 _PADDING0_[0x4];
/*0x048*/ struct _tagWND* spwndNext;
/*0x050*/ struct _tagWND* spwndPrev;
/*0x058*/ struct _tagWND* spwndParent;
/*0x060*/ struct _tagWND* spwndChild;
/*0x068*/ struct _tagWND* spwndOwner;
/*0x070*/ struct _tagRECT rcWindow; // 4 elements, 0x10 bytes (sizeof)
/*0x080*/ struct _tagRECT rcClient; // 4 elements, 0x10 bytes (sizeof)
/*0x090*/ FUNCT_0075_0FB0_lpfnWndProc_aStoCidPfn* lpfnWndProc;
/*0x098*/ struct _tagCLS* pcls;
/*0x0A0*/ struct _HRGN__* hrgnUpdate;
/*0x0A8*/ struct _tagPROPLIST* ppropList;
/*0x0B0*/ struct _tagSBINFO* pSBInfo;
/*0x0B8*/ struct _tagMENU* spmenuSys;
/*0x0C0*/ struct _tagMENU* spmenu;
/*0x0C8*/ struct _HRGN__* hrgnClip;
/*0x0D0*/ struct _HRGN__* hrgnNewFrame;
/*0x0D8*/ struct _LARGE_UNICODE_STRING strName; // 4 elements, 0x10 bytes (sizeof)
/*0x0E8*/ INT32 cbwndExtra;
/*0x0EC*/ UINT8 _PADDING1_[0x4];
/*0x0F0*/ struct _tagWND* spwndLastActive;
/*0x0F8*/ struct _HIMC__* hImc;
/*0x100*/ UINT64 dwUserData;
/*0x108*/ struct _ACTIVATION_CONTEXT* pActCtx;
/*0x110*/ struct _D3DMATRIX* pTransform;
/*0x118*/ struct _tagWND* spwndClipboardListenerNext;
union // 2 elements, 0x4 bytes (sizeof)
/*0x120*/ ULONG32 ExStyle2;
struct // 12 elements, 0x4 bytes (sizeof)
/*0x120*/ INT32 bClipboardListener : 1; // 0 BitPosition
/*0x120*/ INT32 bLayeredInvalidate : 1; // 1 BitPosition
/*0x120*/ INT32 bRedirectedForPrint : 1; // 2 BitPosition
/*0x120*/ INT32 bLinked : 1; // 3 BitPosition
/*0x120*/ INT32 bLayeredForDWM : 1; // 4 BitPosition
/*0x120*/ INT32 bLayeredLimbo : 1; // 5 BitPosition
/*0x120*/ INT32 bHIGHDPI_UNAWARE_Unused : 1; // 6 BitPosition
/*0x120*/ INT32 bVerticallyMaximizedLeft : 1; // 7 BitPosition
/*0x120*/ INT32 bVerticallyMaximizedRight : 1; // 8 BitPosition
/*0x120*/ INT32 bHasOverlay : 1; // 9 BitPosition
/*0x120*/ INT32 bConsoleWindow : 1; // 10 BitPosition
/*0x120*/ INT32 bChildNoActivate : 1; // 11 BitPosition
;
;
tagWND, *PtagWND;
可以看到,大部分的信息都可以直接看到的.
好的,那定一个目标,最后实现的结果是什么样的?
1.支持win10 14393-win10 17763 x64 只弄下x64, x86原理一致
2.输出窗口的句柄,tagWnd,窗口标题,窗口类名信息,下一个窗口,上一个窗口,父窗口,RECT,以及样式
Ojbk!开整!
How to Gao ?
回想一下,5*16*16+2*16+2=1282+32=1314,522是16进制的1314,黑客情人节啊!
额...不好意思,突然脑抽想到了这个.
正经的
第一步:我们需要得到所有的tagWnd.嗯 year.
怎么得到tagWnd呢?稍微了解一点子系统的小哥哥小姐姐就知道win32k!ValidateHwndEx返回tagWnd. So,We need to see see it!
怎么得到所有的tagWnd呢?啊哈哈哈哈哈哈哈.see later.
第二步:得到偏移,取值
得到了tagWnd,就是找偏移,取值了,这些偏移怎么搞到?
想一下:5*16*16+2*16+2=1282+32=1314,522是16进制的1314,黑客情人节啊!
.....额...看win32k相关api的实现啊.
就两步呗,那ojbk啊.
How Get tagWnd on win10 ?
First,We need IDA!打开我从某解下载的泄露版ida 7.0!O shit,i love ida.
先从简单的搞起,看下7601 win32k!ValidateHwnd:
为什么说[rdi+0x10]可以看出rdi就是tagWnd呢?
看下公开的结构体就知道了,都对的上,标题,RECT,句柄,啥的都是ojbk的.
Ojbk!
So,总结一下:
Win7的tagWnd计算公式:
[hwnd->cx*[gSharedInfo+0x10]] + [gSharedInfo+0x8]]
到这里,我们可以猜想,如何枚举所有窗口的tagWnd呢?
1.公式的唯一变数就是hwnd的低16位,那么0~0xffff就是所有的啦
2.tagWnd中记录了上一个窗口和下一个窗口,并且打开彗星小助手或者spy++,会发现总窗口(最大的那个窗口hwnd是固定的,就是0x10010),通过把0x10010转换为tagWnd,然后通过下一个窗口遍历即可.
Ojbk!
搞win10!
先搞一个14393的!
ida打开win32kbase!ValidateHwndEx
大概看下 公式也没变,只是部分偏移改变了
So,
14393:[hwnd->cx*[gSharedInfo+0x10]] + [gSharedInfo+0x8]]
鉴于篇幅,还有写此文章时的电脑并非调试机,就简单说下
Win10:
14393的计算公式同win7
>= 15063 的计算公式都改变了
上面说过了>=15063的公式是改变的
下面就选择16299的win32kbase.sys来看
同样的,也是看win32kbase!ValidateHwndEx
然后特殊一点的是15063:
只是基数不同
So,总结一下:
7601:[hwnd->cx*[gSharedInfo+0x10]] + [gSharedInfo+0x8]]
14393:同7601
15063:[[gpKernelHandleTable] + 0x10 * ((hwnd->cx * [gSharedInfo+0x10]) >> 5)]
16299:[[gpKernelHandleTable] + 0x18 * ((hwnd->cx * [gSharedInfo+0x10]) >> 5)]
17134:[[gpKernelHandleTable] + 0x18 * ((hwnd->cx * [gSharedInfo+0x10]) >> 5)]
17763:[[gpKernelHandleTable] + 0x18 * ((hwnd->cx * [gSharedInfo+0x10]) >> 5)]
Win10中的gpKernelHandleTable和gSharedInfo是导出的.So
How Get Window Info in tagWnd ?
到这里,我们已经可以得到所有tagWnd了(1903还没看),那么下面就是去tagWnd获取信息了.
我们需要以下信息:
1.窗口hwnd(好废话)
2.窗口标题
3.窗口类名
4.窗口RECT
5.窗口的样式
6.窗口的进程信息
提一下:应用层与驱动层都有tagWnd结构,在7601-16299 结构体是相同的
但>16299是不同的,也就是说在>16299的win10中有两个tagWnd,一个是用户层的,一个是内核的,虽然名字一样(看符号),但是内容不一样,用户层获取用户层的tagWnd最简单的就是调用一下NtUserCallOneParam(hwnd, xxx),这个xxx不同的build都不同,最后都是调用到内核的MapDesktopObject.
鉴于不可抗拒的原因,这里只列出内核的tagWnd
- Hwnd
这个是最简单的,tagWnd的前8个字节就是hwnd.
- 窗口标题
联想一下:5*16*16+2*16+2=1282+32........
好的,继续,窗口标题,看下win32kfull!NtUserFindWindowEx
鉴于篇幅,这里只看下14393的,其他一样.
NtUserFindWindowEx->_FindWindow
其中0xe0就是偏移(wchar*) 其实d8就是一个UNICODE_STRING
Ojbk,其他的这里总结下:
strName:
7601:0xe0
14393:0xe0
15063:0xf0
16299:0xf0
17134:0xa8
17763:0xa8
- 窗口类名索引
窗口类名并没有直接保存在tagWNd,而是通过索引去查Atom表
这里就只说下索引
看win32kfull!NtUserGetClassName(15063)
或者
窗口标题那张图的上一句
在调试过程中并没有走到v12!=0x19里面
其中Index就是索引
总结一下:
14393:WORD[[tagWnd+0x98] + 0xA]
15063:WORD[[tagWnd+0xA8] + 0xA]
16299:WORD[[tagWnd+0xA8] + 0xA]
17763:*(_WORD *)(*(_QWORD *)(*(_QWORD *)(tagWnd + 0x70) + 8i64) + 2i64)
- 窗口RECT
有两个RECT,一个是RcWindow,一个是Rcclient
是一个tagRect结构
RcClient的上8个字节就是RcWindow
看下win32kfull!xxxGetUpdateRect(15063)
0x90指向一个tagRect结构,而0x90-8则指向RcWindow
RcClient:
14393:[tagWnd+0x80] hrgnUpdate=0xA0
15063:[tagWnd+0x90] hrgnUpdate=0xB0
16299:[tagWnd+0x90] hrgnUpdate=0xB0
17763:[[tagWnd+0x28]+0x68] hrgnUpdate=[[tagWnd+0x28]+0x88]
RcWindow:
偏移-8
17763:[[tagWnd+0x28]+0x60] hrgnUpdate=[[tagWnd+0x28]+0x88]
- 窗口样式
内核中共有3个样式
- Style
- ExStyle
- ExStyle2
怎么找?
Win32kfull!xxxSetWindowStyle(15063)
ExStyle2往下找UnsetLayeredWindow的上一句
这里的样式并不是用户层spy++或者彗星小助手显示的样式格式,需要转换,这里就不进行转换了.
14393:
Style:0x34 DWORD
ExStyle:0x30 DWORD
ExStyle2:0x120 DWORD
15063:
Style:0x44 DWORD
ExStyle:0x40 DWORD
ExStyle2:0x130 DWORD
16299:
Style:0x44 DWORD
ExStyle:0x40 DWORD
ExStyle2:0x130 DWORD
17763:
Style:DWORD[[tagWnd+0x28] + 0x1c]
ExStyle:DWORD[[tagWnd+0x28] + 0x18]
ExStyle2:DWORD[[tagWnd+0x28] + 0xe8]
- 窗口进程信息
这个也很简单,在tagWnd+0x10是线程对象,你懂我意思吧.
- 窗口关系
窗口关系在tagWnd总是按顺序排列的
tagWND* spwndNext
tagWnd* spwndPrev
tagWnd* spwndParent
tagWnd* spwndChild
tagWnd* spwndOwner
看win32kfull!BuildHwndList(16299)
0x58为spwndNext
再往下拉一点即可看到Child
总结下:只列出spwndNext的偏移,其它的偏移都是按指定顺序排列(dd tagWnd xxxxxx 查看句柄验证)
7601:0x48
14393:0x58
15063:0x58
16299:0x58
17134:0x40
17763:0x40
以上是关于win10 tagWnd部分成员逆向(窗口隐藏,窗口保护)的主要内容,如果未能解决你的问题,请参考以下文章
零基础逆向工程40_Win32_14_枚举窗口_模拟鼠标键盘