Under certain circumstances, fwrite
writes extra data (more bytes than requested). The output of a short demo is the easiest way to explain. The demo attempts to create two 2048 byte files and checks the offset after each fwrite
call to determine the number of bytes written. The first fwrite
call writes two extra bytes:
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
The program runs successfully (writes 2048 bytes to both files) when compiled as an ELF (unix binary), but fails (as shown above) when compiled as a PE (windows binary/executable). I've tried compiling and testing with:
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
The actual data in the buffer passed to fwrite
affects the number of extra bytes written, but it happens virtually every time (unless you're writing NULL bytes).
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
and stub2.h
are generated from the 2048 bytes of /dev/urandom and 2048 bytes from /dev/zero (respectively) with xxd
. For example:
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
Disclaimer: It's been 5 days and no one has posted an "official" answer, so I'm making this answer and accepting it. Credit goes to Christophe
and Retired Ninja
for actually answering the question.
fopen
's 2nd argument).By default, fopen
opens files in text mode, rather than binary mode. In text mode, the newline character (\n
) is replaced by the operating system's newline sequence when writing to the file, and vice versa when reading. Unlike POSIX systems (Linux, OSX, BSD, etc), which use a single character (\n
) as the newline, Windows uses the \r\n
newline sequence.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With