Skip to content
Advertisement

Is it possible to make a hardcoding with the help of the command objcopy

I’m working on Linux and I’ve just heard that there was a command objcopy, I’ve found the relative command on my x86_64 PC: x86_64-linux-gnu-objcopy.

With its help, I can convert a file into an obj file: x86_64-linux-gnu-objcopy -I binary -O elf64-x86-64 custom.config custom.config.o

The file custom.config is a human-readable file. It contains two lines:

name titi
password 123

Now I can execute objdump -x -s custom.config.o to check its information.

custom.config.o:     file format elf64-little
custom.config.o
architecture: UNKNOWN!, flags 0x00000010:
HAS_SYMS
start address 0x0000000000000000

Sections:
Idx Name          Size      VMA               LMA               File off  Algn
  0 .data         00000017  0000000000000000  0000000000000000  00000040  2**0
                  CONTENTS, ALLOC, LOAD, DATA
SYMBOL TABLE:
0000000000000000 l    d  .data  0000000000000000 .data
0000000000000000 g       .data  0000000000000000 _binary_custom_config_start
0000000000000017 g       .data  0000000000000000 _binary_custom_config_end
0000000000000017 g       *ABS*  0000000000000000 _binary_custom_config_size


Contents of section .data:
 0000 6e616d65 20746974 690a7061 7373776f  name titi.passwo
 0010 72642031 32330a                      rd 123.

As all we know, we can open, read or write a file, such as custom.config in any C/C++ project. Now, I’m thinking if it’s possible to use this obj file custom.config.o immediately in a C/C++ project. For example, is it possible to read the content of the file custom.config.o immediately without calling the I/O functions, such as open, read or write. If possible, I think this might become some kind of hardcoding style and avoid calling the I/O functions?

Advertisement

Answer

Even if I tried this on Win10 with MinGW (MinGW-W64 project, GCC 8.1.0), this should work for you with only minor adaptions.

As you see from the info objdump gave you, the file’s contents is placed in the .data section that is the common section for non-constant variables.

And some symbols were defined for it. You can declare these symbols in your C source.

The absolute value _binary_custom_config_size is special, because it is marked *ABS*. Currently I know no other way to obtain its value than to declare a variable of any type and take its address.

This is my show_config.c:

#include <stdio.h>
#include <string.h>

extern const char _binary_custom_config_start[];
extern const char _binary_custom_config_size;

int main(void) {
  size_t size = (size_t)&_binary_custom_config_size;
  char config[size + 1];
  strncpy(config, _binary_custom_config_start, size);
  config[size] = '';
  printf("config = "%s"n", config);
  return 0;
}

Because the “binary” file (actually a text) has no final '' character, you need to append one to get a correctly terminated C string.

You could as well declare _binary_custom_config_end and use it to calculate the size, or as a limit.

Building everything goes like this (I used the -g option to debug):

$ objcopy -I binary -O elf64-x86-64 -B i386 custom.config custom.config.o
$ gcc -Wall -Wextra -pedantic -g show_config.c custom.config.o -o show_config

And the output shows the success:

$ show_config.exe
config = "name titi
password 123"

If you need the file’s contents in another section, you will add the option to rename the section to objcopy‘s call. Add any flag you need, the example shows .rodata that is used for read-only data:

--rename-section .data=.rodata,alloc,load,readonly,data,contents

User contributions licensed under: CC BY-SA
2 People found this is helpful
Advertisement