12 #define starts_with_flag(b, c) (!strncmp(b, c, strlen(c)))
19 char ch =
function->name[
i];
20 if (ch >
' ' && ch <=
'~') {
25 function->name[
i] =
'?';
32 name += strlen(
"sym.");
34 name += strlen(
"flirt.");
51 strncpy(function->name,
name, namelen);
57 function->offset = address -
offset;
58 function->negative_offset =
offset < address;
59 function->is_local = is_local;
72 RZ_LOG_ERROR(
"FLIRT: cannot allocate module tail list\n");
77 if (!
module->public_functions) {
78 RZ_LOG_ERROR(
"FLIRT: cannot allocate module public function list\n");
83 if (!
module->referenced_functions) {
84 RZ_LOG_ERROR(
"FLIRT: cannot allocate module referenced function list\n");
88 if (b_size > 0 &&
buffer) {
98 if (
mask[
i] != 0xff) {
103 RZ_LOG_ERROR(
"FLIRT: cannot allocate or append tail byte to module list\n");
114 RZ_LOG_ERROR(
"FLIRT: cannot append function to public list\n");
135 RZ_LOG_ERROR(
"FLIRT: cannot allocate child module list.\n");
141 RZ_LOG_ERROR(
"FLIRT: cannot allocate child module list.\n");
148 RZ_LOG_ERROR(
"FLIRT: cannot allocate child pattern buffer.\n");
196 RZ_LOG_ERROR(
"FLIRT: cannot append module to child.\n");
217 if (
a->length !=
b->length) {
218 return a->length -
b->length;
226 if (
a->pattern_mask[0] == 0xFF &&
b->pattern_mask[0] == 0xFF) {
227 return memcmp(
a->pattern_bytes,
b->pattern_bytes,
RZ_MIN(
a->length,
b->length));
229 return a->pattern_mask[0] == 0xFF ? -1 : 1;
250 rz_list_foreach (
root->child_list, it, child) {
267 }
else if (child->
length ==
i) {
274 }
else if (node->
length ==
i) {
279 RZ_LOG_ERROR(
"FLIRT: cannot append child to optimized list.\n");
290 it->
data = middle_node;
292 RZ_LOG_ERROR(
"FLIRT: cannot append child to optimized list.\n");
297 RZ_LOG_ERROR(
"FLIRT: cannot append child to optimized list.\n");
309 RZ_LOG_ERROR(
"FLIRT: cannot shorten node or append child to optimized list.\n");
324 if (!
root->child_list) {
333 rz_list_foreach (childs, it, child) {
358 RZ_LOG_ERROR(
"FLIRT: optimization value is invalid (%u > RZ_FLIRT_NODE_OPTIMIZE_MAX).\n", optimization);
363 RZ_LOG_ERROR(
"FLIRT: There are no analyzed functions. Have you run 'aa'?\n");
376 rz_list_foreach (analysis->fcns, it, func) {
391 RZ_LOG_ERROR(
"FLIRT: this function exceeds the max size allowed by iob->read_at.\n");
392 RZ_LOG_ERROR(
"FLIRT: this should never happen. please open a bug report.\n");
398 RZ_LOG_ERROR(
"FLIRT: cannot allocate function buffer.\n");
402 if (!analysis->iob.read_at(analysis->iob.io, func->
addr, pattern, (
int)func_size)) {
410 RZ_LOG_ERROR(
"FLIRT: cannot calculate pattern mask.\n");
419 for (
ut32 i = func_size - 1;
i > 1; --
i) {
420 if (
mask[
i] != 0xFF) {
431 RZ_LOG_ERROR(
"FLIRT: cannot append child to root list.\n");
438 RZ_LOG_ERROR(
"FLIRT: cannot create signature file when i do not have signatures.\n");
RZ_API ut64 rz_analysis_function_linear_size(RzAnalysisFunction *fcn)
RZ_API ut8 * rz_analysis_mask(RzAnalysis *analysis, ut32 size, const ut8 *data, ut64 at)
RZ_API RZ_OWN RzFlirtNode * rz_sign_flirt_node_new(RZ_NONNULL RzAnalysis *analysis, ut32 optimization)
Generates the FLIRT signatures and returns an RzFlirtNode.
int flirt_compare_node(const RzFlirtNode *a, const RzFlirtNode *b)
static RzFlirtModule * flirt_module_new(RzAnalysis *analysis, RzAnalysisFunction *func, const ut8 *buffer, const ut8 *mask, ut64 b_size, bool tail_bytes)
void module_free(RzFlirtModule *module)
static bool flirt_node_shorten_and_insert(const RzFlirtNode *root, RzFlirtNode *node)
static RzFlirtNode * flirt_create_child_from_analysis(RzAnalysis *analysis, RzAnalysisFunction *func, const ut8 *buffer, const ut8 *mask, ut32 b_size, bool tail_bytes)
static RzFlirtFunction * flirt_function_new(const char *name, bool is_local, ut64 offset, ut64 address)
static void flirt_node_shorten_pattern(RzFlirtNode *node, ut32 from)
#define starts_with_flag(b, c)
static int flirt_compare_module(const RzFlirtModule *a, const RzFlirtModule *b)
bool flirt_node_optimize(RzFlirtNode *root)
static RzFlirtNode * flirt_create_child(const ut8 *buffer, const ut8 *mask, ut32 b_size)
static void flirt_function_sanitize_name(RzFlirtFunction *function)
ut16 flirt_crc16(const ut8 *data_p, size_t length)
static bool is_valid_mask_prelude(const ut8 *buffer, ut32 b_size)
static static sync static getppid static getegid const char static filename char static len const char char static bufsiz static mask static vfork const void static prot static getpgrp const char static swapflags static arg static fd static protocol static who struct sockaddr static addrlen static backlog struct timeval struct timezone static tz const struct iovec static count static mode const void const struct sockaddr static tolen const char static pathname void static offset struct stat static buf void long static basep static whence static length const void static len static semflg const void static shmflg const struct timespec struct timespec static rem const char static group const void length
RZ_API void Ht_() free(HtName_(Ht) *ht)
memcpy(mem, inblock.get(), min(CONTAINING_RECORD(inblock.get(), MEMBLOCK, data) ->size, size))
RZ_API RZ_OWN RzList * rz_list_newf(RzListFree f)
Returns a new initialized RzList pointer and sets the free method.
RZ_API void rz_list_sort(RZ_NONNULL RzList *list, RZ_NONNULL RzListComparator cmp)
Sorts via merge sort or via insertion sort a list.
RZ_API bool rz_list_join(RZ_NONNULL RzList *list1, RZ_NONNULL RzList *list2)
Joins 2 list into one (list2 pointer needs to be freed by the user)
RZ_API RZ_BORROW void * rz_list_first(RZ_NONNULL const RzList *list)
Returns the first element of the list.
RZ_API ut32 rz_list_length(RZ_NONNULL const RzList *list)
Returns the length of the list.
RZ_API RZ_BORROW RzListIter * rz_list_append(RZ_NONNULL RzList *list, void *data)
Appends at the end of the list a new element.
RZ_API void rz_list_free(RZ_NONNULL RzList *list)
Empties the list and frees the list pointer.
void * malloc(size_t size)
@ RZ_ANALYSIS_FCN_TYPE_SYM
@ RZ_ANALYSIS_FCN_TYPE_LOC
@ RZ_ANALYSIS_FCN_TYPE_FCN
#define rz_return_val_if_fail(expr, val)
RZ_API void rz_sign_flirt_node_free(RZ_NULLABLE RzFlirtNode *node)
Frees an RzFlirtNode struct.
#define RZ_FLIRT_MAX_PRELUDE_SIZE
@ RZ_FLIRT_NODE_OPTIMIZE_NONE
keeps the structure flattened (keep the tail bytes)
@ RZ_FLIRT_NODE_OPTIMIZE_MAX
optimize the tree structure and drops the tail bytes
#define RZ_FLIRT_NAME_MAX
void(* RzListFree)(void *ptr)
int(* RzListComparator)(const void *value, const void *list_data)
#define RZ_LOG_WARN(fmtstr,...)
#define RZ_LOG_ERROR(fmtstr,...)
#define rz_strf(buf,...)
Convenience macro for local temporary strings.
static struct sockaddr static addrlen static backlog const void static flags void struct sockaddr from
char name[RZ_FLIRT_NAME_MAX]
ut64(WINAPI *w32_GetEnabledXStateFeatures)()