From: silver k. <he...@ho...> - 2020-06-22 04:51:13
|
Hi Joseph, Thanks for the answer, I made the changes you suggested. In my previous post I said that after adding new data to the .data section, the .data section get moved to another memory address. I inspected this more carefully using readelf -S hello and I discovered is that actually none of the memory sections get moved around (as in all the memory sections start at the same address before and after editing the elf file) what changes is the Offset Align for the .data section from 1030 to 930 but it's still inside the memory range of the .data section, I'm not sure if this is good or bad. My problem is that let's say I have two global variables defined in hello.c and I want to modify the value of the first variable, using the code that I have below, the program actually "overwrites" the variable with the value that I'm modifying and the second variable gets erased. Using the code that I have below I get an error "Error in ./prog4: double free or corruption(out): 0x00007ffd98fa9640 *** Aborted (core dumped). My other question is how can I specify which global variable I want to modify? do I assign to the "data" type the offset align of the global data I want to modify? as in data = offset align; ? #include <err.h> #include <fcntl.h> #include <gelf.h> #include <stdio.h> #include <stdint.h> #include <stdlib.h> #include <unistd.h> #include <bsd/vis.h> int main(int argc, char **argv) { int fd; Elf *e; char *name, *p, pc[4*sizeof(char)]; Elf_Scn *scn; Elf_Data *data; GElf_Shdr shdr; GElf_Sym sym; size_t n, shstrndx, sz; uint32_t some_string[] = {0xaf}; if (argc != 2) errx(EXIT_FAILURE, "usage: %s file-name", argv[0]); if (elf_version(EV_CURRENT) == EV_NONE) errx(EXIT_FAILURE, "ELF library initialization " "failed: %s", elf_errmsg(-1)); if ((fd = open(argv[1], O_RDWR, 0)) < 0) err(EXIT_FAILURE, "open \%s\" failed", argv[1]); if ((e = elf_begin(fd, ELF_C_RDWR, NULL)) == NULL) errx(EXIT_FAILURE, "elf_begin() failed: %s.", elf_errmsg(-1)); if (elf_kind(e) != ELF_K_ELF) errx(EXIT_FAILURE, "%s is not an ELF object.", argv[1]); if ((scn = elf_getscn(e, 24)) == NULL) errx(EXIT_FAILURE, "elf_scn() failed: %s.", elf_errmsg(-1)); if (gelf_getshdr(scn, &shdr) != &shdr) errx(EXIT_FAILURE, "getshdr(shstrndx) failed: %s.", elf_errmsg(-1)); data = NULL; if ((data = elf_getdata(scn , data)) == NULL) errx(EXIT_FAILURE, "elf_newdata() failed: %s.", elf_errmsg(-1)); data ->d_align = 1; data ->d_off = 0LL; data ->d_buf = some_string; data ->d_type = ELF_T_WORD; data ->d_size = sizeof(some_string); data ->d_version = EV_CURRENT; (void) printf(".data: size=%jd\n", (uintmax_t)shdr.sh_size); if(elf_update(e,ELF_C_NULL) < 0 ) errx(EXIT_FAILURE, "elf_update(NULL) failed: %s.", elf_errmsg(-1)); (void) elf_flagdata(data, ELF_C_SET, ELF_F_DIRTY); if(elf_update(e,ELF_C_WRITE) < 0 ) errx(EXIT_FAILURE, "elf_update(NULL) failed: %s.", elf_errmsg(-1)); if(elf_update(e,ELF_F_LAYOUT) < 0 ) errx(EXIT_FAILURE, "elf_update(NULL) failed: %s.", elf_errmsg(-1)); (void) putchar('\n'); (void) elf_end(e); (void) close(fd); exit(EXIT_SUCCESS); } My hello.c file still the same. Thanks for any suggestions. ________________________________ From: Joseph Koshy <jko...@gm...> on behalf of Joseph Koshy <jk...@us...> Sent: Sunday, June 21, 2020 3:42 PM To: silver kapo <he...@ho...> Cc: elf...@li... <elf...@li...> Subject: Re: [Elftoolchain-developers] Problem with writing to an elf file using libelf > I'm trying to modify the data of a global > variable in a C file. I was able to write > data to the .data section but I had two > problems. The first one is that when I > open the edited hex file I notice that my > .data section has shifted from 0x1030(where > my .data section starts in the elf file) > to ~0x0930. And the second problem is that > instead of overwriting in the address location > of my global variable, it writes the data in > the next memory address. I.E let's say the > global variable is defined at 0x1030 the new > data get written at 0x1031 instead of 0x1030. ... > if ((data = elf_newdata(scn)) == NULL) > errx(EXIT_FAILURE, "elf_newdata() failed: %s.", > elf_errmsg(-1)); This call to elf_newdata() would add new data to the section 'scn', changing its size and possibly causing the layout of the ELF object to change. If you would like to modify the existing content of the section without changing its size or layout, you could try the following: - read in the section's contents using elf_getdata(), - change the contents of the section (pointed to by the d_buf member of the Elf_Data descriptor returned by elf_getdata()), - set the ELF_F_DIRTY flag on the Elf_Data descriptor using elf_flagdata(), - call elf_update() as before. You might also want to set the ELF_F_LAYOUT flag on the Elf object, to turn off libelf's default layout rules. Regards, Joseph Koshy |