Fix - bad process set up when -R in xnu + minor refactor

This commit is contained in:
Álvaro Felipe Melchor 2017-04-18 00:35:10 +02:00 committed by radare
parent f35f4b04c6
commit c65ba95cb9

@ -198,24 +198,85 @@ static void trace_me () {
}
}
void handle_posix_error(int err) {
switch (err) {
case 0:
// eprintf ("Success\n");
break;
case 22:
eprintf ("posix_spawnp: Invalid argument\n");
break;
case 86:
eprintf ("Unsupported architecture. Please specify -b 32\n");
break;
default:
eprintf ("posix_spawnp: unknown error %d\n", err);
perror ("posix_spawnp");
break;
}
}
static RRunProfile* _get_run_profile(RIO *io, int bits, char **argv) {
char *expr = NULL;
int i;
RRunProfile *rp = r_run_new (NULL);
if (!rp) {
return NULL;
}
for (i = 0; argv[i]; i++) {
rp->_args[i] = argv[i];
}
rp->_args[i] = NULL;
rp->_program = argv[0];
rp->_dodebug = true;
if (io->runprofile && *io->runprofile) {
if (!r_run_parsefile (rp, io->runprofile)) {
eprintf ("Can't find profile '%s'\n", io->runprofile);
return NULL;
}
}
if (bits == 64) {
r_run_parseline (rp, expr=strdup ("bits=64"));
} else if (bits == 32) {
r_run_parseline (rp, expr=strdup ("bits=32"));
}
free (expr);
if (r_run_config_env (rp)) {
eprintf ("Can't config the environment.\n");
return NULL;
}
return rp;
}
// __UNIX__ (not windows)
static int fork_and_ptraceme(RIO *io, int bits, const char *cmd) {
bool runprofile = io->runprofile && *(io->runprofile);
char **argv;
#if __APPLE__ && !__POWERPC__
if (!runprofile) {
pid_t p = -1;
posix_spawn_file_actions_t fileActions;
ut32 ps_flags = POSIX_SPAWN_SETSIGDEF | POSIX_SPAWN_SETSIGMASK;
sigset_t no_signals;
sigset_t all_signals;
size_t copied = 1;
cpu_type_t cpu = CPU_TYPE_ANY;
posix_spawnattr_t attr = {0};
posix_spawnattr_init (&attr);
sigemptyset (&no_signals);
sigfillset (&all_signals);
posix_spawnattr_setsigmask (&attr, &no_signals);
posix_spawnattr_setsigdefault (&attr, &all_signals);
posix_spawn_file_actions_init (&fileActions);
posix_spawn_file_actions_addinherit_np (&fileActions, STDIN_FILENO);
posix_spawn_file_actions_addinherit_np (&fileActions, STDOUT_FILENO);
posix_spawn_file_actions_addinherit_np (&fileActions, STDERR_FILENO);
ps_flags |= POSIX_SPAWN_CLOEXEC_DEFAULT;
ps_flags |= POSIX_SPAWN_START_SUSPENDED;
#define _POSIX_SPAWN_DISABLE_ASLR 0x0100
posix_spawn_file_actions_t fileActions;
ut32 ps_flags = POSIX_SPAWN_SETSIGDEF |
POSIX_SPAWN_SETSIGMASK;
sigset_t no_signals;
sigset_t all_signals;
sigemptyset (&no_signals);
sigfillset (&all_signals);
posix_spawnattr_t attr = {0};
size_t copied = 1;
cpu_type_t cpu;
pid_t p = -1;
if (!runprofile) {
int ret, useASLR = io->aslr;
char *_cmd = io->args
? r_str_appendf (strdup (cmd), " %s", io->args)
@ -231,25 +292,12 @@ static int fork_and_ptraceme(RIO *io, int bits, const char *cmd) {
eprintf ("Invalid execvp\n");
return -1;
}
posix_spawnattr_init (&attr);
if (useASLR != -1) {
if (!useASLR) {
ps_flags |= _POSIX_SPAWN_DISABLE_ASLR;
}
}
posix_spawn_file_actions_init (&fileActions);
posix_spawn_file_actions_addinherit_np (&fileActions, STDIN_FILENO);
posix_spawn_file_actions_addinherit_np (&fileActions, STDOUT_FILENO);
posix_spawn_file_actions_addinherit_np (&fileActions, STDERR_FILENO);
ps_flags |= POSIX_SPAWN_CLOEXEC_DEFAULT;
ps_flags |= POSIX_SPAWN_START_SUSPENDED;
posix_spawnattr_setsigmask (&attr, &no_signals);
posix_spawnattr_setsigdefault (&attr, &all_signals);
(void)posix_spawnattr_setflags (&attr, ps_flags);
cpu = CPU_TYPE_ANY;
#if __x86_64__
if (bits == 32) {
cpu = CPU_TYPE_I386;
@ -264,29 +312,47 @@ static int fork_and_ptraceme(RIO *io, int bits, const char *cmd) {
}
}
ret = posix_spawnp (&p, argv[0], &fileActions, &attr, argv, NULL);
switch (ret) {
case 0:
// eprintf ("Success\n");
break;
case 22:
eprintf ("posix_spawnp: Invalid argument\n");
break;
case 86:
eprintf ("Unsupported architecture. Please specify -b 32\n");
break;
default:
eprintf ("posix_spawnp: unknown error %d\n", ret);
perror ("posix_spawnp");
break;
}
handle_posix_error (ret);
posix_spawn_file_actions_destroy (&fileActions);
r_str_argv_free (argv);
free (_cmd);
return p;
} else {
int ret;
argv = r_str_argv (cmd, NULL);
if (!argv) {
posix_spawn_file_actions_destroy (&fileActions);
return -1;
}
RRunProfile *rp = _get_run_profile (io, bits, argv);
if (!rp) {
r_str_argv_free (argv);
posix_spawn_file_actions_destroy (&fileActions);
return -1;
}
if (rp->_args[0]) {
if (!rp->_aslr) {
ps_flags |= _POSIX_SPAWN_DISABLE_ASLR;
}
#if __x86_64__
if (rp->_bits == 32) {
cpu = CPU_TYPE_I386;
}
#endif
(void)posix_spawnattr_setflags (&attr, ps_flags);
posix_spawnattr_setbinpref_np (&attr, 1, &cpu, &copied);
ret = posix_spawnp (&p, rp->_args[0], &fileActions, &attr, rp->_args, NULL);
handle_posix_error (ret);
}
r_str_argv_free (argv);
r_run_free (rp);
posix_spawn_file_actions_destroy (&fileActions);
return p;
}
posix_spawn_file_actions_destroy (&fileActions);
return -1;
#endif
int ret, status, child_pid;
child_pid = r_sys_fork ();
switch (child_pid) {
case -1:
@ -294,31 +360,13 @@ static int fork_and_ptraceme(RIO *io, int bits, const char *cmd) {
break;
case 0:
if (runprofile) {
char *expr = NULL;
int i;
RRunProfile *rp = r_run_new (NULL);
argv = r_str_argv (cmd, NULL);
for (i = 0; argv[i]; i++) {
rp->_args[i] = argv[i];
if (!argv) {
exit(1);
}
rp->_args[i] = NULL;
rp->_program = argv[0];
rp->_dodebug = true;
if (io->runprofile && *io->runprofile) {
if (!r_run_parsefile (rp, io->runprofile)) {
eprintf ("Can't find profile '%s'\n",
io->runprofile);
exit (MAGIC_EXIT);
}
}
if (bits == 64) {
r_run_parseline (rp, expr=strdup ("bits=64"));
} else if (bits == 32) {
r_run_parseline (rp, expr=strdup ("bits=32"));
}
free (expr);
if (r_run_config_env (rp)) {
eprintf ("Can't config the environment.\n");
RRunProfile *rp = _get_run_profile (io, bits, argv);
if (!rp) {
r_str_argv_free (argv);
exit (1);
}
trace_me ();