权限控制 - c++如何解决windows的c盘下某些文件夹的拒绝访问的权限问题?

浏览:41日期:2023-05-31

问题描述

功能:遍历指定目录(c:windowssystem32)下的所有文件夹,找出所有exe类型的文件上代码

/*遍历文件夹,得到所有exe文件*/void getFiles(string path, string exd, vector<WIN32_FIND_DATA>& files){ /************************************************************************/ /* 获取文件夹下所有文件名 输入: path : 文件夹路径 exd: 所要获取的文件名后缀,如jpg、png等; 文件名, exd = '' 输出: files : 获取的文件名列表 */ /************************************************************************/ BOOL SetPrivilege(HANDLE hToken, LPCTSTR lpszPrivilege, BOOL bEnablePrivilege); //文件句柄 HANDLE hFile = INVALID_HANDLE_VALUE,hExe = INVALID_HANDLE_VALUE; //文件信息 WIN32_FIND_DATA fileinfo,exeinfo; string pathName, exdName; // 有无类型要求 if (0 != strcmp(exd.c_str(), '')) {exdName = '*.' + exd; } else {exdName = '*'; } PVOID OldValue = NULL;// 关闭系统重定向 if (Wow64DisableWow64FsRedirection(&OldValue)) {// 查找指定路径hFile = FindFirstFile(pathName.assign(path).append(exdName).c_str(), &fileinfo);if (FALSE == Wow64RevertWow64FsRedirection(OldValue)){ return;} }// 查找指定路径 // hFile = FindFirstFile(pathName.assign(path).append(exdName).c_str(), &fileinfo); // 是否查找失败 if (hFile == INVALID_HANDLE_VALUE) {// 是否因为权限不足,若不足,则提升权限if (GetLastError() == 5){ HANDLE hToken; BOOL bRet = OpenProcessToken(GetCurrentProcess(), // 进程句柄(当前进程)TOKEN_ALL_ACCESS, // 全权访问令牌&hToken // 返回的参数 进程令牌句柄 (就是AdjustTokenPrivileges的第一个参数)); // 获取进程的令牌句柄 if (bRet != TRUE) {cout << '获取令牌句柄失败!' << endl;return; } BOOL set = SetPrivilege(hToken, SE_DEBUG_NAME, TRUE); if (!set || GetLastError() != ERROR_SUCCESS) {// 设置权限失败cout << '提升权限失败 error:' << GetLastError() << endl;cout << '此文件夹缺少权限访问: ' << pathName.assign(path).append('').c_str() << endl;return; } // 权限设置成功,继续执行 hFile = FindFirstFile(pathName.assign(path).append(exdName).c_str(), &fileinfo); cout << '权限设置完成' << endl; cout << GetLastError()<<endl;}else{ // 不是权限问题 cout << 'FindFirstFile failed ' << GetLastError() << endl; system('pause'); return;} } int flag = MY_NOT_CHECK; int lastError = 0; // 遍历 do {//如果是文件夹,迭代之if ((fileinfo.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)){ if (strcmp(fileinfo.cFileName, '.') != 0 && strcmp(fileinfo.cFileName, '..') != 0)getFiles(pathName.assign(path).append('').append(fileinfo.cFileName), exd, files);}else{ //如果不是文件夹 /* if (strcmp(fileinfo.cFileName, '.') != 0 && strcmp(fileinfo.cFileName, '..') != 0) {for (int i = 0; fileinfo.cFileName[i + 3] != ’0’; i++){ // 判断是否exe if (fileinfo.cFileName[i] == ’.’&& (fileinfo.cFileName[i + 1] == ’e’ || fileinfo.cFileName[i + 1] == ’E’)&& (fileinfo.cFileName[i + 2] == ’x’ || fileinfo.cFileName[i + 2] == ’X’)&& (fileinfo.cFileName[i + 1] == ’e’ || fileinfo.cFileName[i + 1] == ’E’)&& fileinfo.cFileName[i + 4] == ’0’) {files.push_back(fileinfo);break; }} } */ // 如果当前目录还未查找过,查找当前目录的exe文件 if (flag) {// 关闭系统重定向if (Wow64DisableWow64FsRedirection(&OldValue)){ // 查找指定路径 hExe = FindFirstFile(pathName.assign(path).append('*.exe').c_str(), &exeinfo); if (FALSE == Wow64RevertWow64FsRedirection(OldValue)) {return; }}// hExe = FindFirstFile(pathName.assign(path).append('*.exe').c_str(), &exeinfo);if (hExe == INVALID_HANDLE_VALUE){ lastError = GetLastError(); if (lastError == 2) {//cout << setiosflags(ios::left) << setw(50) << path << ' 此目录下没有exe ' << endl; } else {cout << ' 查找exe失败 ' << lastError << endl;return; }}// 遍历所有本文件夹下的exe文件if (lastError != 2){ do {files.push_back(exeinfo); } while (FindNextFile(hExe, &exeinfo)); // 查找完成,此目录已不用遍历,跳出 flag = MY_CHECKED; FindClose(hExe);} }} } while (FindNextFile(hFile, &fileinfo)); FindClose(hFile); return;}

在遍历的过程中,遇到某些文件夹无法打开,getlasterror提示5(拒绝访问),在其他盘正常,所以我猜测是因为c盘的某些文件夹需要权限访问,去网上搜索,使用了这个提高进程权限的方法SetPrivilege():

// 使用这组函数提升权限的前提是进程具备该权限,只是访问令牌中没有启用该权限。// 如果进程的访问令牌中本身就没有关联该权限,这AdjustTokenPrivileges函数调用// 将会返回ERROR_NOT_ALL_ASSIGNED(值为1300L)的错误码。BOOL SetPrivilege( HANDLE hToken, // 得到代表句柄 access token handle LPCTSTR lpszPrivilege, // 要打开或关闭的权限名 name of privilege to enable/disable BOOL bEnablePrivilege // 打开还是关闭权限 to enable or disable privilege ){ TOKEN_PRIVILEGES tp; // 该结构包含一个数组,数据组的每个项指明了权限的类型和要进行的操作 LUID luid; // 查找 if (!LookupPrivilegeValue(NULL, // 系统的名字,null,在本地系统上查找权限 lookup privilege on local systemlpszPrivilege, // 要找的权限名 privilege to lookup &luid))// 通过指针返回权限的LUID receives LUID of privilege {printf('LookupPrivilegeValue error: %un', GetLastError());return FALSE; } tp.PrivilegeCount = 1; // 要修改的特权数目 tp.Privileges[0].Luid = luid; // 代表不同特权类型 if (bEnablePrivilege)tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; elsetp.Privileges[0].Attributes = 0; // 调整访问令牌的权限 Enable the privilege or disable all privileges. if (!AdjustTokenPrivileges(hToken,// OpenProcessToken第三个指针参数传出的访问令牌的句柄FALSE, // 是否禁用所有所有的特权&tp, // 指明要修改的权限sizeof(TOKEN_PRIVILEGES), // PreviousState的长度(PTOKEN_PRIVILEGES)NULL, // 存放修改前的访问权限的信息,可空(PDWORD)NULL)) // 实际PreviousState结构返回的大小 {printf('AdjustTokenPrivileges error: %un', GetLastError());return FALSE; } if (GetLastError() == ERROR_NOT_ALL_ASSIGNED) {printf('令牌没有这个权限 n');return FALSE; } return TRUE;}

方法运行未报错,再次查询,打印getlasterror()的值,仍然是5,也就是说仍然拒绝访问。

请大牛提示下,我是哪里错误了?或者如何正确的提高权限,让我能够访问权限受阻的文件夹或者其他如何遍历c盘文件夹的方法

菜鸟感激不尽!

问题解答

回答1:

找到答案了,在win64下,system32目录会重定向到SysWOW64,所以搜不到文件是因为我没有关闭重定向,至于c盘中的某些文件,的确是无法访问的,但是能够搜索到的文件就能够访问。当程序权限不足时,自动就会询问你是否提升权限。所以有的问题或许并不是你想的那样,理解错了会绕很大的弯子,尽量不要太过绝对。

回答2:

使用管理员运行

回答3:

系统文件里面,管理员权限并不一定有用,还有另一个原因是这些文件的owner不是你,所以反正你是打不开的。

其中的一个例子是Windows 8.1锁屏画面的那张图,你会发现无论你怎么take ownership,都会失败,图片就是打不开。

回答4:

几年前做CTF的时候就有这么一道题首先是管理员权限然后把calc的owner换成自己,然后patch他......你的这个应该也是类似的做法

相关文章: