君士坦丁堡屠城:重新构建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 */

}