7
\$\begingroup\$

This one ought to be a little more of a challenge than your normal "compute these numbers" or "print this sequence of text" puzzles:

Write a program that launches another program and when that other program tries to access a certain file the program causes it to open a different file.

Example:

The program launches Notepad.
Notepad attempts to open "orange.txt"
The program detects it and makes notepad open "green.txt" instead.

Rules:
WinAPI is allowed, but your code will stand out better if you can get this some other way.
You can use any language, but it must be able to run on either Windows or Linux

\$\endgroup\$
2
  • \$\begingroup\$ Since your post doesn't mention the winning criterion being shortest code length, I'm removing the [code-golf] tag. Feel free to readd the tag if you want to add such a criterion. \$\endgroup\$ Commented May 5, 2011 at 0:55
  • \$\begingroup\$ @Chris ok ty. i mostly wanted to see what kind of creative answers people would come up with, so i probably shouldn't have added that tag in the first place :) \$\endgroup\$ Commented May 8, 2011 at 21:01

2 Answers 2

7
\$\begingroup\$

gdb, 108 chars

star
b open if !(int)strcmp(((char**)$esp)[1],"orange.txt")
comm
set((char**)$esp)[1]="green.txt"
c
end
c
q

Save as the file redirect and run like this:

gdb -x redirect <program you want to redirect>

Works on x86 (linux at least, and probably Windows/Mac also). Here's what the lines do:

star = start gets to the beginning of main (needed so open is defined for the next step).

b open if... = break if we're calling open on orange.txt

comm = command the code up to the next end is executed when the breakpoint fires.

set ((char*))... = replace the open argument with green.txt

c=continue

q=quit

\$\endgroup\$
1
  • \$\begingroup\$ It only works on x86-32. On x86-64 the first argument is stored in a register. \$\endgroup\$
    – Lowjacker
    Commented May 5, 2011 at 19:58
6
\$\begingroup\$

C - 146

This is based on an answer to the StackOverflow question "how could I intercept linux sys calls?".

#define r(s)int s(int p,int f,int m)
#define c(s)r(s){return((r((*)))dlsym(-1,#s))(strcmp(p,getenv("OLD"))?p:getenv("NEW"),f,m);}
c(open)c(open64)

This has been tested on Linux/x86, and is unlikely to be portable.

Usage:

$ echo orange > orange.txt
$ echo green > green.txt
$ gcc -fPIC -shared -ldl intercept-open.c -o intercept-open.so
$ cat orange.txt
orange
$ LD_PRELOAD="./intercept-open.so" OLD="orange.txt" NEW="green.txt" cat orange.txt
green

This works with some programs (e.g. cat, less, wc, vim) but not others (e.g. nano, gedit).

\$\endgroup\$

Not the answer you're looking for? Browse other questions tagged or ask your own question.