1 /* radare2 - LGPL - Copyright 2018-2019 - pancake */
2
3 #include <r_bin.h>
4
5 typedef struct {
6 bool rust;
7 bool objc;
8 bool dlang;
9 bool swift;
10 bool cxx;
11 bool msvc;
12 } Langs;
13
check_rust(RBinSymbol * sym)14 static inline bool check_rust(RBinSymbol *sym) {
15 return sym->name && strstr (sym->name, "_$LT$");
16 }
17
check_objc(RBinSymbol * sym)18 static inline bool check_objc(RBinSymbol *sym) {
19 if (sym->name && !strncmp (sym->name, "_OBJC_", 6)) {
20 // free (r_bin_demangle_objc (binfile, sym->name));
21 return true;
22 }
23 return false;
24 }
25
check_dlang(RBinSymbol * sym)26 static bool check_dlang(RBinSymbol *sym) {
27 if (!strncmp (sym->name, "_D2", 3)) {
28 return true;
29 }
30 if (!strncmp (sym->name, "_D4", 3)) {
31 return true;
32 }
33 return false;
34 }
35
check_swift(RBinSymbol * sym)36 static bool check_swift(RBinSymbol *sym) {
37 if (sym->name && strstr (sym->name, "swift_once")) {
38 return true;
39 }
40 return false;
41 }
42
check_golang(RBinSymbol * sym)43 static bool check_golang(RBinSymbol *sym) {
44 return !strncmp (sym->name, "go.", 3);
45 }
46
is_cxx_symbol(const char * name)47 static inline bool is_cxx_symbol (const char *name) {
48 r_return_val_if_fail (name, false);
49 if (!strncmp (name, "_Z", 2)) {
50 return true;
51 }
52 if (!strncmp (name, "__Z", 3)) {
53 return true;
54 }
55 return false;
56 }
57
check_cxx(RBinSymbol * sym)58 static bool check_cxx(RBinSymbol *sym) {
59 return is_cxx_symbol (sym->name);
60 }
61
check_msvc(RBinSymbol * sym)62 static bool check_msvc(RBinSymbol *sym) {
63 return *sym->name == '?';
64 }
65
66 /* This is about 10% of the loading time, optimize if possible */
r_bin_load_languages(RBinFile * binfile)67 R_API int r_bin_load_languages(RBinFile *binfile) {
68 r_return_val_if_fail (binfile, R_BIN_NM_NONE);
69 r_return_val_if_fail (binfile->o, R_BIN_NM_NONE);
70 r_return_val_if_fail (binfile->o->info, R_BIN_NM_NONE);
71 RBinObject *o = binfile->o;
72 RBinInfo *info = o->info;
73 RBinSymbol *sym;
74 RListIter *iter, *iter2;
75 Langs cantbe = {0};
76 bool phobosIsChecked = false;
77 bool swiftIsChecked = false;
78 bool canBeCxx = false;
79 bool cxxIsChecked = false;
80 bool isMsvc = false;
81
82 const char *ft = r_str_get (info->rclass);
83 bool unknownType = info->rclass == NULL;
84 bool isMacho = strstr (ft, "mach");
85 bool isElf = strstr (ft, "elf");
86 bool isPe = strstr (ft, "pe");
87 bool isBlocks = false;
88 bool isObjC = false;
89
90 if (unknownType || !(isMacho || isElf || isPe)) {
91 return R_BIN_NM_NONE;
92 }
93
94 // check in imports . can be slow
95 r_list_foreach (o->imports, iter, sym) {
96 const char *name = sym->name;
97 if (!strcmp (name, "_NSConcreteGlobalBlock")) {
98 isBlocks = true;
99 } else if (!strncmp (name, "objc_", 5)) {
100 isObjC = true;
101 cantbe.objc = true;
102 }
103 }
104
105 r_list_foreach (o->symbols, iter, sym) {
106 char *lib;
107 if (!cantbe.rust) {
108 if (check_rust (sym)) {
109 info->lang = "rust";
110 return R_BIN_NM_RUST;
111 }
112 }
113 if (check_golang (sym)) {
114 info->lang = "go";
115 return R_BIN_NM_GO;
116 }
117 if (!cantbe.swift) {
118 bool hasswift = false;
119 if (!swiftIsChecked) {
120 r_list_foreach (o->libs, iter2, lib) {
121 if (strstr (lib, "swift")) {
122 hasswift = true;
123 break;
124 }
125 }
126 swiftIsChecked = true;
127 }
128 if (hasswift || check_swift (sym)) {
129 info->lang = "swift";
130 return R_BIN_NM_SWIFT;
131 }
132 }
133 if (!cantbe.cxx) {
134 bool hascxx = false;
135 if (!cxxIsChecked) {
136 r_list_foreach (o->libs, iter2, lib) {
137 if (strstr (lib, "stdc++") ||
138 strstr (lib, "c++")) {
139 hascxx = true;
140 break;
141 }
142 if (strstr (lib, "msvcp")) {
143 info->lang = "msvc";
144 return R_BIN_NM_MSVC;
145 }
146 }
147 cxxIsChecked = true;
148 }
149 if (hascxx || check_cxx (sym)) {
150 canBeCxx = true;
151 cantbe.cxx = true;
152 }
153 }
154 if (!cantbe.objc) {
155 if (check_objc (sym)) {
156 info->lang = "objc";
157 return R_BIN_NM_OBJC;
158 }
159 }
160 if (!cantbe.dlang) {
161 bool hasdlang = false;
162 if (!phobosIsChecked) {
163 r_list_foreach (o->libs, iter2, lib) {
164 if (strstr (lib, "phobos")) {
165 hasdlang = true;
166 break;
167 }
168 }
169 phobosIsChecked = true;
170 }
171 if (hasdlang || check_dlang (sym)) {
172 info->lang = "dlang";
173 return R_BIN_NM_DLANG;
174 }
175 }
176 if (!cantbe.msvc) {
177 if (!isMsvc && check_msvc (sym)) {
178 isMsvc = true;
179 }
180 }
181 }
182 if (isObjC) {
183 return R_BIN_NM_OBJC | (isBlocks?R_BIN_NM_BLOCKS:0);
184 }
185 if (canBeCxx) {
186 return R_BIN_NM_CXX | (isBlocks?R_BIN_NM_BLOCKS:0);
187 }
188 if (isMsvc) {
189 return R_BIN_NM_MSVC;
190 }
191 return R_BIN_NM_C | (isBlocks?R_BIN_NM_BLOCKS:0);
192 }
193
r_bin_lang_type(RBinFile * binfile,const char * def,const char * sym)194 R_IPI int r_bin_lang_type(RBinFile *binfile, const char *def, const char *sym) {
195 int type = 0;
196 RBinPlugin *plugin;
197 if (sym && sym[0] == sym[1] && sym[0] == '_') {
198 type = R_BIN_NM_CXX;
199 }
200 if (def && *def) {
201 type = r_bin_demangle_type (def);
202 if (type != R_BIN_NM_NONE) {
203 return type;
204 }
205 }
206 plugin = r_bin_file_cur_plugin (binfile);
207 if (plugin && plugin->demangle_type) {
208 type = plugin->demangle_type (def);
209 } else {
210 if (binfile && binfile->o && binfile->o->info) {
211 type = r_bin_demangle_type (binfile->o->info->lang);
212 }
213 }
214 if (type == R_BIN_NM_NONE) {
215 type = r_bin_demangle_type (def);
216 }
217 return type;
218 }
219
r_bin_lang_tostring(int lang)220 R_API const char *r_bin_lang_tostring(int lang) {
221 switch (lang & 0xffff) {
222 case R_BIN_NM_SWIFT:
223 return "swift";
224 case R_BIN_NM_GO:
225 return "go";
226 case R_BIN_NM_JAVA:
227 return "java";
228 case R_BIN_NM_KOTLIN:
229 return "kotlin";
230 case R_BIN_NM_C:
231 return (lang & R_BIN_NM_BLOCKS)? "c with blocks": "c";
232 case R_BIN_NM_CXX:
233 return (lang & R_BIN_NM_BLOCKS)? "c++ with blocks": "c++";
234 case R_BIN_NM_DLANG:
235 return "d";
236 case R_BIN_NM_OBJC:
237 return (lang & R_BIN_NM_BLOCKS)? "objc with blocks": "objc";
238 case R_BIN_NM_MSVC:
239 return "msvc";
240 case R_BIN_NM_RUST:
241 return "rust";
242 }
243 return NULL;
244 }
245
246