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