获取进程token(令牌)和sd(安全描述符)

本文介绍了如何在Windows系统中通过Windbg获取进程的Token和安全描述符信息。首先,找到Windbg进程内核对象指针,然后查看进程Token,包括其在模拟令牌中的应用。接着,通过内核对象的偏移获取Token详细信息。最后,探讨了安全描述符在内核对象中的位置,并展示了如何使用!sd命令查看其详细信息。

先找到windbg进程内核对象指针

lkd> !process 0 0 windbg.exe
Unable to read selector for PCR for processor 0
PROCESS 8144c3a8  SessionId: 0  Cid: 02ac    Peb: 7ffdb000  ParentCid: 0820
    DirBase: 0c0c05a0  ObjectTable: e5bcf470  HandleCount: 525.
    Image: windbg.exe

 

查看进程token信息

token存在于进程和线程中。一般情况下线程是没有token的。线程的token称为impersonation token(模拟令牌)。

模拟令牌的应用主要有两种:

1. 模拟其他用户

2. 模拟主令牌(所属进程),在主令牌的基础上增加或删除特权等。

将方法一的计划任务 + 特权访问令牌这种方式合到我目前的代码中,实现QT 程序以管理员权限静默启动(无 UAC 弹窗)#include "mainwindow.h" #include "lockwgt.h" #include <QApplication> #include <QSharedMemory> #include <QMessageBox> #include <Windows.h> #include <shellapi.h> #include <sddl.h> #include <QProcess> #include <QDir> // 检查当前进程是否以管理员权限运行 bool IsElevated() { HANDLE hToken = nullptr; if (!OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &hToken)) return false; TOKEN_ELEVATION elevation; DWORD dwSize; bool isAdmin = false; if (GetTokenInformation(hToken, TokenElevation, &elevation, sizeof(elevation), &dwSize)) { isAdmin = elevation.TokenIsElevated != 0; } CloseHandle(hToken); return isAdmin; } // 尝试以管理员权限重新启动程序 bool RunAsAdmin() { wchar_t szPath[MAX_PATH]; if (!GetModuleFileNameW(nullptr, szPath, ARRAYSIZE(szPath))) return false; SHELLEXECUTEINFOW sei = { sizeof(sei) }; sei.lpVerb = L"runas"; // 请求管理员权限 sei.lpFile = szPath; // 当前程序路径 sei.hwnd = nullptr; sei.nShow = SW_NORMAL; // 使用 ShellExecuteExW 启动 if (!ShellExecuteExW(&sei)) { return false; } // 检查执行结果 return reinterpret_cast<DWORD_PTR>(sei.hInstApp) > 32; } // 创建具有安全描述符的共享内存句柄 HANDLE CreateGlobalSharedMemory(const wchar_t* name) { // 创建安全描述符(允许所有用户访问) SECURITY_DESCRIPTOR sd; if (!InitializeSecurityDescriptor(&sd, SECURITY_DESCRIPTOR_REVISION)) { return nullptr; } // 设置 NULL DACL(允许所有访问) if (!SetSecurityDescriptorDacl(&sd, TRUE, nullptr, FALSE)) { return nullptr; } SECURITY_ATTRIBUTES sa; sa.nLength = sizeof(SECURITY_ATTRIBUTES); sa.lpSecurityDescriptor = &sd; sa.bInheritHandle = FALSE; // 创建文件映射对象 HANDLE hMapFile = CreateFileMappingW( INVALID_HANDLE_VALUE, // 使用分页文件 &sa, // 安全属性 PAGE_READWRITE, // 读写访问 0, // 高位文件大小 1, // 低位文件大小(1字节) name // 共享内存名称 ); return hMapFile; } int main(int argc, char *argv[]) { // 1. 首先检查是否以管理员权限运行 if (!IsElevated()) { // 尝试以管理员权限重新启动 if (runAsAdminSilently()) { // 新进程已启动,退出当前非管理员进程 return 0; } else { // 用户拒绝或提权失败 QMessageBox::critical(nullptr, "权限错误", "需要管理员权限运行此程序!\n请右键选择'以管理员身份运行'"); return 1; } } // 2. 使用Windows API创建全局共享内存 const wchar_t* SHARED_MEM_NAME = L"Global\\FaceLogin"; HANDLE hSharedMem = CreateGlobalSharedMemory(SHARED_MEM_NAME); if (hSharedMem == nullptr) { DWORD error = GetLastError(); QMessageBox::critical(nullptr, "错误", "无法创建共享内存块!错误代码: " + QString::number(error)); return 1; } // 3. 检查是否已有实例运行(通过错误代码判断) if (GetLastError() == ERROR_ALREADY_EXISTS) { CloseHandle(hSharedMem); QMessageBox::warning(nullptr, "警告", "程序已在运行中!"); return 1; } // 4. 主程序逻辑(管理员权限下) QApplication a(argc, argv); MainWindow w; int result = a.exec(); // 5. 程序退出时清理共享内存 CloseHandle(hSharedMem); return result; }
06-24
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值