Exemplo n.º 1
0
static int status_ptrace(void)
{
    int ret;
    void *addr_current_ex;
    struct php_info info;
    pt_status_t statusst;

    if (get_php_info(&info, clictx.pid) == -1) {
        pt_error("Fetching PHP info failed");
        return -1;
    }
    sdsfree(info.binary);

    pt_ptrace_preset_t *preset = pt_ptrace_preset(info.version, info.sapi_module,
            info.sapi_globals, info.executor_globals);
    if (preset == NULL) {
        pt_error("Preset not found for PHP %d", info.version);
        return -1;
    }

    if (pt_ptrace_attach(clictx.pid) == -1) {
        pt_error("ptrace attach failed");
        return -1;
    }
    pt_info("ptrace attach success");

    /* Fetch current_execute_data */
    addr_current_ex = pt_ptrace_fetch_current_ex(preset, clictx.pid);
    if (addr_current_ex == (void *) -1) {
        pt_error("ptrace peek failed");
        DEINIT_RETURN(-1);
    } else if (addr_current_ex == NULL) {
        pt_error("Process %d not active", clictx.pid);
        DEINIT_RETURN(-1);
    }

    /* Fetch status */
    if (pt_ptrace_build_status(&statusst, preset, clictx.pid, addr_current_ex,
                               info.version) != 0) {
        pt_error("Status fetch failed");
        DEINIT_RETURN(-1);
    }
    pt_type_display_status(&statusst);
    pt_type_destroy_status(&statusst, 1);
    DEINIT_RETURN(0);

deinit:
    if (pt_ptrace_detach(clictx.pid) == -1) {
        pt_error("ptrace detach failed");
        return -1;
    }
    pt_info("ptrace detach success");

    return ret;
}
Exemplo n.º 2
0
static void p1_tester(const void *data)
{
    const Test *test = (const Test *)data;
	int       rv;
	char      buffer[MAX_FIXDECSTRLEN];

    rv = dec_fix(&test->dv, test->dp, test->plus, buffer, sizeof(buffer));
    if (rv != 0 || strcmp(test->res, buffer) != 0)
    {
        pt_fail("input <<%s>> (%d dp)\n", test->val, test->dp);
        pt_info("got    <<%s>>\n", buffer);
        pt_info("wanted <<%s>>\n", test->res);
        pt_info("error = %d\n", rv);
    }
    else
        pt_pass("input <<%s>> (%d dp) = <<%s>>\n", test->val, test->dp, buffer);
}
Exemplo n.º 3
0
static int get_php_info(struct php_info *info, pid_t pid)
{
    FILE *fp;
    long addr;
    ssize_t len;
    char path[128], buf[BUFSIZ];

    memset(info, 0, sizeof(struct php_info));

    /* PHP binary path */
    sprintf(path, "/proc/%d/exe", pid);
    len = readlink(path, buf, PATH_MAX);
    if (len == -1 || len >= PATH_MAX) {
        return -1;
    }
    info->binary = sdsnewlen(buf, len);

    if (info->binary[len - 3] == 'p' &&
        info->binary[len - 2] == 'h' &&
        info->binary[len - 1] == 'p') {
        pt_info("PHP binary: %s", info->binary);
    } else {
        pt_error("\"%s\" looks not like a PHP binary", info->binary);
        return -1;
    }

    /* PHP version */
    sprintf(buf, "%s -v | awk 'NR == 1 {print $2}'", info->binary);
    pt_debug("popen commmand: %s", buf);
    if ((fp = popen(buf, "r")) == NULL) {
        return -1;
    }
    fgets(buf, sizeof(buf), fp);
    pclose(fp);

    /* Convert version string "5.6.3" to id 50603 */
    if (strlen(buf) < 5 || (buf[0] != '7' && buf[0] != '5') || buf[1] != '.' || buf[3] != '.') {
        pt_error("invalid PHP version string \"%s\"", buf);
        return -1;
    }
    info->version  = (buf[0] - '0') * 10000;
    info->version += (buf[2] - '0') * 100;
    if (isdigit(buf[5])) {
        info->version += (buf[4] - '0') * 10;
        info->version += (buf[5] - '0') * 1;
    } else {
        info->version += (buf[4] - '0') * 1;
    }
    pt_info("PHP version id: %d", info->version);

    /* global address */
    sprintf(buf, "gdb --batch -nx %s %d "
                 "-ex 'p &sapi_module' -ex 'p &sapi_globals' -ex 'p &executor_globals' "
                 "2>/dev/null | awk '$1 ~ /^\\$/ {print $1 $(NF-1)}'" , info->binary, pid);
    pt_debug("popen commmand: %s", buf);
    if ((fp = popen(buf, "r")) == NULL) {
        return -1;
    }
    while (fgets(buf, sizeof(buf), fp) != NULL) {
        addr = strtol(buf + 4, NULL, 16);

        if (addr == 0) {
            /* some unexpected happend... */
            pt_error("global address invalid, set more verbose to check");
            pclose(fp);
            return -1;
        }

        if (buf[1] == '1') {
            info->sapi_module = (void *) addr;
        } else if (buf[1] == '2') {
            info->sapi_globals = (void *) addr;
        } else if (buf[1] == '3') {
            info->executor_globals = (void *) addr;
        }
    }
    pclose(fp);

    pt_info("sapi_module:       0x%lx", info->sapi_module);
    pt_info("sapi_globals:      0x%lx", info->sapi_globals);
    pt_info("executor_globals:  0x%lx", info->executor_globals);

    return 0;
}
Exemplo n.º 4
0
static int status_ext(void)
{
    int cfd, ret, msg_type;
    fd_set read_fds;
    struct timeval timeout;

    pt_comm_message_t *msg;
    pt_status_t statusst;

    cfd = 0;
    FD_ZERO(&read_fds);
    FD_SET(clictx.sfd, &read_fds);
    timeout.tv_sec = 2;
    timeout.tv_usec = 0;

    pt_ctrl_set_active(&clictx.ctrl, clictx.pid);

    /* Waiting connect */
    ret = select(clictx.sfd + 1, &read_fds, NULL, NULL, &timeout);
    if (ret == -1) {
        if (errno == EINTR) {
            DEINIT_RETURN(0);
        } else {
            pt_error("Waiting for client connect failed");
            DEINIT_RETURN(-1);
        }
    } else if (ret == 0) {
        pt_warning("Waiting for client connect timeout");
        DEINIT_RETURN(-2); /* timeout */
    }

    /* Client accept & send command */
    cfd = pt_comm_accept(clictx.sfd);
    pt_info("client accepted fd:%d", cfd);

    if (pt_comm_send_type(cfd, PT_MSG_DO_STATUS) == -1) {
        pt_error("Command sending failed");
        DEINIT_RETURN(-1);
    }

    FD_ZERO(&read_fds);
    FD_SET(cfd, &read_fds);
    timeout.tv_sec = 2;
    timeout.tv_usec = 0;

    /* Waiting recv */
    ret = select(cfd + 1, &read_fds, NULL, NULL, &timeout);
    if (ret == -1) {
        if (errno == EINTR) {
            DEINIT_RETURN(0);
        } else {
            pt_error("Waiting for client send failed");
            DEINIT_RETURN(-1);
        }
    } else if (ret == 0) {
        pt_warning("Waiting for client send timeout");
        DEINIT_RETURN(-2); /* timeout */
    }

    /* recv message */
    msg_type = pt_comm_recv_msg(cfd, &msg);
    pt_debug("recv message type: 0x%08x len: %d", msg_type, msg->len);
    if (msg_type == PT_MSG_STATUS) {
        pt_type_unpack_status(&statusst, msg->data);
        pt_type_display_status(&statusst);
        pt_type_destroy_status(&statusst, 1);
        DEINIT_RETURN(0);
    } else {
        pt_error("unknown message received with type 0x%08x", msg_type);
        DEINIT_RETURN(-1);
    }

deinit:
    if (cfd) {
        pt_comm_close(cfd, NULL);
    }
    pt_ctrl_set_inactive(&clictx.ctrl, clictx.pid);

    return ret;
}