Пример #1
0
void pvt_fprintf(const char* fmt, ...)
{
    va_list args;
    char* new_str;

    TSRMLS_FETCH();

    va_start(args, fmt);
    new_str = pvt_sprintf_real(fmt, args);
    va_end(args);

    if (PVT_G(trace_file_f)) {
        fprintf(PVT_G(trace_file_f), "%s", new_str);
    }

    efree(new_str);
}
Пример #2
0
/* {{{ dump_op
 */
static void dump_op(zend_op_array *op_array, zend_op *opi, int num, zend_uint base_address)
{
    unsigned int flags, op1_type, op2_type, res_type;
    char *op_result = NULL;
    char *op_op1 = NULL;
    char *op_op2 = NULL;

    TSRMLS_FETCH();

    /* EXT_STMT */
    if (opi->opcode == 101) {
        fprintf(PVT_G(log_file_path), "\t<tr class=\"s\">");
    } else {
        fprintf(PVT_G(log_file_path), "\t<tr>");
    }

    fprintf(PVT_G(log_file_path),
        "<td>%d</td><td>%d</td><td title=\"%d\" class=\"wz\">%s</td>",
        num, opi->lineno, opi->opcode, opname(opi->opcode)
    );

    if (!(opi->PVT_EXTENDED_VALUE(result) & EXT_TYPE_UNUSED)) {
        op_result = format_znode(&opi->result, base_address);
        fprintf(PVT_G(log_file_path),
            "<td>%s</td>", op_result
        );
        if (op_result) {
            efree(op_result);
        }
    } else {
        fprintf(PVT_G(log_file_path), "<td></td>");
    }

    op_op1 = format_znode(&opi->op1, base_address);
    fprintf(PVT_G(log_file_path),
        "<td>%s</td>", op_op1
    );

    if (op_op1) {
        efree(op_op1);
    }

    op_op2 = format_znode(&opi->op2, base_address);
    fprintf(PVT_G(log_file_path),
        "<td>%s</td></tr>\n", op_op2
    );
    if (op_op2) {
        efree(op_op2);
    }
}
Пример #3
0
void trace_function_entry(HashTable *func_table, const char *func_name, int type, const char *filename, int linenum)
{
    int *function_index;
    int tmp_function_index;
    int *filenum;
    int tmp_filenum;
    int tmp_block_num;
    int *block_num;
    int esp         = 0;
    int flag_x      = 0;
    int is_dynamic  = 0;
    int is_evil     = 0;
    char *fname = NULL;

    TSRMLS_FETCH();

    if (PVT_G(pvt_count_stat)) {
        PVT_G(stats)->func_calls += 1;
    }
    allf_index += 1;

    is_evil = is_dangerous(func_name);

    /* Functions tracing */

    if (zend_hash_find(PVT_G(file_summary), (char *) filename, strlen(filename) + 1, (void *) &filenum) == FAILURE) {

        tmp_filenum = ++PVT_G(file_index);

        fprintf(PVT_G(trace_file_f), " \t| #%d\t| \t%s %s()\n", tmp_filenum, filename, func_name);

        zend_hash_add(PVT_G(file_summary), (char *) filename, strlen(filename) + 1, &(tmp_filenum), sizeof(int), NULL);

        if (PVT_G(pvt_count_stat)) {
            PVT_G(stats)->file_amount += 1;
        }
    } else {
        tmp_filenum = *filenum;
    }


    if (is_func_dyn(func_name)) {
        fname = (char *) pvt_sprintf("%s_%d", func_name, tmp_filenum);
        local_index = 0;
        is_dynamic  = 1;
    } else {
        fname = (char *) pvt_sprintf("%s", func_name);
    }

    /* Files tracing */

    if (zend_hash_find(PVT_G(function_summary), (char *) fname, strlen(fname) + 1, (void *) &function_index) == SUCCESS) {

        tmp_function_index = *function_index;

        fprintf(PVT_G(trace_file_f), " %d\t| -->\t| %s() %s #%d {\n", linenum,  fname, filename, tmp_function_index);
        new_var = 0;

    } else {

        /* We enter in new function */
        tmp_function_index = ++PVT_G(function_index);

        zend_hash_add(PVT_G(function_summary), (char *) fname, strlen(fname) + 1, &(tmp_function_index), sizeof(int), NULL);

        fprintf(PVT_G(trace_file_f), " \t| #%d\t| %s() %d\n", tmp_function_index, fname, type);
        fprintf(PVT_G(trace_file_f), " %d\t| -->\t| %s() %s #%d .{\n", linenum,  fname, filename, tmp_function_index);

        if (!is_dynamic && PVT_G(pvt_count_stat)) {
            PVT_G(stats)->func_amount += 1;
        }
    }

    /* For *.dot graphs */

    if (zend_hash_find(PVT_G(block_summary), (char *) fname, strlen(fname) + 1, (void *) &block_num) == FAILURE) {

        /* Files and user functions */
        if (2 == type) {

            tmp_block_num = ++PVT_G(block_index);
            zend_hash_add(PVT_G(block_summary), (char *) fname, strlen(fname) + 1, &(tmp_block_num), sizeof(int), NULL);
            flag_x = 1;
            new_var = 1;
        }
    } else {
        tmp_block_num = *block_num;
    }

    local_index += 1;

    if (2 == type) {

        PVT_G(funcs_stack)->func_id = realloc(PVT_G(funcs_stack)->func_id, (PVT_G(funcs_stack)->len+1) * sizeof(int));
        PVT_G(funcs_stack)->func_id[PVT_G(funcs_stack)->len] = tmp_block_num;

        PVT_G(funcs_stack)->len += 1;
        esp = PVT_G(funcs_stack)->func_id[PVT_G(funcs_stack)->len-1];
    } else {
        /* In file or in function
         * Note: here was a problem with finding esp with dynamic content, had
         * to add second check 'is_dynamic'. Find better fix?
         */
        if (allf_index - tmp_filenum == 0 && !is_dynamic) {
            esp = PVT_G(funcs)->file_id[PVT_G(funcs)->len - local_index + 1];
        } else {
            /* In function */
            esp = PVT_G(funcs_stack)->func_id[PVT_G(funcs_stack)->len-1];
        }
    }

    if (flag_x) {

        PVT_G(dot_funcs_i)->file_id = realloc(PVT_G(dot_funcs_i)->file_id, (PVT_G(dot_funcs_i)->len+1) * sizeof(int));
        PVT_G(dot_funcs_i)->file_id[PVT_G(dot_funcs_i)->len] = PVT_G(funcs_stack)->i;

        PVT_G(dot_funcs_i)->empty = realloc(PVT_G(dot_funcs_i)->empty, (PVT_G(dot_funcs_i)->len+1) * sizeof(int));
        PVT_G(dot_funcs_i)->empty[PVT_G(dot_funcs_i)->len] = 0;

        PVT_G(dot_funcs_i)->len += 1;
    }

    if (PVT_G(pvt_count_stat)) {
        if (esp > PVT_G(stats)->max_fileid) {
            PVT_G(stats)->max_fileid = esp;
        }
    }


    /* Save variable and related block node number */
    PVT_G(funcs)->func_id = realloc(PVT_G(funcs)->func_id, (PVT_G(funcs)->len+1) * sizeof(int));
    PVT_G(funcs)->func_id[PVT_G(funcs)->len] = tmp_function_index;

    PVT_G(funcs)->file_id = realloc(PVT_G(funcs)->file_id, (PVT_G(funcs)->len+1) * sizeof(int));
    PVT_G(funcs)->file_id[PVT_G(funcs)->len] = esp;

    PVT_G(funcs)->line = realloc(PVT_G(funcs)->line, (PVT_G(funcs)->len+1) * sizeof(int));
    PVT_G(funcs)->line[PVT_G(funcs)->len] = linenum;

    PVT_G(funcs)->type = realloc(PVT_G(funcs)->type, (PVT_G(funcs)->len+1) * sizeof(int));
    PVT_G(funcs)->type[PVT_G(funcs)->len] = type;

    PVT_G(funcs)->stack = realloc(PVT_G(funcs)->stack, (PVT_G(funcs)->len+1) * sizeof(int));
    PVT_G(funcs)->stack[PVT_G(funcs)->len] = PVT_G(funcs_stack)->i;

    PVT_G(funcs)->hide = realloc(PVT_G(funcs)->hide, (PVT_G(funcs)->len+1) * sizeof(int));
    PVT_G(funcs)->hide[PVT_G(funcs)->len] = 0;

    PVT_G(funcs)->is_dyn = realloc(PVT_G(funcs)->is_dyn, (PVT_G(funcs)->len+1) * sizeof(int));
    PVT_G(funcs)->is_dyn[PVT_G(funcs)->len] = is_dynamic;

    PVT_G(funcs)->is_evil = realloc(PVT_G(funcs)->is_evil, (PVT_G(funcs)->len+1) * sizeof(int));
    PVT_G(funcs)->is_evil[PVT_G(funcs)->len] = is_evil;

    PVT_G(funcs)->file_name = realloc(PVT_G(funcs)->file_name, sizeof(char*) * (PVT_G(funcs)->len+1));
    PVT_G(funcs)->file_name[PVT_G(funcs)->len] = malloc(strlen(filename) + 1);
    memcpy(PVT_G(funcs)->file_name[PVT_G(funcs)->len], filename, strlen(filename) + 1);
    PVT_G(funcs)->file_name[PVT_G(funcs)->len][strlen(filename)] = '\0';

    PVT_G(funcs)->func_name = realloc(PVT_G(funcs)->func_name, sizeof(char*) * (PVT_G(funcs)->len+1));
    PVT_G(funcs)->func_name[PVT_G(funcs)->len] = malloc(strlen(fname) + 1);
    memcpy(PVT_G(funcs)->func_name[PVT_G(funcs)->len], fname, strlen(fname) + 1);
    PVT_G(funcs)->func_name[PVT_G(funcs)->len][strlen(fname)] = '\0';

    flag_empty = tmp_function_index;

    PVT_G(funcs)->len += 1;
    if (2 == type) {
        PVT_G(funcs_stack)->i += 1;
    }

    if (PVT_G(pvt_count_stat)) {
        if (PVT_G(funcs_stack)->i > PVT_G(stats)->max_stack) {
            PVT_G(stats)->max_stack = PVT_G(funcs_stack)->i;
        }
    }

    if (fname) {
        efree(fname);

}

void trace_function_exit(char *func_name, char *filename, int type, int line)
{
    int *function_index;
    int *filenum;
    int tmp_func_index;
    char *fname;

    TSRMLS_FETCH();

    if (zend_hash_find(PVT_G(file_summary), (char *) filename, strlen(filename) + 1, (void *) &filenum) == FAILURE) {
        /* Do nothing */
    }

    if (is_func_dyn(func_name)) {
        fname = (char *) pvt_sprintf("%s_%d", func_name, *filenum);
        local_index = PVT_G(funcs)->len;
    } else {
        fname = (char *) pvt_sprintf("%s", func_name);
    }

    if (zend_hash_find(PVT_G(function_summary), fname, strlen(fname) + 1, (void *) &function_index) == SUCCESS) {

        tmp_func_index = *function_index;
        fprintf(PVT_G(trace_file_f), " %d\t| <--\t| %s() %s #%d }\n\n", line, fname, filename, tmp_func_index);

    } else {

        tmp_func_index =  ++PVT_G(function_index);
        zend_hash_add(PVT_G(function_summary), fname, strlen(fname) + 1, &(tmp_func_index), sizeof(int), NULL);

        fprintf(PVT_G(trace_file_f), " %d\t| <--\t| %s() %s #%d .}\n\n", line, fname, filename, tmp_func_index);
    }

    allf_index -= 1;

    if (2 == type) {
        PVT_G(funcs_stack)->i -= 1;
        if (flag_empty == tmp_func_index && new_var) {
            PVT_G(dot_funcs_i)->empty[PVT_G(dot_funcs_i)->len-1] = 1;
        }
    }

    if (fname) {
        efree(fname);
    }
}
Пример #4
0
void dump_dot(void)
{

    int x, print_header, key_type;
    int *block_num;
    int c = 0, len = 0, flag_ho;
    long index, key_len;
    char *block_name = NULL;
    char *time_buff = pvt_get_time();
    smart_str str_dot_func = {0};

    TSRMLS_FETCH();

    char *tmp_buff = NULL;
    tmp_buff = pvt_sprintf(tpl_dot[0], time_buff);
    fprintf(PVT_G(trace_file_f_dot), "%s", tmp_buff);
    efree(time_buff);
    efree(tmp_buff);

    if (PVT_G(pvt_graph_fold)) {
        hide_functions();
    }

    /* Iterate through all blocks/nodes */
    for (zend_hash_internal_pointer_reset(PVT_G(block_summary));
        zend_hash_has_more_elements(PVT_G(block_summary)) == SUCCESS;
        zend_hash_move_forward(PVT_G(block_summary))) {

        key_type = zend_hash_get_current_key(PVT_G(block_summary), &block_name, &index, 0);
        if (key_type == HASH_KEY_IS_STRING) {
            key_len = strlen(block_name);
        }
        zend_hash_get_current_data(PVT_G(block_summary), (void*) &block_num);

        print_header = 1;

        int flag_started = 0;
        int flag_break   = 0;
        int flag_nop     = 0;
        flag_ho = 1;

        size_t ret_len;

        /* Iterate through all functions */
        for (x = 0; x < PVT_G(funcs)->len; x++) {

            if (PVT_G(funcs)->file_id[x] == *block_num) {

                flag_started = 1;
                if (print_header) {
                    if (PVT_G(funcs)->type[x] == 2 && flag_ho) {

                        char *ret;
                        php_basename(
                            PVT_G(funcs)->file_name[x],
                            strlen(PVT_G(funcs)->file_name[x]),
                            NULL, 0, &ret, &ret_len TSRMLS_CC
                        );
                        char *escaped_str = php_escape_html_entities(
                            block_name,
                            strlen(block_name),
                            &len, 0, ENT_QUOTES, NULL TSRMLS_CC
                        );
                        /* Print the block header */
                        fprintf(PVT_G(trace_file_f_dot),
                            tpl_point_func[0],
                            *block_num,
                            PVT_G(funcs)->line[x],
                            *block_num,
                            PVT_G(funcs)->file_name[x], PVT_G(funcs)->line[x],
                            ret,
                            escaped_str,
                            PVT_G(funcs)->func_id[x]
                        );
                        flag_ho = 0;
                        efree(ret);
                        efree(escaped_str);
                    }
                }
            }

            if (PVT_G(funcs)->stack[x] <= PVT_G(dot_funcs_i)->file_id[c] && flag_started) {
                if (0 == print_header) {
                    flag_break = 1;
                } else {
                    flag_break = 0;
                }
            }

            if (0 == flag_started) {
                continue;
            }

            if ((PVT_G(funcs)->stack[x]-1) != PVT_G(dot_funcs_i)->file_id[c]) {
                if (!flag_break) {
                    continue;
                } else {
                    flag_nop = 1;
                }
            }

            if (flag_nop != 1) {
                flag_nop = 0;
                if (print_header) {
                    print_header = 0;
                }

                if (PVT_G(dot_funcs_i)->empty[c]) {
                    flag_started = 0;
                    break;
                }

                /* Check if function repeats */
                if (0 == PVT_G(funcs)->hide[x] || !PVT_G(pvt_graph_fold)) {
                    if (2 == PVT_G(funcs)->type[x]) {

                        /* This is USER function */
                        char *escaped_str = php_escape_html_entities(
                            PVT_G(funcs)->func_name[x],
                            strlen(PVT_G(funcs)->func_name[x]),
                            &len, 0, ENT_QUOTES, NULL TSRMLS_CC
                        );

                        fprintf(PVT_G(trace_file_f_dot),
                            tpl_point_func[1],
                            PVT_G(funcs)->line[x],
                            PVT_G(funcs)->line[x],
                            escaped_str,
                            PVT_G(funcs)->func_id[x]
                        );
                        efree(escaped_str);

                        char *tmp_buff = pvt_sprintf(
                            tpl_relation_func[0],
                            *block_num,
                            PVT_G(funcs)->line[x],
                            PVT_G(funcs)->file_id[x],
                            PVT_G(funcs)->file_id[x],
                            PVT_G(funcs)->func_id[x]
                        );
                        smart_str_appends(&str_dot_func, tmp_buff);
                        efree(tmp_buff);

                    } else {
                        /* This is ZEND function */
                        char *escaped_str = php_escape_html_entities(
                            PVT_G(funcs)->func_name[x],
                            strlen(PVT_G(funcs)->func_name[x]),
                            &len, 0, ENT_QUOTES, NULL TSRMLS_CC
                        );

                        fprintf(PVT_G(trace_file_f_dot),
                            tpl_point_func[2],
                            PVT_G(funcs)->line[x],
                            (1 == PVT_G(funcs)->is_evil[x] ? "d63333" : "e0ebcc"),
                            escaped_str,
                            PVT_G(funcs)->func_id[x]
                        );
                        efree(escaped_str);
                    }

                } /* end if (0 ==... */
            } /* end if (flag_nop... */

            if (flag_break) {
                if (!flag_nop) {
                    flag_break   = 0;
                    flag_started = 0;
                    break;
                }
            }
        } /* end for (x... */
        c++;
        fprintf(PVT_G(trace_file_f_dot), "</TABLE>>\n]\n");
    }

    smart_str_0(&str_dot_func);
    if (str_dot_func.c != NULL) {
        fprintf(PVT_G(trace_file_f_dot), "%s", str_dot_func.c);
    }
    smart_str_free(&str_dot_func);
    fprintf(PVT_G(trace_file_f_dot), "\n}\n");
    fclose(PVT_G(trace_file_f_dot));
}
Пример #5
0
/*
 * Hides function repetitions in graph
 */
static void hide_functions(void)
{
    TSRMLS_FETCH();

    int k = 0, i = 0;

    for (k; k < PVT_G(funcs)->len; k++) {

        int index   = PVT_G(funcs)->func_id[k];
        int file_id = PVT_G(funcs)->file_id[k];

        if (0 == k || k == PVT_G(funcs)->len) continue;

        int i = k - 1;
        for (i; i > 0; i--) {

            /* If there is a match with some previous item */
            if (PVT_G(funcs)->func_id[i] == index
                && PVT_G(funcs)->file_id[i] == file_id)
            {

                int dist = k - i;
                int g = i;

                /* This is a temporary rude hack, rarely but it tends to loop.
                 * Thus, I limit maximal amount of functions in block to 29.
                 */
                if (dist > 30) continue;

                /* Drop to the very first block */
                for (g; g < PVT_G(funcs)->len; ) {
                    int e = 0, m = 0;

                    /* Start cycling by blocks */
                    for (e; e < dist; e++) {
                        if ((g + dist + e) >= PVT_G(funcs)->len) {
                            break;
                        }
                        if (PVT_G(funcs)->func_id[g+e] == PVT_G(funcs)->func_id[g+dist+e]) {
                            m++;
                        }
                    }

                    if (m == dist) {
                        g += dist;
                        int q = 0;
                        for (q; q < dist; q++) {
                            PVT_G(funcs)->hide[q + g] = 1;
                        }
                        k = g + dist - 1;
                    } else {
                        break;
                    }
                } /* end for(g... */
            } /* end if (PVT_G(funcs... */
        } /* end for (i... */
    } /* end for (k... */
}