Esempio n. 1
0
static char *swift_demangle_cmd(const char *s) {
	/* XXX: command injection issue here */
	static char *swift_demangle = NULL;
	if (have_swift_demangle == -1) {
		if (!swift_demangle) {
			have_swift_demangle = 0;
			swift_demangle = r_file_path ("swift-demangle");
			if (!swift_demangle || !strcmp (swift_demangle, "swift-demangle")) {
				char *xcrun = r_file_path ("xcrun");
				if (xcrun) {
					if (strcmp (xcrun, "xcrun")) {
						free (swift_demangle);
						swift_demangle = r_str_newf ("%s swift-demangle", xcrun);
						have_swift_demangle = 1;
					}
					free (xcrun);
				}
			}
		}
	}
	if (swift_demangle) {
		if (strstr (s, "'") || strstr (s, "\\")) {
			/* nice try */
			return NULL;
		}
		//char *res = r_sys_cmd_strf ("%s -compact -simplified '%s'",
		char *res = r_sys_cmd_strf ("%s -compact '%s'",
			swift_demangle, s);
		if (res && !*res) {
			free (res);
			res = NULL;
		}
		return r_str_chop (res);
	}
	return NULL;
}
Esempio n. 2
0
static struct cEnv_t* r_egg_Cfile_set_cEnv(const char *arch, const char *os, int bits) {
	struct cEnv_t *cEnv = calloc (1, sizeof (struct cEnv_t));
	bool use_clang;
	char *buffer = NULL;
	char *output = NULL;

	if (!cEnv) {
		return NULL;
	}

	if (!(cEnv->CC = r_egg_Cfile_getCompiler())) {
		goto fail;
	}

	cEnv->SFLIBPATH = r_sys_getenv ("SFLIBPATH");
	if (!cEnv->SFLIBPATH) {
		output = r_sys_cmd_strf ("r2 -hh | grep INCDIR | awk '{print $2}'");
		if (!output || (output[0] == '\0')) {
			eprintf ("Cannot find SFLIBPATH env var.\n"
		  		 "Please define it, or fix r2 installation.\n");
			goto fail;
		}
    
		output[strlen (output) - 1] = '\0'; // strip the ending '\n'
		if (!(cEnv->SFLIBPATH = r_str_newf ("%s/sflib", output))) {
			goto fail;
		}
	}

	cEnv->JMP = r_egg_Cfile_armOrMips (arch) ? "b" : "jmp";

	if (!strcmp (os, "darwin")) {
		cEnv->OBJCOPY = "gobjcopy";
		cEnv->FMT = "mach0";
		if (!strcmp (arch, "x86")) {
			if (bits == 32) {
				cEnv->CFLAGS = strdup ("-arch i386");
				cEnv->LDFLAGS = strdup ("-arch i386 -shared -c");
			} else {
				cEnv->CFLAGS = strdup ("-arch x86_64");
				cEnv->LDFLAGS = strdup ("-arch x86_64 -shared -c");
			}
		} else {
			cEnv->LDFLAGS = strdup ("-shared -c");
		}
		cEnv->SHDR = r_str_newf ("\n.text\n%s _main\n", cEnv->JMP);

	} else {
		cEnv->OBJCOPY = "objcopy";
		cEnv->FMT = "elf";
		cEnv->SHDR = r_str_newf ("\n.section .text\n.globl  main\n"
				   "// .type   main, @function\n%s main\n", cEnv->JMP);
		if (!strcmp (arch, "x86")) {
			if (bits == 32) {
				cEnv->CFLAGS = strdup ("-fPIC -fPIE -pie -fpic -m32");
				cEnv->LDFLAGS = strdup ("-fPIC -fPIE -pie -fpic -m32");
			} else {
				cEnv->CFLAGS = strdup ("-fPIC -fPIE -pie -fpic -m64");
				cEnv->LDFLAGS = strdup ("-fPIC -fPIE -pie -fpic -m64");
			}
		} else {
			cEnv->CFLAGS = strdup ("-fPIC -fPIE -pie -fpic -nostartfiles");
			cEnv->LDFLAGS = strdup ("-fPIC -fPIE -pie -fpic -nostartfiles");
		}
	}

	cEnv->TRIPLET = r_str_newf ("%s-%s-%d", os, arch, bits);

	if (!strcmp (os, "windows")) {
		cEnv->TEXT = ".text";
		cEnv->FMT = "pe";
	} else if (!strcmp (os, "darwin")) {
		cEnv->TEXT = "0.__TEXT.__text";
	} else {
		cEnv->TEXT = ".text";
	}
		
	use_clang = false;
	if (!strcmp (cEnv->TRIPLET, "darwin-arm-64")) {
		free (cEnv->CC);
		cEnv->CC = strdup ("xcrun --sdk iphoneos gcc -arch arm64 -miphoneos-version-min=0.0");
		use_clang = true;
		cEnv->TEXT = "0.__TEXT.__text";
	} else if (!strcmp (cEnv->TRIPLET, "darwin-arm-32")) {
		free (cEnv->CC);
		cEnv->CC = strdup ("xcrun --sdk iphoneos gcc -arch armv7 -miphoneos-version-min=0.0");
		use_clang = true;
		cEnv->TEXT = "0.__TEXT.__text";
	}

	buffer = r_str_newf ("%s -nostdinc -include '%s'/'%s'/sflib.h",
	  		cEnv->CFLAGS, cEnv->SFLIBPATH, cEnv->TRIPLET);
	if (!buffer) {
		goto fail;
	}
	free (cEnv->CFLAGS);
	cEnv->CFLAGS = strdup (buffer);

	if (use_clang) {
		free (buffer);
		buffer = r_str_newf ("%s -fomit-frame-pointer"
		  		" -fno-zero-initialized-in-bss", cEnv->CFLAGS);
		if (!buffer) {
			goto fail;
		}
		free (cEnv->CFLAGS);
		cEnv->CFLAGS = strdup (buffer);
	} else { 
		free (buffer);
		buffer = r_str_newf ("%s -z execstack -fomit-frame-pointer"
				" -finline-functions -fno-zero-initialized-in-bss", cEnv->CFLAGS);
		if (!buffer) {
			goto fail;
		}
		free (cEnv->CFLAGS);
		cEnv->CFLAGS = strdup (buffer);
	}
	free (buffer);
	buffer = r_str_newf ("%s -nostdlib", cEnv->LDFLAGS);
	if (!buffer) {
		goto fail;
	}
	free (cEnv->LDFLAGS);
	cEnv->LDFLAGS = strdup (buffer);

	if (r_egg_Cfile_check_cEnv (cEnv)) {
		eprintf ("Error with cEnv allocation!\n");
		goto fail;
	}

	free (buffer);
	free (output);
	return cEnv;

fail:
	free (buffer);
	free (output);
	r_egg_Cfile_free_cEnv (cEnv);
	return NULL;
}
Esempio n. 3
0
char *r_bin_demangle_swift(const char *s) {
#define STRCAT_BOUNDS(x) if ((x+2+strlen (out))>sizeof (out)) break;
	static char *swift_demangle = NULL;
	char out[8192];
	int i, len, is_generic = 0;;
	int is_first = 1;
	int is_last = 0;
	int retmode = 0;
	if (!strncmp (s, "__", 2)) s = s + 2;
	if (!strncmp (s, "imp.", 4)) s = s + 4;
	if (!strncmp (s, "reloc.", 6)) s = s + 6;
#if 0
	const char *element[] = {
		"module", "class", "method", NULL
	};
#endif
	const char *attr = NULL;
	const char *attr2 = NULL;
	const char *q, *p = s;
	if (strncmp (s, "_T", 2)) {
		return NULL;
	}
	if (strchr (s, '\'') || strchr (s, ' '))
		return NULL;

	if (!swift_demangle) {
		swift_demangle = r_file_path ("swift-demangle");
		if (!swift_demangle || !strcmp (swift_demangle, "swift-demangle")) {
			char *xcrun = r_file_path ("xcrun");
			if (xcrun) {
				free (swift_demangle);
				swift_demangle = r_str_newf ("%s swift-demangle", xcrun);
				free (xcrun);
			}
		}
	}
	if (swift_demangle) {
		char *res = r_sys_cmd_strf ("%s -compact -simplified '%s'",
			swift_demangle, s);
		if (res && !*res) {
			free (res);
			res = NULL;
		}
		return r_str_chop (res);
	}
	out[0] = 0;
	p += 2;
	if (*p == 'F' || *p == 'W') {
		q = numpos (p);
		//printf ("(%s)\n", getstring (p, (q-p)));
		for (i=0, len = 1; len; q += len, i++) {
			if (*q=='P') {
		//		printf ("PUBLIC: ");
				q++;
			}
			q = getnum (q, &len);
			if (!len)
				break;
#if 0
			printf ("%s %d %s\n", element[i],
				len, getstring (q, len));
#endif
			// push string
			if (*out)
				strcat (out, ".");
			STRCAT_BOUNDS (len);
			strcat (out, getstring (q, len));
		}
		p = resolve (flags, q, &attr);
		if (!p && *q=='U') {
			p = resolve (metas, q, &attr);
			if (attr) {
				//printf ("Template (%s)\n", attr);
			} else {
				//printf ("Findus (%s)\n", q);
			}
//			return 0;
		}
		if (attr) {
			int len;
			const char *name;
			/* get field name and then type */
			resolve (types, q, &attr);
			//printf ("Accessor: %s\n", attr);
			q = getnum (q+1, &len);
			name = getstring (q, len);
#if 0
			if (name && *name) {
				printf ("Field Name: %s\n", name);
			}
#endif
			resolve (types, q+len, &attr2);
//			printf ("Field Type: %s\n", attr2);

			do {
				if (name && *name) {
					strcat (out, ".");
					STRCAT_BOUNDS (strlen (name));
					strcat (out, name);
				}
				if (attr && *attr) {
					strcat (out, ".");
					STRCAT_BOUNDS (strlen (attr));
					strcat (out, attr);
				}
				if (attr2 && *attr2) {
					strcat (out, "__");
					STRCAT_BOUNDS (strlen (attr2));
					strcat (out, attr2);
				}
			} while (0);
		} else {
			/* parse function parameters here */
			// type len value
			for (i=0; q; i++) {
				switch (*q) {
				case 'B':
				case 'T':
				case 'I':
				case 'F':
					p = resolve (types, q+3, &attr); // type
					break;
				case 'G':
					q+=2;
					//printf ("GENERIC\n");
					if (!strncmp (q, "_V", 2)) {
						q+=2;
					}
					p = resolve (types, q, &attr); // type
					break;
				case 'V':
				//	printf ("VECTOR\n");
					p = resolve (types, q+1, &attr); // type
					break;
				case '_':

					// it's return value time!
					p = resolve (types, q+1, &attr); // type
					//printf ("RETURN TYPE %s\n", attr);
					break;
				default:
					p = resolve (types, q, &attr); // type
				}
				if (p) {
					q = p;
					q = getnum (p, &len);
					if (!strcmp (attr, "generic"))
						is_generic = 1;
					//printf ("TYPE: %s LEN %d VALUE %s\n",
					//	attr, len, getstring (q, len));
					if (!len) {
						if (retmode) {
							p = resolve (types, q+1, &attr); // type
							//printf ("RETURN TYPE %s\n", attr);
		//					printf ("RET %s\n", attr);
							strcat (out, " -> ");
							STRCAT_BOUNDS (strlen (attr));
							strcat (out, attr);
							break;
						}
						retmode = 1;
						len++;
					}
					if (q[len]) {
						const char *s = getstring (q, len);
						if (s && *s) {
							if (is_first) {	
								strcat (out, is_generic?"<":"(");
								is_first = 0;
							}
							//printf ("ISLAST (%s)\n", q+len);
							is_last = q[len];
							STRCAT_BOUNDS (strlen (attr));
							strcat (out, attr);
							strcat (out, " ");
							STRCAT_BOUNDS (strlen (s));
							strcat (out, s);
							if (is_last) {
								strcat (out, is_generic?">":")");
								is_first = 1;
							} else {
								strcat (out, ", ");
							}
						} else {
							strcat (out, " -> ");
							STRCAT_BOUNDS (strlen (attr));
							strcat (out, attr);

						}
					} else {
					}
					q += len;
				} else {
					//printf ("void\n");
					q++;
					break;
				}
			}
		}
	} else {
		//printf ("Unsupported type: %c\n", *p);
	}
	if (*out) {
		char *p, *outstr = strdup (out);
		p = outstr;
		for (;;) {
			p = strstr (p, ")(");
			if (p) {
				p[0] = '_';
				p[1] = '_';
				p+=2;
			} else break;
		}
		return outstr;
	}
	return NULL;
}
Esempio n. 4
0
R_API char* r_egg_Cfile_parser(const char *file, const char *arch, const char *os, int bits) {
	char *output = NULL;
	char *fileExt = NULL; // "file" with extension (.s, .text, ...)
	struct cEnv_t *cEnv = r_egg_Cfile_set_cEnv (arch, os, bits);

	if (!cEnv) {
		goto fail;
	}

	r_str_sanitize (cEnv->CC);

	//printf ("==> Compile\n");
	printf ("'%s' %s -o '%s.tmp' -S -Os '%s'\n", cEnv->CC, cEnv->CFLAGS, file, file);

	output = r_sys_cmd_strf ("('%s' %s -o '%s.tmp' -S -Os '%s') 2>&1",
	  			cEnv->CC, cEnv->CFLAGS, file, file);
	if (output == NULL) {
		eprintf ("Compilation failed!\n");
		goto fail;
	}
	printf ("%s", output);

	if (!(fileExt = r_str_newf ("%s.s", file))) {
		goto fail;
	}

	if (!r_file_dump (fileExt, (const ut8*) cEnv->SHDR, strlen (cEnv->SHDR), false)) {
		eprintf ("Error while opening %s.s\n", file);
		goto fail;
	}

	if (!r_egg_Cfile_parseCompiled (file)) {
		goto fail;
	}

	//printf ("==> Assemble\n");
	printf ("'%s' %s -Os -o '%s.o' '%s.s'\n", cEnv->CC, cEnv->LDFLAGS, file, file);

	free (output);
	output = r_sys_cmd_strf ("'%s' %s -Os -o '%s.o' '%s.s'",
		   		cEnv->CC, cEnv->LDFLAGS, file, file);
	if (!output) {
		eprintf ("Assembly failed!\n");
		goto fail;
	}
	printf ("%s", output);

	//printf ("==> Link\n");
	printf ("rabin2 -o '%s.text' -O d/S/'%s' '%s.o'\n", file, cEnv->TEXT, file);

	free (output);
	output = r_sys_cmd_strf ("rabin2 -o '%s.text' -O d/S/'%s' '%s'.o",
		   		file, cEnv->TEXT, file);
	if (!output) {
		eprintf ("Linkage failed!\n");
		goto fail;
	}

	free (fileExt);
	if (!(fileExt = r_str_newf ("%s.o", file))) {
		goto fail;
	}

	if (!r_file_exists (fileExt)) {
		eprintf ("Cannot find %s.o\n", file);
		goto fail;
	}

	free (fileExt);
	if (!(fileExt = r_str_newf ("%s.text", file))) {
		goto fail;
	}
	if (r_file_size (fileExt) == 0) {
		printf ("FALLBACK: Using objcopy instead of rabin2");

		free (output);
		output = r_sys_cmd_strf ("'%s' -j .text -O binary '%s.o' '%s.text'", 
		  		cEnv->OBJCOPY, file, file);
		if (!output) {
			eprintf ("objcopy failed!\n");
			goto fail;
		}
	}

	size_t i;
	const char *extArray[] = {"bin", "tmp", "s", "o"};
	for (i = 0; i < 4; i++) {
		free (fileExt);
		if (!(fileExt = r_str_newf ("%s.%s", file, extArray[i]))) {
			goto fail;
		}
		r_file_rm (fileExt);
	}

	free (fileExt);
	if ((fileExt = r_str_newf ("%s.text", file)) == NULL) {
		goto fail;
	}

	free (output);
	r_egg_Cfile_free_cEnv (cEnv);
	return fileExt;

fail:
	free (fileExt);
	free (output);
	r_egg_Cfile_free_cEnv (cEnv);
	return NULL;
}