// if oldtree is not NULL, will continue adding to the oldtree. This has the
// advantage of improving the finding the correct sizes of functions called from
// previous calls of analyze_find_functions
_aatree * analyze_find_functions (unsigned char * data, int data_size,
                                  int mode, uint_t * address, _aatree * old_tree)
{
    int_t offset;
    int bytes_disassembled = 0;
    int_t tmp_address_signed;
    int_t base_address_signed;
    uint_t last_address_end;
    ud_t ud_obj;
    struct _analyze_function analyze_function;
    _aatree * tree;

    if (old_tree == NULL)
        tree = aatree_create(analyze_function_cmp, sizeof(analyze_function));
    else
        tree = old_tree;
    
    // find the start of all functions
    ud_init(&ud_obj);
    ud_set_mode(&ud_obj, mode);
    
    ud_set_input_buffer(&ud_obj, data, data_size);
    
    int_t_uint_t(&base_address_signed, address);
    
    while (ud_disassemble(&ud_obj))
    {
        bytes_disassembled += ud_insn_len(&ud_obj);
        if (    (ud_obj.mnemonic == UD_Icall)
             && (ud_obj.operand[0].type == UD_OP_JIMM)) {
            switch (ud_obj.operand[0].size) {
            case 32 :
                int_t_32_set(&offset, ud_obj.operand[0].lval.udword);
                break;
            case 64 :
                int_t_64_set(&offset, ud_obj.operand[0].lval.uqword);
                break;
            }
            int_t_set(&tmp_address_signed, &base_address_signed);
            int_t_add(&tmp_address_signed, &offset);
            int_t_add_int(&tmp_address_signed, bytes_disassembled);
            uint_t_int_t(&(analyze_function.address), &tmp_address_signed);
            analyze_function.size =  -1;
            aatree_insert(tree, &analyze_function);
        }
    }

    uint_t_set(&last_address_end, address);
    uint_t_add_int(&last_address_end, data_size);
    tree = analyze_find_functions_sizes(tree, &last_address_end);

    return tree;
}
// last address is the address of the right past the end of the last function
// leave it NULL if you don't want to leave size of last function as it is
_aatree * analyze_find_functions_sizes (_aatree * tree, uint_t * last_address_end)
{
    struct _analyze_function * last;
    struct _analyze_function * next;
    _list * list;
    _list_iterator it;
    uint_t tmp;

    // we assume a function ends where the next function begins
    // this is much simpler if we convert our tree to a list first and then reinsert into the tree
    list = list_copy_aatree(tree);
    aatree_destroy(tree);
    tree = aatree_create(analyze_function_cmp, sizeof(struct _analyze_function));
    
    list_iterator(list, &it);
    last = (struct _analyze_function *) list_next(&it);
    if (last != NULL) {
        while ((next = (struct _analyze_function *) list_next(&it)) != NULL) {
            uint_t_set(&tmp, &(next->address));
            uint_t_sub(&tmp, &(last->address));
            last->size = uint_t_get(&tmp);
            aatree_insert(tree, last);
            last = next;
        }
        if (last_address_end != NULL) {
            if (last->size < 0 ) {
                uint_t_set(&tmp, last_address_end);
                uint_t_sub(&tmp, &(last->address));
                last->size = uint_t_get(&tmp);
            }
        }
        aatree_insert(tree, last);
    }

    list_destroy(list);

    return tree;
}
Example #3
0
static void mg_join(struct mg_connection* conn, const struct mg_request_info* ri) {
	if(strcmp(ri->request_method, "GET") == 0) {
		uint new_id = rand_uint();

		if(!aatree_insert(&clients, new_id, (void*)1))
			goto error;

		mg_printf(conn, "%s", standard_reply);
		mg_printf(conn, "%u\n", new_id);

		// Invoke join_cb
		_invoke("join_cb", new_id, NULL);

		return;
	}
	
error:
	mg_error(conn, ri);
}
Example #4
0
game_object_t *
game_object_create(char *name, void *data)
{
    game_object_t *obj = malloc(sizeof(*obj));
    obj->id = global_id_counter++;
    obj->name = lapis_hash(name);
    obj->render_level = 0;
    obj->data = data;
    obj->image = NULL;
    obj->screenx = 0;
    obj->screeny = 0;
    obj->update_callback.type = NONE;
    obj->render_callback.type = NONE;
    obj->recv_callback = NULL;
    obj->messages = NULL;
    obj->messages_len = 0;
    obj->messages_cap = 0;

    /* cache object */
    aatree_node_t *obj_node = aatree_create(lapis_hash(name), obj, 0);
    object_root = aatree_insert(object_root, obj_node);

    return obj;
}