windows - 为什么 WinDBG 可以在 nt!NtCreateFile 而不是 nt!NtAccessCheck 或 nt!SeAccessCheckByType 上中断?
问题描述
我正在尝试在访问检查中检查令牌和安全描述符。出于学习目的,我编写了以下可用于测试的程序:
#include <iostream>
#include <windows.h>
int wmain( int argc, wchar_t *argv[], wchar_t *envp[] )
{
if (argc < 3)
{
std::cerr << "Usage: OpenWithAccess <file> <read/write> [ -d ]" << std::endl;
return ERROR_INVALID_PARAMETER;
}
if (argc == 4 && !_wcsicmp(argv[3], L"-d"))
{
__debugbreak();
}
HANDLE hFile = ::CreateFile(argv[1], !_wcsicmp(argv[2], L"write") ? FILE_ALL_ACCESS : GENERIC_READ, 0, nullptr, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, nullptr);
if (hFile != INVALID_HANDLE_VALUE)
{
std::wcout << L"Successfully opened " << argv[1] << L" with " << argv[2] << L" access" << std::endl;
}
else
{
std::wcout << L"Failed to open " << argv[1] << L" with " << argv[2] << L" access, error = " << ::GetLastError() << std::endl;
}
return ERROR_SUCCESS;
}
当我以标准用户身份运行此程序时OpenWithAccess.exe c:\Windows\system32\drivers\etc\hosts write -d
,我知道调用通过 NtAccessCheck (失败并拒绝访问)。
在内核调试器中,我可以在 nt!NtCreateFile 中设置断点,如下所示:
bp /p <myprocessaddress> nt!NtCreateFile
这很好。然而:
bp /p <myprocessaddress> nt!NtAccessCheck
不断裂。但是,如果我闯入,nt!NtCreateFile
然后继续运行t
以跟踪 API,我最终会以nt!NtAccessCheck
. 那么为什么一个断点有效,而另一个断点无效呢?
我应该注意,如果我在没有当前进程的情况下运行它,例如:
bp nt!NtAccessCheck
它确实中断了,但不是在我当前的线程上,即使我知道它运行了并且捕获了其他一些访问检查,它也会被跳过。我期望的那个永远不会被抓住。我错过了什么?
解决方案
尝试在 nt!SeAccessCheck上设置断点并检查它是否为您提供了足够的信息
我刚刚编译了代码并把它拧到了 nt!SeAccessCheck
0: kd> !process @$proc 3f
PROCESS ffffd10fc1503080
SessionId: 1 Cid: 17b8 Peb: 55e8cf000 ParentCid: 0bd4
DirBase: 0ef40002 ObjectTable: ffffaa883bdb1240 HandleCount: 32.
Image: fufu.exe
命中bp3
0: kd> bp /p ffffd10fc1503080 nt!NtCreateFile
0: kd> bp /p ffffd10fc1503080 nt!IopCreateFile
0: kd> bp /p ffffd10fc1503080 nt!NtAccessCheck
0: kd> bp /p ffffd10fc1503080 nt!SeAccessCheck
0: kd> g
Breakpoint 0 hit
nt!NtCreateFile:
fffff802`4c8974e0 4881ec88000000 sub rsp,88h
1: kd> g
Breakpoint 1 hit
nt!IopCreateFile:
fffff802`4c897570 4c894c2420 mov qword ptr [rsp+20h],r9
1: kd> g
Breakpoint 3 hit
nt!SeAccessCheck:
fffff802`4c3bd730 48895c2410 mov qword ptr [rsp+10h],rbx
1: kd> kb
# RetAddr Call Site
00 fffff802`4c942c28 nt!SeAccessCheck
01 fffff802`4c9417bf nt!ObpLookupObjectName+0x188
02 fffff802`4c897974 nt!ObOpenObjectByNameEx+0x1df
03 fffff802`4c897559 nt!IopCreateFile+0x404
04 fffff802`4c46d785 nt!NtCreateFile+0x79
05 00007fff`2c6e0114 nt!KiSystemServiceCopyEnd+0x25
06 00007fff`295ee5d6 ntdll!NtCreateFile+0x14
07 00007fff`295ee2c6 KERNELBASE!CreateFileInternal+0x2f6
08 00007ff7`afaa12ed KERNELBASE!CreateFileW+0x66
09 ffffffff`fffffffe fufu!wmain+0xed [c:\users\xxx\desktop\fufu\fufu.cpp @ 17]
0a 00007ff7`00000002 0xffffffff`fffffffe
0b 00007ff7`afb39358 0x00007ff7`00000002
0c 00007ff7`afaa1032 fufu!std::classic_locale$initializer$
0d 00007ff7`00000004 fufu!`dynamic initializer for 'std::numpunct<wchar_t>::id''+0x12
0e 00000000`00000080 0x00007ff7`00000004
0f 00000000`00000000 0x80
1: kd> dt nt!_SECURITY_DESCRIPTOR @rcx
+0x000 Revision : 0x1 ''
+0x001 Sbz1 : 0 ''
+0x002 Control : 0x10
+0x008 Owner : 0xffffd10f`bb148fb0 Void
+0x010 Group : 0xffffd10f`bb148fb0 Void
+0x018 Sacl : 0xffffaa88`36e05c10 _ACL
+0x020 Dacl : (null)