From cc622a627113f2612aa77d52f6515de8046e0344 Mon Sep 17 00:00:00 2001 From: xarkes Date: Mon, 31 Jul 2017 15:03:11 +0200 Subject: [PATCH] Added runlib to rarun2 - fix #8045 (#8066) --- libr/include/r_socket.h | 101 +++++++++++++++++++++------------------- libr/include/r_types.h | 53 ++++++++++++++++++++- libr/socket/run.c | 75 +++++++++++++++++++++++++++-- man/rarun2.1 | 14 +++++- 4 files changed, 186 insertions(+), 57 deletions(-) diff --git a/libr/include/r_socket.h b/libr/include/r_socket.h index 50ba530d78..e5b5b73a17 100644 --- a/libr/include/r_socket.h +++ b/libr/include/r_socket.h @@ -12,7 +12,7 @@ extern "C" { #endif -R_LIB_VERSION_HEADER(r_socket); +R_LIB_VERSION_HEADER (r_socket); #if __UNIX__ || __CYGWIN__ || __MINGW64__ && !defined(MINGW32) #include @@ -61,7 +61,7 @@ typedef struct r_socket_t { int fd; #endif int is_ssl; - int local; // TODO: merge ssl with local -> flags/options + int local; // TODO: merge ssl with local -> flags/options int port; struct sockaddr_in sa; #if HAVE_LIB_SSL @@ -76,34 +76,34 @@ typedef struct r_socket_t { #define R_SOCKET_PROTO_UNIX 0x1337 #ifdef R_API -R_API RSocket *r_socket_new_from_fd (int fd); -R_API RSocket *r_socket_new (int is_ssl); -R_API bool r_socket_connect (RSocket *s, const char *host, const char *port, int proto, unsigned int timeout); +R_API RSocket *r_socket_new_from_fd(int fd); +R_API RSocket *r_socket_new(int is_ssl); +R_API bool r_socket_connect(RSocket *s, const char *host, const char *port, int proto, unsigned int timeout); R_API int r_socket_connect_serial(RSocket *sock, const char *path, int speed, int parity); -#define r_socket_connect_tcp(a,b,c,d) r_socket_connect(a,b,c,R_SOCKET_PROTO_TCP,d) -#define r_socket_connect_udp(a,b,c,d) r_socket_connect(a,b,c,R_SOCKET_PROTO_UDP,d) +#define r_socket_connect_tcp(a, b, c, d) r_socket_connect (a, b, c, R_SOCKET_PROTO_TCP, d) +#define r_socket_connect_udp(a, b, c, d) r_socket_connect (a, b, c, R_SOCKET_PROTO_UDP, d) #if __UNIX__ -#define r_socket_connect_unix(a,b) r_socket_connect(a,b,NULL,R_SOCKET_PROTO_UNIX) -R_API int r_socket_unix_listen (RSocket *s, const char *file); +#define r_socket_connect_unix(a, b) r_socket_connect (a, b, NULL, R_SOCKET_PROTO_UNIX) +R_API int r_socket_unix_listen(RSocket *s, const char *file); #endif R_API int r_socket_port_by_name(const char *name); -R_API int r_socket_close_fd (RSocket *s); -R_API int r_socket_close (RSocket *s); -R_API int r_socket_free (RSocket *s); -R_API bool r_socket_listen (RSocket *s, const char *port, const char *certfile); -R_API RSocket *r_socket_accept (RSocket *s); -R_API int r_socket_block_time (RSocket *s, int block, int sec); -R_API int r_socket_flush (RSocket *s); -R_API int r_socket_ready (RSocket *s, int secs, int usecs); -R_API char *r_socket_to_string (RSocket *s); -R_API int r_socket_write (RSocket *s, void *buf, int len); -R_API int r_socket_puts (RSocket *s, char *buf); -R_API void r_socket_printf (RSocket *s, const char *fmt, ...); -R_API int r_socket_read (RSocket *s, ut8 *read, int len); -R_API int r_socket_read_block (RSocket *s, unsigned char *buf, int len); -R_API int r_socket_gets (RSocket *s, char *buf, int size); -R_API ut8* r_socket_slurp(RSocket *s, int *len); -R_API bool r_socket_is_connected (RSocket *); +R_API int r_socket_close_fd(RSocket *s); +R_API int r_socket_close(RSocket *s); +R_API int r_socket_free(RSocket *s); +R_API bool r_socket_listen(RSocket *s, const char *port, const char *certfile); +R_API RSocket *r_socket_accept(RSocket *s); +R_API int r_socket_block_time(RSocket *s, int block, int sec); +R_API int r_socket_flush(RSocket *s); +R_API int r_socket_ready(RSocket *s, int secs, int usecs); +R_API char *r_socket_to_string(RSocket *s); +R_API int r_socket_write(RSocket *s, void *buf, int len); +R_API int r_socket_puts(RSocket *s, char *buf); +R_API void r_socket_printf(RSocket *s, const char *fmt, ...); +R_API int r_socket_read(RSocket *s, ut8 *read, int len); +R_API int r_socket_read_block(RSocket *s, unsigned char *buf, int len); +R_API int r_socket_gets(RSocket *s, char *buf, int size); +R_API ut8 *r_socket_slurp(RSocket *s, int *len); +R_API bool r_socket_is_connected(RSocket *); /* process */ typedef struct r_socket_proc_t { @@ -112,17 +112,17 @@ typedef struct r_socket_proc_t { int pid; } RSocketProc; -R_API RSocketProc *r_socket_proc_open(char* const argv[]); +R_API RSocketProc *r_socket_proc_open(char *const argv[]); R_API int r_socket_proc_close(RSocketProc *sp); -R_API int r_socket_proc_read (RSocketProc *sp, unsigned char *buf, int len); -R_API int r_socket_proc_gets (RSocketProc *sp, char *buf, int size); -R_API int r_socket_proc_write (RSocketProc *sp, void *buf, int len); -R_API void r_socket_proc_printf (RSocketProc *sp, const char *fmt, ...); -R_API int r_socket_proc_ready (RSocketProc *sp, int secs, int usecs); +R_API int r_socket_proc_read(RSocketProc *sp, unsigned char *buf, int len); +R_API int r_socket_proc_gets(RSocketProc *sp, char *buf, int size); +R_API int r_socket_proc_write(RSocketProc *sp, void *buf, int len); +R_API void r_socket_proc_printf(RSocketProc *sp, const char *fmt, ...); +R_API int r_socket_proc_ready(RSocketProc *sp, int secs, int usecs); /* HTTP */ -R_API char *r_socket_http_get (const char *url, int *code, int *rlen); -R_API char *r_socket_http_post (const char *url, const char *data, int *code, int *rlen); +R_API char *r_socket_http_get(const char *url, int *code, int *rlen); +R_API char *r_socket_http_post(const char *url, const char *data, int *code, int *rlen); R_API void r_socket_http_server_set_breaked(bool *b); typedef struct r_socket_http_request { @@ -136,9 +136,9 @@ typedef struct r_socket_http_request { int data_length; } RSocketHTTPRequest; -R_API RSocketHTTPRequest *r_socket_http_accept (RSocket *s, int timeout); -R_API void r_socket_http_response (RSocketHTTPRequest *rs, int code, const char *out, int x, const char *headers); -R_API void r_socket_http_close (RSocketHTTPRequest *rs); +R_API RSocketHTTPRequest *r_socket_http_accept(RSocket *s, int timeout); +R_API void r_socket_http_response(RSocketHTTPRequest *rs, int code, const char *out, int x, const char *headers); +R_API void r_socket_http_close(RSocketHTTPRequest *rs); R_API ut8 *r_socket_http_handle_upload(const ut8 *str, int len, int *olen); typedef int (*rap_server_open)(void *user, const char *file, int flg, int mode); @@ -162,7 +162,7 @@ enum { typedef struct r_socket_rap_server_t { RSocket *fd; char port[5]; - ut8 buf[RAP_RMT_MAX + 32]; //This should be used as a static buffer for everything done by the server + ut8 buf[RAP_RMT_MAX + 32]; // This should be used as a static buffer for everything done by the server rap_server_open open; rap_server_seek seek; rap_server_read read; @@ -170,22 +170,25 @@ typedef struct r_socket_rap_server_t { rap_server_cmd system; rap_server_cmd cmd; rap_server_close close; - void *user; //Always first arg for callbacks + void *user; // Always first arg for callbacks } RSocketRapServer; -R_API RSocketRapServer *r_socket_rap_server_new (int is_ssl, const char *port); -R_API RSocketRapServer *r_socket_rap_server_create (const char *pathname); -R_API void r_socket_rap_server_free (RSocketRapServer *rap_s); -R_API int r_socket_rap_server_listen (RSocketRapServer *rap_s, const char *certfile); -R_API RSocket* r_socket_rap_server_accept (RSocketRapServer *rap_s); -R_API bool r_socket_rap_server_continue (RSocketRapServer *rap_s); +R_API RSocketRapServer *r_socket_rap_server_new(int is_ssl, const char *port); +R_API RSocketRapServer *r_socket_rap_server_create(const char *pathname); +R_API void r_socket_rap_server_free(RSocketRapServer *rap_s); +R_API int r_socket_rap_server_listen(RSocketRapServer *rap_s, const char *certfile); +R_API RSocket *r_socket_rap_server_accept(RSocketRapServer *rap_s); +R_API bool r_socket_rap_server_continue(RSocketRapServer *rap_s); /* run.c */ #define R_RUN_PROFILE_NARGS 512 typedef struct r_run_profile_t { char *_args[R_RUN_PROFILE_NARGS]; + int _argc; char *_system; char *_program; + char *_runlib; + char *_runlib_fcn; char *_stdio; char *_stdin; char *_stdout; @@ -222,20 +225,20 @@ typedef struct r_run_profile_t { R_API RRunProfile *r_run_new(const char *str); R_API bool r_run_parse(RRunProfile *pf, const char *profile); -R_API void r_run_free (RRunProfile *r); -R_API bool r_run_parseline (RRunProfile *p, char *b); +R_API void r_run_free(RRunProfile *r); +R_API bool r_run_parseline(RRunProfile *p, char *b); R_API const char *r_run_help(void); R_API int r_run_config_env(RRunProfile *p); R_API int r_run_start(RRunProfile *p); R_API void r_run_reset(RRunProfile *p); -R_API int r_run_parsefile (RRunProfile *p, const char *b); +R_API int r_run_parsefile(RRunProfile *p, const char *b); /* r2pipe */ R_API int r2p_close(R2Pipe *r2p); R_API R2Pipe *r2p_open(const char *cmd); R_API int r2p_write(R2Pipe *r2p, const char *str); R_API char *r2p_read(R2Pipe *r2p); -R_API void r2p_free (R2Pipe *r2p); +R_API void r2p_free(R2Pipe *r2p); R_API char *r2p_cmd(R2Pipe *r2p, const char *str); R_API char *r2p_cmdf(R2Pipe *r2p, const char *fmt, ...); #endif diff --git a/libr/include/r_types.h b/libr/include/r_types.h index 299f3b244c..8b73c205a1 100644 --- a/libr/include/r_types.h +++ b/libr/include/r_types.h @@ -529,6 +529,56 @@ enum { } #endif +static inline void r_run_call1 (void *fcn, void *arg1) { + ((void (*)(void *))(fcn))(arg1); +} + +static inline void r_run_call2 (void *fcn, void *arg1, void *arg2) { + ((void (*)(void *, void *))(fcn))(arg1, arg2); +} + +static inline void r_run_call3 (void *fcn, void *arg1, void *arg2, void *arg3) { + ((void (*)(void *, void *, void *))(fcn))(arg1, arg2, arg3); +} + +static inline void r_run_call4 (void *fcn, void *arg1, void *arg2, void *arg3, void *arg4) { + ((void (*)(void *, void *, void *, void *))(fcn))(arg1, arg2, arg3, arg4); +} + +static inline void r_run_call5 (void *fcn, void *arg1, void *arg2, void *arg3, void *arg4, void *arg5) { + ((void (*)(void *, void *, void *, void *, void *))(fcn))(arg1, arg2, arg3, arg4, arg5); +} + +static inline void r_run_call6 (void *fcn, void *arg1, void *arg2, void *arg3, void *arg4, void *arg5, + void *arg6) { + ((void (*)(void *, void *, void *, void *, void *, void *))(fcn)) + (arg1, arg2, arg3, arg4, arg5, arg6); +} + +static inline void r_run_call7 (void *fcn, void *arg1, void *arg2, void *arg3, void *arg4, void *arg5, + void *arg6, void *arg7) { + ((void (*)(void *, void *, void *, void *, void *, void *, void *))(fcn)) + (arg1, arg2, arg3, arg4, arg5, arg6, arg7); +} + +static inline void r_run_call8 (void *fcn, void *arg1, void *arg2, void *arg3, void *arg4, void *arg5, + void *arg6, void *arg7, void *arg8) { + ((void (*)(void *, void *, void *, void *, void *, void *, void *, void *))(fcn)) + (arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8); +} + +static inline void r_run_call9 (void *fcn, void *arg1, void *arg2, void *arg3, void *arg4, void *arg5, + void *arg6, void *arg7, void *arg8, void *arg9) { + ((void (*)(void *, void *, void *, void *, void *, void *, void *, void *, void *))(fcn)) + (arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9); +} + +static inline void r_run_call10 (void *fcn, void *arg1, void *arg2, void *arg3, void *arg4, void *arg5, + void *arg6, void *arg7, void *arg8, void *arg9, void *arg10) { + ((void (*)(void *, void *, void *, void *, void *, void *, void *, void *, void *, void *))(fcn)) + (arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10); +} + #endif // Usage: R_DEFINE_OBJECT(r_asm); @@ -540,5 +590,4 @@ enum { R_API struct type##_t* type##_free(struct type##_t *foo) { \ return (type##_deinit(foo), free(foo), NULL); \ } -#endif - +#endif \ No newline at end of file diff --git a/libr/socket/run.c b/libr/socket/run.c index cba380af36..5ea17104de 100644 --- a/libr/socket/run.c +++ b/libr/socket/run.c @@ -93,6 +93,8 @@ R_API bool r_run_parse(RRunProfile *pf, const char *profile) { R_API void r_run_free (RRunProfile *r) { free (r->_system); free (r->_program); + free (r->_runlib); + free (r->_runlib_fcn); free (r->_stdio); free (r->_stdin); free (r->_stdout); @@ -202,6 +204,8 @@ static char *getstr(const char *src) { eprintf ("Invalid hexpair string\n"); free (ret); return NULL; + case '%': + return (char *) strtoul (src + 1, NULL, 0); } r_str_unescape ((ret = strdup (src))); return ret; @@ -328,7 +332,7 @@ static int handle_redirection(const char *cmd, bool in, bool out, bool err) { //XXX handle this in other layer since things changes a little bit //this seems like a really good place to refactor stuff return 0; -#endif +#endif if (cmd[0] == '"') { #if __UNIX__ @@ -411,6 +415,8 @@ R_API bool r_run_parseline (RRunProfile *p, char *b) { } if (!strcmp (b, "program")) p->_args[0] = p->_program = strdup (e); else if (!strcmp (b, "system")) p->_system = strdup (e); + else if (!strcmp (b, "runlib")) p->_runlib = strdup (e); + else if (!strcmp (b, "runlib.fcn")) p->_runlib_fcn = strdup (e); else if (!strcmp (b, "aslr")) p->_aslr = parseBool (e); else if (!strcmp (b, "pid")) p->_pid = atoi (e); else if (!strcmp (b, "pidfile")) p->_pidfile = strdup (e); @@ -454,6 +460,7 @@ R_API bool r_run_parseline (RRunProfile *p, char *b) { int n = atoi (b + 3); if (n >= 0 && n < R_RUN_PROFILE_NARGS) { p->_args[n] = getstr (e); + p->_argc++; } else { eprintf ("Out of bounds args index: %d\n", n); } @@ -669,8 +676,8 @@ static int redirect_socket_to_pty(RSocket *sock) { R_API int r_run_config_env(RRunProfile *p) { int ret; - if (!p->_program && !p->_system) { - printf ("No program or system rule defined\n"); + if (!p->_program && !p->_system && !p->_runlib) { + printf ("No program, system or runlib rule defined\n"); return 1; } // when IO is redirected to a process, handle them together @@ -686,7 +693,7 @@ R_API int r_run_config_env(RRunProfile *p) { if (handle_redirection (p->_stderr, false, false, true) != 0) { return 1; } - if (p->_aslr != -1) + if (p->_aslr != -1) setASLR (p->_aslr); #if __UNIX__ set_limit (p->_docore, RLIMIT_CORE, RLIM_INFINITY); @@ -1016,5 +1023,65 @@ R_API int r_run_start(RRunProfile *p) { exit (execv (p->_program, (char* const*)p->_args)); #endif } + if (p->_runlib) { + if (!p->_runlib_fcn) { + eprintf ("No function specified. Please set runlib.fcn\n"); + return 1; + } + void *addr = r_lib_dl_open (p->_runlib); + if (!addr) { + eprintf ("Could not load the library '%s'\n", p->_runlib); + return 1; + } + void (*fcn)(void) = r_lib_dl_sym (addr, p->_runlib_fcn); + if (!fcn) { + eprintf ("Could not find the function '%s'\n", p->_runlib_fcn); + return 1; + } + switch (p->_argc) { + case 0: + fcn (); + break; + case 1: + r_run_call1 (fcn, p->_args[1]); + break; + case 2: + r_run_call2 (fcn, p->_args[1], p->_args[2]); + break; + case 3: + r_run_call3 (fcn, p->_args[1], p->_args[2], p->_args[3]); + break; + case 4: + r_run_call4 (fcn, p->_args[1], p->_args[2], p->_args[3], p->_args[4]); + break; + case 5: + r_run_call5 (fcn, p->_args[1], p->_args[2], p->_args[3], p->_args[4], + p->_args[5]); + break; + case 6: + r_run_call6 (fcn, p->_args[1], p->_args[2], p->_args[3], p->_args[4], + p->_args[5], p->_args[6]); + break; + case 7: + r_run_call7 (fcn, p->_args[1], p->_args[2], p->_args[3], p->_args[4], + p->_args[5], p->_args[6], p->_args[7]); + break; + case 8: + r_run_call8 (fcn, p->_args[1], p->_args[2], p->_args[3], p->_args[4], + p->_args[5], p->_args[6], p->_args[7], p->_args[8]); + break; + case 9: + r_run_call9 (fcn, p->_args[1], p->_args[2], p->_args[3], p->_args[4], + p->_args[5], p->_args[6], p->_args[7], p->_args[8], p->_args[9]); + break; + case 10: + r_run_call10 (fcn, p->_args[1], p->_args[2], p->_args[3], p->_args[4], + p->_args[5], p->_args[6], p->_args[7], p->_args[8], p->_args[9], p->_args[10]); + break; + default: + eprintf ("Too many arguments.\n"); + return 1; + } + } return 0; } diff --git a/man/rarun2.1 b/man/rarun2.1 index 5e778fb503..917d3e5b2a 100644 --- a/man/rarun2.1 +++ b/man/rarun2.1 @@ -6,7 +6,7 @@ .Sh SYNOPSIS .Nm rarun2 .Op [directives] -.Op [script.rr2] +.Op [script.rr2] .Op [--] [program] [args] .Sh DESCRIPTION This program is used as a launcher for running programs with different environment, arguments, permissions, directories and overridden default filedescriptors. @@ -62,6 +62,10 @@ preload a library (not supported on Windows, only linux,osx,bsd) path to program to be executed .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 r2preload preload with libr2, kill -USR1 to get an r2 shell or -USR2 to spawn a webserver in a thread .It Ar r2preweb @@ -105,8 +109,10 @@ Escape characters useful for hex chars Run command to store the output in the variable .It Ar :102030 Parse hexpair string and store it in the variable -.It Ar :!102030 +.It Ar :!cmd Parse hexpair string from output of command and store it in the variable +.It Ar %1234 +Parses the input string and returns it as integer .El .Sh EXAMPLES Sample rarun2 script @@ -146,6 +152,10 @@ Debugging a program redirecting io to another terminal You can also use the -- flag to specify program and arguments in a more natural way: .Pp $ rarun2 timeout=2 -- sleep 4 +.Pp +Run a library function +.Pp + $ rarun2 runlib=/lib/libc-2.25.so runlib.fcn=system arg1="ls /" .Sh SEE ALSO .Pp .Xr radare2(1) ,