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
).