在某些情况下, fwrite
写入额外的数据(比请求更多的字节)。 简短演示的输出是最简单的解释方式。 演示尝试创build两个2048字节的文件,并在每次fwrite
调用后检查偏移量,以确定写入的字节数。 第一个fwrite
调用写入两个额外的字节:
len: 2048 current offset = 0 wrote 1024 bytes current offset = 1026 EXITING: offset % BLOCKSIZE = 2 len: 2048 current offset = 0 wrote 1024 bytes current offset = 1024 wrote 1024 bytes SUCCESS
当编译为ELF(unix二进制文件)时,程序成功运行(写入2048字节到两个文件),但编译为PE(Windows二进制/可执行文件)时失败(如上所示)。 我试着编译和testing:
Ubuntu 14.04 and gcc 4.8.2 - SUCCESS WINE 1.6.2 and mingw 4.8.2 - FAIL Windows 7 and mingw 4.8.2 - FAIL Windows 7 and Visual Studio 2013 - FAIL
传递给fwrite
的缓冲区中的实际数据会影响写入的额外字节数,但实际上每次都发生(除非您正在编写空字节)。
main.c中:
#include <stdio.h> #include "stub.h" #include "stub2.h" size_t min(size_t a, size_t b) { return a<b?a:b; } #define BLOCKSIZE 1024 void test(char buf[], size_t len) { FILE *f = fopen("out", "w"); printf("len: %lu\n", len); for(size_t i=0;i<len;i+=BLOCKSIZE) { printf("current offset = %lu\n", ftell(f)); if(ftell(f) % BLOCKSIZE) { printf("EXITING:\noffset %% BLOCKSIZE = %d\n\n", ftell(f) % BLOCKSIZE); return; } size_t wrote = fwrite(buf + i, 1, min(len - i, BLOCKSIZE), f); printf("wrote %lu bytes\n", wrote); } printf("SUCCESS\n\n"); fclose(f); } int main() { test(stub_exe, stub_exe_len); test(stub2_exe, stub2_exe_len); return 0; }
stub.h
和stub2.h
是从/ dev / urandom的2048个字节和从/ dev / zero(分别)用xxd
的2048个字节生成的。 例如:
dd if=/dev/urandom of=stub2.exe bs=2048 count=1 xxd -i stub.exe stub.h dd if=/dev/zero of=stub2.exe bs=2048 count=1 xxd -i stub2.exe stub2.h
免责声明:已经5天了,没有人发布“官方”的答案,所以我正在作出这个答复,接受它。 感谢Christophe
和Retired Ninja
,回答这个问题。
fopen
的第二个参数)。 默认情况下, fopen
以文本模式而不是二进制模式打开文件。 在文本模式下,写入文件时换行符( \n
)被操作系统的换行符所取代,反之亦然。 与使用单个字符( \n
)作为换行符的POSIX系统(Linux,OSX,BSD等)不同,Windows使用\r\n
换行符序列。