Skip to content

Commit

Permalink
Add help and colors for rz-run -h (#4225) (#4237)
Browse files Browse the repository at this point in the history
* `-l` flag for listing profile options
* `-d` for ouputing a base profile template.
* Updated relevant manpage.
  • Loading branch information
ahmed-hany94 committed Feb 15, 2024
1 parent ac63502 commit a5297b5
Show file tree
Hide file tree
Showing 4 changed files with 157 additions and 61 deletions.
24 changes: 15 additions & 9 deletions binrz/man/rz-run.1
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,13 @@ This command is part of the Rizin project.
.Pp
This program is used as a launcher for running programs with different environment, arguments, permissions, directories and overridden default filedescriptors.
.Pp
rz-run -t will show the terminal name and wait for a connection from another process. try rz-run stdio=<ttypath> program=/bin/sh
rz-run -l lists all the supported profile options.
.Pp
.Pp
rz-run -t outputs a base template profile. Try rz-run -d > profile.rz
.Pp
.Pp
rz-run -w shows the terminal name and wait for a connection from another process. Try rz-run stdio=<ttypath> program=/bin/sh
.Pp
The program just accepts a single argument which is the filename of the configuration file to run the program.
.Pp
Expand All @@ -22,7 +28,7 @@ It is useful when you have to run a program using long arguments or pass long da
.Pp
The rrz (rz-run) configuration file accepts the following directives, described as key=value entries and comments defined as lines starting with '#'.
.Bl -tag -width Fl
.It Ar arg[0-N]
.It Ar arg[0-511]
Set value for argument N passed to the program
.It Ar aslr
Enable or disable ASLR
Expand All @@ -32,8 +38,6 @@ Set 32 or 64 bit (if the architecture supports it)
Change directory before executing the program
.It Ar chroot
Run the program in chroot. requires some previous setup
.It Ar clearenv
Unset the whole environment
.It Ar core
Set no limit the core file size
.It Ar connect
Expand Down Expand Up @@ -68,16 +72,12 @@ Path to program to be executed
Set to true to print the PID of the process to stderr
.It Ar pidfile
Print the PID of the process to the specified file
.It Ar execve
Use execve instead of posix_spawn (osx tricks)
.It Ar runlib
Path to the library to be executed
.It Ar runlib.fcn
Function name to call from runlib library
.It Ar rzpreload
Preload with librz, kill -USR1 to get an rizin shell or -USRZ to spawn a webserver in a thread
.It Ar rzpreweb
Run the webserver in a thread just at starting the rzpreload
.It Ar setenv
Set value for given environment variable
.It Ar setegid
Expand All @@ -90,10 +90,16 @@ Set process group id
Set process uid
.It Ar sleep
Sleep for the given amount of seconds
.It Ar stdio=value
Set io streams (stdin, stdout, stderr) to a value
.It Ar stdio=!cmd
Redirect input/output to the process created by the specified command
.It Ar stdin
Select file to read data from stdin
Set stdin, stdout, and stderr streams to the specified value
.It Ar stdout
Select file to replace stdout file descriptor
.It Ar stderr
Select file to replace stderr file descriptor
.It Ar system
Execute the given command
.It Ar timeout
Expand Down
1 change: 0 additions & 1 deletion librz/include/rz_socket.h
Original file line number Diff line number Diff line change
Expand Up @@ -275,7 +275,6 @@ RZ_API RzRunProfile *rz_run_new(const char *str);
RZ_API bool rz_run_parse(RzRunProfile *pf, const char *profile);
RZ_API void rz_run_free(RzRunProfile *r);
RZ_API bool rz_run_parseline(RzRunProfile *p, const char *b);
RZ_API const char *rz_run_help(void);
RZ_API int rz_run_config_env(RzRunProfile *p);
RZ_API int rz_run_start(RzRunProfile *p);
RZ_API void rz_run_reset(RzRunProfile *p);
Expand Down
145 changes: 142 additions & 3 deletions librz/main/rz-run.c
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#include <rz_util.h>
#include <rz_main.h>
#include <rz_socket.h>
#include <rz_util/rz_print.h>

#if __UNIX__
static void fwd(int sig) {
Expand All @@ -22,19 +23,157 @@ static void rz_run_tty(void) {
}
#endif

static void rz_run_help(int v) {
if (v == 0) {
printf(Color_CYAN "Usage: ");
printf(Color_RESET "[directives] [script.rz] [--] [program] [args]\n");
const char *options[] = {
// clang-format off
"-h", "", "Show this help",
"-l", "", "Show profile options",
"-t", "", "Output template profile",
"-v", "", "Show version information",
"-w", "", "Wait for incoming terminal process",
"--", "[program] [args]", "Run commands",
// clang-format on
};
size_t maxOptionAndArgLength = 0;
for (int i = 0; i < sizeof(options) / sizeof(options[0]); i += 3) {
size_t optionLength = strlen(options[i]);
size_t argLength = strlen(options[i + 1]);
size_t totalLength = optionLength + argLength;
if (totalLength > maxOptionAndArgLength) {
maxOptionAndArgLength = totalLength;
}
}
for (int i = 0; i < sizeof(options) / sizeof(options[0]); i += 3) {
if (i + 1 < sizeof(options) / sizeof(options[0])) {
rz_print_colored_help_option(options[i], options[i + 1], options[i + 2], maxOptionAndArgLength);
}
}
}
if (v == 1) {
// clang-format off
printf(
"program=/bin/ls\n"
"arg1=/bin\n"
"# arg2=hello\n"
"# arg3=\"hello\\nworld\"\n"
"# arg4=:048490184058104849\n"
"# arg5=:!rz-gg -p n50 -d 10:0x8048123\n"
"# [email protected]\n"
"# arg7=@300@ABCD # 300 chars filled with ABCD pattern\n"
"# system=rizin -\n"
"# daemon=false\n"
"# aslr=no\n"
"setenv=FOO=BAR\n"
"# unsetenv=FOO\n"
"# clearenv=true\n"
"# envfile=environ.txt\n"
"timeout=3\n"
"# timeoutsig=SIGTERM # or 15\n"
"# connect=localhost:8080\n"
"# listen=8080\n"
"# pty=false\n"
"# fork=true\n"
"# bits=32\n"
"# pid=0\n"
"# pidfile=/tmp/foo.pid\n"
"# #sleep=0\n"
"# #maxfd=0\n"
"# #execve=false\n"
"# #maxproc=0\n"
"# #maxstack=0\n"
"# #core=false\n"
"# #stdio=blah.txt\n"
"# #stderr=foo.txt\n"
"# stdout=foo.txt\n"
"# stdin=input.txt # or !program to redirect input from another program\n"
"# input=input.txt\n"
"# chdir=/\n"
"# chroot=/mnt/chroot\n"
"# libpath=$PWD:/tmp/lib\n"
"# rzpreload=yes\n"
"# preload=/lib/libfoo.so\n"
"# setuid=2000\n"
"# seteuid=2000\n"
"# setgid=2001\n"
"# setegid=2001\n"
"# nice=5\n"
""
);
// clang-format on
}
if (v == 2) {
// clang-format off
printf(Color_CYAN "Supported RzRun profile options:\n"
Color_RESET
"arg[0-511] Set value for argument N passed to the program\n"
"aslr Enable or disable ASLR\n"
"bits Set 32 or 64 bit (if the architecture supports it)\n"
"chdir Change directory before executing the program\n"
"chroot Run the program in chroot. requires some previous setup\n"
"connect Connect stdin/stdout/stderr to a socket\n"
"core Set no limit the core file size\n"
"daemon Set to false by default, otherwise it will run the program in background, detached from the terminal\n"
"envfile Set a file with lines like `var=value` to be used as env\n"
"fork Used with the listen option, allow to spawn a different process for each connection. Ignored when debugging.\n"
"input Set string to be passed to the program via stdin\n"
"libpath Override path where the dynamic loader will look for shared libraries\n"
"listen Bound stdin/stdout/stderr to a listening socket\n"
"maxfd Set the maximum number of file descriptors\n"
"maxproc Set the maximum number of processes\n"
"maxstack Set the maximum size for the stack\n"
"nice Set the niceness level of the process\n"
"pid Set to true to print the PID of the process to stderr\n"
"pidfile Print the PID of the process to the specified file\n"
"preload Preload a library (not supported on Windows, only linux,osx,bsd)\n"
"program Path to program to be executed\n"
"pty Use a pty for connection over socket (with connect/listen)\n"
"runlib Path to the library to be executed\n"
"runlib.fcn Function name to call from runlib library\n"
"rzpreload Preload with librz, kill -USR1 to get an rizin shell or -USRZ to spawn a webserver in a thread\n"
"setegid Set effective process group id\n"
"setenv Set value for given environment variable (setenv=FOO=BAR)\n"
"seteuid Set effective process uid\n"
"setgid Set process group id\n"
"setuid Set process uid\n"
"sleep Sleep for the given amount of seconds\n"
"sterr Select file to replace stderr file descriptor\n"
"stdin Select file to read data from stdin\n"
"stdio Select io stream to redirect data from/to\n"
" Redirect input/output to the process created by the specified command prefixed by '!' (stdio=!cmd)\n"
"stdout Select file to replace stdout file descriptor\n"
"system Execute the given command\n"
"timeout Set a timeout\n"
"timeoutsig Signal to use when killing the child because the timeout happens\n"
"unsetenv Unset one environment variable\n"
"");
// clang-format off
}
}


RZ_API int rz_main_rz_run(int argc, const char **argv) {
RzRunProfile *p;
int i, ret;
if (argc == 1 || !strcmp(argv[1], "-h")) {
printf("Usage: rz-run -v|-t|script.rz [directive ..]\n");
printf("%s", rz_run_help());
rz_run_help(0);
return 1;
}
if (!strcmp(argv[1], "-v")) {
return rz_main_version_print("rz-run");
}
if (!strcmp(argv[1], "-t")) {
rz_run_help(1);
return 0;
}
if (!strcmp(argv[1], "-l")) {
rz_run_help(2);
return 0;
}
const char *file = argv[1];
if (!strcmp(file, "-t")) {
if (!strcmp(file, "-w")) {
#if __UNIX__
rz_run_tty();
return 0;
Expand Down
48 changes: 0 additions & 48 deletions librz/socket/run.c
Original file line number Diff line number Diff line change
Expand Up @@ -655,54 +655,6 @@ RZ_API bool rz_run_parseline(RzRunProfile *p, const char *b) {
return true;
}

RZ_API const char *rz_run_help(void) {
return "program=/bin/ls\n"
"arg1=/bin\n"
"# arg2=hello\n"
"# arg3=\"hello\\nworld\"\n"
"# arg4=:048490184058104849\n"
"# arg5=:!rz-gg -p n50 -d 10:0x8048123\n"
"# [email protected]\n"
"# arg7=@300@ABCD # 300 chars filled with ABCD pattern\n"
"# system=rizin -\n"
"# daemon=false\n"
"# aslr=no\n"
"setenv=FOO=BAR\n"
"# unsetenv=FOO\n"
"# clearenv=true\n"
"# envfile=environ.txt\n"
"timeout=3\n"
"# timeoutsig=SIGTERM # or 15\n"
"# connect=localhost:8080\n"
"# listen=8080\n"
"# pty=false\n"
"# fork=true\n"
"# bits=32\n"
"# pid=0\n"
"# pidfile=/tmp/foo.pid\n"
"# #sleep=0\n"
"# #maxfd=0\n"
"# #execve=false\n"
"# #maxproc=0\n"
"# #maxstack=0\n"
"# #core=false\n"
"# #stdio=blah.txt\n"
"# #stderr=foo.txt\n"
"# stdout=foo.txt\n"
"# stdin=input.txt # or !program to redirect input from another program\n"
"# input=input.txt\n"
"# chdir=/\n"
"# chroot=/mnt/chroot\n"
"# libpath=$PWD:/tmp/lib\n"
"# rzpreload=yes\n"
"# preload=/lib/libfoo.so\n"
"# setuid=2000\n"
"# seteuid=2000\n"
"# setgid=2001\n"
"# setegid=2001\n"
"# nice=5\n";
}

#if HAVE_OPENPTY && HAVE_FORKPTY && HAVE_LOGIN_TTY
static int fd_forward(int in_fd, int out_fd, char **buff) {
int size = 0;
Expand Down

0 comments on commit a5297b5

Please sign in to comment.