Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Cheating Linux: executables and dependent libraries via LD_PRELOAD

Tags:

c++

c

linux

bash

Sorry about the title, couldn't really think of anything else to describe the problem :)

Ok, so the thing is like this: I'm trying to use a proprietary freeware application under Linux (and hence the problem; if I had the source, I could have rebuilt it). Furthermore, I'm trying to run it on an unsupported flavor of Linux, and nearly all components of the application work individually, but not together (as they should if the application ran fully).

Let me clarify a bit. There is a GUI, that starts up fine in the unsupported OS. Then, from this GUI, you can call a bunch of command line tools - helpfully, the GUI also spits out the command line being called in each case.

Now, called from the GUI some of these commands fail - however, since I have the actual command line called (let's say: "extprogram -arg1 1 -arg2 2 ..."), I can repeat these from the terminal. And so, I discover that the application as a whole carries it's own libc libraries; and using these libraries, (some of) the commands (ran from the terminal) tend to fail - however, I discovered that from the command line, this usually works for those that fail:

LD_PRELOAD=/usr/lib/libstdc++.so.6 extprogram -arg1 1 -arg2 2 ...

# or alternatively, this works too:
# LD_LIBRARY_PATH=/usr/lib extprogram -arg1 1 -arg2 2 ...

(in other words, using the system libstdc++ instead of the application supplied one, tends to fix things)

 

So, now if I could persuade the GUI to call these tools with "LD_PRELOAD"/"LD_LIBRARY_PATH" - I guess, all would work fine...

Unfortunately, the GUI doesn't call a script that would further call these executables, which I could change directly (as far as I could see via grepping) - seemingly, it's the GUI executable that creates the system calls; I tried 'strace'-ing, but I cannot find something like a temporary script or anything that I could change...

 

So, I thought maybe I could "cheat" with making an executable bash script; so I move the executable - and create a script that should call the moved executable with LD_ prepended:

mv extprogram extprogram.old
cat > extprogram <<EOF
LD_LIBRARY_PATH=/usr/lib extprogram $@
EOF

... but this fails; apparently GUI application recognizes something is not right.

 

So, I was thinking - is it possible to somehow, maybe, have a C/C++ code "wrapper" that would somehow "load" this executable, but in an "environment" which has "LD_LIBRARY_PATH=/usr/lib" set - and pass it its arguments (and also return it's return value)? Then I could build this "wrapper" natively on the OS, with the same name as the original executable - and have the whole thing working, without touching the original executable (apart from renaming).

Many thanks in advance for any answers,
Cheers!

like image 598
sdaau Avatar asked Dec 27 '22 11:12

sdaau


2 Answers

You're close. You forgot the shebang and to make the script executable. Also you were calling the wrong external program. Finally, I'd use the absolute path to the old script, because you don't know what the CWD will be for the GUI.

mv extprogram extprogram.old
cat > extprogram <<EOF
#!/bin/sh
LD_LIBRARY_PATH=/usr/lib exec /psth/to/extprogram.old "$@"
EOF
chmod +x extprogram
like image 167
Chris Eberle Avatar answered Feb 27 '23 21:02

Chris Eberle


using the system libstdc++ instead of the application supplied one, tends to fix things

I'd be curious to know what problems using the application-supplied libstdc++.so.6 causes, but if the system one fixes things, then a much simpler solution is to remove (rename) the troublesome library, rather than doing the whole shell wrapper solution.

If the application can't find the "bad" library, there is a good chance it will find the system one.

like image 27
Employed Russian Avatar answered Feb 27 '23 21:02

Employed Russian