get soname of shared library
代码
/*********************************************************
File Name: get_soname.cc
Author: Abby Cin
Mail: abbytsing@gmail.com
Created Time: Sat 18 Jan 2020 09:44:03 AM CST
**********************************************************/
#include <functional>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/types.h>
#include <elf.h>
#include <sys/mman.h>
#include <sys/stat.h>
#if __x86_64__
typedef Elf64_Ehdr Elf_Ehdr;
typedef Elf64_Shdr Elf_Shdr;
typedef Elf64_Dyn Elf_Dyn;
#else
typedef Elf32_Ehdr Elf_Ehdr;
typedef Elf32_Shdr Elf_Shdr;
typedef Elf32_Dyn Elf_dyn;
#endif
void err_exit(int x, const char* s)
{
if(x == -1)
{
perror(s);
exit(1);
}
}
struct Guard
{
Guard(std::function<void()>&& c) : cb{std::move(c)} {}
~Guard() { cb(); }
std::function<void()> cb;
};
int main(int argc, char *argv[])
{
if(argc != 2)
{
fprintf(stderr, "%s file\n", argv[0]);
return 1;
}
int fd = open(argv[1], O_RDONLY);
err_exit(fd, "open");
Guard fdGuard{[fd] { ::close(fd); }};
struct stat st;
fstat(fd, &st);
char* mem = (char*)mmap(nullptr, st.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
if(mem == MAP_FAILED)
{
err_exit(-1, "mmap");
}
Guard memGuard{[mem, st] { ::munmap(mem, st.st_size); }};
// offset 0
Elf_Ehdr* eh = (Elf_Ehdr*)mem;
if(eh->e_type != ET_DYN)
{
err_exit(-1, "not shared lib");
}
if(eh->e_shstrndx == SHN_UNDEF)
{
err_exit(-1, "no section name string table");
}
// offset 0
Elf_Shdr* sections = (Elf_Shdr*)&mem[eh->e_shoff];
int dynIndex = -1;
int strIndex = -1;
for(int i = 0; i < eh->e_shnum; ++i)
{
if(sections[i].sh_type == SHT_DYNAMIC)
{
dynIndex = i;
}
if(sections[i].sh_type == SHT_STRTAB)
{
strIndex = i;
}
if(dynIndex >=0 && strIndex >= 0)
{
break;
}
}
if(dynIndex < 0 || strIndex < 0)
{
printf("no .dynamic or .dynstr section found!\n");
return 1;
}
char* strTab = (char*)&mem[sections[strIndex].sh_offset];
Elf_Dyn* dyn = (Elf_Dyn*)&mem[sections[dynIndex].sh_offset];
char* soname = 0;
while(dyn->d_tag != DT_NULL)
{
if(dyn->d_tag == DT_SONAME)
{
soname = &strTab[dyn->d_un.d_val];
break;
}
dyn++;
}
if(soname)
{
printf("SONAME: %s\n", soname);
}
else
{
printf("no soname\n");
}
}
参考
Linux二进制分析