是否可以修改正在运行的C程序?

时间:2017-12-13 09:44:13

标签: c linux binary system

我想知道在运行时是否可以修改一个C程序(或其他二进制文件)?

我写了这个小C程序:

#include <stdio.h>
#include <stdint.h>

static uint32_t gcui32_val_A = 0xAABBCCDD;

int main(int argc, char *argv[])  {

    uint32_t ui32_val_B = 0;
    uint32_t ui32_cpt = 0;

    printf("\n\n Program SHOW\n\n");

    while(1) {

        if(gcui32_val_A != ui32_val_B) {
            printf("Value[%d] of A : %x\n",ui32_cpt,gcui32_val_A);
            ui32_val_B = gcui32_val_A;
            ui32_cpt++;
        }
    }

    return 0;
}

使用十六进制编辑器,我能够找到&#34; 0xAABBCCDD&#34;并在程序停止时修改它。当我重新编写程序时,修改工作。很酷!

我想在程序运行时这样做吗?

这是一个简单的例子,可以理解这些现象并与之发挥作用,但我真正的项目更大。

  • 我有一个名为Dangerous Dave的旧DOS游戏。
  • 我只需编辑二进制文件即可修改切片(感谢http://www.shikadi.net/moddingwiki/Dangerous_Dave
  • 我开发了一个小编辑器,可以很好地完成这项工作并且玩得很开心。
  • 我使用DOSBOX启动DOS游戏,它有效!

我想在游戏运行时动态执行此操作。有可能吗?

PS:我在Debian 64bit下工作

问候

2 个答案:

答案 0 :(得分:2)

  

我想知道在它运行时是否可以修改一个C程序(或其他二进制文件)?

不在标准(和便携式)C11中。阅读n1570规范进行检查。请注意,大部分时间在实践中,不是正在运行的C source程序(由多个translation units组成),而是某些executable&amp; compiler的结果; linker

但是,在Linux上(例如Debian / Sid / x86-64),您可以使用以下一些技巧(通常使用函数指针):

我建议稍微使用/proc/(请参阅proc(5)),并尝试至少在某些终端中运行以下命令

 cat /proc/self/maps
 cat /proc/$$/maps
 ls /proc/$$/fd/

(并阅读足够的内容以了解他们的输出)以了解process“是什么”。

所以覆盖你的text segment(如果你真的需要这样做)是可能的,但也许比你相信的更棘手!

(你介意工作几周或几个月只是为了改善一些旧的游戏体验吗?)

另请阅读homoiconic编程语言(使用SBCL尝试使用Common Lisp),约dynamic software updating,约persistence,约application checkpointing和约{{ 3}}(我建议:operating systems&amp; Operating Systems: Three Easy Pieces wiki)

  

我在Debian 64bit下工作

我认为你有编程技巧并且知道C.然后你应该阅读OsDev或一些较新的Linux编程书(当然还要查看ALP&amp; intro(2)&amp; { {3}}和其他手册等...)

BTW,在您的特定情况下,也许“OS”是DOSBOX(充当某些虚拟机)。您可以在DOSBOX(或其他命令或进程)上使用syscalls(2),或研究其源代码。

你在提问时提到游戏。如果您想对某些代码进行编码,请考虑intro(3)strace(1)SDLSFML,......等库。

答案 1 :(得分:1)

是的,您可以在C中运行时修改一段代码。您必须有指向程序存储区的指针,以及要更改的已编译代码段。当然,这被认为是一种危险的做法,有很多限制,并且有很多错误的可能性。然而,这是在古老时代的记忆是珍贵的。