功能:遍历指定目录(c:\windows\system32)下的所有文件夹,找出所有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 system
lpszPrivilege, // 要找的权限名 privilege to lookup
&luid)) // 通过指针返回权限的LUID receives LUID of privilege
{
printf("LookupPrivilegeValue error: %u\n", GetLastError());
return FALSE;
}
tp.PrivilegeCount = 1; // 要修改的特权数目
tp.Privileges[0].Luid = luid; // 代表不同特权类型
if (bEnablePrivilege)
tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
else
tp.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: %u\n", GetLastError());
return FALSE;
}
if (GetLastError() == ERROR_NOT_ALL_ASSIGNED)
{
printf("令牌没有这个权限 \n");
return FALSE;
}
return TRUE;
}
方法运行未报错,再次查询,打印getlasterror()的值,仍然是5,也就是说仍然拒绝访问。
请大牛提示下,我是哪里错误了?
或者如何正确的提高权限,让我能够访问权限受阻的文件夹
或者其他如何遍历c盘文件夹的方法
菜鸟感激不尽!
PHP中文网2017-04-17 13:06:25
I found the answer. Under win64, the system32 directory will be redirected to SysWOW64, so the file cannot be found because I did not turn off redirection. As for some files in the c drive, they are indeed inaccessible, but they can be searched. The files can be accessed.
When the program has insufficient permissions, you will automatically be asked whether to increase the permissions.
So some problems may not be what you think. Misunderstanding will lead to big detours, so try not to be too absolute.
PHPz2017-04-17 13:06:25
In system files, administrator rights are not necessarily useful. Another reason is that the owner of these files is not you, so you can't open them anyway.
One example is the picture of the Windows 8.1 lock screen. You will find that no matter how you take ownership, it will fail and the picture just cannot be opened.
怪我咯2017-04-17 13:06:25
There was such a question when I was doing CTF a few years ago
First of all, administrator rights
Then change the owner of calc to yourself, and then patch him...
This is yours It should be a similar approach