int main(void) { tree_t tree; long set[NNODES]; node_t nodes[NNODES], key, *sNode, *nodeA; unsigned i, j, k; fprintf(stderr, "Test begin\n"); /* Initialize tree. */ tree_new(&tree, 42); /* * Empty tree. */ fprintf(stderr, "Empty tree:\n"); /* trp_first(). */ nodeA = tree_first(&tree); if (nodeA == NULL) { fprintf(stderr, "trp_first() --> nil\n"); } else { fprintf(stderr, "trp_first() --> %ld\n", nodeA->key); } /* trp_last(). */ nodeA = tree_last(&tree); if (nodeA == NULL) { fprintf(stderr, "trp_last() --> nil\n"); } else { fprintf(stderr, "trp_last() --> %ld\n", nodeA->key); } /* trp_search(). */ key.key = 0; key.magic = NODE_MAGIC; nodeA = tree_search(&tree, &key); if (nodeA == NULL) { fprintf(stderr, "trp_search(0) --> nil\n"); } else { fprintf(stderr, "trp_search(0) --> %ld\n", nodeA->key); } /* trp_nsearch(). */ key.key = 0; key.magic = NODE_MAGIC; nodeA = tree_nsearch(&tree, &key); if (nodeA == NULL) { fprintf(stderr, "trp_nsearch(0) --> nil\n"); } else { fprintf(stderr, "trp_nsearch(0) --> %ld\n", nodeA->key); } /* trp_psearch(). */ key.key = 0; key.magic = NODE_MAGIC; nodeA = tree_psearch(&tree, &key); if (nodeA == NULL) { fprintf(stderr, "trp_psearch(0) --> nil\n"); } else { fprintf(stderr, "trp_psearch(0) --> %ld\n", nodeA->key); } /* trp_insert(). */ srandom(42); for (i = 0; i < NSETS; i++) { for (j = 0; j < NNODES; j++) { set[j] = (long) (((double) NNODES) * ((double) random() / ((double)RAND_MAX))); } for (j = 1; j <= NNODES; j++) { #ifdef VERBOSE fprintf(stderr, "Tree %u, %u node%s\n", i, j, j != 1 ? "s" : ""); #endif /* Initialize tree and nodes. */ tree_new(&tree, 42); for (k = 0; k < j; k++) { nodes[k].magic = NODE_MAGIC; nodes[k].key = set[k]; } /* Insert nodes. */ for (k = 0; k < j; k++) { #ifdef VERBOSE fprintf(stderr, "trp_insert(%3ld)", nodes[k].key); #endif tree_insert(&tree, &nodes[k]); #ifdef TREE_PRINT fprintf(stderr, "\n\t tree: "); #endif #ifdef FORWARD_PRINT fprintf(stderr, "\n\tforward: "); #endif assert(k + 1 == treeIterate(&tree)); #ifdef REVERSE_PRINT fprintf(stderr, "\n\treverse: "); #endif assert(k + 1 == treeIterateReverse(&tree)); #ifdef VERBOSE fprintf(stderr, "\n"); #endif sNode = tree_first(&tree); assert(sNode != NULL); sNode = tree_last(&tree); assert(sNode != NULL); sNode = tree_next(&tree, &nodes[k]); sNode = tree_prev(&tree, &nodes[k]); } /* Remove nodes. */ switch (i % 4) { case 0: { for (k = 0; k < j; k++) { nodeRemove(&tree, &nodes[k], j - k); } break; } case 1: { for (k = j; k > 0; k--) { nodeRemove(&tree, &nodes[k-1], k); } break; } case 2: { node_t *start; unsigned nNodes = j; start = NULL; do { start = tree_iter(&tree, start, removeIterateCb, (void *)&nNodes); nNodes--; } while (start != NULL); assert(nNodes == 0); break; } case 3: { node_t *start; unsigned nNodes = j; start = NULL; do { start = tree_reverse_iter(&tree, start, removeReverseIterateCb, (void *)&nNodes); nNodes--; } while (start != NULL); assert(nNodes == 0); break; } default: { assert(false); } } } } fprintf(stderr, "Test end\n"); return 0; }
void * search_open(uschar *filename, int search_type, int modemask, uid_t *owners, gid_t *owngroups) { void *handle; tree_node *t; search_cache *c; lookup_info *lk = lookup_list + search_type; uschar keybuffer[256]; int old_pool = store_pool; /* Change to the search store pool and remember our reset point */ store_pool = POOL_SEARCH; if (search_reset_point == NULL) search_reset_point = store_get(0); DEBUG(D_lookup) debug_printf("search_open: %s \"%s\"\n", lk->name, (filename == NULL)? US"NULL" : filename); /* See if we already have this open for this type of search, and if so, pass back the tree block as the handle. The key for the tree node is the search type plus '0' concatenated with the file name. There may be entries in the tree with closed files if a lot of files have been opened. */ sprintf(CS keybuffer, "%c%.254s", search_type + '0', (filename == NULL)? US"" : filename); if ((t = tree_search(search_tree, keybuffer)) != NULL) { c = (search_cache *)(t->data.ptr); if (c->handle != NULL) { DEBUG(D_lookup) debug_printf(" cached open\n"); store_pool = old_pool; return t; } DEBUG(D_lookup) debug_printf(" cached closed\n"); } /* Otherwise, we need to open the file or database - each search type has its own code, which is now split off into separately compiled modules. Before doing this, if the search type is one that uses real files, check on the number that we are holding open in the cache. If the limit is reached, close the least recently used one. */ if (lk->type == lookup_absfile && open_filecount >= lookup_open_max) { if (open_bot == NULL) log_write(0, LOG_MAIN|LOG_PANIC, "too many lookups open, but can't find " "one to close"); else { search_cache *c = (search_cache *)(open_bot->data.ptr); DEBUG(D_lookup) debug_printf("Too many lookup files open\n closing %s\n", open_bot->name); open_bot = c->up; if (open_bot != NULL) ((search_cache *)(open_bot->data.ptr))->down = NULL; else open_top = NULL; ((lookup_list + c->search_type)->close)(c->handle); c->handle = NULL; open_filecount--; } } /* If opening is successful, call the file-checking function if there is one, and if all is still well, enter the open database into the tree. */ handle = (lk->open)(filename, &search_error_message); if (handle == NULL) { store_pool = old_pool; return NULL; } if (lk->check != NULL && !lk->check(handle, filename, modemask, owners, owngroups, &search_error_message)) { lk->close(handle); store_pool = old_pool; return NULL; } /* If this is a search type that uses real files, keep count. */ if (lk->type == lookup_absfile) open_filecount++; /* If we found a previously opened entry in the tree, re-use it; otherwise insert a new entry. On re-use, leave any cached lookup data and the lookup count alone. */ if (t == NULL) { t = store_get(sizeof(tree_node) + Ustrlen(keybuffer)); t->data.ptr = c = store_get(sizeof(search_cache)); c->item_cache = NULL; Ustrcpy(t->name, keybuffer); tree_insertnode(&search_tree, t); } else c = t->data.ptr; c->handle = handle; c->search_type = search_type; c->up = c->down = NULL; store_pool = old_pool; return t; }
int main(void) { tree_t tree; long set[NNODES]; node_t nodes[NNODES], key, *sNode, *nodeA; unsigned i, j, k, blackHeight, imbalances; fprintf(stderr, "Test begin\n"); /* Initialize tree. */ tree_new(&tree); /* * Empty tree. */ fprintf(stderr, "Empty tree:\n"); /* rb_first(). */ nodeA = tree_first(&tree); if (nodeA == NULL) { fprintf(stderr, "rb_first() --> nil\n"); } else { fprintf(stderr, "rb_first() --> %ld\n", nodeA->key); } /* rb_last(). */ nodeA = tree_last(&tree); if (nodeA == NULL) { fprintf(stderr, "rb_last() --> nil\n"); } else { fprintf(stderr, "rb_last() --> %ld\n", nodeA->key); } /* rb_search(). */ key.key = 0; key.magic = NODE_MAGIC; nodeA = tree_search(&tree, &key); if (nodeA == NULL) { fprintf(stderr, "rb_search(0) --> nil\n"); } else { fprintf(stderr, "rb_search(0) --> %ld\n", nodeA->key); } /* rb_nsearch(). */ key.key = 0; key.magic = NODE_MAGIC; nodeA = tree_nsearch(&tree, &key); if (nodeA == NULL) { fprintf(stderr, "rb_nsearch(0) --> nil\n"); } else { fprintf(stderr, "rb_nsearch(0) --> %ld\n", nodeA->key); } /* rb_psearch(). */ key.key = 0; key.magic = NODE_MAGIC; nodeA = tree_psearch(&tree, &key); if (nodeA == NULL) { fprintf(stderr, "rb_psearch(0) --> nil\n"); } else { fprintf(stderr, "rb_psearch(0) --> %ld\n", nodeA->key); } /* rb_insert(). */ srandom(42); for (i = 0; i < NSETS; i++) { if (i == 0) { // Insert in order. for (j = 0; j < NNODES; j++) { set[j] = j; } } else if (i == 1) { // Insert in reverse order. for (j = 0; j < NNODES; j++) { set[j] = NNODES - j - 1; } } else { for (j = 0; j < NNODES; j++) { set[j] = (long) (((double) NNODES) * ((double) random() / ((double)RAND_MAX))); } } fprintf(stderr, "Tree %u\n", i); for (j = 1; j <= NNODES; j++) { if (verbose) { fprintf(stderr, "Tree %u, %u node%s\n", i, j, j != 1 ? "s" : ""); } /* Initialize tree and nodes. */ tree_new(&tree); tree.rbt_nil.magic = 0; for (k = 0; k < j; k++) { nodes[k].magic = NODE_MAGIC; nodes[k].key = set[k]; } /* Insert nodes. */ for (k = 0; k < j; k++) { if (verbose) { fprintf(stderr, "rb_insert(%3ld)", nodes[k].key); } tree_insert(&tree, &nodes[k]); if (tree_print) { fprintf(stderr, "\n\t tree: "); } rbtn_black_height(node_t, link, &tree, blackHeight); imbalances = treeRecurse(tree.rbt_root, blackHeight, 0, &(tree.rbt_nil)); if (imbalances != 0) { fprintf(stderr, "\nTree imbalance\n"); abort(); } if (forward_print) { fprintf(stderr, "\n\tforward: "); } assert(k + 1 == treeIterate(&tree)); if (reverse_print) { fprintf(stderr, "\n\treverse: "); } assert(k + 1 == treeIterateReverse(&tree)); if (verbose) { fprintf(stderr, "\n"); } sNode = tree_first(&tree); assert(sNode != NULL); sNode = tree_last(&tree); assert(sNode != NULL); sNode = tree_next(&tree, &nodes[k]); sNode = tree_prev(&tree, &nodes[k]); } /* Remove nodes. */ switch (i % 4) { case 0: { for (k = 0; k < j; k++) { nodeRemove(&tree, &nodes[k], j - k); } break; } case 1: { for (k = j; k > 0; k--) { nodeRemove(&tree, &nodes[k-1], k); } break; } case 2: { node_t *start; unsigned nNodes = j; start = NULL; do { start = tree_iter(&tree, start, removeIterateCb, (void *)&nNodes); nNodes--; } while (start != NULL); assert(nNodes == 0); break; } case 3: { node_t *start; unsigned nNodes = j; start = NULL; do { start = tree_reverse_iter(&tree, start, removeReverseIterateCb, (void *)&nNodes); nNodes--; } while (start != NULL); assert(nNodes == 0); break; } default: { assert(false); } } } } fprintf(stderr, "Test end\n"); return 0; }
/* get the node corresponding to path, or NULL */ static Node* get_node_path(const char* path) { return(tree_search(path)); }
int rop_build_arith_register_gadget(struct Node *root, struct Gadget **arithREG, struct Arg *arg) { struct Node *temp; char gadget_string[MaxGadgetLen] = ""; char regexp_string[MaxRegExpLen] = ""; char *op[4] = {"eax"}; int i, depth; printf("\n3. Build ArithREG Gadgets\n"); *arithREG = (struct Gadget *)malloc(sizeof(struct Gadget)); if(!*arithREG) { fprintf(stderr ,"malloc failed.\n"); return -1; } rop_chain_list_init(*arithREG); for(i = 0; i < 1; i++) { /* Find xor gadget */ strcpy(regexp_string, "^xor ___, ___"); strncpy(®exp_string[5], op[i], 3); strncpy(®exp_string[10], op[i], 3); for(depth = 1; depth < arg->depth; depth++) { memset(gadget_string, 0, MaxGadgetLen); temp = tree_search(root, regexp_string, gadget_string, depth, arg); if(temp) { printf(" O: Find XOR Gadget \"%s\"\n", gadget_string); break; } else if(depth == arg->depth-1) { printf(" X: Can't find gadget \"%s\"\n", regexp_string); rop_chain_list_free(*arithREG); return -1; } } rop_chain_list_add(*arithREG, temp->address, gadget_string, 1); /* Find inc gadget */ strcpy(regexp_string, "^inc ___$"); strncpy(®exp_string[5], op[i], 3); for(depth = 1; depth < arg->depth; depth++) { memset(gadget_string, 0, MaxGadgetLen); temp = tree_search(root, regexp_string, gadget_string, depth, arg); if(temp) { printf(" O: Find INC Gadget \"%s\"\n", gadget_string); break; } else if(depth == arg->depth-1) { printf(" X: Can't find gadget \"%s\"\n", regexp_string); return -1; } } rop_chain_list_add(*arithREG, temp->address, gadget_string, 1); } return 1; }
static int examine_log(char * file_name, char **table_names) { uint command,result,files_open; ulong access_time,length; my_off_t filepos; int lock_command,mi_result; char isam_file_name[FN_REFLEN],llbuff[21],llbuff2[21]; uchar head[20]; uchar* buff; struct test_if_open_param open_param; IO_CACHE cache; File file; FILE *write_file; enum ha_extra_function extra_command; TREE tree; struct file_info file_info,*curr_file_info; DBUG_ENTER("examine_log"); if ((file=my_open(file_name,O_RDONLY,MYF(MY_WME))) < 0) DBUG_RETURN(1); write_file=0; if (write_filename) { if (!(write_file=my_fopen(write_filename,O_WRONLY,MYF(MY_WME)))) { my_close(file,MYF(0)); DBUG_RETURN(1); } } init_io_cache(&cache,file,0,READ_CACHE,start_offset,0,MYF(0)); memset(com_count, 0, sizeof(com_count)); init_tree(&tree,0,0,sizeof(file_info),(qsort_cmp2) file_info_compare,1, (tree_element_free) file_info_free, NULL); (void) init_key_cache(dflt_key_cache,KEY_CACHE_BLOCK_SIZE,KEY_CACHE_SIZE, 0, 0); files_open=0; access_time=0; while (access_time++ != number_of_commands && !my_b_read(&cache,(uchar*) head,9)) { isamlog_filepos=my_b_tell(&cache)-9L; file_info.filenr= mi_uint2korr(head+1); isamlog_process=file_info.process=(long) mi_uint4korr(head+3); if (!opt_processes) file_info.process=0; result= mi_uint2korr(head+7); if ((curr_file_info=(struct file_info*) tree_search(&tree, &file_info, tree.custom_arg))) { curr_file_info->accessed=access_time; if (update && curr_file_info->used && curr_file_info->closed) { if (reopen_closed_file(&tree,curr_file_info)) { command=sizeof(com_count)/sizeof(com_count[0][0])/3; result=0; goto com_err; } } } command=(uint) head[0]; if (command < sizeof(com_count)/sizeof(com_count[0][0])/3 && (!table_names[0] || (curr_file_info && curr_file_info->used))) { com_count[command][0]++; if (result) com_count[command][1]++; } switch ((enum myisam_log_commands) command) { case MI_LOG_OPEN: if (!table_names[0]) { com_count[command][0]--; /* Must be counted explicite */ if (result) com_count[command][1]--; } if (curr_file_info) printf("\nWarning: %s is opened with same process and filenumber\n" "Maybe you should use the -P option ?\n", curr_file_info->show_name); if (my_b_read(&cache,(uchar*) head,2)) goto err; buff= 0; file_info.name=0; file_info.show_name=0; file_info.record=0; if (read_string(&cache, &buff, (uint) mi_uint2korr(head))) goto err; { uint i; char *pos,*to; /* Fix if old DOS files to new format */ for (pos=file_info.name=(char*)buff; (pos=strchr(pos,'\\')) ; pos++) *pos= '/'; pos=file_info.name; for (i=0 ; i < prefix_remove ; i++) { char *next; if (!(next=strchr(pos,'/'))) break; pos=next+1; } to=isam_file_name; if (filepath) to=convert_dirname(isam_file_name,filepath,NullS); my_stpcpy(to,pos); fn_ext(isam_file_name)[0]=0; /* Remove extension */ } open_param.name=file_info.name; open_param.max_id=0; (void) tree_walk(&tree,(tree_walk_action) test_if_open,(void*) &open_param, left_root_right); file_info.id=open_param.max_id+1; /* * In the line below +10 is added to accomodate '<' and '>' chars * plus '\0' at the end, so that there is place for 7 digits. * It is improbable that same table can have that many entries in * the table cache. * The additional space is needed for the sprintf commands two lines * below. */ file_info.show_name=my_memdup(PSI_NOT_INSTRUMENTED, isam_file_name, (uint) strlen(isam_file_name)+10, MYF(MY_WME)); if (file_info.id > 1) sprintf(strend(file_info.show_name),"<%d>",file_info.id); file_info.closed=1; file_info.accessed=access_time; file_info.used=1; if (table_names[0]) { char **name; file_info.used=0; for (name=table_names ; *name ; name++) { if (!strcmp(*name,isam_file_name)) file_info.used=1; /* Update/log only this */ } } if (update && file_info.used) { if (files_open >= max_files) { if (close_some_file(&tree)) goto com_err; files_open--; } if (!(file_info.isam= mi_open(isam_file_name,O_RDWR, HA_OPEN_WAIT_IF_LOCKED))) goto com_err; if (!(file_info.record=my_malloc(PSI_NOT_INSTRUMENTED, file_info.isam->s->base.reclength, MYF(MY_WME)))) goto end; files_open++; file_info.closed=0; } (void) tree_insert(&tree, (uchar*) &file_info, 0, tree.custom_arg); if (file_info.used) { if (verbose && !record_pos_file) printf_log("%s: open -> %d",file_info.show_name, file_info.filenr); com_count[command][0]++; if (result) com_count[command][1]++; } break; case MI_LOG_CLOSE: if (verbose && !record_pos_file && (!table_names[0] || (curr_file_info && curr_file_info->used))) printf_log("%s: %s -> %d",FILENAME(curr_file_info), command_name[command],result); if (curr_file_info) { if (!curr_file_info->closed) files_open--; (void) tree_delete(&tree, (uchar*) curr_file_info, 0, tree.custom_arg); } break; case MI_LOG_EXTRA: if (my_b_read(&cache,(uchar*) head,1)) goto err; extra_command=(enum ha_extra_function) head[0]; if (verbose && !record_pos_file && (!table_names[0] || (curr_file_info && curr_file_info->used))) printf_log("%s: %s(%d) -> %d",FILENAME(curr_file_info), command_name[command], (int) extra_command,result); if (update && curr_file_info && !curr_file_info->closed) { if (mi_extra(curr_file_info->isam, extra_command, 0) != (int) result) { fflush(stdout); (void) fprintf(stderr, "Warning: error %d, expected %d on command %s at %s\n", my_errno(),result,command_name[command], llstr(isamlog_filepos,llbuff)); fflush(stderr); } } break; case MI_LOG_DELETE: if (my_b_read(&cache,(uchar*) head,8)) goto err; filepos=mi_sizekorr(head); if (verbose && (!record_pos_file || ((record_pos == filepos || record_pos == NO_FILEPOS) && !cmp_filename(curr_file_info,record_pos_file))) && (!table_names[0] || (curr_file_info && curr_file_info->used))) printf_log("%s: %s at %ld -> %d",FILENAME(curr_file_info), command_name[command],(long) filepos,result); if (update && curr_file_info && !curr_file_info->closed) { if (mi_rrnd(curr_file_info->isam,curr_file_info->record,filepos)) { if (!recover) goto com_err; if (verbose) printf_log("error: Didn't find row to delete with mi_rrnd"); com_count[command][2]++; /* Mark error */ } mi_result=mi_delete(curr_file_info->isam,curr_file_info->record); if ((mi_result == 0 && result) || (mi_result && (uint) my_errno() != result)) { if (!recover) goto com_err; if (mi_result) com_count[command][2]++; /* Mark error */ if (verbose) printf_log("error: Got result %d from mi_delete instead of %d", mi_result, result); } } break; case MI_LOG_WRITE: case MI_LOG_UPDATE: if (my_b_read(&cache,(uchar*) head,12)) goto err; filepos=mi_sizekorr(head); length=mi_uint4korr(head+8); buff=0; if (read_string(&cache,&buff,(uint) length)) goto err; if ((!record_pos_file || ((record_pos == filepos || record_pos == NO_FILEPOS) && !cmp_filename(curr_file_info,record_pos_file))) && (!table_names[0] || (curr_file_info && curr_file_info->used))) { if (write_file && (my_fwrite(write_file,buff,length,MYF(MY_WAIT_IF_FULL | MY_NABP)))) goto end; if (verbose) printf_log("%s: %s at %ld, length=%ld -> %d", FILENAME(curr_file_info), command_name[command], filepos,length,result); } if (update && curr_file_info && !curr_file_info->closed) { if (curr_file_info->isam->s->base.blobs) fix_blob_pointers(curr_file_info->isam,buff); if ((enum myisam_log_commands) command == MI_LOG_UPDATE) { if (mi_rrnd(curr_file_info->isam,curr_file_info->record,filepos)) { if (!recover) { result=0; goto com_err; } if (verbose) printf_log("error: Didn't find row to update with mi_rrnd"); if (recover == 1 || result || find_record_with_key(curr_file_info,buff)) { com_count[command][2]++; /* Mark error */ break; } } mi_result=mi_update(curr_file_info->isam,curr_file_info->record, buff); if ((mi_result == 0 && result) || (mi_result && (uint) my_errno() != result)) { if (!recover) goto com_err; if (verbose) printf_log("error: Got result %d from mi_update instead of %d", mi_result, result); if (mi_result) com_count[command][2]++; /* Mark error */ } } else { mi_result=mi_write(curr_file_info->isam,buff); if ((mi_result == 0 && result) || (mi_result && (uint) my_errno() != result)) { if (!recover) goto com_err; if (verbose) printf_log("error: Got result %d from mi_write instead of %d", mi_result, result); if (mi_result) com_count[command][2]++; /* Mark error */ } if (!recover && filepos != curr_file_info->isam->lastpos) { printf("error: Wrote at position: %s, should have been %s", llstr(curr_file_info->isam->lastpos,llbuff), llstr(filepos,llbuff2)); goto end; } } } my_free(buff); break; case MI_LOG_LOCK: if (my_b_read(&cache,(uchar*) head,sizeof(lock_command))) goto err; memcpy(&lock_command, head, sizeof(lock_command)); if (verbose && !record_pos_file && (!table_names[0] || (curr_file_info && curr_file_info->used))) printf_log("%s: %s(%d) -> %d\n",FILENAME(curr_file_info), command_name[command],lock_command,result); if (update && curr_file_info && !curr_file_info->closed) { if (mi_lock_database(curr_file_info->isam,lock_command) != (int) result) goto com_err; } break; case MI_LOG_DELETE_ALL: if (verbose && !record_pos_file && (!table_names[0] || (curr_file_info && curr_file_info->used))) printf_log("%s: %s -> %d\n",FILENAME(curr_file_info), command_name[command],result); break; default: fflush(stdout); (void) fprintf(stderr, "Error: found unknown command %d in logfile, aborted\n", command); fflush(stderr); goto end; } } end_key_cache(dflt_key_cache,1); delete_tree(&tree); (void) end_io_cache(&cache); (void) my_close(file,MYF(0)); if (write_file && my_fclose(write_file,MYF(MY_WME))) DBUG_RETURN(1); DBUG_RETURN(0); err: fflush(stdout); (void) fprintf(stderr,"Got error %d when reading from logfile\n",my_errno()); fflush(stderr); goto end; com_err: fflush(stdout); (void) fprintf(stderr,"Got error %d, expected %d on command %s at %s\n", my_errno(),result,command_name[command], llstr(isamlog_filepos,llbuff)); fflush(stderr); end: end_key_cache(dflt_key_cache, 1); delete_tree(&tree); (void) end_io_cache(&cache); (void) my_close(file,MYF(0)); if (write_file) (void) my_fclose(write_file,MYF(MY_WME)); DBUG_RETURN(1); }
int rop_build_write_memory_gadget(struct Node *root, struct Gadget **writeMEM, struct Arg *arg) { struct Node *temp,*mov_temp; char gadget_string[MaxGadgetLen] = ""; char regexp_string[MaxRegExpLen] = ""; char op[2][4]; int i, depth, restart; printf("\n1. Build WriteMem Gadgets\n"); while(true) { restart = 0; *writeMEM = (struct Gadget *)malloc(sizeof(struct Gadget)); if(!*writeMEM) { fprintf(stderr ,"malloc failed.\n"); return -1; } rop_chain_list_init(*writeMEM); /* find mov gadget */ strcpy(regexp_string, "mov dword ptr .e[abcds][xip]], e[abcds][xip]"); for(depth = 1; depth < arg->depth; depth++) { memset(gadget_string, 0, MaxGadgetLen); mov_temp = tree_search(root, regexp_string, gadget_string, depth, arg); if(mov_temp) { printf(" O: Find MOV Gadget \"%s\"\n", gadget_string); break; } else if(depth == arg->depth-1) { printf(" X: Can't find gadget \"%s\"\n", regexp_string); return -1; } } strncpy(op[0], &gadget_string[15], 3); strncpy(op[1], &gadget_string[21], 3); op[0][3] = 0; op[1][3] = 0; if(!strcmp(op[0], "esp") || !strcmp(op[1], "esp")) { printf(" X: Can't use esp gadget. Try to find other mov gadget\n"); mov_temp->vaild = 0; continue; } rop_chain_list_add(*writeMEM, mov_temp->address, gadget_string, 1); /* find pop e_x gadget */ for(i = 0; i < 2; i++) { strcpy(regexp_string, "^pop ___$"); strncpy(®exp_string[5], op[i], 3); for(depth = 1; depth < arg->depth; depth++) { memset(gadget_string, 0, MaxGadgetLen); temp = tree_search(root, regexp_string, gadget_string, depth, arg); if(temp) { printf(" O: Find POP Gadget \"%s\"\n", gadget_string); break; } else if(depth == arg->depth-1) { printf(" X: Can't find gadget \"%s\" Try to find other mov gadget\n", regexp_string); mov_temp->vaild = 0; rop_chain_list_free(*writeMEM); restart = 1; break; } } if(!restart) { rop_chain_list_add(*writeMEM, temp->address, gadget_string, 0); } else { break; } } if(restart) { continue; } /* find xor e_x gadget */ strcpy(regexp_string, "^xor ___, ___"); strncpy(®exp_string[5], op[1], 3); strncpy(®exp_string[10], op[1], 3); for(depth = 1; depth < arg->depth; depth++) { memset(gadget_string, 0, MaxGadgetLen); temp = tree_search(root, regexp_string, gadget_string, depth, arg); if(temp) { printf(" O: Find XOR Gadget \"%s\"\n", gadget_string); break; } else if(depth == arg->depth-1) { printf(" X: Can't find gadget \"%s\" Try to find other mov gadget\n", regexp_string); mov_temp->vaild = 0; rop_chain_list_free(*writeMEM); restart = 1; break; } } if(restart) { continue; } rop_chain_list_add(*writeMEM, temp->address, gadget_string, 0); break; } return 1; }
static tree_node_t *find_node(const struct strings *strings, uint32_t hash) { tree_node_t key; key.hash = hash; return tree_search(&strings->hash_map, &key); }
struct rb_node *tree_find(struct redblack_tree *tree, int key) { return tree_search(tree->root, key); }
static uschar * internal_search_find(void *handle, uschar *filename, uschar *keystring) { tree_node *t = (tree_node *)handle; search_cache *c = (search_cache *)(t->data.ptr); expiring_data *e; uschar *data = NULL; int search_type = t->name[0] - '0'; int old_pool = store_pool; /* Lookups that return DEFER may not always set an error message. So that the callers don't have to test for NULL, set an empty string. */ search_error_message = US""; search_find_defer = FALSE; DEBUG(D_lookup) debug_printf("internal_search_find: file=\"%s\"\n " "type=%s key=\"%s\"\n", filename, lookup_list[search_type]->name, keystring); /* Insurance. If the keystring is empty, just fail. */ if (keystring[0] == 0) return NULL; /* Use the special store pool for search data */ store_pool = POOL_SEARCH; /* Look up the data for the key, unless it is already in the cache for this file. No need to check c->item_cache for NULL, tree_search will do so. */ if ( (t = tree_search(c->item_cache, keystring)) && (!(e = t->data.ptr)->expiry || e->expiry > time(NULL)) ) { /* Data was in the cache already; set the pointer from the tree node */ data = e->ptr; DEBUG(D_lookup) debug_printf("cached data used for lookup of %s%s%s\n", keystring, filename ? US"\n in " : US"", filename ? filename : US""); } else { uint do_cache = UINT_MAX; int keylength = Ustrlen(keystring); DEBUG(D_lookup) { if (t) debug_printf("cached data found but past valid time; "); debug_printf("%s lookup required for %s%s%s\n", filename ? US"file" : US"database", keystring, filename ? US"\n in " : US"", filename ? filename : US""); } /* Call the code for the different kinds of search. DEFER is handled like FAIL, except that search_find_defer is set so the caller can distinguish if necessary. */ if (lookup_list[search_type]->find(c->handle, filename, keystring, keylength, &data, &search_error_message, &do_cache) == DEFER) search_find_defer = TRUE; /* A record that has been found is now in data, which is either NULL or points to a bit of dynamic store. Cache the result of the lookup if caching is permitted. Lookups can disable caching, when they did something that changes their data. The mysql and pgsql lookups do this when an UPDATE/INSERT query was executed. */ else if (do_cache) { int len = keylength + 1; if (t) /* Previous, out-of-date cache entry. Update with the */ { /* new result and forget the old one */ e->expiry = do_cache == UINT_MAX ? 0 : time(NULL)+do_cache; e->ptr = data; } else { e = store_get(sizeof(expiring_data) + sizeof(tree_node) + len); e->expiry = do_cache == UINT_MAX ? 0 : time(NULL)+do_cache; e->ptr = data; t = (tree_node *)(e+1); memcpy(t->name, keystring, len); t->data.ptr = e; tree_insertnode(&c->item_cache, t); } } /* If caching was disabled, empty the cache tree. We just set the cache pointer to NULL here, because we cannot release the store at this stage. */ else { DEBUG(D_lookup) debug_printf("lookup forced cache cleanup\n"); c->item_cache = NULL; } } DEBUG(D_lookup) { if (data) debug_printf("lookup yielded: %s\n", data); else if (search_find_defer) debug_printf("lookup deferred: %s\n", search_error_message); else debug_printf("lookup failed\n"); } /* Return it in new dynamic store in the regular pool */ store_pool = old_pool; return data ? string_copy(data) : NULL; }
bool compile_project_prepare (CompileProject *project) { ListNode *node; Directory *sub_directory; Compile *compile; Compile *sub_compile; TreeIterator *iterator; if (!project) { error (InvalidArgument); return false; } if (!directory_read (project->directory)) { compile_print ("Failed to read directory: %s\n", project->directory->name); error_code (FunctionCall, 1); return false; } for (node = list_first (project->directory->directories); node; node = list_next (node)) { if (!(sub_directory = node->data)) { error_code (InvalidOperation, 1); return false; } if (!string_begins_with (sub_directory->name, "lib.") && !string_begins_with (sub_directory->name, "app.") && !string_begins_with (sub_directory->name, "plugin.")) { continue; } if (!(compile = compile_create (project->directory, sub_directory))) { error_code (FunctionCall, 2); return false; } if (!list_append (project->nodes, compile)) { compile_destroy (compile); error_code (FunctionCall, 3); return false; } if (!topological_add_vertex (project->topological, (Object *)compile)) { error_code (FunctionCall, 4); return false; } if (!tree_insert (project->directory_to_compile, (Object *)sub_directory, compile)) { error_code (FunctionCall, 5); return false; } } for (node = list_first (project->directory->directories); node; node = list_next (node)) { if (!(sub_directory = node->data)) { error_code (InvalidOperation, 3); return false; } if (!string_begins_with (sub_directory->name, "lib.") && !string_begins_with (sub_directory->name, "app.") && !string_begins_with (sub_directory->name, "plugin.")) { continue; } if (!(compile = tree_search (project->directory_to_compile, (Object *)sub_directory))) { error_code (InvalidOperation, 5); return false; } if (!compile_prepare (compile)) { error_code (FunctionCall, 6); return false; } if (!(iterator = tree_iterator_create (compile->libraries))) { error_code (FunctionCall, 7); return false; } while (tree_iterator_next (iterator)) { if (string_equals (sub_directory->name, ((Directory *)iterator->key)->name)) { continue; } if (!(sub_compile = tree_search (project->directory_to_compile, iterator->key))) { tree_iterator_destroy (iterator); error_code (InvalidOperation, 6); return false; } if (!topological_set_edge (project->topological, (Object *)compile, (Object *)sub_compile)) { tree_iterator_destroy (iterator); error_code (FunctionCall, 8); return false; } } tree_iterator_destroy (iterator); } if (!(project->sorted = topological_sort (project->topological))) { compile_print ("Topological sort of project directories failed.\n"); error_code (InvalidOperation, 7); return false; } for (node = list_first (project->sorted); node; node = list_next (node)) { if (!recursively_flatten_libraries (project, node->data)) { return false; } if (!sort_libraries (project, node->data)) { return false; } } for (node = list_last (project->sorted); node; node = list_previous (node)) { if (!compile_actions (node->data, project->directory->path)) { error_code (FunctionCall, 9); return false; } } return true; }