|
From: Frank T. <fra...@ts...> - 2014-07-24 10:38:16
|
Dear all,
I am trying to add a new section with an application specific content to
an existing ELF file. Unfortunately the resulting ELF file is erroneous
as the size/offset of the new section and the section type are not
correctly set (see code snippet below).
"Readelf" indicates the following information (section 37 is the newly
added section):
...
[36] .strtab STRTAB 00000000 013ccc 000356 00 0
0 1
[37] NULL 00000000 000000 8048154 8048168
0 65539 0
The type of the section (NULL) and the size/offset (should be 8 bytes
starting at offset 0x14022) are wrong. I have manually verified the
correct values within the data structures using a debugger. So I would
guess that something gets broken during the final call to elf_update().
OS is Kubuntu 12.04 with package 'libelf1" installed (Version indicated
is 0.152-1ubuntu).
I've read some old postings regarding the libelf support for ELF_C_RDWR
which recommended to copy the sections to a new file due to a broken
implementation. Are these bugs still present?
Or am I just missing something? Any hints?
Frank
--------------------------------------------------------------------------------------
int fd;
Elf *elf_ref = NULL;
Elf32_Ehdr *ehdr;
Elf_Scn *elf_scn, *sig_scn;
Elf_Data *elf_data;
Elf32_Shdr *signature_scn_header;
unsigned char sample_data[] = {0xca, 0xfe, 0xba, 0xbe, 0xca, 0xfe,
0xba, 0xbe};
if (argc != 2) {
return -1;
}
fd = open(argv[1], O_RDWR);
/* Protect from using a lower ELF version and initialize ELF library */
if (elf_version(EV_CURRENT) == EV_NONE) {
printf("ELF library init failed: %s\n", elf_errmsg(-1));
close(fd);
return -1;
}
elf_ref = elf_begin(fd, ELF_C_RDWR, NULL);
if (elf_kind(elf_ref) != ELF_K_ELF) {
printf("Program is not an ELF binary\n");
close(fd);
return -2;
}
sig_scn = elf_newscn(elf_ref);
elf_data = elf_newdata(sig_scn);
elf_data->d_align = 1;
elf_data->d_off = 0LL ;
elf_data->d_buf = sample_data ;
elf_data->d_type = ELF_T_BYTE ;
elf_data->d_size = sizeof(sample_data);
elf_data->d_version = EV_CURRENT ;
signature_scn_header = elf32_getshdr(sig_scn);
signature_scn_header->sh_name = 0;
signature_scn_header->sh_type = SHT_LOUSER + 10;
if (elf_update(elf_ref , ELF_C_NULL ) < 0) {
printf("ELF update failed: %s", elf_errmsg (-1));
return -3;
}
(void) elf_flagshdr(sig_scn, ELF_C_SET, ELF_F_DIRTY);
(void) elf_flagscn(sig_scn, ELF_C_SET, ELF_F_DIRTY);
(void) elf_flagdata(elf_data, ELF_C_SET, ELF_F_DIRTY);
(void) elf_flagehdr(elf_ref, ELF_C_SET, ELF_F_DIRTY);
(void) elf_flagelf(elf_ref, ELF_C_SET, ELF_F_DIRTY);
if (elf_update(elf_ref , ELF_C_WRITE ) < 0) {
printf("ELF update failed: %s", elf_errmsg (-1));
return -4;
}
elf_end(elf_ref);
close(fd);
|