简体   繁体   中英

Why doesn't it work to convert EXE-file to binary code, add to C and re-create?

This is purely experimental and has no real usefulness (at least not according to my knowledge). I'm reading some literature about the PE-format and wanted to try this out if this was possible.

I created a simple program that prints ”Hello World” in C and compiled it to an EXE on a Windows computer, after that I opened the file in a hex editor and saved the content as a C-file (the hex editor has that as an option) and added it as a string in another C script.

The C-program:

#include <stdio.h>

int main(void)
{
    printf("Hello World");
    return 0;
}

Binary code for C:

0x23, 0x69, 0x6E, 0x63, 0x6C, 0x75, 0x64, 0x65, 0x20, 0x3C, 0x73, 0x74,
0x64, 0x69, 0x6F, 0x2E, 0x68, 0x3E, 0x0D, 0x0A, 0x23, 0x69, 0x6E, 0x63,
0x29, 0x3B, 0x0D, 0x0A, 0x09, 0x0D, 0x0A, 0x09, 0x72, 0x65, 0x74, 0x75,
0x72, 0x6E, 0x20, 0x30, 0x3B, 0x0D, 0x0A, 0x7D, 0x0D, 0x0A [...]

This other C script writes out the content in the string to the disk and saves it as an EXE-file that (according to my theory) would be able to execute. However, when I execute it I receive the message ”This app can't run on your PC”.

The other C-program:

#include <stdio.h>

int main()
{
    FILE* file_ptr = fopen("test_file.exe", "w");

    unsigned char rawData[106] = {
    0x23, 0x69, 0x6E, 0x63, 0x6C, 0x75, 0x64, 0x65, 0x20, 0x3C, 0x73, 0x74,
    0x64, 0x69, 0x6F, 0x2E, 0x68, 0x3E, 0x0D, 0x0A, 0x23, 0x69, 0x6E, 0x63,

    [...]   

    0x48, 0x65, 0x6C, 0x6C, 0x6F, 0x20, 0x57, 0x6F, 0x72, 0x6C, 0x64, 0x22,
    0x29, 0x3B, 0x0D, 0x0A, 0x09, 0x0D, 0x0A, 0x09, 0x72, 0x65, 0x74, 0x75,
    0x72, 0x6E, 0x20, 0x30, 0x3B, 0x0D, 0x0A, 0x7D, 0x0D, 0x0A
    };

    fprintf(file_ptr, "%s", rawData);
    fclose(file_ptr);
    return 0;
}

Why doesn't this work? I mean, it's pure machine code of the EXE-file which worked perfectly before. I guess something must happen in the compiller but I don't understand what exactly.

Anybody who could explain?

The format specifier "%s" is for null-terminated byte strings . The null-terminator equals the byte 0 ( 0x00 ). It's very likely that it exists somewhere in the array data. You need some other way to write it, like eg fwrite .

Also, since you're writing a binary file, you should open it in binary mode as well. Otherwise any byte corresponding to the newline character ( '\\n' , 0x0a in ASCII encoding ) will be translated to the Windows newline sequence "\\r\\n" .

Lastly, the attributes of the file you create will not include the executable flag.

fprintf is for writing text to a file or stream. The %s format specifier will stop on a null character, which is obviously not going to work for binary data which can contain nulls anywhere.

Just the fact that it's binary data should be enough to deter you from using fprintf and other text IO functions, but in particular the PE-EXE format is guaranteed to have nulls within its content by virtue of its very header which begins with the magic number "PE\\0\\0" .

Use the function fwrite to write binary data to a file:

fwrite(rawData, 1, sizeof(rawData), file_ptr);

The "binary" file you are writing is a source file, not an executable. If I translate your raw data:

unsigned char rawData[106] = {
0x23, 0x69, 0x6E, 0x63, 0x6C, 0x75, 0x64, 0x65, 0x20, 0x3C, 0x73, 0x74,
0x64, 0x69, 0x6F, 0x2E, 0x68, 0x3E, 0x0D, 0x0A, 0x23, 0x69, 0x6E, 0x63,

It corresponds to the text:

#include

(etc)

This is not an executable, it is the source file!

You cannot simply save a C source file with an "exe" extension and have it be able to run. You need to actually compile it.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM