Rizin
unix-like reverse engineering framework and cli tools
cannotated_code.c
Go to the documentation of this file.
1 // SPDX-FileCopyrightText: 2020 NIRMAL MANOJ C <nimmumanoj@gmail.com>
2 // SPDX-License-Identifier: LGPL-3.0-only
4 
5 #include <rz_util.h>
6 #include <rz_core.h>
7 #include <rz_types.h>
8 #include <rz_vector.h>
9 
11  PJ *pj = pj_new();
12  if (!pj) {
13  return;
14  }
15 
16  pj_o(pj);
17  pj_ks(pj, "code", code->code);
18 
19  pj_k(pj, "annotations");
20  pj_a(pj);
21 
22  char *type_str;
23  RzCodeAnnotation *annotation;
24  rz_vector_foreach(&code->annotations, annotation) {
25  pj_o(pj);
26  pj_kn(pj, "start", (ut64)annotation->start);
27  pj_kn(pj, "end", (ut64)annotation->end);
28  switch (annotation->type) {
30  pj_ks(pj, "type", "offset");
31  pj_kn(pj, "offset", annotation->offset.offset);
32  break;
34  pj_ks(pj, "type", "function_name");
35  pj_ks(pj, "name", annotation->reference.name);
36  pj_kn(pj, "offset", annotation->reference.offset);
37  break;
39  pj_ks(pj, "type", "global_variable");
40  pj_kn(pj, "offset", annotation->reference.offset);
41  break;
43  pj_ks(pj, "type", "constant_variable");
44  pj_kn(pj, "offset", annotation->reference.offset);
45  break;
47  pj_ks(pj, "type", "local_variable");
48  pj_ks(pj, "name", annotation->variable.name);
49  break;
51  pj_ks(pj, "type", "function_parameter");
52  pj_ks(pj, "name", annotation->variable.name);
53  break;
55  pj_ks(pj, "type", "syntax_highlight");
56  type_str = NULL;
57  switch (annotation->syntax_highlight.type) {
59  type_str = "keyword";
60  break;
62  type_str = "comment";
63  break;
65  type_str = "datatype";
66  break;
68  type_str = "function_name";
69  break;
71  type_str = "function_parameter";
72  break;
74  type_str = "local_variable";
75  break;
77  type_str = "constant_variable";
78  break;
80  type_str = "global_variable";
81  break;
82  }
83  if (type_str) {
84  pj_ks(pj, "syntax_highlight", type_str);
85  }
86  break;
87  }
88  pj_end(pj);
89  }
90  pj_end(pj);
91 
92  pj_end(pj);
93  rz_cons_printf("%s\n", pj_string(pj));
94  pj_free(pj);
95 }
96 
97 #define PALETTE(x) (cons && cons->context->pal.x) ? cons->context->pal.x
98 #define PRINT_COLOR(x) \
99  do { \
100  if (cons->context->color_mode) { \
101  rz_cons_printf("%s", (x)); \
102  } \
103  } while (0)
104 
109  static const char *fmt[9] = {
110  "0x%08" PFMT64x,
111  "0x%09" PFMT64x,
112  "0x%010" PFMT64x,
113  "0x%011" PFMT64x,
114  "0x%012" PFMT64x,
115  "0x%013" PFMT64x,
116  "0x%014" PFMT64x,
117  "0x%015" PFMT64x,
118  "0x%016" PFMT64x
119  };
120  if (width < 8) {
121  width = 8;
122  }
123  if (width > 16) {
124  width = 16;
125  }
126  width -= 8;
127 
128  RzCons *cons = rz_cons_singleton();
129  rz_cons_printf(" ");
130  if (offset == UT64_MAX) {
131  rz_cons_print(" ");
132  while (width > 0) {
133  rz_cons_print(" ");
134  width--;
135  }
136  } else {
138  : Color_GREEN);
139  rz_cons_printf(fmt[width], offset);
141  }
142  rz_cons_printf(" |");
143 }
144 
146  if (code->annotations.len == 0) {
147  rz_cons_printf("%s\n", code->code);
148  return;
149  }
150 
151  size_t cur = 0;
152  size_t line_idx = 0;
153  size_t len = strlen(code->code);
154 
155  size_t offset_width = 0;
156  if (line_offsets) {
157  ut64 *offset;
158  ut64 offset_max = 0;
159  rz_vector_foreach(line_offsets, offset) {
160  if (*offset != UT64_MAX && *offset > offset_max) {
161  offset_max = *offset;
162  }
163  }
164  while (offset_max) {
165  offset_width += 1;
166  offset_max >>= 4;
167  }
168  if (offset_width < 4) {
169  offset_width = 4;
170  }
171  }
172 
173  RzCons *cons = rz_cons_singleton();
174  RzCodeAnnotation *annotation;
175  rz_vector_foreach(&code->annotations, annotation) {
176  if (annotation->type != RZ_CODE_ANNOTATION_TYPE_SYNTAX_HIGHLIGHT) {
177  continue;
178  }
179 
180  // (1/3)
181  // now we have a syntax highlighting annotation.
182  // pick a suitable color for it.
183  const char *color = Color_RESET;
184  switch (annotation->syntax_highlight.type) {
186  color = PALETTE(comment)
187  : Color_WHITE;
188  break;
190  color = PALETTE(pop)
191  : Color_MAGENTA;
192  break;
194  color = PALETTE(func_var_type)
195  : Color_BLUE;
196  break;
198  color = PALETTE(fname)
199  : Color_RED;
200  break;
202  color = PALETTE(num)
203  : Color_YELLOW;
204  default:
205  break;
206  }
207 
208  // (2/3)
209  // the chunk before the syntax highlighting annotation should not be colored
210  for (; cur < annotation->start && cur < len; cur++) {
211  // if we are starting a new line and we are printing with offsets
212  // we need to prepare the bar with offsets on the left handside before that
213  if (line_offsets && (cur == 0 || code->code[cur - 1] == '\n')) {
214  ut64 offset = 0;
215  if (line_idx < line_offsets->len) {
216  offset = *(ut64 *)rz_vector_index_ptr(line_offsets, line_idx);
217  }
219  line_idx++;
220  }
221  rz_cons_printf("%c", code->code[cur]);
222  }
223 
224  // (3/3)
225  // everything in between the "start" and the "end" inclusive should be highlighted
227  for (; cur < annotation->end && cur < len; cur++) {
228  // if we are starting a new line and we are printing with offsets
229  // we need to prepare the bar with offsets on the left handside before that
230  if (line_offsets && (cur == 0 || code->code[cur - 1] == '\n')) {
231  ut64 offset = 0;
232  if (line_idx < line_offsets->len) {
233  offset = *(ut64 *)rz_vector_index_ptr(line_offsets, line_idx);
234  }
238  line_idx++;
239  }
240  rz_cons_printf("%c", code->code[cur]);
241  }
243  }
244  // the rest of the decompiled code should be printed
245  // without any highlighting since we don't have any annotations left
246  for (; cur < len; cur++) {
247  // if we are starting a new line and we are printing with offsets
248  // we need to prepare the bar with offsets on the left handside before that
249  if (line_offsets && (cur == 0 || code->code[cur - 1] == '\n')) {
250  ut64 offset = 0;
251  if (line_idx < line_offsets->len) {
252  offset = *(ut64 *)rz_vector_index_ptr(line_offsets, line_idx);
253  }
255  line_idx++;
256  }
257  rz_cons_printf("%c", code->code[cur]);
258  }
259 }
260 
261 static bool foreach_offset_annotation(void *user, const ut64 offset, const void *val) {
262  RzAnnotatedCode *code = user;
263  const RzCodeAnnotation *annotation = val;
264  char *b64statement = rz_base64_encode_dyn((const ut8 *)(code->code + annotation->start),
265  annotation->end - annotation->start);
266  rz_cons_printf("CCu base64:%s @ 0x%" PFMT64x "\n", b64statement, annotation->offset.offset);
267  free(b64statement);
268  return true;
269 }
270 
272  RzCodeAnnotation *annotation;
273  HtUP *ht = ht_up_new0();
274  rz_vector_foreach(&code->annotations, annotation) {
275  if (annotation->type != RZ_CODE_ANNOTATION_TYPE_OFFSET) {
276  continue;
277  }
278  // choose the "best" annotation at a single offset
279  RzCodeAnnotation *prev_annot = ht_up_find(ht, annotation->offset.offset, NULL);
280  if (prev_annot) {
281  if (annotation->end - annotation->start < prev_annot->end - prev_annot->start) {
282  continue;
283  }
284  }
285  ht_up_update(ht, annotation->offset.offset, annotation);
286  }
287  ht_up_foreach(ht, foreach_offset_annotation, code);
288  ht_up_free(ht);
289 }
size_t len
Definition: 6502dis.c:15
ut16 val
Definition: armass64_const.h:6
#define PRINT_COLOR(x)
RZ_API void rz_core_annotated_code_print_json(RzAnnotatedCode *code)
RZ_API void rz_core_annotated_code_print(RzAnnotatedCode *code, RzVector *line_offsets)
static void print_offset_in_binary_line_bar(RzAnnotatedCode *code, ut64 offset, size_t width)
RZ_API void rz_core_annotated_code_print_comment_cmds(RzAnnotatedCode *code)
#define PALETTE(x)
static bool foreach_offset_annotation(void *user, const ut64 offset, const void *val)
RZ_API RzCons * rz_cons_singleton(void)
Definition: cons.c:300
RZ_API int rz_cons_printf(const char *format,...)
Definition: cons.c:1202
#define RZ_API
#define NULL
Definition: cris-opc.c:27
RZ_API void Ht_() free(HtName_(Ht) *ht)
Definition: ht_inc.c:130
voidpf uLong offset
Definition: ioapi.h:144
uint8_t ut8
Definition: lh5801.h:11
static static fork const void static count static fd const char const char static newpath char char char static envp time_t static t const char static mode static whence const char static dir time_t static t unsigned static seconds const char struct utimbuf static buf static inc static sig const char static mode static oldfd struct tms static buf static getgid static geteuid const char static filename static arg static mask struct ustat static ubuf static getppid static setsid static egid sigset_t static set struct timeval struct timezone static tz fd_set fd_set fd_set struct timeval static timeout const char char static bufsiz const char static swapflags void static offset const char static length static mode static who const char struct statfs static buf unsigned unsigned num
Definition: sflib.h:126
@ RZ_CODE_ANNOTATION_TYPE_GLOBAL_VARIABLE
@ RZ_CODE_ANNOTATION_TYPE_FUNCTION_PARAMETER
@ RZ_CODE_ANNOTATION_TYPE_CONSTANT_VARIABLE
@ RZ_CODE_ANNOTATION_TYPE_LOCAL_VARIABLE
@ RZ_CODE_ANNOTATION_TYPE_OFFSET
@ RZ_CODE_ANNOTATION_TYPE_SYNTAX_HIGHLIGHT
@ RZ_CODE_ANNOTATION_TYPE_FUNCTION_NAME
@ RZ_SYNTAX_HIGHLIGHT_TYPE_LOCAL_VARIABLE
@ RZ_SYNTAX_HIGHLIGHT_TYPE_FUNCTION_NAME
@ RZ_SYNTAX_HIGHLIGHT_TYPE_CONSTANT_VARIABLE
@ RZ_SYNTAX_HIGHLIGHT_TYPE_KEYWORD
@ RZ_SYNTAX_HIGHLIGHT_TYPE_DATATYPE
@ RZ_SYNTAX_HIGHLIGHT_TYPE_FUNCTION_PARAMETER
@ RZ_SYNTAX_HIGHLIGHT_TYPE_GLOBAL_VARIABLE
@ RZ_SYNTAX_HIGHLIGHT_TYPE_COMMENT
RZ_API char * rz_base64_encode_dyn(const ut8 *bin, size_t sz)
Definition: ubase64.c:92
#define Color_RESET
Definition: rz_cons.h:617
#define Color_WHITE
Definition: rz_cons.h:625
#define Color_MAGENTA
Definition: rz_cons.h:629
#define Color_GREEN
Definition: rz_cons.h:627
#define Color_RED
Definition: rz_cons.h:623
#define Color_YELLOW
Definition: rz_cons.h:631
#define Color_BLUE
Definition: rz_cons.h:635
RZ_API PJ * pj_new(void)
Definition: pj.c:25
RZ_API PJ * pj_k(PJ *j, const char *k)
Definition: pj.c:104
RZ_API PJ * pj_end(PJ *j)
Definition: pj.c:87
RZ_API const char * pj_string(PJ *pj)
Definition: pj.c:57
RZ_API void pj_free(PJ *j)
Definition: pj.c:34
RZ_API PJ * pj_o(PJ *j)
Definition: pj.c:75
RZ_API PJ * pj_ks(PJ *j, const char *k, const char *v)
Definition: pj.c:170
RZ_API PJ * pj_kn(PJ *j, const char *k, ut64 n)
Definition: pj.c:121
RZ_API PJ * pj_a(PJ *j)
Definition: pj.c:81
#define PFMT64x
Definition: rz_types.h:393
#define UT64_MAX
Definition: rz_types_base.h:86
static void * rz_vector_index_ptr(RzVector *vec, size_t index)
Definition: rz_vector.h:88
#define rz_vector_foreach(vec, it)
Definition: rz_vector.h:169
Definition: inftree9.h:24
Definition: rz_pj.h:12
This structure contains the decompiled code and all the annotations for the decompiled code.
Annotations for the decompiled code are represented using this structure.
RzCodeAnnotationType type
struct rz_code_annotation_t::@297::@300 syntax_highlight
struct rz_code_annotation_t::@297::@301 reference
struct rz_code_annotation_t::@297::@302 variable
int width
Definition: main.c:10
static int color
Definition: visual.c:20
ut64(WINAPI *w32_GetEnabledXStateFeatures)()