为什么 WinDBG 可以在 nt!NtCreateFile 而不是 nt!NtAccessCheck 或 nt!SeAccessCheckByType 上中断?
Why can WinDBG break on nt!NtCreateFile but not nt!NtAccessCheck or 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)
我正在尝试检查访问检查中的令牌和安全描述符。出于学习目的,我编写了以下可用于测试的程序:
#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)