首页
社区
课程
招聘
[求助]so dlopen返回NULL [已搞定]
发表于: 2013-11-19 10:17 4373

[求助]so dlopen返回NULL [已搞定]

2013-11-19 10:17
4373
现象:有些进程so注入时dlopen返回NULL
完整代码这里:
http://bbs.pediy.com/showthread.php?t=181037
代码:
static int inject_so(pid_t pid, char* so_path)
{
        int status = 0;
        struct user oregs, iregs;
        uintptr_t p, dlopen_addr;
        uint8_t *sp;

        dlopen_addr = (uintptr_t)dlsym(NULL, "dlopen") +
                      ((uintptr_t)get_module_base(pid, "libdl") -
                       (uintptr_t)get_module_base(-1, "libdl"));

        printf("dlopen_addr:%p\n", (void*)dlopen_addr);

        if (ptrace(PTRACE_ATTACH, pid, NULL, NULL) < 0)
                return -1;

        waitpid(-1, &status, 0);

        ptrace(PTRACE_GETREGS, pid, NULL, &oregs);
        iregs = oregs;

        /*
         * write args to stacks
         * lib_name_string
         * arg2 mode
         * arg1 pLibName
         * ret_addr     <-      SP
         */
        REGS_SP(iregs) = REGS_SP(iregs) - 0x200;
        sp = (uint8_t *)REGS_SP(iregs);

        p = -1;
        ptrace_writedata(pid, sp, (uint8_t*)&p, sizeof(p));

        p = (uintptr_t)sp + 3*sizeof(size_t);
        ptrace_writedata(pid, sp + sizeof(size_t), (uint8_t*)&p, sizeof(p));

        p = RTLD_LAZY | RTLD_GLOBAL;
        ptrace_writedata(pid, sp + 2*sizeof(size_t), (uint8_t*)&p, sizeof(p));

        ptrace_writedata(pid, sp + 3*sizeof(size_t), (uint8_t*)so_path, strlen(so_path) + 1);

#if __WORDSIZE == 64
        iregs.regs.rdi = (uintptr_t)sp + 3*sizeof(size_t);         //arg1
        iregs.regs.rsi = RTLD_LAZY | RTLD_GLOBAL;       //arg2
#endif

        REGS_IP(iregs) = dlopen_addr;
        REGS_AX(iregs) = 0;

        //ptrace continue
        ptrace(PTRACE_SETREGS, pid, NULL, &iregs);
        ptrace(PTRACE_CONT, pid, NULL, NULL);
        waitpid(pid, &status, 0);

        ptrace(PTRACE_GETREGS, pid, NULL, &iregs);
        printf("call dlopen_addr:%p ret %p %p %x sp %p\n",
               (void*)dlopen_addr,
               (void*)REGS_AX(iregs),
               (void*)REGS_IP(iregs),
               status,
               sp
              );

        if (REGS_IP(iregs) != -1) {
                char buf[128] = {0};
                ptrace_readdata(pid, (uintptr_t)REGS_IP(iregs) - 0x20, buf, 0x40);
                hexdump(buf, 0x40);
        }
        //restore context and exit
        ptrace(PTRACE_SETREGS, pid, NULL, &oregs);
        ptrace(PTRACE_CONT, pid, NULL, NULL);
        ptrace(PTRACE_DETACH, pid, NULL, NULL);

        return 0;
}

日志:

定位最终失败IP为ld-2.15.so位置如下:


下了libc源码大致如下位置:
_dl_open->_dl_catch_error->dl_open_worker->_dl_map_object->glibc-2.11/elf/dl-load.c::_dl_map_object_from_fd


求解?

[培训]科锐逆向工程师培训第53期2025年7月8日开班!

上传的附件:
收藏
免费 0
支持
分享
最新回复 (0)
游客
登录 | 注册 方可回帖
返回