0

I am trying to understand how to set the value of a string in the rodata segment as loading it using an environment variable gives me issues. I want to externally set a constant string in the rodata section. This function should be independent of the code executed. So, when I do

"objdump -c foo"

the rodata section must enlist this string without the file foo.c having to do it. How do I set a constant in the .rodata section ?

Edit: Linux OS and using GCC

I cannot use an environment var as that would mean that the c code is modified, I want the c code untouched and add the constant, say "Goo" to the rodata segment.

LockStock
  • 199
  • 12
  • Could you please clarify what you want to accomplish? As given it is very unclear. Normally, data is automatically placed into the `rodata` _section_ ("segments" are something different) by the compiler. These are `const` variables and such like _string-literals_. If you want your program write into a variable in this section: this is undefined behaviour and on architectures with protected memory normally not allowed/possible. In C, writing to string literals is explicitly undefined behaviour. – too honest for this site Aug 29 '15 at 18:38
  • Sorry for being vague.. I want to externally set a constant string in the rodata section. This function should be independent of the code executed. So, when I do "objdump -c foo", the rodata section must enlist this string without the file foo.c having to do it. – LockStock Aug 29 '15 at 18:41
  • Please edit your question, not in a comment. However, I think I got the idea (it is still not completely clear). You want to expand the `rodata` section by another field, i.e. manipulate the object file. This is likely dependent on the file-format and the toolchain. Also: is that to be done static or when loading? If you just want to pass something, the enviroment variable might be the easier&better approach. If that is an option, perhaps you better try find out why it did not work. – too honest for this site Aug 29 '15 at 18:43
  • Can it be done statically ? The location of the environment variable seems to change when I load the file . – LockStock Aug 29 '15 at 18:49
  • What do you mean by "location" Please state OS, tollchain (GNU or CLAng, I presume?), how you read that variable, how you set it. Do you use [`getenv`](http://port70.net/~nsz/c/c11/n1570.html#7.22.4.6)? – too honest for this site Aug 29 '15 at 18:51
  • But if the C code is not aware: how does it access this variable? And yhy not edit the code? Sorry if I'm wrong, but that starts sounding a bit suspisious now. Even more, as binaries are normally `r-x`. – too honest for this site Aug 29 '15 at 18:59
  • I am just experimenting with the code so it's not of any use specifically. In any case, I do not want the c code to access the value, I just want to modif the segment. – LockStock Aug 29 '15 at 19:01
  • 1
    What is the bigger context? What problem are you trying to solve (and how did you arrive at the solution of directly modifying executables)? – melpomene Aug 29 '15 at 19:01

2 Answers2

0

Then you need to write a program that lets you modify the binary file.

Read the ELF file specifications.

Then write a program that modifies the ELF program and section headers and adds the data to the .rodata section.

John Hammond
  • 467
  • 1
  • 4
  • 14
0

I've managed to write a small bash script that does more or less what I think you want.

First let's consider this sample program:

test.c

#include <stdio.h>
const char message[1024] = "world";
int main()
{
    printf("hello %s\n", message);
}

The target variable will be message. Note that I will not change the size of the variable, that would be a mess, you be careful to reserve as much memory as you will ever need.

Now the script:

patchsym

#!/bin/bash
# usage: patchsym PROGRAM SYMBOL < NEWCONTENT
EXE="$1"
SYMBOL="$2"
OFFS=$((0x$(objdump -t "$EXE" | grep " $SYMBOL$" | cut -d ' ' -f 1)))
OFFS=2176
dd of="$EXE" bs=1 seek=$OFFS conv=notrunc

The new message content will be:

newmsg

universe^@

(where ^@ is actually a NUL character).

Now just do:

$ gcc test.c -o test
$ ./test
hello world
$ ./patchsym test message < newmsg
$ ./test
hello universe
Community
  • 1
  • 1
rodrigo
  • 94,151
  • 12
  • 143
  • 190