1

For example,I wrote a simple C program:

#include<stdio.h>
int a;
int main(){
    printf("a:%d\n", a);
    return 0;
}

Then I use gcc to compile it and it output a executable file a.exe.
Now I want to write another program to read a.exe and change the value of the variable a.
How can I do it ?


I just want to save some data rather than hack.
Is there any libraries to help me do this?

Pudron
  • 66
  • 1
  • 7
  • With the code above I would be surprised if the variable `a` even existed in `a.exe`. Most compilers would realise that the value must be zero and just call `printf` with that value and not have a variable at all. – john Apr 01 '20 at 12:45
  • Anyway there's no answer to this question, because it depends on many different things. Like what version of the compiler you are using, what architecture you are compiling for etc. etc. And even if you know all those things it's not a simple task that can be quickly answered here. – john Apr 01 '20 at 12:48
  • 3
    So you want to hack an executable? – Weather Vane Apr 01 '20 at 12:48
  • If the variable would exist at all, it will be in the bss. You cannot change or patch a variable in the bss because it does not exist in the executable image. It is created as a zero-initialized variable upon loading. – Paul Ogilvie Apr 01 '20 at 12:50
  • We hardly understand what you want to do. If you want to share a piece of memory between different programs, look at https://stackoverflow.com/questions/3760552/c-shared-memory – Pierre François Apr 01 '20 at 12:54
  • I doubt you REALLY want to do this... – Jean-Baptiste Yunès Apr 01 '20 at 12:55

2 Answers2

4

I'm not sure there's any value in modifying executable files in this way. If you need different copies of a program to use different options, try using configuration files or environment variables.

You'll also find it impossible to distribute the modified application if you use code signing. Without a valid signature, people will be rather disinclined to run your code at all.

Having said that, I don't think there's much point embarking on a detailed study of executable file formats in order to achieve something of such little value. So you might as well make life easy for yourself by flagging the location of the data you want to change. Here's a simple example of how you could do it. (I'm running Mac OS here, but a similar approach might work in Windows too.)

Source code:

A simple program that prints the number 1 and exits. Save this in a file called app1.c.

#include <stdio.h>

int main() {
    volatile unsigned int v[3] = { 0xdeadbeef, 0x00000001, 0xbadc0de };
    printf("This is app%u\n", v[1]);
    return 0;
}

The volatile keyword tells the compiler to keep this array in the compiled code, even though it can be optimized away.

Compile:

Compile the source code into an application called app1.

cc app1.c -o app1

Modify:

Run a one-line Perl script to change the value of v[1] from 1 to 2 and save the result in a file called app2. The chmod 0755 command makes the output file executable.

perl -pe 's/\xef\xbe\xad\xde\x01\x00\x00\x00\xde\xc0\xad\x0b/\xef\xbe\xad\xde\x02\x00\x00\x00\xde\xc0\xad\x0b/' <app1 >app2
chmod 0755 app2

Note: On x86 machines (which means most desktop PCs nowadays), int values are stored in little-endian byte order. For this reason, the bytes used to match the contents of v[] appear in reverse order (e.g., ef be ad de instead of de ad be ef).

Community
  • 1
  • 1
r3mainer
  • 23,981
  • 3
  • 51
  • 88
  • Thanks, I will try it. – Pudron Apr 01 '20 at 14:00
  • 1
    @r3mainer Wouldn't `volatile unsigned int v[3] = { 0xdeadbeef, 0x00000001, 0xbadc0de };` help hinting the compiler not to optimise it? – Kamil.S Apr 03 '20 at 11:47
  • @Kamil.S Yes, that would make sense. In fact, it just occurred to me that the `xxd` editing method won't be reliable either, since it still adds a line break after every 60 characters even with the `-p` flag. I'll go back and edit the answer. – r3mainer Apr 03 '20 at 13:00
1

You'd need to write a program to read the executable file and make the appropriate modifications. On Windows your program would need to understand the Portable Executable file format. On Linux and many other Unix-alike OS's your program would have to understand ELF or a.out or perhaps COFF. Macs and other Apple devices use Mach-O. Gosh there's a lot of such formats - your program is going to have to be pretty smart.