【发布时间】:2021-10-30 22:02:00
【问题描述】:
我正在尝试在访问检查中检查令牌和安全描述符。出于学习目的,我编写了以下可用于测试的程序:
#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
它确实中断了,但不是在我当前的线程上,即使我知道它运行并且捕获了其他一些访问检查,它也会被跳过。我期望的那个永远不会被抓住。我错过了什么?
【问题讨论】:
-
如果你这样做
bu nt!NtAccessCheck ".if (@$proc != <yourproc>) { gc; }"会发生什么?出于本练习的目的而忽略性能。