Rizin
unix-like reverse engineering framework and cli tools
bin_language.c File Reference
#include <rz_bin.h>

Go to the source code of this file.

Macros

#define LANGUAGE_WITH_BLOCKS   " with blocks"
 
#define language_apply_blocks_mask(x, b)   (b ? (RZ_BIN_LANGUAGE_BLOCKS | (x)) : (x))
 
#define language_apply_blocks_string(x, b)   (RZ_BIN_LANGUAGE_HAS_BLOCKS(x) ? (b LANGUAGE_WITH_BLOCKS) : (b))
 

Functions

static bool check_rust (RzBinSymbol *sym)
 
static bool check_objc (RzBinSymbol *sym)
 
static bool check_dlang (RzBinSymbol *sym)
 
static bool check_swift (RzBinSymbol *sym)
 
static bool check_golang (RzBinSymbol *sym)
 
static bool check_cxx (RzBinSymbol *sym)
 
static bool check_msvc (RzBinSymbol *sym)
 
static bool check_kotlin (RzBinSymbol *sym)
 
static bool check_groovy (RzBinSymbol *sym)
 
static bool check_dart (RzBinSymbol *sym)
 
RZ_API RzBinLanguage rz_bin_language_detect (RzBinFile *binfile)
 Tries to detect which language is used in the binary based on symbols and libraries. More...
 
RZ_API RzBinLanguage rz_bin_language_to_id (const char *language)
 returns the language identifier based on the given lang name More...
 
RZ_API const char * rz_bin_language_to_string (RzBinLanguage language)
 returns the language name based on the given language identifier More...
 

Macro Definition Documentation

◆ language_apply_blocks_mask

#define language_apply_blocks_mask (   x,
  b 
)    (b ? (RZ_BIN_LANGUAGE_BLOCKS | (x)) : (x))

Definition at line 9 of file bin_language.c.

◆ language_apply_blocks_string

#define language_apply_blocks_string (   x,
  b 
)    (RZ_BIN_LANGUAGE_HAS_BLOCKS(x) ? (b LANGUAGE_WITH_BLOCKS) : (b))

Definition at line 10 of file bin_language.c.

◆ LANGUAGE_WITH_BLOCKS

#define LANGUAGE_WITH_BLOCKS   " with blocks"

Definition at line 8 of file bin_language.c.

Function Documentation

◆ check_cxx()

static bool check_cxx ( RzBinSymbol sym)
inlinestatic

Definition at line 37 of file bin_language.c.

37  {
38  if (!strncmp(sym->name, "_Z", 2)) {
39  return true;
40  }
41  return !strncmp(sym->name, "__Z", 3);
42 }
char * name
Definition: rz_bin.h:675

References rz_bin_symbol_t::name.

Referenced by rz_bin_language_detect().

◆ check_dart()

static bool check_dart ( RzBinSymbol sym)
inlinestatic

Definition at line 56 of file bin_language.c.

56  {
57  return strstr(sym->name, "io_flutter_");
58 }

References rz_bin_symbol_t::name.

Referenced by rz_bin_language_detect().

◆ check_dlang()

static bool check_dlang ( RzBinSymbol sym)
inlinestatic

Definition at line 21 of file bin_language.c.

21  {
22  if (!strncmp(sym->name, "_D2", 3)) {
23  return true;
24  }
25  return !strncmp(sym->name, "_D4", 3);
26 }

References rz_bin_symbol_t::name.

Referenced by rz_bin_language_detect().

◆ check_golang()

static bool check_golang ( RzBinSymbol sym)
inlinestatic

Definition at line 32 of file bin_language.c.

32  {
33  return !strncmp(sym->name, "go.", 3) ||
34  strstr(sym->name, "gopclntab");
35 }

References rz_bin_symbol_t::name.

Referenced by rz_bin_language_detect().

◆ check_groovy()

static bool check_groovy ( RzBinSymbol sym)
inlinestatic

Definition at line 52 of file bin_language.c.

52  {
53  return strstr(sym->name, "_groovy");
54 }

References rz_bin_symbol_t::name.

Referenced by rz_bin_language_detect().

◆ check_kotlin()

static bool check_kotlin ( RzBinSymbol sym)
inlinestatic

Definition at line 48 of file bin_language.c.

48  {
49  return strstr(sym->name, "kotlin_");
50 }

References rz_bin_symbol_t::name.

Referenced by rz_bin_language_detect().

◆ check_msvc()

static bool check_msvc ( RzBinSymbol sym)
inlinestatic

Definition at line 44 of file bin_language.c.

44  {
45  return *sym->name == '?';
46 }

References rz_bin_symbol_t::name.

Referenced by rz_bin_language_detect().

◆ check_objc()

static bool check_objc ( RzBinSymbol sym)
inlinestatic

Definition at line 17 of file bin_language.c.

17  {
18  return !strncmp(sym->name, "_OBJC_", 6);
19 }

References rz_bin_symbol_t::name.

Referenced by rz_bin_language_detect().

◆ check_rust()

static bool check_rust ( RzBinSymbol sym)
inlinestatic

Definition at line 12 of file bin_language.c.

12  {
13  return strstr(sym->name, "_$LT$") ||
14  strstr(sym->name, "_rust_oom");
15 }

References rz_bin_symbol_t::name.

Referenced by rz_bin_language_detect().

◆ check_swift()

static bool check_swift ( RzBinSymbol sym)
inlinestatic

Definition at line 28 of file bin_language.c.

28  {
29  return strstr(sym->name, "swift_once");
30 }

References rz_bin_symbol_t::name.

Referenced by rz_bin_language_detect().

◆ rz_bin_language_detect()

RZ_API RzBinLanguage rz_bin_language_detect ( RzBinFile binfile)

Tries to detect which language is used in the binary based on symbols and libraries.

Currently this method can detect the language only from bins that are either ELF, PE, Mach-O, Java Class and Dex.

The current supported languages are: c, cxx, dart, dlang, go, groovy, java, kotlin, msvc, objc, rust, swift.

Definition at line 69 of file bin_language.c.

69  {
70  rz_return_val_if_fail(binfile && binfile->o, RZ_BIN_LANGUAGE_UNKNOWN);
71  RzBinObject *o = binfile->o;
72  RzBinInfo *info = o->info;
73  RzBinSymbol *sym;
76 
77  if (!info) {
79  }
81  if (lang != RZ_BIN_LANGUAGE_UNKNOWN &&
82  lang != RZ_BIN_LANGUAGE_C &&
83  lang != RZ_BIN_LANGUAGE_OBJC) {
84  // avoid detecting a language if was already specified.
85  return lang;
86  }
87 
88  bool is_macho = info->rclass ? strstr(info->rclass, "mach") : false;
89  bool is_elf = info->rclass ? strstr(info->rclass, "elf") : false;
90  bool is_pe = info->rclass ? strstr(info->rclass, "pe") : false;
91  bool is_class = info->rclass ? strstr(info->rclass, "class") : false;
92  bool is_blocks = false;
93  bool is_objc = false;
94  bool is_cpp = false;
95  char *lib = NULL;
96 
97  if (!is_macho && !is_elf && !is_pe && !is_class) {
99  }
100 
101  if (is_macho || is_elf) {
102  rz_list_foreach (o->imports, iter, sym) {
103  const char *name = sym->name;
104  if (!strcmp(name, "_NSConcreteGlobalBlock")) {
105  is_blocks = true;
106  } else if (!strncmp(name, "objc_", 5)) {
107  is_objc = true;
108  }
109  }
110  }
111  rz_list_foreach (o->libs, iter, lib) {
112  if (is_macho && strstr(lib, "swift")) {
113  info->lang = "swift";
115  } else if (strstr(lib, "stdc++") || strstr(lib, "c++")) {
116  is_cpp = true;
117  } else if (strstr(lib, "msvcp")) {
118  info->lang = "msvc";
119  return RZ_BIN_LANGUAGE_MSVC;
120  } else if (strstr(lib, "phobos")) {
121  info->lang = "dlang";
122  return RZ_BIN_LANGUAGE_DLANG;
123  }
124  }
125  if (is_objc) {
126  info->lang = "objc";
128  }
129 
130  rz_list_foreach (o->symbols, iter, sym) {
131  if (!sym->name) {
132  continue;
133  }
134  if (check_rust(sym)) {
135  info->lang = "rust";
136  return RZ_BIN_LANGUAGE_RUST;
137  } else if (check_golang(sym)) {
138  info->lang = "go";
139  return RZ_BIN_LANGUAGE_GO;
140  } else if (check_swift(sym)) {
141  info->lang = "swift";
143  } else if (check_cxx(sym)) {
144  is_cpp = true;
145  } else if (check_objc(sym)) {
146  info->lang = "objc";
148  } else if (check_dlang(sym)) {
149  info->lang = "dlang";
150  return RZ_BIN_LANGUAGE_DLANG;
151  } else if (check_kotlin(sym)) {
152  info->lang = "kotlin";
153  return RZ_BIN_LANGUAGE_KOTLIN;
154  } else if (check_groovy(sym)) {
155  info->lang = "groovy";
156  return RZ_BIN_LANGUAGE_GROOVY;
157  } else if (check_msvc(sym)) {
158  info->lang = "c";
159  return RZ_BIN_LANGUAGE_MSVC;
160  } else if (check_dart(sym)) {
161  info->lang = "dart";
162  return RZ_BIN_LANGUAGE_DART;
163  }
164  }
165 
166  if (is_macho || is_elf) {
167  rz_list_foreach (o->sections, iter, section) {
168  if (!section->name) {
169  continue;
170  }
171  if (strstr(section->name, "note.go.buildid") ||
172  strstr(section->name, "gopclntab") ||
173  strstr(section->name, "go_export")) {
174  info->lang = "go";
175  return RZ_BIN_LANGUAGE_GO;
176  }
177  }
178  }
179  if (is_cpp) {
180  info->lang = "c++";
182  } else if (!info->lang) {
183  info->lang = "c";
184  } else if (strstr(info->lang, "java")) {
185  return RZ_BIN_LANGUAGE_JAVA;
186  }
188 }
static bool check_rust(RzBinSymbol *sym)
Definition: bin_language.c:12
static bool check_kotlin(RzBinSymbol *sym)
Definition: bin_language.c:48
static bool check_dlang(RzBinSymbol *sym)
Definition: bin_language.c:21
static bool check_objc(RzBinSymbol *sym)
Definition: bin_language.c:17
RZ_API RzBinLanguage rz_bin_language_to_id(const char *language)
returns the language identifier based on the given lang name
Definition: bin_language.c:193
#define language_apply_blocks_mask(x, b)
Definition: bin_language.c:9
static bool check_swift(RzBinSymbol *sym)
Definition: bin_language.c:28
static bool check_cxx(RzBinSymbol *sym)
Definition: bin_language.c:37
static bool check_msvc(RzBinSymbol *sym)
Definition: bin_language.c:44
static bool check_groovy(RzBinSymbol *sym)
Definition: bin_language.c:52
static bool check_golang(RzBinSymbol *sym)
Definition: bin_language.c:32
static bool check_dart(RzBinSymbol *sym)
Definition: bin_language.c:56
RzBinInfo * info(RzBinFile *bf)
Definition: bin_ne.c:86
#define NULL
Definition: cris-opc.c:27
#define false
#define rz_return_val_if_fail(expr, val)
Definition: rz_assert.h:108
RzBinLanguage
Definition: rz_bin.h:145
@ RZ_BIN_LANGUAGE_UNKNOWN
Definition: rz_bin.h:146
@ RZ_BIN_LANGUAGE_GROOVY
Definition: rz_bin.h:157
@ RZ_BIN_LANGUAGE_OBJC
Definition: rz_bin.h:151
@ RZ_BIN_LANGUAGE_KOTLIN
Definition: rz_bin.h:156
@ RZ_BIN_LANGUAGE_RUST
Definition: rz_bin.h:155
@ RZ_BIN_LANGUAGE_DLANG
Definition: rz_bin.h:153
@ RZ_BIN_LANGUAGE_C
Definition: rz_bin.h:148
@ RZ_BIN_LANGUAGE_JAVA
Definition: rz_bin.h:147
@ RZ_BIN_LANGUAGE_DART
Definition: rz_bin.h:158
@ RZ_BIN_LANGUAGE_CXX
Definition: rz_bin.h:150
@ RZ_BIN_LANGUAGE_SWIFT
Definition: rz_bin.h:152
@ RZ_BIN_LANGUAGE_MSVC
Definition: rz_bin.h:154
@ RZ_BIN_LANGUAGE_GO
Definition: rz_bin.h:149
Definition: z80asm.h:102
RzBinObject * o
Definition: rz_bin.h:305
const char * lang
Definition: rz_bin.h:224
char * rclass
Definition: rz_bin.h:213
RzList * imports
Definition: rz_bin.h:268
RzList * symbols
Definition: rz_bin.h:269
RzBinInfo * info
Definition: rz_bin.h:287
RzList * libs
Definition: rz_bin.h:278
RzList * sections
Definition: rz_bin.h:267

References check_cxx(), check_dart(), check_dlang(), check_golang(), check_groovy(), check_kotlin(), check_msvc(), check_objc(), check_rust(), check_swift(), rz_bin_object_t::imports, info(), rz_bin_object_t::info, rz_bin_info_t::lang, language_apply_blocks_mask, rz_bin_object_t::libs, rz_bin_symbol_t::name, NULL, rz_bin_file_t::o, rz_bin_info_t::rclass, RZ_BIN_LANGUAGE_C, RZ_BIN_LANGUAGE_CXX, RZ_BIN_LANGUAGE_DART, RZ_BIN_LANGUAGE_DLANG, RZ_BIN_LANGUAGE_GO, RZ_BIN_LANGUAGE_GROOVY, RZ_BIN_LANGUAGE_JAVA, RZ_BIN_LANGUAGE_KOTLIN, RZ_BIN_LANGUAGE_MSVC, RZ_BIN_LANGUAGE_OBJC, RZ_BIN_LANGUAGE_RUST, RZ_BIN_LANGUAGE_SWIFT, rz_bin_language_to_id(), RZ_BIN_LANGUAGE_UNKNOWN, rz_return_val_if_fail, rz_bin_object_t::sections, and rz_bin_object_t::symbols.

Referenced by rz_bin_object_set_items().

◆ rz_bin_language_to_id()

RZ_API RzBinLanguage rz_bin_language_to_id ( const char *  language)

returns the language identifier based on the given lang name

Definition at line 193 of file bin_language.c.

193  {
194  if (RZ_STR_ISEMPTY(language)) {
196  }
197  bool has_blocks = strstr(language, LANGUAGE_WITH_BLOCKS);
198  if (strstr(language, "swift")) {
200  } else if (strstr(language, "java")) {
201  return RZ_BIN_LANGUAGE_JAVA;
202  } else if (strstr(language, "groovy")) {
203  return RZ_BIN_LANGUAGE_GROOVY;
204  } else if (strstr(language, "kotlin")) {
205  return RZ_BIN_LANGUAGE_KOTLIN;
206  } else if (strstr(language, "objc")) {
208  } else if (strstr(language, "cxx") || strstr(language, "c++")) {
210  } else if (strstr(language, "dlang")) {
211  return RZ_BIN_LANGUAGE_DLANG;
212  } else if (strstr(language, "msvc")) {
213  return RZ_BIN_LANGUAGE_MSVC;
214  } else if (strstr(language, "rust")) {
215  return RZ_BIN_LANGUAGE_RUST;
216  } else if (strstr(language, "dart")) {
217  return RZ_BIN_LANGUAGE_DART;
218  } else if (!strcmp(language, "c") || !strcmp(language, "c" LANGUAGE_WITH_BLOCKS)) {
219  return language_apply_blocks_mask(RZ_BIN_LANGUAGE_C, has_blocks);
220  } else if (!strcmp(language, "go")) {
221  return RZ_BIN_LANGUAGE_GO;
222  }
224 }
#define LANGUAGE_WITH_BLOCKS
Definition: bin_language.c:8
#define RZ_STR_ISEMPTY(x)
Definition: rz_str.h:67

References language_apply_blocks_mask, LANGUAGE_WITH_BLOCKS, RZ_BIN_LANGUAGE_C, RZ_BIN_LANGUAGE_CXX, RZ_BIN_LANGUAGE_DART, RZ_BIN_LANGUAGE_DLANG, RZ_BIN_LANGUAGE_GO, RZ_BIN_LANGUAGE_GROOVY, RZ_BIN_LANGUAGE_JAVA, RZ_BIN_LANGUAGE_KOTLIN, RZ_BIN_LANGUAGE_MSVC, RZ_BIN_LANGUAGE_OBJC, RZ_BIN_LANGUAGE_RUST, RZ_BIN_LANGUAGE_SWIFT, RZ_BIN_LANGUAGE_UNKNOWN, and RZ_STR_ISEMPTY.

Referenced by rz_bin_demangle(), and rz_bin_language_detect().

◆ rz_bin_language_to_string()

RZ_API const char* rz_bin_language_to_string ( RzBinLanguage  language)

returns the language name based on the given language identifier

Definition at line 229 of file bin_language.c.

229  {
230  switch (RZ_BIN_LANGUAGE_MASK(language)) {
232  return language_apply_blocks_string(language, "swift");
233  case RZ_BIN_LANGUAGE_GO:
234  return "go";
236  return "java";
238  return "kotlin";
239  case RZ_BIN_LANGUAGE_C:
240  return language_apply_blocks_string(language, "c");
241  case RZ_BIN_LANGUAGE_CXX:
242  return language_apply_blocks_string(language, "c++");
244  return "dlang";
246  return language_apply_blocks_string(language, "objc");
248  return "msvc";
250  return "rust";
252  return "groovy";
254  return "dart";
255  default:
256  return NULL;
257  }
258 }
#define language_apply_blocks_string(x, b)
Definition: bin_language.c:10
#define RZ_BIN_LANGUAGE_MASK(x)
Definition: rz_bin.h:162

References language_apply_blocks_string, NULL, RZ_BIN_LANGUAGE_C, RZ_BIN_LANGUAGE_CXX, RZ_BIN_LANGUAGE_DART, RZ_BIN_LANGUAGE_DLANG, RZ_BIN_LANGUAGE_GO, RZ_BIN_LANGUAGE_GROOVY, RZ_BIN_LANGUAGE_JAVA, RZ_BIN_LANGUAGE_KOTLIN, RZ_BIN_LANGUAGE_MASK, RZ_BIN_LANGUAGE_MSVC, RZ_BIN_LANGUAGE_OBJC, RZ_BIN_LANGUAGE_RUST, and RZ_BIN_LANGUAGE_SWIFT.

Referenced by rz_bin_demangle(), and rz_bin_file_set_obj().