我正在尝试使用 libelf 生成一个简单的静态 ELF,但我似乎遇到了麻烦。
我不希望生成一个目标文件然后用 LD 链接它,而是我希望自己生成它。
该程序的主要目的是生成带有一个 LOAD 段的静态 ELF 并执行代码。
主要问题不在于 shellcode 本身,而可能在于我试图以错误的方式生成的某些标头。当我尝试运行生成的 ELF 时,它会被杀死,就好像内核无法找到它刚刚加载的段一样。
如果你们能暗示我,我会很高兴的。
create_elf.3.c
#include <err.h>
#include <fcntl.h>
#include <libelf.h>
#include <stdio.h>
#include <stdlib.h>
#include <sysexits.h>
#include <unistd.h>
unsigned char code[] =
"\x0b\x58\x99\x52\x66\x68\x2d\x70"
"\x89\xe1\x52\x6a\x68\x68\x2f\x62\x61"
"\x73\x68\x2f\x62\x69\x6e\x89\xe3\x52"
"\x51\x53\x89\xe1\xcd\x80";
int main(int argc, char *argv[])
{
int fd;
Elf *e;
Elf_Scn *scn;
Elf_Data *data;
Elf32_Ehdr *ehdr;
Elf32_Phdr *phdr;
Elf32_Shdr *shdr;
if (argc != 2)
errx(EX_USAGE,"input... ./%s filename\n",argv[0]);
if (elf_version(EV_CURRENT) == EV_NONE)
errx(EX_SOFTWARE,"elf_version is ev_none, wtf? %s\n",elf_errmsg(-1));
if ((fd = open(argv[1], O_WRONLY | O_CREAT, 0777)) < 0)
errx(EX_OSERR, "open %s\n",elf_errmsg(-1));
if ((e = elf_begin(fd, ELF_C_WRITE, NULL)) == NULL)
errx(EX_SOFTWARE,"elf_begin %s\n",elf_errmsg(-1));
if ((ehdr = elf32_newehdr(e)) == NULL)
errx(EX_SOFTWARE,"elf32_newehdr %s\n",elf_errmsg(-1));
/*
without these definitions objdump/readelf/strace/elf loader
will fail to load the binary correctly
be sure to pick them carefully and correctly, preferred exactly like the
ones like the system you are running on (so if you are running x86,
pick the same values you seen on a regular readelf -a /bin/ls
*/
ehdr->e_ident[EI_DATA] = ELFDATA2LSB;
ehdr->e_ident[EI_CLASS] = ELFCLASS32;
ehdr->e_machine = EM_386;
ehdr->e_type = ET_EXEC;
ehdr->e_entry = 0x8040800;
if ((phdr = elf32_newphdr(e,1)) == NULL)
errx(EX_SOFTWARE,"elf32_newphdr %s\n",elf_errmsg(-1));
if ((scn = elf_newscn(e)) == NULL)
errx(EX_SOFTWARE,"elf32_newscn %s\n",elf_errmsg(-1));
if ((data = elf_newdata(scn)) == NULL)
errx(EX_SOFTWARE,"elf32_newdata %s\n",elf_errmsg(-1));
data->d_align = 4;
data->d_off = 0LL;
data->d_buf = code;
data->d_type = ELF_T_WORD; // code :x
data->d_size = sizeof(code);
data->d_version = EV_CURRENT;
if ((shdr = elf32_getshdr(scn)) == NULL)
errx(EX_SOFTWARE,"elf32_getshdr %s\n",elf_errmsg(-1));
shdr->sh_name = 0;
shdr->sh_type = SHT_PROGBITS;
shdr->sh_flags = SHF_EXECINSTR | SHF_ALLOC;
shdr->sh_entsize = 0; // only used if we hold a table
if (elf_update(e, ELF_C_NULL) < 0)
errx(EX_SOFTWARE,"elf_update_1 %s\n",elf_errmsg(-1));
phdr->p_type = PT_LOAD;
phdr->p_offset = ehdr->e_phoff;
phdr->p_filesz = elf32_fsize(ELF_T_PHDR, 1, EV_CURRENT);
phdr->p_vaddr = 0x8040800;
phdr->p_paddr = 0x8040800;
phdr->p_align = 4;
phdr->p_filesz = sizeof(code);
phdr->p_memsz = sizeof(code);
phdr->p_flags = PF_X | PF_R;
elf_flagphdr(e, ELF_C_SET, ELF_F_DIRTY);
if (elf_update(e, ELF_C_WRITE) < 0 )
errx(EX_SOFTWARE,"elf32_update_2 %s\n",elf_errmsg(-1));
elf_end(e);
close(fd);
return 1;
}
如果有人能提示我这里出了什么问题,我会很高兴
谢谢
编辑
很抱歉没有提供更多细节,
ELF 生成似乎工作正常,我没有收到任何语法错误等,但是每当我尝试运行我生成的 ELF 时,例如 ./create_elf.3 foo14 (而 foo14 是生成的 ELF)
它被杀死了,好像 execve/kernel 不想正确加载它我尝试使用 IDA 加载它,但 IDA 显示反汇编代码足够好
这是 readelf 的输出
readelf -a foo14
ELF Header:
Magic: 7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00
Class: ELF32
Data: 2's complement, little endian
Version: 1 (current)
OS/ABI: UNIX - System V
ABI Version: 0
Type: EXEC (Executable file)
Machine: Intel 80386
Version: 0x1
Entry point address: 0x8040800
Start of program headers: 52 (bytes into file)
Start of section headers: 116 (bytes into file)
Flags: 0x0
Size of this header: 52 (bytes)
Size of program headers: 32 (bytes)
Number of program headers: 1
Size of section headers: 40 (bytes)
Number of section headers: 2
Section header string table index: 0
Section Headers:
[Nr] Name Type Addr Off Size ES Flg Lk Inf Al
[ 0] <no-name> NULL 00000000 000000 000000 00 0 0 0
[ 1] <no-name> PROGBITS 00000000 000054 000020 00 AX 0 0 4
Key to Flags:
W (write), A (alloc), X (execute), M (merge), S (strings)
I (info), L (link order), G (group), T (TLS), E (exclude), x (unknown)
O (extra OS processing required) o (OS specific), p (processor specific)
There are no section groups in this file.
Program Headers:
Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align
LOAD 0x000034 0x08040800 0x08040800 0x00021 0x00021 R E 0x4
There is no dynamic section in this file.
There are no relocations in this file.
There are no unwind sections in this file.
No version information found in this file.