C应用程序如何在运行时在Linux环境中自行更新

时间:2015-06-11 07:28:02

标签: c linux

首先,我想问一个应用程序是否有可能在运行时在相同的地址空间上更新自己? 如果是,那么实现逻辑的最佳方式是什么? 用例:我的应用程序在连接到网络的主板上运行。在运行时,如果它检测到相同应用程序的新版本,那么如何在存储前一个存储器的相同存储器地址上更新应用程序。 根据我的理解,我们首先应该更新备份,在启动加载时,应该使用备份更新主应用程序,然后正常启动应用程序。我是对的吗?

2 个答案:

答案 0 :(得分:1)

通常,您可以在运行时替换包含可执行文件的文件而不会出现问题。

更新文件后,您可以像往常一样启动应用程序,并关闭正在运行的实例。

如果你想在运行时这样做(即没有分叉或开始新的过程),我认为没有非常奇怪的黑客是不可能的:

  • 如果你打算用新的可执行代码“重新”程序存储器,你需要计算每个线程的堆栈,内存和指令指针。你需要成为一个反汇编程序。
  • 如果你计划在将程序加载到辅助内存段后调用程序中的存根,那很好,但你需要确定目标函数的位置,以及如果它在你的下一次更新中消失了会发生什么。此外,它完全针对特定平台。
  • 如果您计划通过使用动态加载和卸载的共享库来标准化上述方法,我认为没有问题 - 它与重新启动整个过程的方法非常相似。

如果我有充分的理由,我会选择更换可执行文件,或第三个选项。最后一个选项很好,因为它允许您单独更新应用程序的组件(但同时这可能会导致您以后的维护问题。)

答案 1 :(得分:0)

您需要的是类似于引导程序的东西。在这种情况下:您将在设备上有两个程序,以下称为加载程序和应用程序。

在初始安装系统时:将应用程序编写到内存的开头,将编译器写入更远的位置,以便在将来应用程序的大小增加时留出空间。 (记下Loader的起始内存地址)

应用程序将正常运行,就像它是唯一的程序一样,定期检查自身的更新。如果它在网络上找到更新,请使用GOTO转到Loader的第一个内存位置,然后该位置将开始运行,并可以使用网络上找到的新应用程序覆盖原始应用程序。在你的Loader结束时,GOTO回到(新)应用程序。

有关如何GOTO到特定内存地址的建议,请参阅此Stack Overflow问题。 Goto a specific Address in C