static int agg_instance_read (agg_instance_t *inst, cdtime_t t) /* {{{ */ { value_list_t vl = VALUE_LIST_INIT; char pi_prefix[DATA_MAX_NAME_LEN]; /* Pre-set all the fields in the value list that will not change per * aggregation type (sum, average, ...). The struct will be re-used and must * therefore be dispatched using the "secure" function. */ vl.time = t; vl.interval = 0; vl.meta = meta_data_create (); if (vl.meta == NULL) { ERROR ("aggregation plugin: meta_data_create failed."); return (-1); } meta_data_add_boolean (vl.meta, "aggregation:created", 1); if (AGG_MATCHES_ALL (inst->ident.host)) sstrncpy (vl.host, "global", sizeof (vl.host)); else sstrncpy (vl.host, inst->ident.host, sizeof (vl.host)); sstrncpy (vl.plugin, "aggregation", sizeof (vl.plugin)); if (AGG_MATCHES_ALL (inst->ident.plugin)) { if (AGG_MATCHES_ALL (inst->ident.plugin_instance)) sstrncpy (pi_prefix, "", sizeof (pi_prefix)); else sstrncpy (pi_prefix, inst->ident.plugin_instance, sizeof (pi_prefix)); } else { if (AGG_MATCHES_ALL (inst->ident.plugin_instance)) sstrncpy (pi_prefix, inst->ident.plugin, sizeof (pi_prefix)); else ssnprintf (pi_prefix, sizeof (pi_prefix), "%s-%s", inst->ident.plugin, inst->ident.plugin_instance); } sstrncpy (vl.type, inst->ident.type, sizeof (vl.type)); if (!AGG_MATCHES_ALL (inst->ident.type_instance)) sstrncpy (vl.type_instance, inst->ident.type_instance, sizeof (vl.type_instance)); #define READ_FUNC(func, rate) do { \ if (inst->state_ ## func != NULL) { \ agg_instance_read_func (inst, #func, rate, \ inst->state_ ## func, &vl, pi_prefix, t); \ } \ } while (0) pthread_mutex_lock (&inst->lock); READ_FUNC (num, (gauge_t) inst->num); /* All other aggregations are only defined when there have been any values * at all. */ if (inst->num > 0) { READ_FUNC (sum, inst->sum); READ_FUNC (average, (inst->sum / ((gauge_t) inst->num))); READ_FUNC (min, inst->min); READ_FUNC (max, inst->max); READ_FUNC (stddev, sqrt((((gauge_t) inst->num) * inst->squares_sum) - (inst->sum * inst->sum)) / ((gauge_t) inst->num)); } /* Reset internal state. */ inst->num = 0; inst->sum = 0.0; inst->squares_sum = 0.0; inst->min = NAN; inst->max = NAN; pthread_mutex_unlock (&inst->lock); meta_data_destroy (vl.meta); vl.meta = NULL; return (0); } /* }}} int agg_instance_read */
/* For 32-bit build, supports looking for x64 marker (in WOW64 process). * For 64-bit build, only supports looking for x64 marker. */ static int read_and_verify_dr_marker_common(HANDLE process, dr_marker_t *marker, bool x64) { byte buf[8]; /* only needs to be 5, but dword pad just in case */ size_t res; void *target = NULL; #if !defined(NOT_DYNAMORIO_CORE) && !defined(NOT_DYNAMORIO_CORE_PROPER) GET_NTDLL(DR_MARKER_HOOKED_FUNCTION, DR_MARKER_HOOKED_FUNCTION_ARGS); void *hook_func = (void *)DR_MARKER_HOOKED_FUNCTION; #else if (IF_X64_ELSE(!x64, x64 && !is_wow64_process(NT_CURRENT_PROCESS))) return DR_MARKER_ERROR; if (x64) { # ifndef X64 uint64 hook_func = get_proc_address_64 (get_module_handle_64(L_DR_MARKER_HOOKED_DLL), DR_MARKER_HOOKED_FUNCTION_STRING); uint64 landing_pad = 0; if (hook_func == 0) return DR_MARKER_ERROR; if (!NT_SUCCESS(nt_wow64_read_virtual_memory64(process, hook_func, buf, 5, &res)) || res != 5) { return DR_MARKER_ERROR; } if (buf[0] != OP_jmp_byte) return DR_MARKER_NOT_FOUND; /* jmp offset + EIP (after jmp = hook_func + size of jmp (5 bytes)) */ /* for 64-bit, the target is stored in front of the trampoline */ landing_pad = *(int *)&buf[1] + hook_func + 5 - 8; if (!NT_SUCCESS(nt_wow64_read_virtual_memory64(process, landing_pad, buf, 8, &res)) || res != 8U) return DR_MARKER_ERROR; /* trampoline address is stored at the top of the landing pad for 64-bit */ target = (void *)PAGE_START(*(ptr_int_t *)buf); } else { # endif /* !X64 */ void *hook_func = (void *)GetProcAddress(GetModuleHandle(DR_MARKER_HOOKED_DLL), DR_MARKER_HOOKED_FUNCTION_STRING); #endif void *landing_pad; if (hook_func == NULL) return DR_MARKER_ERROR; if (!READ_FUNC(process, hook_func, buf, 5, &res) || res != 5) return DR_MARKER_ERROR; if (buf[0] != OP_jmp_byte) return DR_MARKER_NOT_FOUND; /* jmp offset + EIP (after jmp = hook_func + size of jmp (5 bytes)) */ landing_pad = (void *)(*(int *)&buf[1] + (ptr_int_t)hook_func + 5); /* for 64-bit, the target is stored in front of the trampoline */ if (x64) landing_pad = (byte *)landing_pad - 8; /* see emit_landing_pad_code() for layout of landing pad */ if (!READ_FUNC(process, landing_pad, buf, (x64 ? 8 : 5), &res) || res != (x64 ? 8U : 5U)) return DR_MARKER_ERROR; if (x64) { /* trampoline address is stored at the top of the landing pad for 64-bit */ target = (void *)PAGE_START(*(ptr_int_t *)buf); } else { /* jmp offset + EIP (after jmp = landing_pad + size of jmp (5 bytes)) */ target = (void *)PAGE_START(*(int *)&buf[1] + (ptr_int_t)landing_pad + 5); } #if defined(NOT_DYNAMORIO_CORE) || defined(NOT_DYNAMORIO_CORE_PROPER) } #endif if (target == NULL) return DR_MARKER_ERROR; if (!READ_FUNC(process, target, marker, sizeof(dr_marker_t), &res) || res != sizeof(dr_marker_t)) { return DR_MARKER_NOT_FOUND; } if (dr_marker_verify(process, marker)) { return DR_MARKER_FOUND; } return DR_MARKER_NOT_FOUND; /* probably some other hooker */ }