Run program and intercept and redirect syscalls
up vote
1
down vote
favorite
I would like to run a program, and when that program attempts to read a specific file, I would like it to read a different file of my choosing instead.
Specifically, the program attempts to read a configuration file, and is poorly designed and doesn't allow the user to specify the location of the configuration file. I also don't have permission to edit the file at the location the program attempts to read from.
I know it's possible to detect syscalls made by the program using strace
, and I am able to see the sole open()
syscall made by the program by running it under strace
. It there any way to intercept that syscall and change it's behaviour to open a different file of my choice?
linux strace syscalls
add a comment |
up vote
1
down vote
favorite
I would like to run a program, and when that program attempts to read a specific file, I would like it to read a different file of my choosing instead.
Specifically, the program attempts to read a configuration file, and is poorly designed and doesn't allow the user to specify the location of the configuration file. I also don't have permission to edit the file at the location the program attempts to read from.
I know it's possible to detect syscalls made by the program using strace
, and I am able to see the sole open()
syscall made by the program by running it under strace
. It there any way to intercept that syscall and change it's behaviour to open a different file of my choice?
linux strace syscalls
add a comment |
up vote
1
down vote
favorite
up vote
1
down vote
favorite
I would like to run a program, and when that program attempts to read a specific file, I would like it to read a different file of my choosing instead.
Specifically, the program attempts to read a configuration file, and is poorly designed and doesn't allow the user to specify the location of the configuration file. I also don't have permission to edit the file at the location the program attempts to read from.
I know it's possible to detect syscalls made by the program using strace
, and I am able to see the sole open()
syscall made by the program by running it under strace
. It there any way to intercept that syscall and change it's behaviour to open a different file of my choice?
linux strace syscalls
I would like to run a program, and when that program attempts to read a specific file, I would like it to read a different file of my choosing instead.
Specifically, the program attempts to read a configuration file, and is poorly designed and doesn't allow the user to specify the location of the configuration file. I also don't have permission to edit the file at the location the program attempts to read from.
I know it's possible to detect syscalls made by the program using strace
, and I am able to see the sole open()
syscall made by the program by running it under strace
. It there any way to intercept that syscall and change it's behaviour to open a different file of my choice?
linux strace syscalls
linux strace syscalls
asked Nov 27 at 5:55
Drew
1185
1185
add a comment |
add a comment |
1 Answer
1
active
oldest
votes
up vote
2
down vote
LD_PRELOAD
can do this on linux; first up our application to modify, app.c
#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>
int main(int argc, char *argv)
{
char c;
int fd;
fd = open(*++argv, O_RDONLY);
read(fd, &c, 1);
printf("%cn", c);
return 0;
}
which serves to read a character from a file:
$ make app
cc app.c -o app
$ echo a > a
$ echo b > b
$ ./app a ; ./app b
a
b
changing this up requires a library that fakes out open
, fakeopen.c
:
#define _GNU_SOURCE
#include <dlfcn.h>
#include <fcntl.h>
#include <stdarg.h>
#include <stdlib.h>
#include <string.h>
typedef int (*orig_open) (const char *path, int oflag, ...);
int open(const char *path, int oflag, ...)
{
orig_open fn;
mode_t cmode = 0;
va_list ap;
if ((oflag & O_CREAT) == O_CREAT) {
va_start(ap, oflag);
cmode = (mode_t) va_arg(ap, int);
va_end(ap);
}
if (strncmp(path, "a", 2) == 0)
path = getenv("FAKE");
fn = (orig_open) dlsym(RTLD_NEXT, "open");
return fn(path, oflag, cmode);
}
which when compiled and used via LD_PRELOAD
and when the filename is what we're looking for and assuming FAKE
has something that is the path:
$ cat Makefile
fakeopen.so: fakeopen.c
$(CC) $(CFLAGS) -shared -fPIC -ldl fakeopen.c -o fakeopen.so
$ rm fakeopen.so
$ cat Makefile
fakeopen.so: fakeopen.c
$(CC) $(CFLAGS) -shared -fPIC -ldl fakeopen.c -o fakeopen.so
$ make fakeopen.so
cc -shared -fPIC -ldl fakeopen.c -o fakeopen.so
$ FAKE=b LD_PRELOAD=`pwd`/fakeopen.so ./app a
b
we can make ./app a
instead read file b
. Of course there will need to be more error checking and other rakes that may be stepped on, but this should be the gist of modifying an open(2)
call.
that will only work if open(2) is called directly, not via fopen(3); eg. yourfakeopen.so
will work willcat file
but not withsort file
. And it's the same with all libc functions that call open(2) internally.
– mosvy
Nov 27 at 13:27
add a comment |
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
2
down vote
LD_PRELOAD
can do this on linux; first up our application to modify, app.c
#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>
int main(int argc, char *argv)
{
char c;
int fd;
fd = open(*++argv, O_RDONLY);
read(fd, &c, 1);
printf("%cn", c);
return 0;
}
which serves to read a character from a file:
$ make app
cc app.c -o app
$ echo a > a
$ echo b > b
$ ./app a ; ./app b
a
b
changing this up requires a library that fakes out open
, fakeopen.c
:
#define _GNU_SOURCE
#include <dlfcn.h>
#include <fcntl.h>
#include <stdarg.h>
#include <stdlib.h>
#include <string.h>
typedef int (*orig_open) (const char *path, int oflag, ...);
int open(const char *path, int oflag, ...)
{
orig_open fn;
mode_t cmode = 0;
va_list ap;
if ((oflag & O_CREAT) == O_CREAT) {
va_start(ap, oflag);
cmode = (mode_t) va_arg(ap, int);
va_end(ap);
}
if (strncmp(path, "a", 2) == 0)
path = getenv("FAKE");
fn = (orig_open) dlsym(RTLD_NEXT, "open");
return fn(path, oflag, cmode);
}
which when compiled and used via LD_PRELOAD
and when the filename is what we're looking for and assuming FAKE
has something that is the path:
$ cat Makefile
fakeopen.so: fakeopen.c
$(CC) $(CFLAGS) -shared -fPIC -ldl fakeopen.c -o fakeopen.so
$ rm fakeopen.so
$ cat Makefile
fakeopen.so: fakeopen.c
$(CC) $(CFLAGS) -shared -fPIC -ldl fakeopen.c -o fakeopen.so
$ make fakeopen.so
cc -shared -fPIC -ldl fakeopen.c -o fakeopen.so
$ FAKE=b LD_PRELOAD=`pwd`/fakeopen.so ./app a
b
we can make ./app a
instead read file b
. Of course there will need to be more error checking and other rakes that may be stepped on, but this should be the gist of modifying an open(2)
call.
that will only work if open(2) is called directly, not via fopen(3); eg. yourfakeopen.so
will work willcat file
but not withsort file
. And it's the same with all libc functions that call open(2) internally.
– mosvy
Nov 27 at 13:27
add a comment |
up vote
2
down vote
LD_PRELOAD
can do this on linux; first up our application to modify, app.c
#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>
int main(int argc, char *argv)
{
char c;
int fd;
fd = open(*++argv, O_RDONLY);
read(fd, &c, 1);
printf("%cn", c);
return 0;
}
which serves to read a character from a file:
$ make app
cc app.c -o app
$ echo a > a
$ echo b > b
$ ./app a ; ./app b
a
b
changing this up requires a library that fakes out open
, fakeopen.c
:
#define _GNU_SOURCE
#include <dlfcn.h>
#include <fcntl.h>
#include <stdarg.h>
#include <stdlib.h>
#include <string.h>
typedef int (*orig_open) (const char *path, int oflag, ...);
int open(const char *path, int oflag, ...)
{
orig_open fn;
mode_t cmode = 0;
va_list ap;
if ((oflag & O_CREAT) == O_CREAT) {
va_start(ap, oflag);
cmode = (mode_t) va_arg(ap, int);
va_end(ap);
}
if (strncmp(path, "a", 2) == 0)
path = getenv("FAKE");
fn = (orig_open) dlsym(RTLD_NEXT, "open");
return fn(path, oflag, cmode);
}
which when compiled and used via LD_PRELOAD
and when the filename is what we're looking for and assuming FAKE
has something that is the path:
$ cat Makefile
fakeopen.so: fakeopen.c
$(CC) $(CFLAGS) -shared -fPIC -ldl fakeopen.c -o fakeopen.so
$ rm fakeopen.so
$ cat Makefile
fakeopen.so: fakeopen.c
$(CC) $(CFLAGS) -shared -fPIC -ldl fakeopen.c -o fakeopen.so
$ make fakeopen.so
cc -shared -fPIC -ldl fakeopen.c -o fakeopen.so
$ FAKE=b LD_PRELOAD=`pwd`/fakeopen.so ./app a
b
we can make ./app a
instead read file b
. Of course there will need to be more error checking and other rakes that may be stepped on, but this should be the gist of modifying an open(2)
call.
that will only work if open(2) is called directly, not via fopen(3); eg. yourfakeopen.so
will work willcat file
but not withsort file
. And it's the same with all libc functions that call open(2) internally.
– mosvy
Nov 27 at 13:27
add a comment |
up vote
2
down vote
up vote
2
down vote
LD_PRELOAD
can do this on linux; first up our application to modify, app.c
#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>
int main(int argc, char *argv)
{
char c;
int fd;
fd = open(*++argv, O_RDONLY);
read(fd, &c, 1);
printf("%cn", c);
return 0;
}
which serves to read a character from a file:
$ make app
cc app.c -o app
$ echo a > a
$ echo b > b
$ ./app a ; ./app b
a
b
changing this up requires a library that fakes out open
, fakeopen.c
:
#define _GNU_SOURCE
#include <dlfcn.h>
#include <fcntl.h>
#include <stdarg.h>
#include <stdlib.h>
#include <string.h>
typedef int (*orig_open) (const char *path, int oflag, ...);
int open(const char *path, int oflag, ...)
{
orig_open fn;
mode_t cmode = 0;
va_list ap;
if ((oflag & O_CREAT) == O_CREAT) {
va_start(ap, oflag);
cmode = (mode_t) va_arg(ap, int);
va_end(ap);
}
if (strncmp(path, "a", 2) == 0)
path = getenv("FAKE");
fn = (orig_open) dlsym(RTLD_NEXT, "open");
return fn(path, oflag, cmode);
}
which when compiled and used via LD_PRELOAD
and when the filename is what we're looking for and assuming FAKE
has something that is the path:
$ cat Makefile
fakeopen.so: fakeopen.c
$(CC) $(CFLAGS) -shared -fPIC -ldl fakeopen.c -o fakeopen.so
$ rm fakeopen.so
$ cat Makefile
fakeopen.so: fakeopen.c
$(CC) $(CFLAGS) -shared -fPIC -ldl fakeopen.c -o fakeopen.so
$ make fakeopen.so
cc -shared -fPIC -ldl fakeopen.c -o fakeopen.so
$ FAKE=b LD_PRELOAD=`pwd`/fakeopen.so ./app a
b
we can make ./app a
instead read file b
. Of course there will need to be more error checking and other rakes that may be stepped on, but this should be the gist of modifying an open(2)
call.
LD_PRELOAD
can do this on linux; first up our application to modify, app.c
#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>
int main(int argc, char *argv)
{
char c;
int fd;
fd = open(*++argv, O_RDONLY);
read(fd, &c, 1);
printf("%cn", c);
return 0;
}
which serves to read a character from a file:
$ make app
cc app.c -o app
$ echo a > a
$ echo b > b
$ ./app a ; ./app b
a
b
changing this up requires a library that fakes out open
, fakeopen.c
:
#define _GNU_SOURCE
#include <dlfcn.h>
#include <fcntl.h>
#include <stdarg.h>
#include <stdlib.h>
#include <string.h>
typedef int (*orig_open) (const char *path, int oflag, ...);
int open(const char *path, int oflag, ...)
{
orig_open fn;
mode_t cmode = 0;
va_list ap;
if ((oflag & O_CREAT) == O_CREAT) {
va_start(ap, oflag);
cmode = (mode_t) va_arg(ap, int);
va_end(ap);
}
if (strncmp(path, "a", 2) == 0)
path = getenv("FAKE");
fn = (orig_open) dlsym(RTLD_NEXT, "open");
return fn(path, oflag, cmode);
}
which when compiled and used via LD_PRELOAD
and when the filename is what we're looking for and assuming FAKE
has something that is the path:
$ cat Makefile
fakeopen.so: fakeopen.c
$(CC) $(CFLAGS) -shared -fPIC -ldl fakeopen.c -o fakeopen.so
$ rm fakeopen.so
$ cat Makefile
fakeopen.so: fakeopen.c
$(CC) $(CFLAGS) -shared -fPIC -ldl fakeopen.c -o fakeopen.so
$ make fakeopen.so
cc -shared -fPIC -ldl fakeopen.c -o fakeopen.so
$ FAKE=b LD_PRELOAD=`pwd`/fakeopen.so ./app a
b
we can make ./app a
instead read file b
. Of course there will need to be more error checking and other rakes that may be stepped on, but this should be the gist of modifying an open(2)
call.
answered Nov 27 at 6:29
thrig
23.8k12955
23.8k12955
that will only work if open(2) is called directly, not via fopen(3); eg. yourfakeopen.so
will work willcat file
but not withsort file
. And it's the same with all libc functions that call open(2) internally.
– mosvy
Nov 27 at 13:27
add a comment |
that will only work if open(2) is called directly, not via fopen(3); eg. yourfakeopen.so
will work willcat file
but not withsort file
. And it's the same with all libc functions that call open(2) internally.
– mosvy
Nov 27 at 13:27
that will only work if open(2) is called directly, not via fopen(3); eg. your
fakeopen.so
will work will cat file
but not with sort file
. And it's the same with all libc functions that call open(2) internally.– mosvy
Nov 27 at 13:27
that will only work if open(2) is called directly, not via fopen(3); eg. your
fakeopen.so
will work will cat file
but not with sort file
. And it's the same with all libc functions that call open(2) internally.– mosvy
Nov 27 at 13:27
add a comment |
Thanks for contributing an answer to Unix & Linux Stack Exchange!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Some of your past answers have not been well-received, and you're in danger of being blocked from answering.
Please pay close attention to the following guidance:
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f484368%2frun-program-and-intercept-and-redirect-syscalls%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown