コード例 #1
0
ファイル: type.cpp プロジェクト: Frky/scat
VOID check_parameter_out(ADDRINT addr) {
    trace_enter();

    if (call_stack.is_top_forgotten()) {
        trace_leave();
        return;
    }

    FID fid = call_stack.top();
    UINT64 sp = sp_stack.top();
    if (sp + 1000 <= addr && addr < sp) {
        trace_leave();
        return;
    }

    unsigned int param_val_size = 1 + nb_param_int[fid] + nb_param_int_stack[fid];
    for (unsigned int pid = 1; pid < param_val_size; pid++) {
        if (param_val[fid][pid]->back() == addr) {
            nb_out[fid][pid]++;
            trace_leave();
            return;
        }
    }

    trace_leave();
}
コード例 #2
0
ファイル: memblock.cpp プロジェクト: chubbymaggie/scat
VOID fn_ret(CONTEXT *ctxt, UINT32 fid) {
    trace_enter();
    
    counter += 1;

    if (!call_stack.is_top_forgotten()) {
        while (is_jump_stack.top()) {
            FID fid = call_stack.top();
            if (is_instrumented[fid]) {
                param_t *new_ret = (param_t *) malloc(sizeof(param_t));
                new_ret->fid = fid;
                new_ret->counter = counter;
                new_ret->val = val_from_reg(ctxt, 0); 
                new_ret->is_addr = param_addr[fid][0];
                param_out->push_front(new_ret);
            }
            call_stack.pop();
            is_jump_stack.pop();
        }
        FID fid = call_stack.top();
        if (is_instrumented[fid]) {
            param_t *new_ret = (param_t *) malloc(sizeof(param_t));
            new_ret->fid = fid;
            new_ret->counter = counter;
            new_ret->val = val_from_reg(ctxt, 0); 
            new_ret->is_addr = param_addr[fid][0];
            param_out->push_front(new_ret);
        }
        call_stack.pop();
        is_jump_stack.pop();
    }

    trace_leave();
    return;
}
コード例 #3
0
void syslogd_open_sockets (struct socket *sockets) 

{
	struct socket *socket = sockets;

#if SYSLOGD_TRACE

	trace_enter ("syslogd_open_sockets");

#endif

	do 
	{
		socket = socket->next;
		if (socket->desc != -1) 
		{
			continue;
		}
		if (socket->sockaddr == (struct sockaddr *)(0)) 
		{
			syslogd_error (EINVAL, "Missing socket address");
			continue;
		}

#ifdef SYSLOGD_UNIXAF

		if (socket->sockaddr->sa_family == AF_UNIX) 
		{
			struct sockaddr_un * sockaddr_un = (struct sockaddr_un *)(socket->sockaddr);
			syslogd_print (SYSLOG_SYSLOG | SYSLOG_NOTICE, "Opening host connection on %s", sockaddr_un->sun_path);
			socket->desc = syslogd_unix_socket (sockaddr_un);
			continue;
		}

#endif
#ifdef SYSLOGD_INETAF

		if (socket->sockaddr->sa_family == AF_INET) 
		{
			char buffer [HOSTADDR_MAX];
			struct sockaddr_in * sockaddr_in = (struct sockaddr_in *)(socket->sockaddr);
			getsocketname (buffer, sizeof (buffer), sockaddr_in);
			syslogd_print (SYSLOG_SYSLOG | SYSLOG_NOTICE, "Opening inet connection on %s", buffer);
			socket->desc = syslogd_inet_socket (sockaddr_in);
			continue;
		}

#endif

	}
	while (socket != sockets);

#if SYSLOGD_TRACE

	trace_leave ("syslogd_open_sockets");

#endif

	return;
}
コード例 #4
0
ファイル: memblock.cpp プロジェクト: chubbymaggie/scat
void fn_registered(
                    FID fid, 
                    unsigned int nb_param, 
                    vector<bool> type_param
                ) {

    trace_enter();

    /* Set the number of parameters */
    nb_p[fid] = nb_param;
    /* Set the array of booleans indicating which parameter is an ADDR */
    param_addr[fid] = (bool *) calloc(nb_p[fid], sizeof(bool));

    /* Is this function instrumented?*/
    is_instrumented[fid] = false;

    /* Iteration on parameters */
    for (unsigned int i = 0; i <= nb_p[fid]; i++) {
        if (type_param[i]) {
            param_addr[fid][i] = true;
            is_instrumented[fid] = true;
        }
        else
            param_addr[fid][i] = false;
    }

    trace_leave();
    return;
}
コード例 #5
0
void syslogd_print (int priority, char const * format, ...) 

{ 
	extern char const * host_name; 
	extern char const * program_name; 
	char buffer [TEXTLINE_MAX] = "no error message"; 
	size_t length = 0; 

#if SYSLOGD_TRACE

	trace_enter ("syslogd_error"); 

#endif

	if (program_name != (char const *) (0)) 
	{ 
		length += snprintf (buffer + length, sizeof (buffer) - length, "%s: ", program_name); 
	} 
	if ((format != (char const *) (0)) && (* format != (char) (0))) 
	{ 
		va_list arglist; 
		va_start (arglist, format); 
		length += vsnprintf (buffer + length, sizeof (buffer) - length, format, arglist); 
		va_end (arglist); 
	} 
	syslogd_queue (priority, host_name, buffer); 

#if SYSLOGD_TRACE

	trace_leave ("syslogd_error"); 

#endif

	return; 
} 
コード例 #6
0
ファイル: type.cpp プロジェクト: Frky/scat
/*  Instrumentation of each instruction
 *  that uses a memory operand
 */
VOID Instruction(INS ins, VOID *v) {
    trace_enter();

    if (!INS_IsStackRead(ins)) {
        for (UINT32 memopIdx = 0; memopIdx < INS_MemoryOperandCount(ins); memopIdx++) {
            if (INS_MemoryOperandIsWritten(ins, memopIdx)) {
                INS_InsertCall(ins,
                                IPOINT_BEFORE,
                                (AFUNPTR) update_stack_heap_region,
                                IARG_CONST_CONTEXT,
                                IARG_MEMORYOP_EA, memopIdx,
                                IARG_END);

                UINT32 opIdx = INS_MemoryOperandIndexToOperandIndex(ins, memopIdx);
                REG base_reg = INS_OperandMemoryBaseReg(ins, opIdx);
                if (base_reg != REG_INVALID()) {
                    INS_InsertCall(ins,
                                    IPOINT_BEFORE,
                                    (AFUNPTR) check_parameter_out,
                                    IARG_REG_VALUE, base_reg,
                                    IARG_END);
                }
            }
        }
    }

    if (INS_IsCall(ins)) {
        if (INS_IsDirectCall(ins)) {
            ADDRINT addr = INS_DirectBranchOrCallTargetAddress(ins);
            FID fid = fn_lookup_by_address(addr);

            INS_InsertCall(ins,
                        IPOINT_BEFORE,
                        (AFUNPTR) fn_call,
                        IARG_CONST_CONTEXT,
                        IARG_UINT32, fid,
                        IARG_END);
        }
        else {
            INS_InsertCall(ins,
                        IPOINT_BEFORE,
                        (AFUNPTR) fn_indirect_call,
                        IARG_CONST_CONTEXT,
                        IARG_BRANCH_TARGET_ADDR,
                        IARG_END);
        }
    }

    if (INS_IsRet(ins)) {
        INS_InsertCall(ins,
                    IPOINT_BEFORE,
                    (AFUNPTR) fn_ret,
                    IARG_CONST_CONTEXT,
                    IARG_END);
    }

    trace_leave();
}
コード例 #7
0
ファイル: type.cpp プロジェクト: Frky/scat
VOID update_stack_heap_region(CONTEXT* ctxt, ADDRINT addr) {
    trace_enter();

    if (!is_addr(addr)) {
        stack_heap_region.extend(addr);
    }

    trace_leave();
}
コード例 #8
0
ファイル: memcollect.cpp プロジェクト: chubbymaggie/scat
VOID fn_call(CONTEXT *ctxt, FID fid, bool is_jump) {
    
    trace_enter();

    call_stack.push(fid);
    is_jump_stack.push(is_jump);
    counter += 1;

    bool param_pushed = false;

    if (!is_instrumented[fid]) {
        trace_leave();
        return;
    }

    for (unsigned int i = 1; i <= nb_p[fid]; i++) {
        if (!param_addr[fid][i])
            continue;
        param_t *new_param = (param_t *) malloc(sizeof(param_t));
        new_param->fid = fid;
        new_param->counter = counter;
        new_param->val = val_from_reg(ctxt, i); 
        new_param->is_addr = param_addr[fid][i];
        new_param->pos = i;
        param_in->push_front(new_param);
        param_pushed = true;
    }

    /* If the function is instrumented (ie for instance has an ADDR as
       a return value) AND was not logged yet, create a special
       entry to log the date of call */
    if (!param_pushed) {
        param_t *new_addr = (param_t *) malloc(sizeof(param_t));
        new_addr->fid = fid;
        new_addr->counter = counter;
        new_addr->val = 0; // val_from_reg(ctxt, i); 
        new_addr->pos = 0;
        new_addr->is_addr = false; // true;
        param_in->push_front(new_addr);
    }

    trace_leave();
    return;
}
コード例 #9
0
ファイル: memblock.cpp プロジェクト: chubbymaggie/scat
VOID Fini(INT32 code, VOID *v) {

    trace_enter();

    list<param_t *>::reverse_iterator it_in, it_out;
    it_in = param_in->rbegin();
    it_out = param_out->rbegin();

    int depth = 0;
    UINT64 last_date = -1;
    bool is_in = false;

    gettimeofday(&stop, NULL);

    ofile << "Elapsed time ] Commence ; Fini [ : " << (stop.tv_usec / 1000.0 + 1000 * stop.tv_sec - start.tv_sec * 1000 - start.tv_usec / 1000.0) / 1000.0 << "s" << endl;

    while (it_in != param_in->rend() || it_out != param_out->rend()) {
        // for (int i = 0; i < depth; i++) 
        //  ofile << " ";
        param_t *p;
        if (it_in == param_in->rend()) {
            p = *it_out;
            it_out++;
            is_in = false;
            ofile << "out:";
        } else if (it_out == param_out->rend() || (*it_out)->counter >= (*it_in)->counter) {
            p = *it_in;
            it_in++;
            is_in = true;
            ofile << "in:";
        } else {
            p = *it_out;
            it_out++;
            is_in = false;
            ofile << "out:";
        }
        if (p->is_addr)
            ofile << "addr:";
        else 
            ofile << "int:";
        if (last_date != p->counter) {
            if (is_in)
                depth++;
            else
                depth--;
        }
        last_date = p->counter;
        ofile << p->val << ":" << fn_img(p->fid) << ":" << fn_imgaddr(p->fid) << ":" << fn_name(p->fid) << ":" << p->pos << ":" << p->counter << endl;
    }
    ofile.close();

    trace_leave();

    return;
}
コード例 #10
0
ファイル: memblock.cpp プロジェクト: chubbymaggie/scat
VOID Commence() {

    trace_enter();

    /* Init instruction counter */
    counter = 0;
    init = true;
    string _addr, _name;
    if (ifile.is_open()) {
        while (ifile) {
            char m;
            unsigned int nb_param = 0;
            vector<bool> type_param;
            string img_name = read_part(&m);

            if (img_name.empty()) {
                continue;
            }

            ADDRINT img_addr = atol(read_part(&m).c_str());
            string name = read_part(&m);

            /* Read parameters */
            while (ifile && m != '\n') {
                string part = read_part(&m);
                switch (part[0]) {
                case 'A':
                    type_param.push_back(true);
                    break;
                case 'I':
                case 'V':
                    type_param.push_back(false);
                    break;
                case 'F':
                    type_param.push_back(false);
                    break;
                default:
                    type_param.push_back(false);
                }
                nb_param += 1;
            }

            FID fid = fn_register(img_name, img_addr, name);
            if (fid != FID_UNKNOWN) {
                fn_registered(fid, nb_param - 1, type_param);
            }
        }
    }

    gettimeofday(&start, NULL);

    trace_leave();

    return;
}
コード例 #11
0
ファイル: memblock.cpp プロジェクト: chubbymaggie/scat
VOID fn_icall(CONTEXT* ctxt, ADDRINT target, bool is_jump) {
    
    trace_enter();

    // Indirect call, we have to look up the function each time
    // The functions `fn_lookup` & `fn_register` needs PIN's Lock.
    // Locking is not implicit in inserted call, as opposed
    // to callback added with *_AddInstrumentFunction().
    PIN_LockClient();
    FID fid = fn_lookup_by_address(target);
    if (is_jump && fid == FID_UNKNOWN) {
        trace_leave();
        return;
    }
    PIN_UnlockClient();

    fn_call(ctxt, fid, is_jump);

    trace_leave();
    return;
}
コード例 #12
0
ファイル: type.cpp プロジェクト: Frky/scat
VOID image_loaded(IMG img, void* data) {
    trace_enter();

    for (int i = 0; i < IMG_NumRegions(img); i++) {
        Region* region = data_regions + data_regions_size;
        data_regions_size++;

        region->low = IMG_RegionLowAddress(img, i);
        region->high = IMG_RegionHighAddress(img, i);
    }

    trace_leave();
}
コード例 #13
0
void syslogd_stop (struct syslogd * syslogs, flag_t flags)

{
    extern char const * program_name;
    struct syslogd * syslog;

#if SYSLOGD_TRACE

    trace_enter ("syslogd_stop");

#endif

    syslogd_print (SYSLOG_SYSLOG | SYSLOG_NOTICE, "%s %s.%s stopped", program_name, VERSION, RELEASE);
    while (syslogs->next != syslogs)
    {
        syslog = syslogs->next;
        syslog->next->prev = syslogs;
        syslogs->next = syslog->next;
        if (syslog->f_repeat > 0)
        {
            syslogd_write (syslog, flags);
        }
        if (syslog->f_sockaddr_in != (struct sockaddr_in *) (0))
        {
            free (syslog->f_sockaddr_in);
            syslog->f_sockaddr_in = (struct sockaddr_in *) (0);
        }
        switch (syslog->f_type)
        {
        case SYSLOGD_TYPE_HOST:
        case SYSLOGD_TYPE_FILE:
        case SYSLOGD_TYPE_PIPE:
        case SYSLOGD_TYPE_TERM:
        case SYSLOGD_TYPE_CONSOLE:
            close (syslog->f_desc);
            break;
        }
        syslog->prev = (struct syslogd *) (0);
        syslog->next = (struct syslogd *) (0);
        free (syslog->f_name);
        free (syslog);
    }

#if SYSLOGD_TRACE

    trace_leave ("syslogd_stop");

#endif

    return;
}
コード例 #14
0
ファイル: memblock.cpp プロジェクト: chubbymaggie/scat
ADDRINT val_from_reg(CONTEXT *ctxt, unsigned int pid) {

    trace_enter();

    REG reg;
    switch (pid) {
    case 0:
        reg = REG_RAX;
        break;
    case 1:
        reg = REG_RDI;
        break;
    case 2:
        reg = REG_RSI;
        break;
    case 3:
        reg = REG_RDX;
        break;
    case 4:
        reg = REG_RCX;
        break;
    case 5:
        reg = REG_R8;
        break;
    case 6:
        reg = REG_R9;
        break;
    default:

        trace_leave();

        return 0;
    }

    trace_leave();

    return PIN_GetContextReg(ctxt, reg);
}
コード例 #15
0
ファイル: type.cpp プロジェクト: Frky/scat
VOID add_val(unsigned int fid, CONTEXT *ctxt, unsigned int pid, UINT64 sp) {
    trace_enter();

    if (param_val[fid][pid]->size() >= MAX_VALS_TO_COLLECT) {
        trace_leave();
        return;
    }

    UINT64 val;
    if (pid < 1 + nb_param_int[fid]) {
        PIN_GetContextRegval(ctxt, param_reg(pid), (UINT8*) &val);
    }
    else {
        unsigned int sp_offset = pid - (1 + nb_param_int[fid]);
        UINT64* addr = (UINT64*) (sp + sp_offset * 8);
        val = *addr;
    }

    if (val != 0)
        param_val[fid][pid]->push_front(val);

    trace_leave();
}
コード例 #16
0
ファイル: type.cpp プロジェクト: Frky/scat
VOID fn_ret(CONTEXT *ctxt) {
    trace_enter();

    if (!call_stack.is_top_forgotten()) {
        FID fid = call_stack.top();

        if (has_return[fid] == 1) {
            add_val(fid, ctxt, 0, 0);
        }
    }

    call_stack.pop();
    sp_stack.pop();

    trace_leave();
}
コード例 #17
0
void syslogd_configure (struct syslogd * syslogs, flag_t flags, char const * filename) 

{ 
	file_t fd; 
	char string [TEXTLINE_MAX]; 
	size_t lineno = 0; 

#if SYSLOGD_TRACE

	trace_enter ("syslogd_configure"); 

#endif

	if ((fd = open (filename, O_RDONLY)) == - 1) 
	{ 
		syslogd_error (errno, "cant open %s", filename); 
		return; 
	} 
	while (statement (fd, string, sizeof (string), & lineno)) 
	{ 
		if (* string != (char) (0)) 
		{ 
			struct syslogd * syslog = NEW (struct syslogd); 
			syslogd_parse (syslog, flags, string); 
			if (syslog->f_type == SYSLOGD_TYPE_NONE) 
			{ 
				free (syslog->f_name); 
				free (syslog); 
				continue; 
			} 
			syslog->prev = syslogs->prev; 
			syslogs->prev->next = syslog; 
			syslogs->prev = syslog; 
			syslog->next = syslogs; 
		} 
	} 
	close (fd); 

#if SYSLOGD_TRACE

	trace_leave ("syslogd_configure"); 

#endif

	return; 
} 
コード例 #18
0
ファイル: type.cpp プロジェクト: Frky/scat
VOID fn_call(CONTEXT *ctxt, FID fid) {
    trace_enter();

    call_stack.push(fid);

    UINT64 sp;
    PIN_GetContextRegval(ctxt, REG_RSP, (UINT8*) &sp);
    sp_stack.push(sp);

    nb_call[fid]++;
    unsigned int param_val_size = 1 + nb_param_int[fid] + nb_param_int_stack[fid];
    for (unsigned int pid = 1; pid < param_val_size; pid++) {
        if (!param_is_not_addr[fid][pid])
            add_val(fid, ctxt, pid, sp);
    }

    trace_leave();
}
コード例 #19
0
void syslogd_admin (struct syslogd * syslogs, flag_t flags, char const * filename) 

{ 
	FILE * fp; 
	struct syslogd * syslog; 

#if SYSLOGD_TRACE

	trace_enter ("syslogd_admin"); 

#endif

	if ((filename == (char *) (0)) || (* filename == (char) (0))) 
	{ 
		return; 
	} 
	if ((fp = fopen (filename, "w")) == (FILE *) (0)) 
	{ 
		syslogd_error (errno, "can't open %s", filename); 
		return; 
	} 
	syslogd_enumerate (syslogs, flags, fp); 
	for (syslog = syslogs->next; syslog != syslogs; syslog = syslog->next) 
	{ 
		syslogd_state (syslog, flags, fp); 
	} 
	syslogd_state (syslog, flags, fp); 
	fclose (fp); 

#if SYSLOGD_TRACE

	trace_leave ("syslogd_admin"); 

#endif

	return; 
} 
コード例 #20
0
void syslogd_start (struct syslogd * syslogs, flag_t flags, char const * filename) 

{ 
	extern char const * program_name; 
	char buffer [TEXTLINE_MAX]; 
	size_t lineno = 0; 
	file_t fd; 

#if SYSLOGD_TRACE

	trace_enter ("syslogd_start"); 

#endif

	if ((fd = open (filename, O_RDONLY)) == - 1) 
	{ 
		syslogd_error (errno, "Can't open %s", filename); 
		return; 
	} 
	while (statement (fd, buffer, sizeof (buffer), & lineno)) 
	{ 
		struct syslogd * syslog = NEW (struct syslogd); 
		memset (syslog, 0, sizeof (struct syslogd)); 
		syslog->f_type = SYSLOGD_TYPE_NONE; 
		syslog->f_name = ""; 
		syslog->f_line = lineno; 
		syslog->f_desc = - 1; 
		syslog->f_time = time ((time_t *) (0)); 
		syslogd_parse (syslog, flags, buffer); 
		syslogd_ready (syslog, flags); 
		if (syslog->f_type == SYSLOGD_TYPE_NONE) 
		{ 
			free (syslog->f_name); 
			free (syslog); 
			continue; 
		} 
		syslog->prev = syslogs->prev; 
		syslogs->prev->next = syslog; 
		syslogs->prev = syslog; 
		syslog->next = syslogs; 
		for (syslog = syslogs->next; syslog != syslogs->prev; syslog = syslog->next) 
		{ 
			if (!strcmp (syslog->f_name, syslogs->prev->f_name)) 
			{ 
				syslogd_print (SYSLOG_SYSLOG | SYSLOG_WARNING, "New %s selections on line %d replace old ones on line %d", syslogs->prev->f_name, syslogs->prev->f_line, syslog->f_line); 
				syslog->next->prev = syslog->prev; 
				syslog->prev->next = syslog->next; 
				syslog->prev = (struct syslogd *) (0); 
				syslog->next = (struct syslogd *) (0); 
				free (syslog->f_name); 
				free (syslog); 
				break; 
			} 
		} 
	} 
	close (fd); 
	syslogd_print (SYSLOG_SYSLOG | SYSLOG_NOTICE, "%s %s.%s started", program_name, VERSION, RELEASE); 
	syslogd_print (SYSLOG_SYSLOG | SYSLOG_INFO, "Configured with %s", filename); 

#if SYSLOGD_TRACE

	trace_leave ("syslogd_start"); 

#endif

	return; 
} 
コード例 #21
0
ファイル: type.cpp プロジェクト: Frky/scat
VOID Fini(INT32 code, VOID *v) {
    trace_enter();

    #define append_type(type) \
            if (need_comma) \
                ofile << "," ; \
            ofile << (type); \
            need_comma = true

    for(unsigned int fid = 1; fid <= fn_nb(); fid++) {
        if (nb_call[fid] < NB_CALLS_TO_CONCLUDE)
            continue;

        ofile << fn_img(fid) << ":" << fn_imgaddr(fid)
                << ":" << fn_name(fid)
                << ":";

        bool need_comma = false;

        unsigned int param_val_size = 1 + nb_param_int[fid] + nb_param_int_stack[fid];
        for (unsigned int pid = 0; pid < param_val_size; pid++) {
            if (((float) nb_out[fid][pid]) > 0.75 * ((float) nb_call[fid])) {
                debug("Found 'out parameter' candidate : [%s@%lX] %s %u (%u <=> %u)\n",
                        fn_img(fid).c_str(),
                        fn_imgaddr(fid),
                        fn_name(fid).c_str(),
                        pid,
                        nb_out[fid][pid],
                        nb_call[fid]);
            }

            if (pid == 0 && has_return[fid] == 0) {
                append_type("VOID");
            }
            else if (pid == 0 && has_return[fid] == 2) {
                append_type("FLOAT");
            }
            else if (pid < 1 + nb_param_int[fid] && param_is_not_addr[fid][pid]) {
                append_type("INT");
            }
            else if (param_val[fid][pid]->size() == 0) {
                append_type("UNDEF");
            }
            else {
                int param_addr = 0;
                for (list<UINT64>::iterator it = param_val[fid][pid]->begin(); it != param_val[fid][pid]->end(); it++) {
                    if (is_addr(*it)) {
                        param_addr++;
                    }
                }

                float coef = ((float) param_addr) / ((float) param_val[fid][pid]->size());
                append_type(coef > THRESHOLD ? "ADDR" : "INT");

                ofile << "(" << coef << ")";
            }
        }

        for (unsigned int pid = 0;
                pid < nb_param_float[fid] + nb_param_float_stack[fid];
                pid++) {
            append_type("FLOAT");
        }

        ofile << endl;
    }

    ofile.close();

    trace_leave();
}
コード例 #22
0
ファイル: memcollect.cpp プロジェクト: chubbymaggie/scat
VOID Fini(INT32 code, VOID *v) {

    trace_enter();

    list<param_t *>::reverse_iterator it_in, it_out;
    it_in = param_in->rbegin();
    it_out = param_out->rbegin();

    int depth = 0;
    UINT64 last_date = -1;
    bool is_in = false;

    gettimeofday(&stop, NULL);

    ofile << "Elapsed time ] Commence ; Fini [ : " << (stop.tv_usec / 1000.0 + 1000 * stop.tv_sec - start.tv_sec * 1000 - start.tv_usec / 1000.0) / 1000.0 << "s" << endl;

    while (it_in != param_in->rend() || it_out != param_out->rend()) {
        param_t *p;
        if (it_in == param_in->rend()) {
            p = *it_out;
            it_out++;
            is_in = false;
        } else if (it_out == param_out->rend() || (*it_out)->counter >= (*it_in)->counter) {
            p = *it_in;
            it_in++;
            is_in = true;
        } else {
            p = *it_out;
            it_out++;
            is_in = false;
        }
#if 0
        if (p->is_addr)
            ofile << "a:";
        else 
            ofile << "n:";
#endif
        if (last_date != p->counter) {
            if (is_in)
                depth++;
            else
                depth--;
        }
        last_date = p->counter;
        char head = 0x00;
        /* Construct the first byte */
        /* First two bits are for i/o  and addr/not addr */
        head |= 0x80 & ((is_in?1:0) << 7);
        head |= 0x40 & ((p->is_addr?1:0) << 6);
        /* Then we encode the position of the parameter */
        head |= 0x3F & p->pos;
        if (!pushed_in_log[p->fid]) {
            ofile << '\xff' << p->fid << ":" <<  fn_img(p->fid) << ":" << fn_imgaddr(p->fid) << ":" << fn_name(p->fid) << endl;
            pushed_in_log[p->fid] = true;
        }
        ofile << head;
        ofile << p->fid << ":" << p->counter << ":" << p->val << endl;
#if 0
        ofile << p->val << ":" << fn_img(p->fid) << ":" << fn_imgaddr(p->fid) << ":" << fn_name(p->fid) << ":" << p->pos << ":" << p->counter << endl;
#endif
    }
    ofile.close();

    trace_leave();

    return;
}