0

I try to write a C code such that executing its binary a.out changes the a.out file itself.

For example, I want to write foo.c like:

% gcc foo.c
% a.out
Hello world!
% a.out
Bus error
% 
1
  • 2
    Yes, what have you done? Commented Feb 6, 2014 at 10:30

3 Answers 3

2

This is not possible to do in a portable way (the way the executable is structured will be different on every system - ELF vs .exe, amb64 vs ARM), but you can bundle something like libgcc or libclang with your output file which should allow codegeneration + compilation.

Look at the code for the clang executable here which should give you some good ideas.

What you might do (in pseudo code):

string myNewCode("#include <stdio.h>\nint main(int argc, char *argv[]){ printf(\"Bus error\\n\");return 1; }");
var compiler = new Compiler();
var temp_file = new tempFile();
compiler->compile(myNewCode, temp_file);
move_file(temp_file, argv[0]);

(secondary edit: having giving this a little more thought, this is completely possible and portable with libclang)

Sign up to request clarification or add additional context in comments.

Comments

1

Not portably, no.

In many flavors of Windows, you can't modify the executable of a program being run. This is often highly annoying, even when doing something "more sane" than what you're proposing.

In Linux I think it would be fine, just open argv[0] and modify it. Of course if your process was loaded off the path you migth have issues locating the proper file, but there should be some /sys entry or something that can lead you (down) to the absolute path.

7 Comments

argv[0] is the program itself? Wow! I only thought it was the name of the program.
@NlightNFotis It's only the name, he means that to know what to open you need to know the name :)
@NlightNFotis It is the name of the program. Not sure what you thought I meant. I imagined the OP doing e.g. open(argv[0], ...) to open the file that contains the running program for modification.
Under Linux, /proc/$pid/exe is a symlink to the program file.
Wouldn't another viable way (on Linux) to change the program at runtime be to open /proc/$pid/mem and modify it? I'm just asking, never done it myself. I know that you can open /dev/mem and modify it, with crashtastic sequences, so I guess it's usage might be the same.
|
0

I went ahead an tried it. The example below works on Linux as per your spec (Beware, this is hacky, non-dynamic code!)

#include <stdio.h>

const char str1[]="Hello world!"; //12 chars + \0
//        echo -n "Bus error"| wc -c  # 9 + \0 -- need to pad by 3

int main(int argc, char const * const argv[]){
  puts(str1);
  system("sed 's/Hello world!/Bus error\\x0\\x0\\x0/' a.out -i~\n"
         "rm a.out~\n");
  return 0;
}

You can't write to that file in place though (unless you want to bring the app down to a noisy crash). Using -i~ doesn't write in place, but rather moves the original file to a.out~, while creating a modified copy named a.out. (The OS continues reading the same file regardless of the name change. Removing/unlinking is also OK -- Linux programs can continue accessing unlinked files if they had opened them (without closing) before the unlinking).

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.