Cheating Linux: executables and dependent libraries via LD_PRELOAD - c++

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!

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

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.

Related

How to set scons to output full expanded command line?

I've come across a build system that uses scons. Not being familiar at all with scons itself being a rather sophisticated framework I get very frustrated not being able to debug build issues.
I want scons to printout the fully expanded command line being invoke ( as you see with most build systems) I found out you could use the --debug=presub option but ( at least on OSX ) it is useless since it prints the value of unexpanded variables
for example:
Building build/obj/ios-uni-rel-sta-clang/common/libs/boost/libs/date_time/src/gregorian/date_generators.i386.o with action:
$SHCXX -o $TARGET -c $SHCXXFLAGS $SHCCFLAGS $_CCCOMCOM $SOURCES
There is also a VERBOSE=1 parameter you can supply on the scons command line but ( at least with the 2.3.4 ) version I got, it doesn't seem to be verbose much anything.
I'm not saying Scons is bad, but it is become a bit taxing and expansive to maintain :(
Anyone familiar with Scons? What module, where is the actual command gets invoked? I just want to add a few prints ...
Alternatively, how can you setup PyDev or PyCharm to hook up using the scons --debug=pdb? Did anyone this?
Somewhere in a SConstruct, SConscript, or some python module loaded by either (could be in site_scons under top dir) someone is changing the *COMSTR env variables.
It will look something like:
env['SHCXXCOMSTR'] = "Building $TARGET"
or:
for k in env.keys():
if k.endswith('COMSTR'):
env[k] = "Building $TARGET"
You'll want to comment out those lines.
The default SCons behavior is to show the command lines.
http://scons.org/doc/production/HTML/scons-man.html#cv-SHCXXCOMSTR
SHOWBUILD=1
For example:
$>scons SHOWBUILD=1
This worked for me

Can't find program entry point in a C++ project

I have a C++ project in Ubuntu 12.04. To run the project the make file requires the following files:
1-All the .cpp files
2-All the .h files
3-Three shared libraries.
The project is fully functionall and performs according to the specifications. All the required .cpp files and .h files are available. The problem is that there is no main() function in any of the source files and the program entry point resides in one of the three shared libraries. My job is to find out the program execution pipeline and without having any main file I am not able to do that. I can't run the project in any IDE (i.e: eclipse) because there is no main function available.
Question: Can you please tell me how to find the program entry point?
P.S: I will be glad to provide any kind of information or material you may need to solve my problem.
Edit: The CMakeLists.txt file available here.
Edit 2: The build.sh file available here.
To find enty point look into each shared object with:
nm $library | egrep "T main$"
Library with main() will output something like
090d8ab0 T main
Very usefull way to visualize execution tree is to run:
valgrind --tool=callgrind ./my_executable -arg -arg ....
(you can abort execution early with Ctrl+C)
This will output callgrind.<pid> file. To visualize it run kcachegrind callgrind.<pid>.
You will need valgrind:
sudo apt-get install valgrind
and kcachegrind
sudo apt-get install kcachegrind
Build it with the debug option -g and step into the program with a debugger like gdb (or cgdb or ddd). You'll need any appropriate debug libraries libraries though.
Short of that, play with the code a bit. Try putting printf or cout statements that print internal variables in any functions that look important, and see what the program status is and how frequently they get called. If main is hidden in a library, there's probably another function somewhere that behaves like main for the purposes of the API provided by whatever library has the real main.
What's the API documentation for your libraries? (is this a school project?). It sounds odd to have a hidden main and not say anything about it.
In case you use a build system (CMake, SCons, ...) it is highly possible that the build system is also generating some files, and one of them might be containing the main() method. We use this methodology when we generate the main function in order to instantiate classes for libraries that were specifically selected in CMake-gui.
And again, it is possible that the build system deletes the generated files due to some obscure policy the original developers thought of but didn't tell you. So search through your build system files, see what is actually happening there.
Edit
So, after seeing you CMakeLists.txt:
check ${DIR_EXT}/covis/src/ci.cpp where DIR_EXT is SET( DIR_EXT "../ext/" CACHE PATH "Folder holding external libraries" )
See what's in there and let us know :)
Edit2
After seeing build.sh (execute steps in order):
1.
change
`cmake -D COMPILE_BINARY=ON ..`
to
`cmake -D COMPILE_BINARY=ON -DCMAKE_BUILD_TYPE=Debug ..`
and add the same -DCMAKE_BUILD_TYPE=Debug to the other cmake command too.
This will build your library and executable in debug mode.
2.
Now, in one of the c++ source files you have access to and you are sure will be called (the earlier the function will be calle the better), add:
asm("int $0x03");
This will create a breakpoint in your application.
(If you do not want to use this, see below).
3.
Build your application.
4.
Run it via a debugger in terminal:
gdb ./myapplication <ENTER>
(this will give you a gdb prompt)
(if you did not add the asm breakpoint from above, type in the gdb prompt: break filename.cpp:linenumber or break methodname to add a gdb breakpoint).
run <ENTER>
Now your application should stop in your function when it is executed.
You are still in the gdb prompt, so type:
bt <ENTER>
This will print out the backtrace of your application. Somewhere you should see a main function, together with filename and linenumber.
However, that setnames.sh looks interesting, see if it does not do anything funny :)

How do I compile multi-file C++ programs in all subdirectories?

I have a bunch of C++ programs each in its own sub-directory. Each sub-directory has a single C++ program in several files -- a .h and a .cpp file for each class plus a main .cpp program. I want to compile each program placing the executable in the corresponding sub-directory. (I also want to run each program and redirect its output to a file that is placed in the corresponding sub-directory but if I can get the compilation to work, I shouldn't have a problem figuring out this part.)
I'm using the bash shell on a UNIX system (actually the UNIX emulator Cygwin that runs on top of Windows).
I've managed to find on the web, a short scrip for compiling one-file programs in the current directory but that's as far as I've gotten. That script is as follows.
for f in *.cpp;
do g++ -Wall -O2 "$f" -o "{f/.cpp/}";
done;
I would really appreciate it someone could help me out. I need to do this task on average once every two weeks (more like 8 weeks in a row, then not for 8 weeks, etc.)
Unless you're masochistic, use makefiles instead of shell scripts.
Since (apparently) each executable depends on all the .h and .cpp files in the same directory, the makefiles will be easy to write -- each will have something like:
whatever.exe: x.obj y.obj z.obj
g++ -o whatever.exe x.obj y.obj z.obj
You can also add a target in each to run the resulting executable:
run:
whatever.exe
With that you'll use make run to run the executable.
Then you'll (probably) want a makefile in the root directory that recursively makes the target in each subdirectory, then runs each (as described above).
This has a couple of good points -- primarily that it's actually built for this kind of task, so it actually does it well. Another is that it takes note of the timestamps on the files, so it only rebuilds the executables that actually need it (i.e., where at least one of the files that executable depends on has been modified since the executable itself was built).
Assuming you have a directory all of whose immediate subdirectories are all c++ programs, then use some variation on this...
for D in */; do cd "$D";
# then either call make or call your g++
# with whatever arguments in here
# or nest that script you found online if it seems to
# be doing the trick for you.
cd ../;
done;
That will move in to each directory, do its thing (whatever you want that to be) and then move back out.

Using Eclipse CDT from command line

I need to have some of my C++ classes, functions and namespaces renamed as a part of my build script, which is runned by my CI system.
Unfortunatly a simple sad/awk/gsar/... technique is not enough, and I need smart rename refactoring, that carefully analyses my code.
Actually I found out, that CDT C/C++ rename refactoring does, what I need. But it does it from Eclipse IDE. So I need to find a way to start it from command line, and to make it a part of my CI build script.
I know that Eclipse has eclipsec executable, that allowes running some Eclipse functions from command line (see e.g. here).
But I can't find any suitable documentation for functions, CDT exports to command line. The only thing, I found is the this. But it doesn't solve my problem.
So, I need help to run CDT rename refactoring from command line (or someway like that). If it is not possible, may be someone will advice another tool, that can do rename refactoring for C++ from command line ?
Pragmatic Approach
"I need to have renamed as a part of my build script"
This sounds a bit like a design problem. However, I remember having been guilty of the same sin once writing a C++ application on AIX/Win32: most notably, I wanted to be able to link 'conflicting' versions of shared objects. I solved it using a simple preprocessor hack like this:
# makefile
#if($(ALTERNATIVE))
CPPFLAGS+=-DLIBNAMESPACE=MYLIB_ALTERNATIVE
#else
CPPFLAGS+=-DLIBNAMESPACE=MYLIB
#endif
./obj64/%.o: %cpp
xlC++ $(CPPFLAGS) $^ -o %#
Sample source/header file:
namespace MYLIB
{
class LibService :
{
};
}
As you can see, this required only a single
find -iname '*.[hc]pp' -o -iname '*.[hc]' -print0 |
xargs -0 sed -i 's/OldNamespace/MYLIB/g'
Eclipse Automation
You could have a look at eclim, which does most, if not all, of what you describe, however it targets the vim editor.
What eclim boasts, is full eclipse intergration (completion, refactoring, usage search etc.) from an external program. I'm not fully up to speed with the backend of eclim, but I do know that it works with a eclimd server process that exposes the service interface used by the vim plugin.
I suspect you should be able to reuse the code from eclimd if not just use eclim for your purposes.
We are completing a command-line rename tool for C++, that uses compiler accurate parsing and name resolution, including handling of shadowed names. Contact me (see bio) for further details or if you might be interested in a beta.

How to bundle C/C++ code with C-shell-script?

I have a C shell script that calls two
C programs - one after the another
with some file handling before,
in-between and afterwards.
Now, as such I have three different files - one C shell script and 2 .c files.
I need to give this script to other users. The problem is that I have to distribute three files - which the users must keep in the same folder and then execute the script.
Is there some better way to do this?
[I know I can make one C code file out of those two... but I will still be left with a shell script and a C code. Actually, the two C codes do entirely different things... so I want them to be separate]
Sounds like you're worried that your users aren't savy enough to figure out how to resolve issues like command not found errors and the like. If absolutely MUST hide "complexity" of a collection of files you could have your script create the other files. In most other circumstances I would suggest that this approach is only going to increase your support workload since semi-experienced users are less likely to know how to troubleshoot the process.
If you choose to rely on the presence of a compiler on the system that you are running on you can store the C code as a collection of cat $STRING >> file.c commands to to create your two C files, which you then compile and use.
If you would want to use pre-compiled programsn instead then the same basic process can be used except instead use xxd to both generate the strings in your script and reverse the conversion process to give you working binaries. Note: Remember to chmod the binary so that it is executable.
use shar command to create self-extracting archive.
or better yet use unzipsfx with AUTORUN option.
This provides users with ONE file, and only ONE command to execute (as opposed to one for untarring and one for execution).
NOTE: The unzip command to run should use "-n" option, that way only the first run would extract the files and the subsequent would skip the extraction.
Use a zip or tar file? And you do realize that .c files aren't executable, you need to compile & link them first?
You can include the c code inside the shell script as a here document:
#!/bin/bash
cat > code.c << EOF
line #1
line #2
...
EOF
# compile
# execute
If you want to get fancy, you can test for the existence of the executable and skip compiling them if they exists.
If you are doing much shell programming, the rest of the Advanced Bash-Scripting Guide is worth looking at as well.