功能技术模块
病毒木马的入侵并潜伏在用户计算机上总是有着某种目的,例如获取用户隐私的办公文件或是账号密码,或是控制肉鸡,或是进行加密磁盘文件然后进行勒索。
文件遍历
文件搜索功能应该是应用程序比较常见的功能了,大多数程序或多或少地涉及文件搜索功能,比如:查找用户的隐私数据等。当下万众瞩目的勒索软件病毒就是使用文件遍历功能对硬盘上存储的所有文件全部进行加密操作。
WIN API
FindFirstFile
用于搜索与特定名称匹配的文件或者子目录(或使用通配符时使用的部分名称)
函数声明:
HANDLE WINAPI FindFirstFile(
LPCTSTR lpFileName,
LPWIN32_FIND_DATA lpFindFileData)
参数说明:
- lpFileName:指定目录、路径、以及文件名。文件名可以包括通配符,如*,?。此参数不应为NULL,无效的字符串,尾部以反斜杠结尾的字符串。如果以通配符结尾,则需要对该目录具有访问权限。
- lpFindFileData:指向WIN32_FIND_DATA结构的指针,用于接收搜索到的文件或目录信息。
返回值:
- 如果执行成功,返回搜索句柄,lpFindFileData参数包含搜索到的第一个文件或目录的信息。
- 执行失败或者无法从lpFileName参数的搜索字符串中找到文件,则返回值为INVALID_HANDLE_VALUE,并且lpFindFileData内容不确定
FindNextFile
继续搜索文件
函数声明:
BOOL WINAPI FindNextFile(
HANDLE hFindFile,
LPWIN32_FIND_DATA lpFindFileData)
参数说明:
- hFindFile:指向由前一次调用FindFirstFile函数返回的搜索句柄。
- lpFindFileData:指向WIN32_FIND_DATA结构的指针,该结构接受搜索到的文件或子目录的信息。
返回值:
- 执行成功,则返回不为0,lpFindFileData参数包含搜索到的下一个文件或目录的信息
- 执行失败则返回0,并且lpFindFileData中的内容是不确定的
FindClose
用于释放上述函数执行成功后的句柄
函数声明:
BOOL WINAPI FindClose(
_Inout_ HANDLE hFindFile
);
WIN32_FIND_DATA结构体说明
该结构体常用来接收搜索到的文件信息
结构体定义:
typedef struct _WIN32_FIND_DATAW {
DWORD dwFileAttributes;
FILETIME ftCreationTime;
FILETIME ftLastAccessTime;
FILETIME ftLastWriteTime;
DWORD nFileSizeHigh;
DWORD nFileSizeLow;
DWORD dwReserved0;
DWORD dwReserved1;
_Field_z_ WCHAR cFileName[ MAX_PATH ];
_Field_z_ WCHAR cAlternateFileName[ 14 ];
#ifdef _MAC
DWORD dwFileType;
DWORD dwCreatorType;
WORD wFinderFlags;
#endif
} WIN32_FIND_DATAW, *PWIN32_FIND_DATAW, *LPWIN32_FIND_DATAW;
成员说明:
成员 | 含义 |
---|---|
dwFileAttributes | 指定文件的文件属性,值FILE_ATTRIBUTE_DIRECTORY表示文件是个目录 |
ftCreationTime | 指定文件或目录何时创建的FILETIME结构,如果底层文件系统不支持创建时间,则此成员为0 |
ftLastAccessTime | 它是FILETIME结构,对于一个文件,结构指定文件最后读取、写入或运行可执行文件的时间 |
ftLastWriteTime | 它是FILETIME结构,对于一个文件,该结构指定文件上次写入、截断或覆盖的时间,例如使用WriteFile或SetEndOfFile时 |
nFileSizeHigh | 指定文件大小的高阶DWORD值,以字节为单位 |
nFileSizeLow | 指定文件大小的低阶DWORD值,以字节为单位 |
dwReserved0 | 若dwFileAttributes成员包含FILE_ATTRIBUTE_REPARSE_POINT属性,则此成员将指定重新标记解析点,若未定义,则不应使用。 |
dwReserved1 | 系统保留,留作将来使用 |
cFileName | 指向文件名称 |
cAlternateFileName | 指向该文件的替代名称 |
编码实现
指定目录+通配符进行搜索文件,若为子目录,则进行循环搜索,若为文件,则列出该文件的名称和创建时间。
// ConsoleApplication1.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//
#include <windows.h>
#include <stdio.h>
#include "resource.h"
#include "ConsoleApplication1.h"
#include <tchar.h>
#include <cstring>
#include <shlobj.h>
#include <tlhelp32.h>
BOOL find_file(LPCTSTR pszDirectory)
{
DWORD dwBufferSize = 2048;
wchar_t* pszFileName = new wchar_t[dwBufferSize];
WIN32_FIND_DATA FileData = { 0 };
wsprintf(pszFileName, L"%s\\*.*", pszDirectory);
HANDLE hFile = FindFirstFile(pszFileName, &FileData);
if (hFile != INVALID_HANDLE_VALUE)
{
do
{
//过滤掉当前目录“.”和上级目录“..”,否则会进入死循环
if ('.' == FileData.cFileName[0])
{
continue;
}
wchar_t* pszFileType = new wchar_t[dwBufferSize];
wsprintf(pszFileType, L"%s\\%s", pszDirectory, FileData.cFileName);
if (FileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
{
find_file(pszFileType);
}
else
{
SYSTEMTIME filetime;
FILETIME filetime2;
FileTimeToLocalFileTime(&FileData.ftCreationTime, &filetime2);
FileTimeToSystemTime(&filetime2, &filetime);
printf("File:%ws, Time:%d-%d-%d:%d-%d-%d\n", pszFileType, filetime.wYear, filetime.wMonth, filetime.wDay,filetime.wHour, filetime.wMinute, filetime.wSecond);
}
delete[] pszFileType;
} while (FindNextFile(hFile, &FileData));
FindClose(hFile);
delete[] pszFileName;
}
return TRUE;
}
int main()
{
LPCTSTR filepath = L"C:\\Users\\49627\\Desktop\\temp";
find_file(filepath);
return 0;
}
运行效果
可对代码进行改进,读取指定目录下特定后缀的文件