C++ 欺骗Linux:通过LD_预加载的可执行文件和依赖库

C++ 欺骗Linux:通过LD_预加载的可执行文件和依赖库,c++,c,linux,bash,C++,C,Linux,Bash,关于标题,很抱歉,我真的想不出其他任何东西来描述这个问题:) 好的,事情是这样的:我试图在Linux下使用一个专有的免费软件应用程序(因此出现了问题;如果我有源代码,我可以重建它)。此外,我正在尝试在不受支持的Linux版本上运行它,并且几乎应用程序的所有组件都是单独工作的,而不是一起工作的(如果应用程序完全运行,它们应该一起工作) 让我澄清一下。有一个GUI,可以在不受支持的操作系统中正常启动。然后,从这个GUI中,您可以调用一组命令行工具——很有帮助,GUI还可以输出在每种情况下调用的命令行

关于标题,很抱歉,我真的想不出其他任何东西来描述这个问题:)

好的,事情是这样的:我试图在Linux下使用一个专有的免费软件应用程序(因此出现了问题;如果我有源代码,我可以重建它)。此外,我正在尝试在不受支持的Linux版本上运行它,并且几乎应用程序的所有组件都是单独工作的,而不是一起工作的(如果应用程序完全运行,它们应该一起工作)

让我澄清一下。有一个GUI,可以在不受支持的操作系统中正常启动。然后,从这个GUI中,您可以调用一组命令行工具——很有帮助,GUI还可以输出在每种情况下调用的命令行

现在,从GUI调用其中一些命令失败-但是,因为我调用了实际的命令行(比如:“
extprogram-arg1-arg2…
”),所以我可以从终端重复这些命令。因此,我发现整个应用程序都有自己的libc库;使用这些库,(一些)命令(从终端运行)往往会失败-然而,我发现从命令行,这通常适用于那些失败的命令:

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 ...
(换句话说,使用系统libstdc++而不是应用程序提供的系统,可以解决问题)

因此,现在如果我能说服GUI使用“
LD\u PRELOAD
”/“
LD\u LIBRARY\u PATH
”-我想,所有这些工具都可以正常工作

不幸的是,GUI没有调用一个脚本来进一步调用这些可执行文件,我可以直接更改这些脚本(就我通过
grep
ping所见)-似乎是GUI可执行文件创建了系统调用;我尝试过“
strace
”-ing,但找不到类似临时脚本或任何可以更改的内容

所以,我想也许我可以通过制作一个可执行的bash脚本来“欺骗”;因此,我移动了可执行文件,并创建了一个脚本,该脚本应调用移动的可执行文件,并在前面加上
LD

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

cat>extprogram你很接近了。您忘记了shebang并使脚本可执行。同时,您调用了错误的外部程序。最后,我将使用旧脚本的绝对路径,因为您不知道GUI的CWD是什么

mv extprogram extprogram.old
cat > extprogram <<EOF
#!/bin/sh
LD_LIBRARY_PATH=/usr/lib exec /psth/to/extprogram.old "$@"
EOF
chmod +x extprogram
mv extprogram extprogram.old
cat>extprogram
使用libstdc++系统而不是应用程序提供的系统,可以解决问题

我很想知道使用libstdc++.so.6提供的应用程序会导致什么问题,但是如果system one解决了问题,那么一个更简单的解决方案是删除(重命名)麻烦的库,而不是执行整个shell包装解决方案


如果应用程序找不到“坏”库,它很有可能找到系统库。

这个GUI应用程序是从某种包装器脚本运行的,它首先会改变LD_library_路径吗?谢谢你的评论,@bdonlan-我想是的(实际上有几个GUI,有些GUI不是通过包装器脚本启动的——这一个导致了问题)。我也尝试过在包装器脚本中更改内容(我应该提到这一点)没有太大影响。干杯!如果该脚本被调用两次,它不会覆盖
extprogram.old
,因此
extprogram
extprogram.old
都是由该脚本生成的修改版本吗?Woooot!!它很有效!!!:)非常感谢@Chris(注意:该死的shebangs和所有:)!请注意,最终对我有效的实际脚本是:“
!/bin/sh;MYDIR=$(readlink-f“$(dirname“$0”)”;LD\u LIBRARY\u PATH=/usr/lib:$LD\u LIBRARY\u PATH$MYDIR/ext\u program$@;
”。。。再次感谢-干杯!我已将此代码修复为使用
“$@”
而不是
$@
。(如果任何参数包含空格,后者将断开。)我还添加了一个“exec”,这样shell进程将被实际的可执行文件替换,这将保留退出状态以及其他一些好东西。为此,@Employed Russian-它导致了类似的问题:
version'GLIBCXX_3.4.11'未找到(由…
(然后是第三个。所以)-我想我甚至尝试过重命名应用程序库-但是其他以前有效的工具在那一点上开始失败:)然而,到目前为止还不错-shell包装器似乎对我有效…干杯!