【问题标题】:Cheating Linux: executables and dependent libraries via LD_PRELOAD欺骗 Linux:通过 LD_PRELOAD 的可执行文件和依赖库
【发布时间】:2011-12-20 18:33:43
【问题描述】:

抱歉标题,实在想不出其他什么来描述这个问题:)

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

让我澄清一下。有一个 GUI,可以在不受支持的操作系统中正常启动。然后,从这个 GUI 中,您可以调用一堆命令行工具 - 有用的是,GUI 还会在每种情况下吐出被调用的命令行。

现在,从 GUI 调用其中一些命令失败 - 但是,由于我调用了实际的命令行(比如说:“extprogram -arg1 1 -arg2 2 ...”),我可以从终端重复这些命令。因此,我发现整个应用程序都带有它自己的 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_PRELOAD”/“LD_LIBRARY_PATH”来调用这些工具 - 我想,一切都会好起来的......

不幸的是,GUI 没有调用会进一步调用这些可执行文件的脚本,我可以直接更改(据我通过grepping 看到的)- 看起来,创建系统调用的是 GUI 可执行文件;我试过'strace'-ing,但我找不到临时脚本或任何我可以更改的东西......

 

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

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

...但这失败了;显然 GUI 应用程序识别出一些不正确的东西。

 

所以,我在想 - 是否有可能以某种方式,也许,有一个 C/C++ 代码“包装器”,它会以某种方式“加载”这个可执行文件,但在一个“环境”中设置了“LD_LIBRARY_PATH=/usr/lib” -并将其参数传递给它(并返回它的返回值)?然后我可以在操作系统上本地构建这个“包装器”,与原始可执行文件具有相同的名称 - 并且让整个工作正常,而无需触及原始可执行文件(除了重命名)。

非常感谢您的任何回答,
干杯!

【问题讨论】:

  • 这个 GUI 应用程序是否从某种首先更改 LD_LIBRARY_PATH 的包装脚本运行?
  • 感谢@bdonlan 的评论-我想是的(实际上有几个GUI,有些不是通过包装脚本开始的-导致问题的这个)。我也尝试更改包装脚本中的内容(我应该提到这一点),但没有太大效果。干杯!
  • 如果那个脚本被调用了两次,会不会覆盖extprogram.old,这样extprogramextprogram.old都是脚本产生的修改版本?

标签: c++ c linux bash


【解决方案1】:

你已经接近了。您忘记了 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

【讨论】:

  • 呜呜呜!!有用!!! :) 非常非常感谢@Chris(自我说明:该死的 shebangs 和所有 :))!请注意,最终对我有用的实际脚本是:“#!/bin/sh ; MYDIR=$(readlink -f "$(dirname "$0")") ; LD_LIBRARY_PATH=/usr/lib:$LD_LIBRARY_PATH $MYDIR/ext_program $@ ;”......再次非常感谢 - 干杯!
  • 我已修复此代码以使用 "$@" 而不是 $@。 (如果任何参数包含空格,后者将中断。)我还添加了一个“exec”,以便 shell 进程将被实际的可执行文件替换,从而保留退出状态以及其他不错的东西。
【解决方案2】:

使用系统 libstdc++ 而不是提供的应用程序,往往会解决问题

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

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

【讨论】:

  • 谢谢你,@Employed 俄语 - 它引起了类似的问题:version 'GLIBCXX_3.4.11' not found (required by ...(然后是第三个 .so) - 我想我什至尝试重命名应用程序库 - 但后来是其他工具,以前工作的,那时会开始失败:​​) 但是,到目前为止一切都很好 - shell 包装器似乎对我有用......干杯!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-11-07
  • 1970-01-01
  • 2014-12-16
  • 2020-06-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多