君士坦丁堡屠城:重新构建ELF
来源:百度文库 编辑:偶看新闻 时间:2024/04/30 10:00:51
#include
#include
#include
#include
#include
#include
#include
void die(const char *fmt, ...)
{
va_list ap;
va_start(ap, fmt);
vfprintf(stderr, fmt, ap);
va_end(ap);
fputc('\n', stderr);
exit(1);
}
#define PAGE_SIZE 4096
static char shstr[] =
"\0"
".symtab\0"
".strtab\0"
".shstrtab\0"
".interp\0"
".hash\0"
".dynsym\0"
".dynstr\0"
".rel.got\0"
".rel.bss\0"
".rel.plt\0"
".init\0"
".plt\0"
".text\0"
".fini\0"
".rodata\0"
".data\0"
".ctors\0"
".dtors\0"
".got\0"
".dynamic\0"
".bss\0"
".comment\0"
".note"
;
char *xget(int fd, int off, int sz)
{
char *buf;
if (lseek(fd, off, SEEK_SET) < 0) die("Seek error");
buf = (char *)malloc(sz);
if (buf == NULL) die("No memory");
if (read(fd, buf, sz) != sz) die("Read error");
return buf;
}
void do_elf_checks(Elf32_Ehdr *ehdr)
{
if (strncmp(ehdr->e_ident, ELFMAG, SELFMAG)) die("File not ELF");
if (ehdr->e_type != ET_CORE) die("ELF type not ET_CORE");
//if (ehdr->e_machine != EM_386 && ehdr->e_machine != EM_486)
//die("ELF machine type not EM_386 or EM_486");
if (ehdr->e_version != EV_CURRENT) die("ELF version not current");
}
int main(int argc, char *argv[])
{
Elf32_Ehdr ehdr, *core_ehdr;
Elf32_Phdr *phdr, *core_phdr, *tmpphdr;
Elf32_Shdr shdr;
char *core;
char *data[2], *core_data[3];
int prog[2], core_prog[3];
int in, out;
int i, p;
int plen;
if (argc >2) die("usage: %s [core-file]");
if (argc == 2) core = argv[1];
else core = "core.3665";
in = open(core, O_RDONLY);
if (in < 0) die("Coudln't open file: %s", core);
if (read(in, &ehdr, sizeof(ehdr)) != sizeof(ehdr)) die("Read error");
do_elf_checks(&ehdr);
if (lseek(in, ehdr.e_phoff, SEEK_SET) < 0) die("Seek error");
phdr = (Elf32_Phdr *)malloc(plen = sizeof(Elf32_Phdr)*ehdr.e_phnum);
if (read(in, phdr, plen) != plen) die("Read error");
for (i = 0; i < ehdr.e_phnum; i++)
printf("0x%x - 0x%x (%i)\n",
phdr[i].p_vaddr, phdr[i].p_vaddr + phdr[i].p_memsz, phdr[i].p_memsz);
/*
copy segments (in memory)
prog/data[0] ... text
prog/data[1] ... data
prog/data[2] ... dynamic
*/
for (i = 0, p = 0; i < ehdr.e_phnum; i++) {
if (
phdr[i].p_vaddr >= 0x8000000 &&
phdr[i].p_type == PT_LOAD
) {
prog[p] = i;
if (p == 1) break;
++p;
}
}
if (i == ehdr.e_phnum) die("Couldnt find TEXT/DATA");
for (i = 0; i < 2; i++) data[i] = xget(
in,
phdr[prog[i]].p_offset,
(phdr[prog[i]].p_memsz + 4095) & 4095
);
core_ehdr = (Elf32_Ehdr *)&data[0][0];
core_phdr = (Elf32_Phdr *)&data[0][core_ehdr->e_phoff];
for (i = 0, p = 0; i < core_ehdr->e_phnum; i++) {
if (core_phdr[i].p_type == PT_LOAD) {
core_prog[p] = i;
if (p == 0) {
core_data[0] = &data[0][0];
} else {
core_data[1] = &data[1][
(core_phdr[i].p_vaddr & 4095)
];
break;
}
++p;
}
}
if (i == core_ehdr->e_phnum) die("No TEXT and DATA segment");
for (i = 0; i < core_ehdr->e_phnum; i++) {
if (core_phdr[i].p_type == PT_DYNAMIC) {
core_prog[2] = i;
core_data[2] = &data[1][64];
break;
}
}
if (i == core_ehdr->e_phnum) die("No DYNAMIC segment");
out = open("a.out", O_WRONLY | O_CREAT | O_TRUNC);
if (out < 0) die("Coudln't open file: %s", "a.out");
core_ehdr->e_shoff =
core_phdr[core_prog[2]].p_offset +
core_phdr[core_prog[2]].p_filesz +
sizeof(shstr);
/*
text
data
bss
dynamic
shstrtab
*/
core_ehdr->e_shnum = 6;
core_ehdr->e_shstrndx = 5;
for (i = 0; i < 2; i++) {
Elf32_Phdr *p = &core_phdr[core_prog[i]];
int sz = p->p_filesz;
if (lseek(out, p->p_offset, SEEK_SET) < 0) goto cleanup;
if (write(out, core_data[i], sz) != sz) goto cleanup;
}
if (write(out, shstr, sizeof(shstr)) != sizeof(shstr)) goto cleanup;
memset(&shdr, 0, sizeof(shdr));
if (write(out, &shdr, sizeof(shdr)) != sizeof(shdr)) goto cleanup;
/*
text section
*/
tmpphdr = &core_phdr[core_prog[0]];
shdr.sh_name = 95;
shdr.sh_type = SHT_PROGBITS;
shdr.sh_addr = tmpphdr->p_vaddr;
shdr.sh_offset = 0;
shdr.sh_size = tmpphdr->p_filesz;
shdr.sh_flags = SHF_ALLOC | SHF_EXECINSTR;
shdr.sh_link = 0;
shdr.sh_info = 0;
shdr.sh_addralign = 16;
shdr.sh_entsize = 0;
if (write(out, &shdr, sizeof(shdr)) != sizeof(shdr)) goto cleanup;
/*
data section
*/
tmpphdr = &core_phdr[core_prog[1]];
shdr.sh_name = 115;
shdr.sh_type = SHT_PROGBITS;
shdr.sh_addr = tmpphdr->p_vaddr;
shdr.sh_offset = tmpphdr->p_offset;
shdr.sh_size = tmpphdr->p_filesz;
shdr.sh_flags = SHF_ALLOC | SHF_WRITE;
shdr.sh_link = 0;
shdr.sh_info = 0;
shdr.sh_addralign = 4;
shdr.sh_entsize = 0;
if (write(out, &shdr, sizeof(shdr)) != sizeof(shdr)) goto cleanup;
/*
dynamic section
*/
for (i = 0; i < core_ehdr->e_phnum; i++) {
if (core_phdr[i].p_type == PT_DYNAMIC) {
tmpphdr = &core_phdr[i];
break;
}
}
shdr.sh_name = 140;
shdr.sh_type = SHT_PROGBITS;
shdr.sh_addr = tmpphdr->p_vaddr;
shdr.sh_offset = tmpphdr->p_offset;
shdr.sh_size = tmpphdr->p_memsz;
shdr.sh_flags = SHF_ALLOC;
shdr.sh_link = 0;
shdr.sh_info = 0;
shdr.sh_addralign = 4;
shdr.sh_entsize = 8;
if (write(out, &shdr, sizeof(shdr)) != sizeof(shdr)) goto cleanup;
/*
bss section
*/
shdr.sh_name = 149;
shdr.sh_type = SHT_PROGBITS;
shdr.sh_addr = tmpphdr->p_vaddr + tmpphdr->p_filesz;
shdr.sh_offset = tmpphdr->p_offset + tmpphdr->p_filesz;
shdr.sh_size = tmpphdr->p_memsz - tmpphdr->p_filesz;
shdr.sh_flags = SHF_ALLOC;
shdr.sh_link = 0;
shdr.sh_info = 0;
shdr.sh_addralign = 1;
shdr.sh_entsize = 0;
if (write(out, &shdr, sizeof(shdr)) != sizeof(shdr)) goto cleanup;
/*
shstrtab
*/
shdr.sh_name = 17;
shdr.sh_type = SHT_STRTAB;
shdr.sh_addr = 0;
shdr.sh_offset = core_ehdr->e_shoff - sizeof(shstr);
shdr.sh_size = sizeof(shstr);
shdr.sh_flags = 0;
shdr.sh_link = 0;
shdr.sh_info = 0;
shdr.sh_addralign = 1;
shdr.sh_entsize = 0;
if (write(out, &shdr, sizeof(shdr)) != sizeof(shdr)) goto cleanup;
return 0;
cleanup:
unlink("a.out");
die("Error writing file: %s", "a.out");
return 1; /* not reached */
}