|
9 | 9 | #include <stdio.h>
|
10 | 10 |
|
11 | 11 | #include "qemu.h"
|
| 12 | +#include "qemu/xxhash.h" |
12 | 13 | #include "unicorn/unicorn.h"
|
13 | 14 | #include "list.h"
|
14 | 15 |
|
@@ -157,6 +158,7 @@ struct hook {
|
157 | 158 | // address (depends on hook type)
|
158 | 159 | void *callback; // a uc_cb_* type
|
159 | 160 | void *user_data;
|
| 161 | + GHashTable *hooked_regions; // The regions this hook instrumented on |
160 | 162 | };
|
161 | 163 |
|
162 | 164 | // Add an inline hook to helper_table
|
@@ -414,6 +416,53 @@ static inline int uc_addr_is_exit(uc_engine *uc, uint64_t addr)
|
414 | 416 | }
|
415 | 417 | }
|
416 | 418 |
|
| 419 | +typedef struct HookedRegion { |
| 420 | + uint64_t start; |
| 421 | + uint64_t length; |
| 422 | +} HookedRegion; |
| 423 | + |
| 424 | +// hooked_regions related functions |
| 425 | +static inline guint hooked_regions_hash(const void* p) { |
| 426 | + HookedRegion *region = (HookedRegion*)p; |
| 427 | + |
| 428 | + return qemu_xxhash4(region->start, region->length); |
| 429 | +} |
| 430 | + |
| 431 | +static inline gboolean hooked_regions_equal(const void* lhs, const void* rhs) { |
| 432 | + HookedRegion *l = (HookedRegion*)lhs; |
| 433 | + HookedRegion *r = (HookedRegion*)rhs; |
| 434 | + |
| 435 | + return l->start == r->start && l->length == r->length; |
| 436 | +} |
| 437 | + |
| 438 | +static inline void hooked_regions_add(struct hook* h, uint64_t start, uint64_t length) { |
| 439 | + HookedRegion tmp; |
| 440 | + tmp.start = start; |
| 441 | + tmp.length = length; |
| 442 | + |
| 443 | + if (!g_hash_table_lookup(h->hooked_regions, (void*)&tmp)) { |
| 444 | + HookedRegion* r = malloc(sizeof(HookedRegion)); |
| 445 | + r->start = start; |
| 446 | + r->length = length; |
| 447 | + g_hash_table_insert(h->hooked_regions, (void*)r, (void*)1); |
| 448 | + } |
| 449 | +} |
| 450 | + |
| 451 | +static inline void hooked_regions_check_single(struct list_item *cur, uint64_t start, uint64_t length) { |
| 452 | + while (cur != NULL) { |
| 453 | + if (HOOK_BOUND_CHECK((struct hook *)cur->data, start)) { |
| 454 | + hooked_regions_add((struct hook *)cur->data, start, length); |
| 455 | + } |
| 456 | + cur = cur->next; |
| 457 | + } |
| 458 | +} |
| 459 | + |
| 460 | +static inline void hooked_regions_check(uc_engine *uc, uint64_t start, uint64_t length) { |
| 461 | + // Only UC_HOOK_BLOCK and UC_HOOK_CODE might be wrongle cached! |
| 462 | + hooked_regions_check_single(uc->hook[UC_HOOK_CODE_IDX].head, start, length); |
| 463 | + hooked_regions_check_single(uc->hook[UC_HOOK_BLOCK_IDX].head, start, length); |
| 464 | +} |
| 465 | + |
417 | 466 | #ifdef UNICORN_TRACER
|
418 | 467 | #define UC_TRACE_START(loc) trace_start(get_tracer(), loc)
|
419 | 468 | #define UC_TRACE_END(loc, fmt, ...) \
|
|
0 commit comments