【发布时间】:2013-12-31 01:08:48
【问题描述】:
为什么将字符插入可执行二进制文件会导致它“中断”?
还有,有什么方法可以在不破坏编译程序的情况下添加字符?
背景
我早就知道可以使用十六进制编辑器更改已编译的可执行文件中的代码,并且仍然可以正常运行...
示例
以下面应用程序为例,Facebook 可以更改为Lacebook,程序仍然可以正常执行:
但它会因新角色而中断
我也知道,如果添加新字符,它会破坏程序并且它不会运行,或者它会立即崩溃。例如,在Facebook 前面添加My 可以实现:
我知道的
- 我已经和
C做了一些工作并且理解code is written in human readable, compiled, and linked into an executable file. - 我已经完成了汇编语言的入门研究,并了解了有关数据、命令和指针移动的概念
- 我为 Windows、Mac 和 Linux 编写了小程序
我不知道的事
- 我不太明白操作系统和可执行文件的关系。我猜当您输入程序名称并按回车键时,您基本上是在指示操作系统“执行”该文件,这基本上意味着将文件加载到内存中,将处理器的指针设置为它,并告诉它“走吧!”
- 我明白为什么二进制文件的文本字符串中有多余的字符会导致问题
我想知道的
- 为什么多余的字符会导致程序中断?
- 是什么决定了程序坏了?操作系统?操作系统是否也将此程序保持为沙盒状态,以免现在整个系统崩溃?
- 有什么方法可以通过十六进制编辑器在编译程序的文本字符串中添加额外的字符,而不会使应用程序中断?
【问题讨论】:
-
程序计数器通常是绝对的,所以如果你移动东西,一切都会中断。
-
非常好的问题,但它需要一个很大的答案。如果还在的话,我会在稍后尝试完整地回答。现在,把函数想象成在内存中。每次调用函数时,您都在告诉代码 跳转 到特定位置。如果您之前添加了额外的字节,您会将函数的代码 shift X 个字节,因此指令将不再有效,并且函数调用肯定不会按照您的想法执行。所有函数调用都是硬编码的指针。
-
在 Q3:否。假设您在字符串“Facebook”之前插入“hello”。然后 every 之后的字符串向上移动 5 个位置。您需要在更改后找到指向字符串的每个字符串 pointer 并将其递增。 (而且“数据”不仅是易于识别的文本字符串!)如果运气不好,您可能还必须在不同的点增加“数据部分”的大小。
-
如果您查看 F (46) 和 L (4C) 的位模式,您会注意到它们具有相同的位数,因此看起来某处有一个校验和适用于位.如果您尝试使用 34($)、43 (C) 或 64 (d),它也可能会起作用。其他任何事情都会破坏校验和
标签: c linux compiler-construction linker hex-editors