You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C++代码复制Windows系统文件后大小异常问题咨询

复制System32文件异常的问题分析与修复

现象

用你提供的C++代码复制C:\Windows\System32\calc.exe到桌面生成aa.exe,文件大小和源文件不一致但仍可正常运行;用CMD的copy命令复制时,目标文件与源文件大小完全匹配。

问题原因

1. 多余的文件指针定位操作

代码中每次循环都调用fseek(fp, unReadLen, SEEK_SET)完全没必要——fread执行成功后,文件指针会自动向后移动对应读取字节数,手动定位属于画蛇添足。若某次读取出现异常(如count计算偏差),会直接导致重复读取或跳过部分内容,最终造成目标文件大小异常。

2. 二进制数据的字符串处理错误

代码里用szFileData.append(databuf)将二进制数据追加到字符串时,append默认会把databuf当作C风格字符串,遇到\0(空字符)就停止追加。可执行文件作为二进制文件,内部大量存在\0,这会导致szFileData内容不完整;不过这步操作不影响文件写入(写入依赖fwrite按实际读取的count字节执行),但属于错误的处理逻辑。

3. 未处理目标文件打开失败场景

若桌面路径不存在或无写入权限,fp2会变为NULL,后续fwrite操作会直接导致程序崩溃,原代码未做任何错误处理。

4. 可能的系统重定向差异

如果你的C++程序是32位版本,在64位Windows系统中,访问C:\Windows\System32会被系统自动重定向到C:\Windows\SysWOW64目录,读取的是32位版calc.exe;而64位CMD复制的是System32目录下的64位版calc.exe,两个源文件本身大小就不同,自然复制后的文件大小存在差异。

修复后的代码

#include <cstdio>
#include <cstring>
#include <string>

#define FILE_NAME_MAX_SIZE 512 
#define buf_len 1024  // 增大缓冲区,提升复制效率

int main() {
    std::string szFileData;
    char file_name[FILE_NAME_MAX_SIZE + 1] = {0};
    char databuf[buf_len] = {0};  // 二进制缓冲区无需额外+1,避免混淆

    // 打开源文件
    FILE* fp = fopen("C:\\Windows\\System32\\calc.exe", "rb");
    if (fp == NULL) {
        printf("源文件打开失败!\n");
        return 1;
    }

    // 打开目标文件
    FILE* fp2 = fopen("C:\\Users\\OS\\Desktop\\aa.exe", "wb");
    if (fp2 == NULL) {
        printf("目标文件打开失败!\n");
        fclose(fp);
        return 1;
    }

    size_t count = 0;
    // 循环读取并写入,依赖fread自动移动文件指针
    while ((count = fread(databuf, 1, buf_len, fp)) > 0) {
        fwrite(databuf, 1, count, fp2);
        
        // 追加二进制数据到string,必须指定长度,避免\0截断
        szFileData.append(databuf, count);

        memset(databuf, 0, sizeof(databuf));
    }

    printf("复制完成\n");
    // 关闭文件
    fclose(fp);
    fclose(fp2);
    return 0;
}

关键修复点

  • 移除多余的fseek和unReadLen变量,让fread自动管理文件指针,避免定位错误。
  • 将缓冲区大小调整为1024,大幅提升复制效率(原5字节缓冲区会导致大量IO操作,效率极低)。
  • 增加目标文件打开失败的处理逻辑,避免程序崩溃。
  • 使用szFileData.append(databuf, count)重载方法追加二进制数据,指定字节数,解决\0截断问题。
  • 若要读取真正的System32目录下的64位文件,可将程序编译为64位版本,或调用Windows APIWow64DisableWow64FsRedirection关闭文件系统重定向。

内容的提问来源于stack exchange,提问作者hahaha1144

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.09 00:14:55