如何从自身取得的指针的节目的特定部分? (也许用了libelf) [英] How to get a pointer to an specific section of a program from within itself? (Maybe with libelf)
问题描述
我在Linux环境下,我需要做检索一些数据被放置在其部分之一的程序。因此,如何从自身取得的指针的节目的部分(通过它的名字)?
I'm on a Linux environment and I need to make a program that retrieves some data that is placed in one of its sections. So, how to get a pointer to a section of a program (by its name) from within itself?
我知道这是可能使用 elf_getdata()
传递部分作为参数的索引来获取和 Elf_Data code>结构和这个结构的领域之一是
d_buf
,这是一个指向实际的数据。然而,似乎在 elf_getdata()
功能使部分数据的副本从文件到记忆这不是我想要的。我想的指针的数据已经被加载到加载时间的存储器
I know it's possible to use elf_getdata()
passing the index of the section as argument to get and Elf_Data
struct and one of the fields of this struct is d_buf
, which is a pointer to the actual data. However, it seems the elf_getdata()
function makes a copy of the section data from the file to the memory and that's not what I want. I want a pointer to the data the has been loaded to the memory in loading time.
所以,伙计们,什么想法?
So, guys, any idea?
推荐答案
其实用 libelf函数
,它可以使用 Elf64_Shdr
结构(64位系统),以获得一个指向一个部分,因为 sh_addr
字段做点那里的部分将被加载的实际ADRESS运行。因此,它可以用作一个指针。通过这种方式,它甚至没有必要使用 elf_getdata()
函数来获取一个 Elf_Data code>结构。
Actually, using libelf
, it's possible to use the Elf64_Shdr
struct (for 64-bit systems) to get a pointer to a section, because the sh_addr
field do points to the actual adress where the section will be loaded in runtime. So, it can be used as a pointer. This way, it's not even necessary to use the elf_getdata()
function to retrieve a Elf_Data
struct.
由于我想要做的是哪些其他目标文件可以对被链接的库,我的code可能有它打开可执行文件本身要利用一些 libelf函数的函数code>的功能,使得它可以从主文件中的节读取数据,如下:
Since what I want to do is a library which other object files can be linked against, my code may have a function which opens the executable file itself to make use of some libelf
features, so that it can read data from the main file sections, as follows:
// A global variable which stores the executable file name
extern const char *__progname;
void retrieve_data() {
int fd; // File descriptor for the executable ELF file
char *section_name, path[256];
size_t shstrndx;
Elf *e; // ELF struct
Elf_Scn *scn; // Section index struct
Elf64_Shdr *shdr; // Section struct
// Create the full path of the executable
getcwd(path, 255);
strcat(path, "/");
strcat(path, __progname);
if(elf_version(EV_CURRENT)==EV_NONE)
errx(EXIT_FAILURE, "ELF library iinitialization failed: %s", elf_errmsg(-1));
if((fd = open(path, O_RDONLY, 0))<0)
err(EXIT_FAILURE, "open \"%s\" failed", path);
if((e = elf_begin(fd, ELF_C_READ, NULL))==NULL)
errx(EXIT_FAILURE, "elf_begin() failed: %s.", elf_errmsg(-1));
// Retrieve the section index of the ELF section containing the string table of section names
if(elf_getshdrstrndx(e, &shstrndx)!=0)
errx(EXIT_FAILURE, "elf_getshdrstrndx() failed: %s.", elf_errmsg(-1));
scn = NULL;
// Loop over all sections in the ELF object
while((scn = elf_nextscn(e, scn))!=NULL) {
// Given a Elf Scn pointer, retrieve the associated section header
if((shdr = elf64_getshdr(scn))!=shdr)
errx(EXIT_FAILURE, "getshdr() failed: %s.", elf_errmsg(-1));
// Retrieve the name of the section name
if((name = elf_strptr(e, shstrndx, shdr->sh_name))==NULL)
errx(EXIT_FAILURE, "elf_strptr() failed: %s.", elf_errmsg(-1));
// If the section is the one we want... (in my case, it is one of the main file sections)
if(!strcmp(section_name, "Section name")) {
// We can use the section adress as a pointer, since it corresponds to the actual
// adress where the section is placed in the virtual memory
struct data_t * section_data = (struct data_t *) shdr->sh_addr;
// Do whatever we want
// End the loop (if we only need this section)
break;
}
}
elf_end(e);
close(fd);
}
这篇关于如何从自身取得的指针的节目的特定部分? (也许用了libelf)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!