Rizin
unix-like reverse engineering framework and cli tools
debruijn.c
Go to the documentation of this file.
1 // SPDX-FileCopyrightText: 2014-2016 crowell <crowell@bu.edu>
2 // SPDX-FileCopyrightText: 2014-2016 pancake <pancake@nopcode.org>
3 // SPDX-License-Identifier: LGPL-3.0-only
4 
5 #include <rz_util.h>
6 
7 // The following two (commented out) lines are the character set used in peda.
8 // You may use this charset instead of the A-Za-z0-9 charset normally used.
9 // char* peda_charset =
10 // "A%sB$nC-(D;)Ea0Fb1Gc2Hd3Ie4Jf5Kg6Lh7Mi8Nj9OkPlQmRnSoTpUqVrWsXtYuZvwxyz";
11 
12 static const char *debruijn_charset = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890";
13 
14 // Generate a De Bruijn sequence.
15 static void de_bruijn_seq(int prenecklace_len_t, int lyndon_prefix_len_p, int order,
16  int maxlen, int size, int *prenecklace_a, char *sequence, const char *charset) {
17  int j;
18  if (!charset || !sequence || strlen(sequence) == maxlen) {
19  return;
20  }
21  if (prenecklace_len_t > order) {
22  if (order % lyndon_prefix_len_p == 0) {
23  for (j = 1; j <= lyndon_prefix_len_p; j++) {
24  sequence[strlen(sequence)] = charset[prenecklace_a[j]];
25  if (strlen(sequence) == maxlen) {
26  return;
27  }
28  }
29  }
30  } else {
31  prenecklace_a[prenecklace_len_t] =
32  prenecklace_a[prenecklace_len_t - lyndon_prefix_len_p];
33  de_bruijn_seq(prenecklace_len_t + 1, lyndon_prefix_len_p, order, maxlen,
34  size, prenecklace_a, sequence, charset);
35  for (j = prenecklace_a[prenecklace_len_t - lyndon_prefix_len_p] + 1;
36  j < size; j++) {
37  prenecklace_a[prenecklace_len_t] = j;
38  de_bruijn_seq(prenecklace_len_t + 1, prenecklace_len_t, order, maxlen,
39  size, prenecklace_a, sequence, charset);
40  }
41  }
42 }
43 
44 // Generate a De Bruijn sequence.
45 // The returned string is malloced, and it is the responsibility of the caller
46 // to free the memory.
47 static char *de_bruijn(const char *charset, int order, int maxlen) {
48  if (!charset) {
49  return NULL;
50  }
51  size_t size = strlen(charset);
52  int *prenecklace_a = calloc(size * (size_t)order, sizeof(int));
53  if (!prenecklace_a) {
54  return NULL;
55  }
56  char *sequence = calloc(maxlen + 1, sizeof(char));
57  if (!sequence) {
58  free(prenecklace_a);
59  return NULL;
60  }
61  de_bruijn_seq(1, 1, order, maxlen, size, prenecklace_a, sequence, charset);
62  free(prenecklace_a);
63  return sequence;
64 }
65 
80 RZ_API RZ_OWN char *rz_debruijn_pattern(int size, int start, const char *charset) {
83  if (!charset) {
84  charset = debruijn_charset;
85  }
86  char *pat = de_bruijn(charset, 3, size + start);
87  if (!pat || start == 0) {
88  return pat;
89  }
90 
91  char *pat2 = RZ_NEWS0(char, size + 1);
92  if (!pat2) {
93  free(pat);
94  return NULL;
95  }
96  size_t len = strlen(pat + start);
98  strcpy(pat2, pat + start);
99  free(pat);
100  return pat2;
101 }
102 
112 RZ_API int rz_debruijn_offset(int start, const char *charset, ut64 value, bool is_big_endian) {
113  int retval = -1;
114  // 0x10000 should be long enough. This is how peda works, and nobody complains
115  // ... but is slow. Optimize for common case.
116  int lens[] = { 0x1000, 0x10000, 0x100000 };
117  int j;
118 
119  if (value == 0) {
120  return -1;
121  }
122 
123  for (j = 0; j < RZ_ARRAY_SIZE(lens) && retval == -1; j++) {
124  char *pattern = rz_debruijn_pattern(lens[j], start, charset);
125  if (!pattern) {
126  return -1;
127  }
128 
129  char buf[9];
130  buf[8] = '\0';
131  if (is_big_endian) {
133  } else {
135  }
136  char *needle;
137  for (needle = buf; !*needle; needle++) {
138  /* do nothing here */
139  }
140 
141  char *pch = strstr(pattern, needle);
142  if (pch) {
143  retval = (int)(size_t)(pch - pattern);
144  }
145  free(pattern);
146  }
147  return retval;
148 }
size_t len
Definition: 6502dis.c:15
static int value
Definition: cmd_api.c:93
#define RZ_API
#define NULL
Definition: cris-opc.c:27
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 start
Definition: sflib.h:133
static void de_bruijn_seq(int prenecklace_len_t, int lyndon_prefix_len_p, int order, int maxlen, int size, int *prenecklace_a, char *sequence, const char *charset)
Definition: debruijn.c:15
static char * de_bruijn(const char *charset, int order, int maxlen)
Definition: debruijn.c:47
RZ_API int rz_debruijn_offset(int start, const char *charset, ut64 value, bool is_big_endian)
Finds the offset of a given value in a debrujn sequence.
Definition: debruijn.c:112
RZ_API RZ_OWN char * rz_debruijn_pattern(int size, int start, const char *charset)
Generate a cyclic pattern following the Debruijn pattern.
Definition: debruijn.c:80
static const char * debruijn_charset
Definition: debruijn.c:12
RZ_API void Ht_() free(HtName_(Ht) *ht)
Definition: ht_inc.c:130
voidpf void uLong size
Definition: ioapi.h:138
voidpf void * buf
Definition: ioapi.h:138
void * calloc(size_t number, size_t size)
Definition: malloc.c:102
bool MACH0_() is_big_endian(struct MACH0_(obj_t) *bin)
Definition: mach0.c:3312
#define rz_return_val_if_fail(expr, val)
Definition: rz_assert.h:108
static void rz_write_be64(void *dest, ut64 val)
Definition: rz_endian.h:119
static void rz_write_le64(void *dest, ut64 val)
Definition: rz_endian.h:277
#define RZ_OWN
Definition: rz_types.h:62
#define RZ_NEWS0(x, y)
Definition: rz_types.h:282
#define RZ_ARRAY_SIZE(x)
Definition: rz_types.h:300
static int
Definition: sfsocketcall.h:114
ut64 maxlen
Definition: core.c:76
ut64(WINAPI *w32_GetEnabledXStateFeatures)()