Example #1
0
static void
wrapper_main(int argc, char * argv[])
{
    pid_t pid;

    /* first, trace target */
    pid = ptrace_execve("./target", argv);

    /* dump stack, find sysinfo */
    struct user_regs_struct regs;
    regs = ptrace_peekuser();

    SYS_TRACE("stack top=0x%x\n", regs.esp);

    struct proc_entry stack_entry;
    stack_entry.addr = regs.esp;
    stack_entry.bits = PE_ADDR;
    proc_fill_entry(&stack_entry, pid);
    SYS_TRACE("stack range: 0x%x-0x%x\n", stack_entry.start, stack_entry.end);

    /* dump the stack and find SYSINFO */
    uint32_t stack_size = stack_entry.end - regs.esp;
    void * stack_image = malloc(stack_size);
    void * elf_table;
    assert(stack_image != 0);
    ptrace_dupmem(stack_image, regs.esp, stack_size);
    elf_table = get_elf_table(stack_image);
    assert(elf_table != NULL);
    SYS_TRACE("elf_table start at %p\n", elf_table);

    /* iterator elf table */
    uint32_t * auxv_entry = elf_table;
    uint32_t * pvdso_ehdr = NULL, * pvdso_entrance = NULL;
    while (*auxv_entry != 0) {
        if (auxv_entry[0] == AT_SYSINFO)
            pvdso_entrance = &auxv_entry[1];
        if (auxv_entry[0] == AT_SYSINFO_EHDR)
            pvdso_ehdr = &auxv_entry[1];
        auxv_entry += 2;
    }
    assert_throw(pvdso_ehdr != NULL, "cannot find vdso ehdr");
    assert_throw(pvdso_entrance != NULL, "cannot find vdso entrance");
    SYS_FORCE("vdso mapped at 0x%x, entry=0x%x\n",
              *pvdso_ehdr, *pvdso_entrance);

    /* begin to map wrapper so */
    map_wrap_so("./syscall_wrapper_entrance.so", 0x3000,
                pvdso_entrance, pvdso_ehdr);

    /* reset the stack */

    ptrace_updmem(stack_image, regs.esp, stack_size);
    free(stack_image);
    ptrace_detach(TRUE);
}
Example #2
0
std::string string_cast(const std::wstring& src)
{
    string dest;
    if (!src.empty()) {
        size_t size = ::WideCharToMultiByte(
            CP_ACP,
            0, //WC_DEFAULTCHAR,
            src.c_str(),
            src.size(), // not incl 0
            NULL,
            0, // return buf size in bytes
            NULL, //"?", // def char
            NULL // &lb_UsedDefChar
            );
        assert_throw(size != 0);
        dest.resize(size);
        ::WideCharToMultiByte(
            CP_ACP,
            0, //WC_DEFAULTCHAR,
            src.c_str(),
            src.size(), // not incl 0
            &dest[0],
            size,
            NULL, //"?", // def char
            NULL  //&lb_UsedDefChar
            );
    }
    return dest;
}
Example #3
0
static void
map_wrap_so(const char * so_file, uintptr_t load_bias,
            uint32_t * pvdso_entrance,
            uint32_t * pvdso_ehdr)
{
    uint32_t name_pos;
    int fd, err;

    struct stat s;
    err = stat(so_file, &s);
    assert_errno_throw("stat file %s failed", so_file);
    assert_throw(S_ISREG(s.st_mode), "file %s not a regular file", so_file);
    /* don't use off_t, it may not be a 32 bit word! */
    int32_t fsize = s.st_size;
    SYS_TRACE("desired so file length is %d\n", fsize);

    /* elf operations */
    void * so_image = load_file(so_file);
    struct elf_handler * h = elf_init(so_image, load_bias);
    /* load program headers */
    int nr_phdr = 0;
    struct elf32_phdr * phdr = elf_get_phdr_table(h, &nr_phdr);
    assert_throw(((phdr != NULL) && (nr_phdr != 0)),
                 "load phdr of file %s failed\n", so_file);
    /* find the entry symbol */
    uintptr_t entry_addr = elf_get_symbol_address(h, "syscall_wrapper_entrace");
    SYS_TRACE("wrapper func address will be 0x%x\n", entry_addr);


    name_pos = ptrace_push(so_file, strlen(so_file), TRUE);
    fd = ptrace_syscall(open, 3, name_pos, O_RDONLY, 0);
    assert_throw(fd >= 0, "open sofile for child failed, return %d", fd);
    SYS_TRACE("open so file for child, fd=%d\n", fd);


    /* for each program header */
    for (int i = 0; i < nr_phdr; i++, phdr ++) {
        SYS_FORCE("phdr %d, type=0x%x, flag=0x%x\n", i,
                  phdr->p_type, phdr->p_flags);
        if (phdr->p_type != PT_LOAD)
            continue;

        int elf_prot = 0, elf_flags = 0;

        if (phdr->p_flags & PF_R)
            elf_prot |= PROT_READ;
        if (phdr->p_flags & PF_W)
            elf_prot |= PROT_WRITE;
        if (phdr->p_flags & PF_X)
            elf_prot |= PROT_EXEC;

        elf_flags = MAP_PRIVATE | MAP_EXECUTABLE;

        unsigned long size = phdr->p_filesz + ELF_PAGEOFFSET(phdr->p_vaddr);
        unsigned long off = phdr->p_offset - ELF_PAGEOFFSET(phdr->p_vaddr);
        int32_t map_addr = load_bias + phdr->p_vaddr - ELF_PAGEOFFSET(phdr->p_vaddr);

        map_addr = ptrace_syscall(mmap2, 6,
                                  map_addr, size,
                                  elf_prot, elf_flags | MAP_FIXED,
                                  fd, off);
        assert_throw(map_addr != 0xffffffff, "map wrap so failed, return 0x%x", map_addr);
    }
    elf_cleanup(h);
    free(so_image);

    if (pvdso_ehdr)
        *pvdso_ehdr = load_bias;
    if (pvdso_entrance)
        *pvdso_entrance = entry_addr;
}