Rizin
unix-like reverse engineering framework and cli tools
rz_basefind.h File Reference
#include <rz_core.h>

Go to the source code of this file.

Classes

struct  rz_basefind_t
 
struct  rz_basefind_info_t
 
struct  rz_basefind_options_t
 

Macros

#define RZ_BASEFIND_STRING_MIN_LENGTH   (10)
 
#define RZ_BASEFIND_BASE_MIN_ADDRESS   (0ull)
 
#define RZ_BASEFIND_BASE_MAX_ADDRESS   (0xf0000000ull)
 
#define RZ_BASEFIND_BASE_ALIGNMENT   (0x1000)
 
#define RZ_BASEFIND_SCORE_MIN_VALUE   (1)
 

Typedefs

typedef struct rz_basefind_t RzBaseFindScore
 
typedef struct rz_basefind_info_t RzBaseFindThreadInfo
 
typedef bool(* RzBaseFindThreadInfoCb) (const RzBaseFindThreadInfo *th_info, void *user)
 
typedef struct rz_basefind_options_t RzBaseFindOpt
 

Functions

RZ_API RZ_OWN RzListrz_basefind (RZ_NONNULL RzCore *core, RZ_NONNULL RzBaseFindOpt *options)
 Calculates a list of possible base addresses candidates using the strings position. More...
 

Macro Definition Documentation

◆ RZ_BASEFIND_BASE_ALIGNMENT

#define RZ_BASEFIND_BASE_ALIGNMENT   (0x1000)

Definition at line 16 of file rz_basefind.h.

◆ RZ_BASEFIND_BASE_MAX_ADDRESS

#define RZ_BASEFIND_BASE_MAX_ADDRESS   (0xf0000000ull)

Definition at line 15 of file rz_basefind.h.

◆ RZ_BASEFIND_BASE_MIN_ADDRESS

#define RZ_BASEFIND_BASE_MIN_ADDRESS   (0ull)

Definition at line 14 of file rz_basefind.h.

◆ RZ_BASEFIND_SCORE_MIN_VALUE

#define RZ_BASEFIND_SCORE_MIN_VALUE   (1)

Definition at line 17 of file rz_basefind.h.

◆ RZ_BASEFIND_STRING_MIN_LENGTH

#define RZ_BASEFIND_STRING_MIN_LENGTH   (10)

Definition at line 13 of file rz_basefind.h.

Typedef Documentation

◆ RzBaseFindOpt

◆ RzBaseFindScore

◆ RzBaseFindThreadInfo

◆ RzBaseFindThreadInfoCb

typedef bool(* RzBaseFindThreadInfoCb) (const RzBaseFindThreadInfo *th_info, void *user)

Definition at line 34 of file rz_basefind.h.

Function Documentation

◆ rz_basefind()

RZ_API RZ_OWN RzList* rz_basefind ( RZ_NONNULL RzCore core,
RZ_NONNULL RzBaseFindOpt options 
)

Calculates a list of possible base addresses candidates using the strings position.

The code finds all the strings in memory with a minimum acceptable size (via opt.min_string_len) and calculates all possible words 32 or 64 bit large sizes (endianness via cfg.bigendian) in the given binary. These addresses are then compared with the strings and a variable base address which is increased over time by opt.alignment.

The scores are added to the result list with the associated base address if their score are higher than opt.min_score, otherwise they are ignored.

It is possible via opt.callback to set a callback function that can stop the search (when returning false) or display the thread statuses (the callback will be called N-times for N spawned threads.

Parameters
coreRzCore struct to use.
optionsPointer to the RzBaseFindOpt structure.

Definition at line 336 of file basefind.c.

336  {
338  RzList *scores = NULL;
339  BaseFindArray *array = NULL;
340  HtUU *pointers = NULL;
341  size_t pool_size = 1;
342  RzThreadPool *pool = NULL;
344  RzThread *user_thread = NULL;
345  BaseFindUIInfo ui_info = { 0 };
346 
347  ut64 base_start = options->start_address;
348  ut64 base_end = options->end_address;
349  ut64 alignment = options->alignment;
350 
351  if (options->pointer_size != 32 && options->pointer_size != 64) {
352  RZ_LOG_ERROR("basefind: supported pointer sizes are 32 and 64 bits.\n");
353  return NULL;
354  } else if (!core->file) {
355  RZ_LOG_ERROR("basefind: the file was not opened via RzCore.\n");
356  return NULL;
357  } else if (base_start >= base_end) {
358  RZ_LOG_ERROR("basefind: start address is greater or equal to end address.\n");
359  return NULL;
360  } else if (alignment < 1) {
361  RZ_LOG_ERROR("basefind: the alignment is set to zero bytes.\n");
362  return NULL;
363  } else if (options->min_score < 1) {
364  RZ_LOG_ERROR("basefind: the minimum score is set to zero.\n");
365  return NULL;
366  } else if (options->min_string_len < 1) {
367  RZ_LOG_ERROR("basefind: the minimum string length is set to zero.\n");
368  return NULL;
369  }
370 
371  if (alignment < RZ_BASEFIND_BASE_ALIGNMENT) {
372  RZ_LOG_WARN("basefind: the alignment is less than 0x%x bytes, "
373  "which may result in a very slow search.\n",
375  }
376 
377  array = basefind_create_array_of_addresses(core, options->min_string_len);
378  if (!array) {
379  goto rz_basefind_end;
380  }
381 
382  pointers = basefind_create_pointer_map(core, options->pointer_size / 8);
383  if (!pointers) {
384  goto rz_basefind_end;
385  }
386 
387  scores = rz_list_newf((RzListFree)free);
388  if (!scores) {
389  RZ_LOG_ERROR("basefind: cannot allocate new scores list.\n");
390  goto rz_basefind_end;
391  }
392 
393  pool = rz_th_pool_new(options->max_threads);
394  if (!pool) {
395  RZ_LOG_ERROR("basefind: cannot allocate thread pool.\n");
396  goto rz_basefind_end;
397  }
398  pool_size = rz_th_pool_size(pool);
399 
400  lock = rz_th_lock_new(false);
401  if (!lock) {
402  RZ_LOG_ERROR("basefind: cannot allocate thread lock.\n");
403  goto rz_basefind_end;
404  }
405 
406  RZ_LOG_VERBOSE("basefind: using %u threads\n", (ut32)pool_size);
407 
408  ut64 io_size = rz_io_size(core->io);
409  ut64 sector_size = (((base_end - base_start) + pool_size - 1) / pool_size);
410  for (size_t i = 0; i < pool_size; ++i) {
412  if (!bftd) {
413  RZ_LOG_ERROR("basefind: cannot allocate BaseFindThreadData.\n");
415  goto rz_basefind_end;
416  }
417  bftd->alignment = alignment;
418  bftd->base_start = base_start + (sector_size * i);
419  bftd->current = bftd->base_start;
420  bftd->base_end = bftd->base_start + sector_size;
421  bftd->score_min = options->min_score;
422  bftd->io_size = io_size;
423  bftd->lock = lock;
424  bftd->scores = scores;
425  bftd->pointers = pointers;
426  bftd->array = array;
427  bftd->loop = rz_atomic_bool_new(true);
428  if (!create_thread_interval(pool, bftd)) {
429  free(bftd);
431  goto rz_basefind_end;
432  }
433  }
434 
435  if (options->callback) {
436  ui_info.pool = pool;
437  ui_info.user = options->user;
438  ui_info.callback = options->callback;
439  ui_info.loop = rz_atomic_bool_new(true);
440  user_thread = rz_th_new((RzThreadFunction)basefind_thread_ui, &ui_info);
441  if (!user_thread) {
443  goto rz_basefind_end;
444  }
445  }
446 
447  // wait the pool to finish
448  rz_th_pool_wait(pool);
449 
450  if (options->callback) {
451  rz_atomic_bool_set(ui_info.loop, false);
452  rz_th_wait(user_thread);
453  rz_th_free(user_thread);
454  rz_atomic_bool_free(ui_info.loop);
455 
456  RzBaseFindThreadInfo th_info;
457  th_info.n_threads = pool_size;
458  for (ut32 i = 0; i < pool_size; ++i) {
459  RzThread *th = rz_th_pool_get_thread(pool, i);
460  if (!th) {
461  continue;
462  }
464  basefind_set_thread_info(bftd, &th_info, i);
465  options->callback(&th_info, options->user);
466  }
467  }
468 
470 
471 rz_basefind_end:
472  if (pool) {
473  for (ut32 i = 0; i < pool_size; ++i) {
474  RzThread *th = rz_th_pool_get_thread(pool, i);
475  if (!th) {
476  continue;
477  }
479  rz_atomic_bool_free(bftd->loop);
480  free(bftd);
481  }
482  rz_th_pool_free(pool);
483  }
485  basefind_array_free(array);
486  ht_uu_free(pointers);
487  return scores;
488 }
lzma_index ** i
Definition: index.h:629
static void basefind_set_thread_info(BaseFindThreadData *bftd, RzBaseFindThreadInfo *th_info, ut32 thread_idx)
Definition: basefind.c:262
static HtUU * basefind_create_pointer_map(RzCore *core, ut32 pointer_size)
Definition: basefind.c:164
static void basefind_array_free(BaseFindArray *array)
Definition: basefind.c:91
static int basefind_score_compare(const RzBaseFindScore *a, const RzBaseFindScore *b)
Definition: basefind.c:203
static void basefind_stop_all_search_threads(RzThreadPool *pool)
Definition: basefind.c:48
static void * basefind_thread_ui(BaseFindUIInfo *ui_info)
Definition: basefind.c:277
static BaseFindArray * basefind_create_array_of_addresses(RzCore *core, ut32 min_string_len)
Definition: basefind.c:109
static bool create_thread_interval(RzThreadPool *pool, BaseFindThreadData *bfd)
Definition: basefind.c:305
#define NULL
Definition: cris-opc.c:27
uint32_t ut32
RZ_API void Ht_() free(HtName_(Ht) *ht)
Definition: ht_inc.c:130
RZ_API RZ_OWN RzList * rz_list_newf(RzListFree f)
Returns a new initialized RzList pointer and sets the free method.
Definition: list.c:248
RZ_API void rz_list_sort(RZ_NONNULL RzList *list, RZ_NONNULL RzListComparator cmp)
Sorts via merge sort or via insertion sort a list.
Definition: list.c:743
RZ_API void rz_th_free(RZ_NULLABLE RzThread *th)
Frees a RzThread structure.
Definition: thread.c:246
RZ_API RZ_OWN void * rz_th_get_user(RZ_NONNULL RzThread *th)
Returns user pointer of thread.
Definition: thread.c:263
RZ_API RZ_OWN RzThread * rz_th_new(RZ_NONNULL RzThreadFunction function, RZ_NULLABLE void *user)
Creates and starts a new thread.
Definition: thread.c:198
RZ_API bool rz_th_wait(RZ_NONNULL RzThread *th)
Awaits indefinetely for a thread to join.
Definition: thread.c:231
static const char struct stat static buf struct stat static buf static vhangup int options
Definition: sflib.h:145
#define rz_return_val_if_fail(expr, val)
Definition: rz_assert.h:108
#define RZ_BASEFIND_BASE_ALIGNMENT
Definition: rz_basefind.h:16
RZ_API ut64 rz_io_size(RzIO *io)
Definition: io.c:399
void(* RzListFree)(void *ptr)
Definition: rz_list.h:11
int(* RzListComparator)(const void *value, const void *list_data)
Definition: rz_list.h:33
#define RZ_LOG_VERBOSE(fmtstr,...)
Definition: rz_log.h:52
#define RZ_LOG_WARN(fmtstr,...)
Definition: rz_log.h:56
#define RZ_LOG_ERROR(fmtstr,...)
Definition: rz_log.h:58
void *(* RzThreadFunction)(void *user)
Definition: rz_th.h:28
#define RZ_NEW(x)
Definition: rz_types.h:285
BaseFindArray * array
Definition: basefind.c:37
RzThreadLock * lock
Definition: basefind.c:34
RzAtomicBool * loop
Definition: basefind.c:38
RzBaseFindThreadInfoCb callback
Definition: basefind.c:45
RzAtomicBool * loop
Definition: basefind.c:42
RzThreadPool * pool
Definition: basefind.c:43
ut32 n_threads
Total number of search threads.
Definition: rz_basefind.h:25
RzThreadPool is a structure which handles n-threads threads.
Definition: thread_pool.c:12
Definition: thread.h:84
RZ_API void rz_th_lock_free(RZ_NULLABLE RzThreadLock *thl)
Frees a RzThreadLock structure.
Definition: thread_lock.c:89
RZ_API RZ_OWN RzThreadLock * rz_th_lock_new(bool recursive)
Allocates and initialize a RzThreadLock structure.
Definition: thread_lock.c:14
RZ_API void rz_th_pool_free(RZ_NULLABLE RzThreadPool *pool)
Kills (and frees) the threads and frees the RzThreadPool struct.
Definition: thread_pool.c:117
RZ_API RZ_BORROW RzThread * rz_th_pool_get_thread(RZ_NONNULL RzThreadPool *pool, size_t index)
Returns the n-th thread in the thread pool.
Definition: thread_pool.c:158
RZ_API bool rz_th_pool_wait(RZ_NONNULL RzThreadPool *pool)
Waits the end of all the threads in the thread pool.
Definition: thread_pool.c:170
RZ_API size_t rz_th_pool_size(RZ_NONNULL RzThreadPool *pool)
Returns the thread pool size.
Definition: thread_pool.c:189
RZ_API RZ_OWN RzThreadPool * rz_th_pool_new(size_t max_threads)
returns a new RzThreadPool structure with a pool of thread
Definition: thread_pool.c:96
RZ_API RZ_OWN RzAtomicBool * rz_atomic_bool_new(bool value)
Initialize a thread safe bool type container.
Definition: thread_types.c:24
RZ_API void rz_atomic_bool_free(RZ_NULLABLE RzAtomicBool *tbool)
Frees a RzAtomicBool structure.
Definition: thread_types.c:39
RZ_API void rz_atomic_bool_set(RZ_NONNULL RzAtomicBool *tbool, bool value)
Sets the value int the RzAtomicBool structure.
Definition: thread_types.c:68
static void lock(volatile int *lk)
Definition: malloc.c:61
ut64(WINAPI *w32_GetEnabledXStateFeatures)()

References basefind_thread_data_t::alignment, basefind_thread_data_t::array, basefind_thread_data_t::base_end, basefind_thread_data_t::base_start, basefind_array_free(), basefind_create_array_of_addresses(), basefind_create_pointer_map(), basefind_score_compare(), basefind_set_thread_info(), basefind_stop_all_search_threads(), basefind_thread_ui(), basefind_ui_info_t::callback, create_thread_interval(), basefind_thread_data_t::current, free(), i, basefind_thread_data_t::io_size, basefind_thread_data_t::lock, lock(), basefind_thread_data_t::loop, basefind_ui_info_t::loop, rz_basefind_info_t::n_threads, NULL, options, basefind_thread_data_t::pointers, basefind_ui_info_t::pool, rz_atomic_bool_free(), rz_atomic_bool_new(), rz_atomic_bool_set(), RZ_BASEFIND_BASE_ALIGNMENT, rz_io_size(), rz_list_newf(), rz_list_sort(), RZ_LOG_ERROR, RZ_LOG_VERBOSE, RZ_LOG_WARN, RZ_NEW, rz_return_val_if_fail, rz_th_free(), rz_th_get_user(), rz_th_lock_free(), rz_th_lock_new(), rz_th_new(), rz_th_pool_free(), rz_th_pool_get_thread(), rz_th_pool_new(), rz_th_pool_size(), rz_th_pool_wait(), rz_th_wait(), basefind_thread_data_t::score_min, basefind_thread_data_t::scores, basefind_ui_info_t::user, and ut64().

Referenced by rz_core_bin_basefind_print().