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

标签 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;
}

使用十六进制编辑器,我能够找到“0xAABBCCDD”并在程序停止时修改它。当我重新启动程序时,修改工作。酷!

我想在程序运行时执行此操作是否可能?

这是一个简单的例子来理解这个现象并尝试一下,但我真正的项目更大。

  • 我有一个旧的 DOS 游戏,叫做 Dangerous Dave。
  • 我可以通过简单地编辑二进制文件来修改图 block (感谢 http://www.shikadi.net/moddingwiki/Dangerous_Dave)
  • 我开发了一个小型编辑器,可以很好地完成这项工作,并且玩得很开心。
  • 我使用 DOSBOX 启动 DOS 游戏,它运行正常!

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

PS : 我在 Debian 64bit 下工作

问候

最佳答案

I was wondering if it is possible to modify a piece of C program (or other binary) while it is running ?

不在标准(和可移植)中 C11 .阅读 n1570规范检查。请注意,在实践中,大多数时候,它不是 C source。正在运行的程序(由多个 translation units 组成),但是一个 executable一些结果 compiler & linker .


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

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

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

(并阅读足够多的东西以了解它们的输出)以更多地了解 process 是什么"is"。

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

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


另请阅读 homoiconic编程语言(尝试使用 SBCL 的 Common Lisp),关于 dynamic software updating , 关于 persistence , 关于 application checkpointing ,以及关于 operating systems (我推荐:Operating Systems: Three Easy Pieces & OsDev wiki)


I work under Debian 64bit

我想你有编程技能并且知道 C。那么你应该阅读 ALP或一些较新的 Linux 编程书籍(当然还要查看 intro(2) & syscalls(2) & intro(3) 和其他手册页等...)

顺便说一句,在您的特定情况下,“操作系统”可能是 DOSBOX(充当某种虚拟机)。您可以使用 strace(1)在 DOSBOX(或其他命令或进程)上,或研究其源代码。


您在问题中提到了游戏。如果您想编写一些代码,请考虑像 SDL 这样的库, SFML , Qt , GTK+ , ....

关于c - 是否可以修改正在运行的 C 程序?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47789854/

相关文章:

c - 你将如何有效地实现tail?

linux - 将 SAS Enterprise Guide 提取到 Unix 服务器可运行批处理中?

c++ - 怎么知道哪段内存全为零

C# Winform 二进制图标

python - 字符串文字前面的 'b' 字符有什么作用?

c - 编写一个 C 程序,读取 5 个数字并计算正数的个数并打印所有正数的平均值

c - 有限差分法中的性能问题

c - 它在不是 16 位的机器上有效吗

binary - 位移位、按位运算符中的 Endian 依赖关系

c - 如何在C中使用简单的文件输入和输出