void Runner::exec(string * obj) { string * str = obj; cout << "expr: " << (*str) << endl; double result = expression_eval(str->c_str()); cout << "result: " << result << endl; }
static guint32 expression_eval (expression_t *exp, test_entry_t *entry) { switch (exp->type) { case EXPRESSION_CONSTANT: return exp->data.constant; case EXPRESSION_VARIABLE: return lookup_var (entry, exp->data.name); case EXPRESSION_ADD: return expression_eval (exp->data.bin.left, entry) + expression_eval (exp->data.bin.right, entry); case EXPRESSION_SUB: return expression_eval (exp->data.bin.left, entry) - expression_eval (exp->data.bin.right, entry); case EXPRESSION_FUNC: return call_func (entry, exp->data.func.name, exp->data.func.args); default: printf ("Invalid expression type %d\n", exp->type); exit (INVALID_EXPRESSION); } return 0; }
static guint32 apply_selector (patch_selector_t *selector, test_entry_t *entry) { guint32 value = 0; if (selector->expression) value = expression_eval (selector->expression, entry); switch (selector->type) { case SELECTOR_ABS_OFFSET: DEBUG_PARSER (printf("\tabsolute offset selector [%04x]\n", value)); return value; default: printf ("Invalid selector type %d\n", selector->type); exit (INVALID_SELECTOR); } }
static void apply_effect (patch_effect_t *effect, test_entry_t *entry, guint32 offset) { gint32 value = 0; char *ptr = entry->data + offset; if (effect->expression) value = expression_eval (effect->expression, entry); switch (effect->type) { case EFFECT_SET_BYTE: DEBUG_PARSER (printf("\tset-byte effect old value [%x] new value [%x]\n", READ_VAR (guint8, ptr), value)); SET_VAR (guint8, ptr, value); break; case EFFECT_SET_USHORT: DEBUG_PARSER (printf("\tset-ushort effect old value [%x] new value [%x]\n", READ_VAR (guint16, ptr), value)); SET_VAR (guint16, ptr, value); break; case EFFECT_SET_UINT: DEBUG_PARSER (printf("\tset-uint effect old value [%x] new value [%x]\n", READ_VAR (guint32, ptr), value)); SET_VAR (guint32, ptr, value); break; case EFFECT_SET_TRUNC: DEBUG_PARSER (printf("\ttrunc effect [%d]\n", offset)); entry->data_size = offset; break; case EFFECT_SET_BIT: DEBUG_PARSER (printf("\tset-bit effect bit %d old value [%x]\n", value, READ_BIT (ptr, value))); SET_BIT (ptr, value); break; case EFFECT_OR_BYTE: DEBUG_PARSER (printf("\tor-byte effect old value [%x] new value [%x]\n", READ_VAR (guint8, ptr), value)); SET_VAR (guint8, ptr, READ_VAR (guint8, ptr) | value); break; case EFFECT_OR_USHORT: DEBUG_PARSER (printf("\tor-ushort effect old value [%x] new value [%x]\n", READ_VAR (guint16, ptr), value)); SET_VAR (guint16, ptr, READ_VAR (guint16, ptr) | value); break; case EFFECT_OR_UINT: DEBUG_PARSER (printf("\tor-uint effect old value [%x] new value [%x]\n", READ_VAR (guint32, ptr), value)); SET_VAR (guint32, ptr, READ_VAR (guint32, ptr) | value); break; default: printf ("Invalid effect type %d\n", effect->type); exit (INVALID_EFFECT); } }
static guint32 call_func (test_entry_t *entry, const char *name, GSList *args) { if (!strcmp ("read.byte", name)) { guint32 offset; if (g_slist_length (args) != 1) { printf ("Invalid number of args to read.ushort %d\n", g_slist_length (args)); exit (INVALID_ARG_COUNT); } offset = expression_eval (args->data, entry); return READ_VAR (guint8, entry->data + offset); } if (!strcmp ("read.ushort", name)) { guint32 offset; if (g_slist_length (args) != 1) { printf ("Invalid number of args to read.ushort %d\n", g_slist_length (args)); exit (INVALID_ARG_COUNT); } offset = expression_eval (args->data, entry); return READ_VAR (guint16, entry->data + offset); } if (!strcmp ("read.uint", name)) { guint32 offset; if (g_slist_length (args) != 1) { printf ("Invalid number of args to read.uint %d\n", g_slist_length (args)); exit (INVALID_ARG_COUNT); } offset = expression_eval (args->data, entry); return READ_VAR (guint32, entry->data + offset); } if (!strcmp ("translate.rva", name)) { guint32 rva; if (g_slist_length (args) != 1) { printf ("Invalid number of args to translate.rva %d\n", g_slist_length (args)); exit (INVALID_ARG_COUNT); } rva = expression_eval (args->data, entry); return translate_rva (entry, rva); } if (!strcmp ("translate.rva.ind", name)) { guint32 rva; if (g_slist_length (args) != 1) { printf ("Invalid number of args to translate.rva.ind %d\n", g_slist_length (args)); exit (INVALID_ARG_COUNT); } rva = expression_eval (args->data, entry); rva = READ_VAR (guint32, entry->data + rva); return translate_rva (entry, rva); } if (!strcmp ("stream-header", name)) { guint32 idx; if (g_slist_length (args) != 1) { printf ("Invalid number of args to stream-header %d\n", g_slist_length (args)); exit (INVALID_ARG_COUNT); } idx = expression_eval (args->data, entry); return get_metadata_stream_header (entry, idx); } if (!strcmp ("table-row", name)) { const char *data; guint32 table, row; const MonoTableInfo *info; if (g_slist_length (args) != 2) { printf ("Invalid number of args to table-row %d\n", g_slist_length (args)); exit (INVALID_ARG_COUNT); } table = expression_eval (args->data, entry); row = expression_eval (args->next->data, entry); info = mono_image_get_table_info (entry->test_set->image, table); data = info->base + row * info->row_size; return data - entry->test_set->assembly_data; } if (!strcmp ("blob.i", name)) { guint32 offset, base; MonoStreamHeader blob = entry->test_set->image->heap_blob; if (g_slist_length (args) != 1) { printf ("Invalid number of args to blob %d\n", g_slist_length (args)); exit (INVALID_ARG_COUNT); } base = blob.data - entry->test_set->image->raw_data; offset = expression_eval (args->data, entry); offset = READ_VAR (guint16, entry->data + offset); return base + offset; } printf ("Unknown function %s\n", name); exit (INVALID_FUNCTION_NAME); }