コード例 #1
0
void test_integration(void) {
  function_t *f = function_create("2**x - log(x)");
  ASSERT_EQ(integrate_simpson(f, 0.5, 2.3), 4.60212);
  function_destroy(f);

  f = function_create("1/x - sin(x)**3");
  ASSERT_EQ(integrate_simpson(f, 2.45, 8.145), 1.54018);
  function_destroy(f);
}
コード例 #2
0
void test_arclength(void) {
  function_t *f = function_create("2**x - log(x)");
  ASSERT_EQ(arc_length(f, 0.5, 2.3), 3.0663188081);
  function_destroy(f);

  f = function_create("1/x + sin(x)**0.3");
  ASSERT_EQ(arc_length(f, 0.5, 2.3), 2.4417982309);
  function_destroy(f);

  f = function_create("3.5*x**4 - 30.3*x**3 + 7.2*x**2 - 3.4*x + 32.0");
  ASSERT_EQ(arc_length(f, -5, 7), 8109.52041086);
  function_destroy(f);

  f = function_create("3.5*x**4 - 7.2*x**2 - 3.4*x - 32.0");
  ASSERT_EQ(arc_length(f, -1.5, 0.73), 14.196939434);
  function_destroy(f);
}
コード例 #3
0
void test_derivates(void) {
  function_t *f = function_create("x**2");
  ASSERT_EQ(derivate_1(f, 0.2), 0.4);
  ASSERT_EQ(derivate_1(f, 0.0), 0.0);
  ASSERT_EQ(derivate_2(f, 0.0), 2.0);
  function_destroy(f);

  f = function_create("cos(x) - x**3");
  ASSERT_EQ(derivate_1(f, 5.0), -75.0-sinl(5.0));
  ASSERT_EQ(derivate_1(f, 0.0), 0.0);
  ASSERT_EQ(derivate_2(f, 0.0), -1.0);
  ASSERT_EQ(derivate_2(f, 3.75), -21.6794);
  ASSERT_EQ(derivate(f, 3, -34.2), -6.34995);
  ASSERT_EQ(derivate(f, 3, -3.2), -5.94163);
  function_destroy(f);

  f = function_create("2**x - log(x)");
  ASSERT_EQ(derivate_1(f, 1.5), 1.29385);
  ASSERT_EQ(derivate_1(f, 3.2), 6.05724);
  ASSERT_EQ(derivate_2(f, 3.2), 4.51282);
  ASSERT_EQ(derivate_2(f, 5.0), 15.41446);
  function_destroy(f);
}
コード例 #4
0
int rdis_user_function (struct _rdis * rdis, uint64_t address)
{
    // get a tree of all functions reachable at this address
    struct _map * functions = loader_function_address(rdis->loader,
                                                      rdis->memory,
                                                      address);

    // add in this address as a new function as well
    struct _function * function = function_create(address);
    map_insert(functions, function->address, function);
    object_delete(function);

    // for each newly reachable function
    struct _map_it * mit;
    for (mit = map_iterator(functions); mit != NULL; mit = map_it_next(mit)) {
        struct _function * function = map_it_data(mit);
        uint64_t fitaddress = function->address;

        // if we already have this function, skip it
        if (map_fetch(rdis->functions, function->address) != NULL)
            continue;

        // add this function to the rdis->function_tree
        map_insert(rdis->functions, function->address, function);

        // add label
        struct _label * label = loader_label_address(rdis->loader,
                                                     rdis->memory,
                                                     fitaddress);
        map_insert(rdis->labels, fitaddress, label);
        object_delete(label);

        // if this function is already in our graph, all we need to do is make
        // sure its a separate node and then remove function predecessors
        struct _graph_node * node = graph_fetch_node_max(rdis->graph, fitaddress);
        if (node != NULL) {

            // already a node, remove function predecessors
            if (node->index == address) {
                remove_function_predecessors(rdis->graph, rdis->functions);
                continue;
            }

            // search for instruction with given address
            struct _list    * ins_list = node->data;
            struct _list_it * it;
            for (it = list_iterator(ins_list); it != NULL; it = it->next) {
                struct _ins * ins = it->data;
                // found instruction
                if (ins->address == fitaddress) {
                    // create a new instruction list.
                    // add remaining instructions to new list while removing them from
                    // the current list
                    struct _list * new_ins_list = list_create();
                    while (1) {
                        list_append(new_ins_list, it->data);
                        it = list_remove(ins_list, it);
                        if (it == NULL)
                            break;
                    }
                    // create a new graph node for this new function
                    graph_add_node(rdis->graph, fitaddress, new_ins_list);
                    // all graph successors from old node are added to new node
                    struct _queue   * queue      = queue_create();
                    struct _list    * successors = graph_node_successors(node);
                    struct _list_it * sit;
                    for (sit = list_iterator(successors);
                         sit != NULL;
                         sit = sit->next) {
                        struct _graph_edge * edge = sit->data;
                        graph_add_edge(rdis->graph,
                                       fitaddress,
                                       edge->tail,
                                       edge->data);
                        queue_push(queue, edge);
                    }
                    object_delete(successors);

                    // and removed from old node
                    while (queue->size > 0) {
                        struct _graph_edge * edge = queue_peek(queue);
                        graph_remove_edge(rdis->graph, edge->head, edge->tail);
                        queue_pop(queue);
                    }
                    object_delete(queue);

                    // that was easy
                    break;
                }
            }
            if (it != NULL)
                continue;
        }

        // we need to create a new graph for this node
        struct _graph * graph = loader_graph_address(rdis->loader,
                                                     rdis->memory,
                                                     fitaddress);
        graph_merge(rdis->graph, graph);
        object_delete(graph);
    }

    object_delete(functions);

    rdis_callback(rdis, RDIS_CALLBACK_ALL);

    return 0;
}
コード例 #5
0
ファイル: x8664.c プロジェクト: 0day1day/rdis
void x8664_functions_r (struct _map  * functions,
                        struct _tree * disassembled,
                        uint64_t       address,
                        struct _map  * memory)
{
    ud_t            ud_obj;
    int             continue_disassembling = 1;

    struct _buffer * buffer = map_fetch_max(memory, address);

    if (buffer == NULL)
        return;

    uint64_t base_address   = map_fetch_max_key(memory, address);

    if (base_address + buffer->size < address)
        return;

    uint64_t offset = address - base_address;

    ud_init      (&ud_obj);
    ud_set_mode  (&ud_obj, 64);
    ud_set_syntax(&ud_obj, UD_SYN_INTEL);
    ud_set_input_buffer(&ud_obj, &(buffer->bytes[offset]), buffer->size - offset);

    while (continue_disassembling == 1) {
        size_t bytes_disassembled = ud_disassemble(&ud_obj);
        if (bytes_disassembled == 0) {
            break;
        }

        if (    (ud_obj.mnemonic == UD_Icall)
             && (ud_obj.operand[0].type == UD_OP_JIMM)) {

            uint64_t target_addr = address
                                   + ud_insn_len(&ud_obj)
                                   + udis86_sign_extend_lval(&(ud_obj.operand[0]));

            if (map_fetch(functions, target_addr) == NULL) {
                struct _function * function = function_create(target_addr);
                map_insert(functions, target_addr, function);
                object_delete(function);
            }
        }

        struct _index * index = index_create(address);
        if (tree_fetch(disassembled, index) != NULL) {
            object_delete(index);
            return;
        }
        tree_insert(disassembled, index);
        object_delete(index);

        // these mnemonics cause us to continue disassembly somewhere else
        struct ud_operand * operand;
        switch (ud_obj.mnemonic) {
        case UD_Ijo   :
        case UD_Ijno  :
        case UD_Ijb   :
        case UD_Ijae  :
        case UD_Ijz   :
        case UD_Ijnz  :
        case UD_Ijbe  :
        case UD_Ija   :
        case UD_Ijs   :
        case UD_Ijns  :
        case UD_Ijp   :
        case UD_Ijnp  :
        case UD_Ijl   :
        case UD_Ijge  :
        case UD_Ijle  :
        case UD_Ijg   :
        case UD_Ijmp  :
        case UD_Iloop :
        case UD_Icall :
            operand = &(ud_obj.operand[0]);

            if (operand->type == UD_OP_JIMM) {
                x8664_functions_r(functions,
                                  disassembled,
                                  address
                                   + ud_insn_len(&ud_obj)
                                   + udis86_sign_extend_lval(operand),
                                  memory);
            }
            break;
        default :
            break;
        }

        // these mnemonics cause disassembly to stop
        switch (ud_obj.mnemonic) {
        case UD_Iret :
        case UD_Ihlt :
        case UD_Ijmp :
            continue_disassembling = 0;
            break;
        default :
            break;
        }

        address += bytes_disassembled;
    }
}
コード例 #6
0
ファイル: elf32.c プロジェクト: TDKPS/rdis
struct _map * elf32_functions (struct _elf32 * elf32, struct _map * memory)
{
    struct _list * entries   = list_create();

    // add the entry point
    struct _function * function = function_create(elf32_entry(elf32));
    list_append(entries, function);
    object_delete(function);

    // check for __libc_start_main loader
    uint64_t target_offset = elf32_entry(elf32) - elf32_base_address(elf32) + 0x17;
    if (target_offset + 0x10 < elf32->data_size) {
        uint8_t * data = &(elf32->data[target_offset]);
        size_t    size = elf32->data_size - target_offset;

        ud_t ud_obj;
        ud_init      (&ud_obj);
        ud_set_mode  (&ud_obj, 32);
        ud_set_syntax(&ud_obj, UD_SYN_INTEL);
        ud_set_input_buffer(&ud_obj, data, size);
        ud_disassemble(&ud_obj);
        if (ud_obj.mnemonic == UD_Ipush) {
            printf("found __libc_start_main loader, main at %llx\n",
                   (unsigned long long) udis86_sign_extend_lval(&(ud_obj.operand[0])));

            // add main to function tree
            struct _function * function;
            function = function_create(udis86_sign_extend_lval(&(ud_obj.operand[0])));
            list_append(entries, function);
            object_delete(function);

        }
        else
            printf("disassembled: %s\n disassembled at %llx\n",
                   ud_insn_asm(&ud_obj),
                   (unsigned long long) target_offset);
    }

    struct _map * functions = elf32_functions_wqueue(elf32, memory, entries);

    // these are the reachable functions
    struct _map_it * mit;
    for (mit = map_iterator(functions); mit != NULL; mit = map_it_next(mit)) {
        struct _function * function = map_it_data(mit);
        function->flags |= FUNCTION_REACHABLE;
    }

    // reset entries
    object_delete(entries);
    entries = list_create();

    // symbols are easy
    int sec_i;
    for (sec_i = 0; sec_i < elf32->ehdr->e_shnum; sec_i++) {
        Elf32_Shdr * shdr = elf32_shdr(elf32, sec_i);
        if (shdr == NULL)
            break;

        if ((shdr->sh_type != SHT_SYMTAB) && (shdr->sh_type != SHT_DYNSYM))
            continue;

        int sym_i;
        for (sym_i = 0; sym_i < shdr->sh_size / shdr->sh_entsize; sym_i++) {
            Elf32_Sym * sym = elf32_section_element(elf32, sec_i, sym_i);
            if (sym == NULL)
                break;

            if (ELF32_ST_TYPE(sym->st_info) != STT_FUNC)
                continue;

            if (sym->st_value == 0)
                continue;

            struct _function * function = function_create(sym->st_value);
            list_append(entries, function);
            object_delete(function);
        }
    }

    struct _map * sym_functions = elf32_functions_wqueue(elf32, memory, entries);
    for (mit = map_iterator(sym_functions); 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);
    }

    object_delete(sym_functions);
    object_delete(entries);

    return functions;
}
コード例 #7
0
ファイル: roots.c プロジェクト: jueqingsizhe66/natools
int main(int argc, char *argv[]) {
  int ret;
  char *x0 = NULL, *x1 = NULL;
  char *epsilon = EPSILON, *func = NULL;
  char *max_iter = MAXITER, *method = "secant";
  long double r;

  /* parse command line */
  while ((ret = getopt(argc, argv, "vm:e:i:a:b:")) != -1) {
    switch (ret) {
      case 'e':
        epsilon = optarg; /* optarg is just a pointer to argv */
        break;
      case 'i':
        max_iter = optarg;
        break;
      case 'a':
        x0 = optarg;
        break;
      case 'b':
        x1 = optarg;
        break;
      case 'm':
        method = optarg;
        break;
      case 'v':
        root_search_verbose = 1;
        break;
      default:
        return 1;
    }
  }
  if (optind >= argc || !x0) {
    fprintf(stderr, "usage: %s [-v] [-e <epsilon>] [-i <max-iter>] [-m <method>]"
            "-a <x0> [-b <x1>] <function eg: cos(x)-x^3>\n", argv[0]);
    return 1;
  } else {
    func = argv[optind];
  }

  function_t *f = function_create(func);
  interval_t *i = interval_create(atof(x0), x1 ? atof(x1) : (atof(x0) + 1.0));
  stop_cond_t *s = stop_cond_create(atof(epsilon), atoi(max_iter));

  if (!strcmp(method, "secant"))
    ret = root_secant(f, i, s, &r);
  else if (!strcmp(method, "bisection"))
    ret = root_bisection(f, i, s, &r);
  else if (!strcmp(method, "regulafalsi"))
    ret = root_regulafalsi(f, i, s, &r);
  else if (!strcmp(method, "newton"))
    ret = root_newton(f, atof(x0), s, &r);
  else {
    fprintf(stderr, "Method not recognized: %s\n", method);
    return 1;
  }

  if (ret) {
    fprintf(stderr, "%s method failed (ret: %d)\n", method, ret);
  } else {
    printf("%.15Lg\n", r);
  }

  function_destroy(f);
  interval_destroy(i);
  stop_cond_destroy(s);

  return ret;
}
コード例 #8
0
ファイル: kplugs.c プロジェクト: XianBeiTuoBaFeng2015/kplugs
/* write callback */
static ssize_t kplugs_write(struct file *filp, const char *buf, size_t count, loff_t *f_pos)
{
	kplugs_command_t *cmd = NULL;
	context_t *file_cont = NULL;
	context_t *cont = NULL;
	bytecode_t *code = NULL;
	function_t *func = NULL;
	exception_t excep;
	stack_t stack;
	word iter, arg;
	word args;
	byte little_endian;
	byte func_name[MAX_FUNC_NAME + 1];
	int err = 0;

#ifdef __LITTLE_ENDIAN
	little_endian = 1;
#else
	little_endian = 0;
#endif
	/* get the user's command */
	cmd = (kplugs_command_t *)buf;
	file_cont = (context_t *)filp->private_data;

	if (count < sizeof(byte) * 3) { /* three bytes of header */
		return create_error(file_cont, -ERROR_PARAM);
	}

	if (cmd->word_size != sizeof(word) || cmd->l_endian != little_endian) {
		return create_error(file_cont, -ERROR_ARCH);
	}

	if (cmd->version_major != VERSION_MAJOR || cmd->version_minor != VERSION_MINOR) {
		return create_error(file_cont, -ERROR_VERSION);
	}

	if (count != sizeof(kplugs_command_t)) {
		return create_error(file_cont, -ERROR_PARAM);
	}

	cont = cmd->is_global ? GLOBAL_CONTEXT : file_cont;

	switch (cmd->type) {
	case KPLUGS_LOAD:
		/* load a new function */

		if (cmd->len2 != 0 || cmd->ptr2 != NULL) {
			return create_error(file_cont, -ERROR_PARAM);
		}

		code = memory_alloc(cmd->len1);
		if (NULL == code) {
			ERROR(create_error(file_cont, -ERROR_MEM));
		}

		err = memory_copy_from_outside(code, cmd->uptr1, cmd->len1);
		if (err < 0) {
			err = create_error(file_cont, err);
			goto clean;
		}

		/* create the function */
		err = function_create(code, cmd->len1, &func);
		if (err < 0) {
			err = create_error(file_cont, err);
			goto clean;
		}

		err = context_add_function(cont, func);
		if (err < 0) {
			err = create_error(file_cont, err);
			goto clean;
		}

		/* return the function's address */
		context_create_reply(file_cont, (word)&func->func_code, NULL);

		return count;

	case KPLUGS_UNLOAD:
		/* unload a function with a name */
		if (NULL != cmd->uptr2) {
			return create_error(file_cont, -ERROR_PARAM);
		}
	case KPLUGS_EXECUTE:
		/* execute (and unload) a function with a name */
		if (cmd->len1 > MAX_FUNC_NAME || (cmd->len2 % sizeof(word)) != 0) {
			return create_error(file_cont, -ERROR_PARAM);
		}

		err = memory_copy_from_outside(func_name, cmd->uptr1, cmd->len1);
		if (err < 0) {
			return create_error(file_cont, err);
		}

		func_name[cmd->len1] = '\0';

		/* find the function */

		if (cmd->type == KPLUGS_UNLOAD) {
			func = context_find_function(cont, func_name);
			if (NULL == func) {
				return create_error(file_cont, -ERROR_UFUNC);
			}
			/* delete the function */
			context_free_function(func);
			err = (int)count;

			goto clean;
		}

		if (!cmd->is_global) {
			func = context_find_function(file_cont, func_name);
		}
		if (NULL == func) {
			func = context_find_function(GLOBAL_CONTEXT, func_name);
			if (NULL == func) {
				return create_error(file_cont, -ERROR_UFUNC);
			}
		}

		goto execute_func;

	case KPLUGS_UNLOAD_ANONYMOUS:
		/* unload an anonymous function */
		if (NULL != cmd->uptr2 || cmd->len1 || cmd->len2) {
			return create_error(file_cont, -ERROR_PARAM);
		}
		func = context_find_anonymous(cont, cmd->ptr1);
		if (NULL == func) {
			return create_error(file_cont, -ERROR_UFUNC);
		}

		/* delete the function */
		context_free_function(func);

		err = (int)count;
		goto clean;
	break;

	case KPLUGS_EXECUTE_ANONYMOUS:
		/* execute (and unload) an anonymous function */
		if (cmd->len1 || (cmd->len2 % sizeof(word)) != 0) {
			return create_error(file_cont, -ERROR_PARAM);
		}

		/* find the function */
		if (!cmd->is_global) {
			func = context_find_anonymous(file_cont, cmd->ptr1);
		}
		if (NULL == func) {
			func = context_find_anonymous(GLOBAL_CONTEXT, cmd->ptr1);
			if (NULL == func) {
				return create_error(file_cont, -ERROR_UFUNC);
			}
		}

execute_func:
		/* do the execution of a function: */

		args = cmd->len2 / sizeof(word);
		if (args > func->num_maxargs || args < func->num_minargs) {
			ERROR_CLEAN(create_error(file_cont, -ERROR_ARGS));
		}

		err = stack_alloc(&stack, sizeof(word), CALL_STACK_SIZE);
		if (err < 0) {
			err = create_error(file_cont, err);
			goto clean;
		}

		/* push the arguments to a stack */
		for (iter = 0; iter < args; ++iter) {
			err = memory_copy_from_outside(&arg, cmd->ptr2 + (iter * sizeof(word)), sizeof(arg));
			if (err < 0) {
				stack_free(&stack);
				err = create_error(file_cont, err);
				goto clean;
			}

			if (NULL == stack_push(&stack, &arg)) {
				stack_free(&stack);
				ERROR_CLEAN(create_error(file_cont, -ERROR_MEM));
			}
		}

		/* execute the function and create an answer */
		arg = vm_run_function(func, &stack, &excep);

		stack_free(&stack);

		if (excep.had_exception) {
			err = -EINVAL; /* it dosen't really matter which error. the value of the error will be taken from the answer */
			arg = excep.value;
		} else {
			err = (int)count;
		}

		context_create_reply(file_cont, arg, &excep);

		goto clean;

	case KPLUGS_GET_LAST_EXCEPTION:
		if (NULL != cmd->uptr2 || cmd->len1 < sizeof(exception_t) || cmd->len2) {
			ERROR(create_error(file_cont, -ERROR_PARAM));
		}

		err = context_get_last_exception(file_cont, (exception_t *)cmd->ptr1);
		if (err < 0) {
			return create_error(file_cont, err);
		}

		return count;

	default:
		return create_error(file_cont, -ERROR_PARAM);
	}
clean:
	if (NULL != func) {
		function_put(func);
	} else if (NULL != code) {
		memory_free(code);
	}
	return err;
}