static void request_game_list(const char *s) { game_t *g; struct iterator it = list_iterator(&public_games); while ((g = iterator_next(&it))) { g->active = FALSE; } struct timespec ts; clock_gettime(CLOCK_REALTIME, &ts); ts.tv_sec += 2; pthread_mutex_lock(&pub_m); mcp_send(0x05, "%w 00 00 00 00 %s 00", request_id, s); request_id++; pthread_cond_timedwait(&pub_cv, &pub_m, &ts); it = list_iterator(&public_games); while ((g = iterator_next(&it))) { if (!g->active) { iterator_remove(&it); plugin_debug("mcp game", "removing inactive game\n"); } } dump_game_list(&public_games); pthread_mutex_unlock(&pub_m); }
void rdis_check_references (struct _rdis * rdis) { struct _graph_it * git; // for each node for (git = graph_iterator(rdis->graph); git != NULL; git = graph_it_next(git)) { struct _graph_node * node = graph_it_node(git); struct _list_it * lit; // for each instruction for (lit = list_iterator(node->data); lit != NULL; lit = lit->next) { struct _ins * ins = lit->data; struct _list_it * rit; // for each reference for (rit = list_iterator(ins->references); rit != NULL; rit = rit->next) { struct _reference * reference = rit->data; if (reference->type == REFERENCE_CONSTANT) { uint64_t lower = map_fetch_max_key(rdis->memory, reference->address); struct _buffer * buffer = map_fetch(rdis->memory, lower); if (buffer == NULL) continue; uint64_t upper = lower + buffer->size; if ( (reference->address < lower) || (reference->address >= upper)) continue; reference->type = REFERENCE_CONSTANT_ADDRESSABLE; } } } } }
int main() { int a = 5; int b = 10; int c = 20; List* list = list_create(); Iterator* iterator = list_iterator(list); assert(false == iterator_has_next(iterator)); iterator_destroy(iterator); list_push(list, &a); list_push(list, &b); list_push(list, &c); iterator = list_iterator(list); assert(true == iterator_has_next(iterator)); assert(&a == iterator_next(iterator)); assert(&b == iterator_next(iterator)); assert(&c == iterator_next(iterator)); assert(false == iterator_has_next(iterator)); iterator_destroy(iterator); return 0; }
static void DefTransitions(struct net_object *netobj, struct net_object *unf_netobj) { struct trans_object *trans_el, *trans, *prev_trans; struct group_object *pri_group, *unf_new_group, *prev_group; list l, curr; int i; /* Immediate transition */ for( pri_group = netobj->groups; pri_group != NULL; pri_group = pri_group->next) { // Create new group unf_new_group = (struct group_object *) Emalloc(sizeof(struct group_object)); unf_new_group->tag = Estrdup(pri_group->tag); unf_new_group->pri = pri_group->pri; unf_new_group->trans = NULL; unf_new_group->center.x = pri_group->center.x; unf_new_group->center.y = pri_group->center.y; unf_new_group->movelink = NULL; unf_new_group->next = unf_netobj->groups; i=0; for( trans_el = pri_group->trans; trans_el != NULL; trans_el = trans_el->next) { l = expandtransition(trans_el, netobj, unf_netobj); curr =NULL; while ( (curr = list_iterator(l, curr)) != NULL ){ trans = (struct trans_object *) DATA(curr); trans->next = unf_new_group->trans; unf_new_group->trans = trans; } } destroy(&l, NULL); unf_netobj->groups = unf_new_group; } /* Exponential and Deterministic Transition */ i = 0; for( trans_el = netobj->trans; trans_el != NULL; trans_el = trans_el->next) { l = expandtransition(trans_el, netobj, unf_netobj); curr = NULL; while ( (curr = list_iterator(l, curr)) != NULL ){ trans = (struct trans_object *) DATA(curr); trans->next = unf_netobj->trans; unf_netobj->trans = trans; } destroy(&l, NULL); } }
struct _map * rdis_g_references (struct _rdis * rdis) { struct _map * references = map_create(); struct _graph_it * git; // for each node for (git = graph_iterator(rdis->graph); git != NULL; git = graph_it_next(git)) { struct _graph_node * node = graph_it_node(git); struct _list_it * lit; // for each instruction for (lit = list_iterator(node->data); lit != NULL; lit = lit->next) { struct _ins * ins = lit->data; struct _list_it * rit; // for each reference for (rit = list_iterator(ins->references); rit != NULL; rit = rit->next) { struct _reference * reference = rit->data; int delete_reference = 0; if (reference->type == REFERENCE_CONSTANT) { uint64_t lower = map_fetch_max_key(rdis->memory, reference->address); struct _buffer * buffer = map_fetch(rdis->memory, lower); if (buffer == NULL) continue; uint64_t upper = lower + buffer->size; if ( (reference->address < lower) || (reference->address >= upper)) continue; reference = object_copy(reference); reference->type = REFERENCE_CONSTANT_ADDRESSABLE; delete_reference = 1; } struct _list * ref_list = map_fetch(references, reference->address); if (ref_list == NULL) { ref_list = list_create(); map_insert(references, reference->address, ref_list); object_delete(ref_list); ref_list = map_fetch(references, reference->address); } list_append(ref_list, reference); if (delete_reference) object_delete(reference); } } } return references; }
DefMarking(struct net_object *netobj, struct net_object *unf_netobj) { struct place_object *place; list curr = NULL; markPTR m; multisetPTR p_MS; int i; char *tag; while ( (curr = list_iterator(gListMarking, curr)) != NULL ){ m = DATA(curr); if(m->type==0){ evalMarking(m, &p_MS); for(i=0; i<CARD(p_MS) ; i++) if( VALUE(SET(p_MS)[i])>0 ){ tag = NewStringCat(m->place->tag, STR_INDEX(SET(p_MS)[i])); for(place = unf_netobj->places; place!=NULL && (strcmp(place->tag, tag)!=0) ; place = place->next); if(place == NULL) Error(UNKN_PLACE_ERR, "DefMarking", tag); else place->m0 = VALUE(SET(p_MS)[i]); } } else{ tag = NewStringCat(m->place->tag, "_"); for(place = unf_netobj->places; place!=NULL && (strcmp(place->tag, tag)!=0) ; place = place->next); if(place == NULL) Error(UNKN_PLACE_ERR, "DefMarking", tag); else place->mpar = m->mrk; } } }
/* ==================================================================== Functions to access a PData tree. 'name' is the pass within tree 'pd' where subtrees are separated by '/' (e.g.: name = 'config/graphics/animations') parser_get_pdata : get pdata entry associated with 'name' parser_get_entries : get list of subtrees (PData structs) in 'name' parser_get_values : get value list of 'name' parser_get_value : get a single value from value list of 'name' parser_get_int : get first value of 'name' converted to integer parser_get_double : get first value of 'name' converted to double parser_get_string : get first value of 'name' _duplicated_ If an error occurs result is set NULL, False is returned and parse_error is set. ==================================================================== */ int parser_get_pdata ( PData *pd, const char *name, PData **result ) { int i, found; PData *pd_next = pd; PData *entry = 0; char *sub = 0; List *path = parser_explode_string( name, '/' ); for ( i = 0, list_reset( path ); i < path->count; i++ ) { ListIterator it; sub = list_next( path ); if ( !pd_next->entries ) { sprintf( parser_sub_error, tr("%s: no subtrees"), pd_next->name ); goto failure; } it = list_iterator( pd_next->entries ); found = 0; while ( ( entry = list_iterator_next( &it ) ) ) if ( strlen( entry->name ) == strlen( sub ) && !strncmp( entry->name, sub, strlen( sub ) ) ) { pd_next = entry; found = 1; break; } if ( !found ) { sprintf( parser_sub_error, tr("%s: subtree '%s' not found"), pd_next->name, sub ); goto failure; } } list_delete( path ); *result = pd_next; return 1; failure: sprintf( parser_error, "parser_get_pdata: %s/%s: %s", pd->name, name, parser_sub_error ); list_delete( path ); *result = 0; return 0; }
extern status add_poly( polynomial *p_poly1, polynomial *p_poly2 ) { /* Polynomial p_poly1 += p_poly2, p_poly2 = 0 */ list lastreturn = NULL, match_node ; term *p_term, *p_match_term ; int coef, degree ; while( ( lastreturn = list_iterator( *p_poly1, lastreturn ) ) != NULL ) { p_term = ( term * ) DATA( lastreturn ) ; if( find_key( *p_poly2, (generic_ptr )p_term, cmp_degree, &match_node ) == OK ) { p_match_term = ( term * ) DATA( match_node ) ; p_term -> coefficient += p_match_term -> coefficient ; delete_node( p_poly2, match_node ) ; free( p_match_term ) ; } } while( empty_list( *p_poly2 ) == FALSE ) { if( term_delete( p_poly2, &coef, °ree ) == ERROR ) return ERROR ; else if( term_insert( p_poly1, coef, degree ) == ERROR ) return ERROR ; } return OK ; }
int rdis_function_reachable (struct _rdis * rdis, uint64_t address) { struct _function * function = map_fetch(rdis->functions, address); if (function == NULL) return -1; function->flags |= FUNCTION_REACHABLE; // get this function's call graph struct _graph * cg = create_call_graph(rdis->graph, address); struct _graph_it * git; // for each function in the graph for (git = graph_iterator(cg); git != NULL; git = graph_it_next(git)) { struct _list * ins_list = graph_it_data(git); struct _list_it * lit; // for each call in the function in the graph for (lit = list_iterator(ins_list); lit != NULL; lit = lit->next) { struct _ins * ins = lit->data; // insure function has correct flags if ( (ins->flags & (INS_TARGET_SET | INS_CALL)) == (INS_TARGET_SET | INS_CALL)) { function = map_fetch(rdis->functions, ins->target); if (function == NULL) continue; function->flags |= FUNCTION_REACHABLE; } } } return 0; }
void l_eval(const char *source, const char *source_file, LClosure *closure) { LAst ast = l_parse(source, source_file); list_iter_p iter = list_iterator(ast, FRONT); while(list_next(iter) != NULL) { l_eval_node((LNode*)list_current(iter), closure); } }
_export void module_cleanup() { struct iterator it = list_iterator(&items); item_t *i; while ((i = iterator_next(&it))) { if (!is_blocked(i)) { logitem("failed to pick "); if (i->amount > 1) logitem("%i ", i->amount); if (i->ethereal) logitem("ethereal "); if (i->quality != 0x00) logitem("%s ", qualities[i->quality]); logitem("%s", lookup_item(i)); if (i->quality != 0x00) logitem(" (%i)", i->level); if (i->sockets > 0) logitem(" [%i]", i->sockets); if (setting("Debug")->b_var) logitem(" distance: %i", i->distance); // test pickit logitem("\n"); } } list_clear(&items); gold = 0; routine_scheduled = FALSE; }
void write_param(param_p p, FILE* f) { list_iter_p iter; desc_p d; if(p == NULL || f == NULL) return; fprintf(f, "%s%s", BEGIN_TABULAR_ROW, BEGIN_TABULAR_CELL); switch(p->type) { case FLOAT: fprintf(f, "float\n"); break; case ENTITY: fprintf(f, "entity\n"); break; case VECTOR: fprintf(f, "vector\n"); break; default: fprintf(stderr, "write_param - Uknown param type %d\n", p->type); exit(EXIT_FAILURE); } fprintf(f, "%s%s", END_TABULAR_CELL, BEGIN_TABULAR_CELL); fprintf(f, "%s\n", p->name); fprintf(f, "%s%s", END_TABULAR_CELL, BEGIN_TABULAR_CELL); iter = list_iterator(p->desc, FRONT); for(d = list_next(iter); d != NULL; d = list_next(iter)) { fprintf(f, "%s", d->desc); } fprintf(f, "%s%s%s", END_TABULAR_CELL, END_TABULAR_ROW, END_TABULAR); }
int plugin_load(char *name) { char filename[256]; struct sa_plugin_t * (*plugin_register)(void); int (*plugin_load)(); struct sa_plugin_t *plugin; char *error; debug_printf("Loading plugin %s\n", name); // Fill in name in list element strcpy(plugin_item.name, name); // Check that plugin is not already loaded list_iter_p iter = list_iterator(plugin_list, FRONT); while (list_next(iter) != NULL) { plugin_item_p = (struct plugin_item_t *)list_current(iter); if (strcmp(plugin_item_p->name, name) == 0) { printf("Error: Plugin already loaded!\n"); return -1; } } // Add plugin location sprintf(filename, "sensact-%s.so", name); // Open plugin plugin_item.handle = dlopen(filename, RTLD_LAZY); if (!plugin_item.handle) { fprintf(stderr, "%s\n", dlerror()); return -1; } else { // Add plugin to list of loaded plugins list_add(plugin_list, &plugin_item, sizeof(plugin_item)); // Call plugin_register() plugin_register = dlsym(plugin_item.handle, "plugin_register"); if ((error = dlerror()) != NULL) fprintf(stderr, "%s\n", error); plugin = (*plugin_register)(); // Print plugin information plugin_print_info(plugin, name); // Call plugin load callback (if defined) if (plugin->load != NULL) { plugin_load = plugin->load; (*plugin_load)(); } } return 0; }
/** * This sets the registered service list to the daemon. * * @param service_list - the list of services. */ i2c_daemon::i2c_daemon(list_p service_list){ //! Init the service list pointer this->_service_list = service_list; //! Create a list iterator this->_iterator = list_iterator(service_list, FRONT); }
int plugin_unload(char *name) { struct sa_plugin_t * (*plugin_register)(void); int (*plugin_unload)(void); struct sa_plugin_t *plugin; char *error; bool found = false; debug_printf("Unloading plugin %s\n", name); // Check that the plugin is loaded list_iter_p iter = list_iterator(plugin_list, FRONT); while (list_next(iter) != NULL) { plugin_item_p = (struct plugin_item_t *)list_current(iter); if (strcmp(plugin_item_p->name, name) == 0) { found = true; break; } } if (!found) { printf("Error: Plugin not found!\n"); return -1; } // Call plugin_register() plugin_register = dlsym(plugin_item_p->handle, "plugin_register"); if ((error = dlerror()) != NULL) { fprintf(stderr, "%s\n", error); return -1; } plugin = (*plugin_register)(); // Call plugin unload callback (if defined) if (plugin->unload != NULL) { plugin_unload = plugin->unload; (*plugin_unload)(); } // Unload plugin if (dlclose(plugin_item_p->handle)) { fprintf(stderr, "%s\n", error); return -1; } // Remove plugin from list of loaded plugins list_pluck(plugin_list, iter->current); return 0; }
game_t * get_new_public_game() { game_t *g; struct iterator it = list_iterator(&public_games); while ((g = iterator_next(&it))) { if (!g->joined) return g; } return NULL; }
int ins_is_call (const struct _ins * ins) { struct _list_it * lit; for (lit = list_iterator(ins->successors); lit != NULL; lit = lit->next) { struct _ins_value * successor = lit->data; if (successor->type == INS_SUC_CALL) return 1; } return 0; }
bool is_blocked(item_t *i) { struct iterator it = list_iterator(&nolog); char *j; while ((j = iterator_next(&it))) { if (!strcmp(j, i->code)) { return TRUE; } } return FALSE; }
void write_params(list_p p, FILE* f) { list_iter_p iter; param_p d; if(p == NULL || f == NULL) return; fprintf(f, "%s", BEGIN_TABULAR); iter = list_iterator(p); for(d = list_next(iter); d != NULL; d = list_next(iter)) { write_param(d, f); } fprintf(f, "%s", END_TABULAR); }
/** * Function for completely destroying an item in the list at a given index. * * \param list pointer to a list * \param idx index of the element to remove */ static void list_remove_at(list_p list, int idx) { container_p cont; list_iter_p iter; lnode_p target = NULL; int i; if(idx < 0 || idx >= list->length || list->length == 0) { return; } iter = list_iterator(list, LIST_FRONT); for(cont = list_next(iter), i = 0; cont != NULL; cont = list_next(iter), i++) { if(i == idx) { target = iter->current; break; } } destroy_iterator(iter); if(target == NULL) { return; } if(list->length == 1) { list->first = list->last = NULL; list->length--; free(target); } else { target->prev->next = target->next; target->next->prev = target->prev; if(target == list->first) { list->first = target->next; } if(target == list->last) { list->last = target->prev; } list->length--; free(target); } if(cont != NULL) { if(cont->pointer == 0 && cont->data != NULL) { list->destructor(cont->data); } free(cont); } }
static void dump_game_list(struct list *l) { ui_console_lock(); plugin_print("mcp game", "public games available (%i):\n\n", list_size(&public_games)); game_t *g; struct iterator it = list_iterator(l); while ((g = iterator_next(&it))) { print("%s%s (%i player%s)%s%s\n", g->joined ? "* " : "", g->name, g->players, g->players != 1 ? "s" : "", strlen(g->desc) ? ": " : "", strlen(g->desc) ? g->desc : ""); } if (list_empty(l)) print("(none)\n"); print("\n"); ui_console_unlock(); }
_export bool module_finit() { unregister_packet_handler(MCP_RECEIVED, 0x07, mcp_charlogon_handler); unregister_packet_handler(MCP_RECEIVED, 0x03, mcp_creategame_handler); unregister_packet_handler(MCP_RECEIVED, 0x04, mcp_joingame_handler); unregister_packet_handler(INTERNAL, D2GS_ENGINE_MESSAGE, on_d2gs_shutdown); unregister_packet_handler(INTERNAL, MCP_ENGINE_MESSAGE, on_mcp_cleanup); unregister_packet_handler(MCP_RECEIVED, 0x05, mcp_gamelist_handler); struct iterator it = list_iterator(&setting_cleaners); setting_cleanup_t *sc; while ((sc = iterator_next(&it))) { sc->cleanup(sc->set); } list_clear(&setting_cleaners); if (keyset) { free(keyset); keyset = NULL; n_keyset = 0; i_keyset = 0; rotated = FALSE; } pthread_cond_destroy(&game_created_cond_v); pthread_cond_destroy(&game_joined_cond_v); pthread_cond_destroy(&mcp_char_logon_cond_v); pthread_cond_destroy(&d2gs_engine_shutdown_cond_v); pthread_mutex_destroy(&game_created_mutex); pthread_mutex_destroy(&game_joined_mutex); pthread_mutex_destroy(&mcp_char_logon_mutex); pthread_mutex_destroy(&d2gs_engine_shutdown_mutex); pthread_mutex_destroy(&mcp_cleanup_m); pthread_cond_destroy(&mcp_cleanup_cv); pthread_mutex_destroy(&pub_m); pthread_cond_destroy(&pub_cv); list_clear(&public_games); ui_add_statistics_plugin("mcp game", "games created: %i\n", n_created); if (module_setting("JoinPublicGames")->b_var) ui_add_statistics_plugin("mcp game", "public games joined: %i\n", n_joined); ui_add_statistics_plugin("mcp game", "failed to join: %i (%i%%)\n", ftj, PERCENT(n_created, ftj)); return TRUE; }
void ui_printShelves(product_t *p) { list_iterator_t *it = list_iterator(product_getShelvesList(p)); if(it != NULL) { puts("Shelf locations:"); while(list_more(it)) { shelf_t *shelf = (shelf_t *)list_next(it); printf(" %c%d\tAvailable: %d\n", storage_getShelfSection(shelf), storage_getShelfNumber(shelf), storage_getShelfCount(shelf)); } list_freeIterator(it); } }
_export void * module_thread(void *arg) { bool hit = FALSE; char s_addr[INET_ADDRSTRLEN]; inet_ntop(AF_INET, &cur_addr, s_addr, INET_ADDRSTRLEN); char *addr = strrchr(s_addr, '.'); plugin_print("dclone", "hit game server %s\n", addr); struct iterator it = list_iterator(&hot_addrs); hot_addr *hot; while ((hot = iterator_next(&it))) { if (!strcmp(addr, hot->s_addr)) { hit = TRUE; hits++; hot->hits++; } } if (hit) { plugin_print("dclone", "found hot address - idling\n"); // sing the pina colada song in order to keep the game open // actually I'm not sure if it's enough to keep the game from closing while (!relieved && !d2gs_cleanup) { int i; for (i = 0; i < (sizeof(pina_colada_song) / sizeof(char *)) && !d2gs_cleanup && !relieved; i++) { d2gs_send(0x14, "00 00 %s 00 00 00", pina_colada_song[i]); thread_idle(2); } } } else { plugin_print("dclone", "sleeping for %i seconds\n", module_setting("GameIdleTime")->i_var); thread_idle(module_setting("GameIdleTime")->i_var); } plugin_print("dclone", "leaving game\n"); d2gs_send(0x69, ""); pthread_exit(NULL); }
/** * Get the element at the given index. * * \param list a list * \param idx index * \return element at given index or NULL if index is out of bounds */ static container_p list_at(list_p list, int idx) { list_iter_p iter; container_p c = NULL; int i; if(idx < 0 || idx >= list->length || list == NULL) { return NULL; } iter = list_iterator(list, LIST_FRONT); for(c = list_next(iter), i = 0; c != NULL; c = list_next(iter), i++) { if(i == idx) { break; } } return c; }
// 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; }
struct _map * elf32_functions_wqueue (struct _elf32 * elf32, struct _map * memory, struct _list * entries) { struct _map * functions = map_create(); struct _wqueue * wqueue = wqueue_create(); struct _list_it * it; for (it = list_iterator(entries); it != NULL; it = it->next) { struct _function * function = it->data; if (map_fetch(functions, function->address) == NULL) map_insert(functions, function->address, function); struct _x86_wqueue * x86w; x86w = x86_wqueue_create(function->address, memory); wqueue_push(wqueue, WQUEUE_CALLBACK(x86_functions_wqueue), x86w); object_delete(x86w); } wqueue_wait(wqueue); struct _map * fmap; while ((fmap = wqueue_peek(wqueue)) != NULL) { struct _map_it * mit; for (mit = map_iterator(fmap); mit != NULL; mit = map_it_next(mit)) { struct _function * function = map_it_data(mit); if (map_fetch(functions, function->address) == NULL) map_insert(functions, function->address, function); } wqueue_pop(wqueue); } object_delete(wqueue); return functions; }
_export bool module_finit() { unregister_packet_handler(MCP_RECEIVED, 0x04, on_mcp_join_game); unregister_packet_handler(INTERNAL, D2GS_ENGINE_MESSAGE, on_d2gs_cleanup); unregister_packet_handler(D2GS_RECEIVED, 0x26, on_d2gs_chat); pthread_mutex_destroy(&d2gs_cleanup_m); pthread_cond_destroy(&d2gs_cleanup_cv); ui_add_statistics_plugin("dclone", "found %i hot IPs (", hits); struct iterator it = list_iterator(&hot_addrs); hot_addr *hot; int i = 0; while ((hot = iterator_next(&it))) { if (i++) ui_add_statistics(" "); ui_add_statistics("%s: %i", hot->s_addr, hot->hits); free(hot->s_addr); } ui_add_statistics(")\n"); list_clear(&hot_addrs); return TRUE; }
int rdis_function_bounds (struct _rdis * rdis, uint64_t address) { struct _function * function = map_fetch(rdis->functions, address); if (function == NULL) return -1; struct _graph * family = graph_family(rdis->graph, address); if (family == NULL) return -1; uint64_t lower = -1; uint64_t upper = 0; struct _graph_it * it; for (it = graph_iterator(family); it != NULL; it = graph_it_next(it)) { struct _graph_node * node = graph_it_node(it); struct _list * ins_list = node->data; struct _list_it * iit; for (iit = list_iterator(ins_list); iit != NULL; iit = iit->next) { struct _ins * ins = iit->data; if (ins->address < lower) lower = ins->address; if (ins->address + ins->size > upper) upper = ins->address + ins->size; } } object_delete(family); function->bounds.lower = lower; function->bounds.upper = upper; return 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; }