一. 被分析的源码
#include <stdio.h>
void main() {
printf("Hello World\n");
}
$ gcc hello.c -o hello
二. 抽取 hello 的 .text节
方法1 :使用objdump
$ objdump -h hello | grep .text
15 .text 00000185 0000000000001060 0000000000001060 00001060 2**4
$ dd if=hello of=out_objdump bs=1 count=$((185)) skip=$((0x1060))
185+0 records in
185+0 records out
185 bytes copied, 0.000357709 s, 517 kB/s
方法2:使用objcopy
$ objcopy --dump-section .text=out_objcopy_dumpsection hello
$ objcopy -O binary --only-section=.text hello out_objcopy_onlysection
方法3:使用 libelf 库
include <stdio.h>
#include <libelf.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
void main() {
Elf *elf = NULL;
Elf_Scn *scn = NULL;
Elf_Data *data = NULL;
Elf64_Shdr *shdr = NULL;
char *name = NULL;
int fd_in = 0, fd_out = 0;
size_t shstrndx = 0, n = 0;
// Necessary to call other libelf library functions
elf_version(EV_CURRENT);
// Open main
fd_in = open("main", O_RDONLY, 0);
// Convert the file descriptor to an ELF handle
elf = elf_begin(fd_in, ELF_C_READ, NULL);
// Retrieve the index of the section name string table
elf_getshdrstrndx(elf, &shstrndx);
// Iterate through the sections
while ((scn = elf_nextscn(elf, scn)) != NULL) {
// Retrieve the section header
shdr = elf64_getshdr(scn);
// Get the name of the section
name = elf_strptr(elf, shstrndx, shdr->sh_name);
// Check if the section is .text
if (strcmp(name, ".text") == 0) {
// Open the binary output file
fd_out = open("out_libelf", O_CREAT | O_WRONLY, S_IRUSR | S_IWUSR);
// Read the section and write it to the file
while ((data = elf_getdata(scn, data)) != NULL) {
write(fd_out, data->d_buf, data->d_size);
}
// Close the file descriptor of output file
close(fd_out);
}
}
// Release the ELF descriptor
elf_end(elf);
// Close main
close(fd_in);
}
$ sudo apt-get install libelf-dev
$ gcc -o elf_analyzer elf_analyzer.c -lelf
$ ./elf_analyzer
三、比较结果
$ diff out_objdump out_objcopy_dumpsection
$ diff out_objdump out_objcopy_onlysection
$ diff out_objdump out_libelf
可以发现这三个文件是相同的。