Example #1
0
int rdis_remove_function (struct _rdis * rdis, uint64_t address)
{
    map_remove(rdis->functions, address);
    map_remove(rdis->labels, address);

    struct _graph * family = graph_family(rdis->graph, address);
    if (family == NULL)
        return -1;

    struct _graph_it * it;

    for (it = graph_iterator(family); it != NULL; it = graph_it_next(it)) {
        struct _graph_node * node = graph_it_node(it);

        printf("rdis_remove_function %p %p %p %llx\n",
               node,
               node->data,
               node->edges,
               (unsigned long long) node->index);

        graph_remove_node(rdis->graph, node->index);
    }

    object_delete(family);

    rdis_callback(rdis, RDIS_CALLBACK_GRAPH
                        | RDIS_CALLBACK_FUNCTION
                        | RDIS_CALLBACK_LABEL);

    return 0;
}
Example #2
0
// Free self, regardless of reference count.
void
graph_free (Graph *self)
{
  // Remove all the edges.
  gint ii;
  for ( ii = 0 ; ii < self->edges->len ; ii++ ) {
    graph_remove_edge (self, g_ptr_array_index (self->edges, ii));
  }

  // Remove all the nodes.
  for ( ii = 0 ; ii < self->nodes->len ; ii++ ) {
    graph_remove_node (self, g_ptr_array_index (self->nodes, ii));
  }

  g_free (self);
}
Example #3
0
int rdis_update_memory (struct _rdis *   rdis,
                        uint64_t         address,
                        struct _buffer * buffer)
{
    if (buffer == NULL)
        return -1;

    mem_map_set (rdis->memory, address, buffer);

    // we will regraph functions whose bounds fall within this updated memory,
    // and all functions whose bounds fall within the bounds of functions to be
    // regraphed (step 2 simplifies things later on)
    struct _queue * queue = queue_create();
    struct _map_it * it;
    for (it = map_iterator(rdis->functions); it != NULL; it = map_it_next(it)) {
        struct _function * function = map_it_data(it);
        if (    (    (function->bounds.lower >= address)
                  && (function->bounds.lower <  address + buffer->size))
             || (    (function->bounds.upper >= address)
                  && (function->bounds.upper <  address + buffer->size))
             || (    (function->bounds.lower <= address)
                  && (function->bounds.upper >= address + buffer->size))) {
            queue_push(queue, function);
        }
    }

    struct _map * regraph_functions = map_create();
    while (queue->size > 0) {
        struct _function * function = queue_peek(queue);

        if (map_fetch(regraph_functions, function->address) != NULL) {
            queue_pop(queue);
            continue;
        }

        printf("adding regraph function %llx\n",
               (unsigned long long) function->address);

        map_insert(regraph_functions, function->address, function);

        for (it = map_iterator(rdis->functions); it != NULL; it = map_it_next(it)) {
            struct _function * cmp_function = map_it_data(it);

            if (    (    (cmp_function->bounds.lower >= function->bounds.lower)
                      && (cmp_function->bounds.lower <  function->bounds.upper))
                 || (    (cmp_function->bounds.upper >= function->bounds.lower)
                      && (cmp_function->bounds.upper <  function->bounds.upper))
                 || (    (cmp_function->bounds.lower <= function->bounds.lower)
                      && (cmp_function->bounds.upper >= function->bounds.upper)))
                queue_push(queue, cmp_function);
        }
    }

    // regraph dem functions
    struct _graph * new_graph;
    new_graph = loader_graph_functions(rdis->loader,
                                       rdis->memory,
                                       regraph_functions);

    // We are now going to go through all nodes in our regraph functions. We
    // will copy over comments to the new instructions and then remove the
    // regraph function nodes from the original graph
    for (it = map_iterator(regraph_functions); it != NULL; it = map_it_next(it)) {
        struct _function * function = map_it_data(it);
        struct _graph    * family   = graph_family(rdis->graph, function->address);
        if (family == NULL)
            continue;

        struct _graph_it * git;
        for (git  = graph_iterator(family);
             git != NULL;
             git  = graph_it_next(git)) {
            struct _list * ins_list = graph_it_data(git);
            struct _list_it * iit;
            for (iit = list_iterator(ins_list); iit != NULL; iit = iit->next) {
                struct _ins * ins = iit->data;

                if (ins->comment == NULL)
                    continue;

                struct _ins * new_ins = graph_fetch_ins(new_graph, ins->address);

                if (ins->size != new_ins->size)
                    continue;

                if (memcmp(ins->bytes, new_ins->bytes, ins->size) == 0) {
                    printf("copy over comment from instruction at %llx\n",
                           (unsigned long long) ins->address);
                    ins_s_comment(new_ins, ins->comment);
                }
            }
            // add node for deletion
            struct _index * index = index_create(graph_it_index(git));
            queue_push(queue, index);
            object_delete(index);
        }

        object_delete(family);

        while (queue->size > 0) {
            struct _index * index = queue_peek(queue);
            graph_remove_node(rdis->graph, index->index);
            queue_pop(queue);
        }
    }

    // merge the new graph with the old graph
    graph_merge(rdis->graph, new_graph);

    // reset bounds of these functions
    for (it = map_iterator(regraph_functions); it != NULL; it = map_it_next(it)) {
        struct _function * function = map_it_data(it);
        rdis_function_bounds(rdis, function->address);
    }

    objects_delete(queue, new_graph, regraph_functions, NULL);

    rdis_callback(rdis, RDIS_CALLBACK_ALL);

    return 0;
}
Example #4
0
File: ui.c Project: imgflo/imgflo
static void
handle_graph_message(UiConnection *self, const gchar *command, JsonObject *payload,
                SoupWebsocketConnection *ws)
{
    g_return_if_fail(payload);

    Graph *graph = NULL;
    if (g_strcmp0(command, "clear") != 0) {
        // All other commands must have graph
        // TODO: change FBP protocol to use 'graph' instead of 'id'?
        const gchar *graph_id = json_object_get_string_member(payload, "graph");
        Network *net = (graph_id) ? g_hash_table_lookup(self->network_map, graph_id) : NULL;
        graph = (net) ? net->graph : NULL;
        g_return_if_fail(graph);
    }

    if (g_strcmp0(command, "clear") == 0) {
        const gchar *graph_id = json_object_get_string_member(payload, "id");
        Graph *graph = graph_new(graph_id, self->component_lib);

        Network *network = network_new(graph);
        ui_connection_add_network(self, graph_id, network);
    } else if (g_strcmp0(command, "addnode") == 0) {
        graph_add_node(graph,
            json_object_get_string_member(payload, "id"),
            json_object_get_string_member(payload, "component")
        );
    } else if (g_strcmp0(command, "removenode") == 0) {
        graph_remove_node(graph,
            json_object_get_string_member(payload, "id")
        );
    } else if (g_strcmp0(command, "changenode") == 0) {
        // Just metadata, ignored
    } else if (g_strcmp0(command, "addinitial") == 0) {
        JsonObject *tgt = json_object_get_object_member(payload, "tgt");
        JsonObject *src = json_object_get_object_member(payload, "src");
        GValue data = G_VALUE_INIT;
        json_node_get_value(json_object_get_member(src, "data"), &data);
        graph_add_iip(graph,
            json_object_get_string_member(tgt, "node"),
            json_object_get_string_member(tgt, "port"),
            &data
        );
        g_value_unset(&data);
    } else if (g_strcmp0(command, "removeinitial") == 0) {
        JsonObject *tgt = json_object_get_object_member(payload, "tgt");
        graph_remove_iip(graph,
            json_object_get_string_member(tgt, "node"),
            json_object_get_string_member(tgt, "port")
        );
    } else if (g_strcmp0(command, "addedge") == 0) {
        JsonObject *src = json_object_get_object_member(payload, "src");
        JsonObject *tgt = json_object_get_object_member(payload, "tgt");
        graph_add_edge(graph,
            json_object_get_string_member(src, "node"),
            json_object_get_string_member(src, "port"),
            json_object_get_string_member(tgt, "node"),
            json_object_get_string_member(tgt, "port")
        );
    } else if (g_strcmp0(command, "removeedge") == 0) {
        JsonObject *src = json_object_get_object_member(payload, "src");
        JsonObject *tgt = json_object_get_object_member(payload, "tgt");
        graph_remove_edge(graph,
            json_object_get_string_member(src, "node"),
            json_object_get_string_member(src, "port"),
            json_object_get_string_member(tgt, "node"),
            json_object_get_string_member(tgt, "port")
        );
    } else if (g_strcmp0(command, "changeedge") == 0) {
        // Just metadata, ignored
    } else {
        imgflo_warning("Unhandled message on protocol 'graph', command='%s'", command);
    }
}