我正在尝试检查访问检查中的令牌和安全描述符。出于学习的目的,我编写了下面的程序,可以用来测试:
#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:Windowssystem32driversetchosts 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:usersxxxdesktopfufufufu.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)