万般含义在皮鞋/p>
本周末,写个小文,就当开胃小食吧,和TCP/IP无关,也没有皮鞋。
Linix系统中可执行文件是ELF格式,Windows系统可执行文件是PE格式,ELF和PE是完全不同的文件格式互不兼容,所以一个可执行文件不能在两个系统之间互相交换执行,然而两个程序均跑在Intel/AMD的处理器上,执行的都是一模一样的指令…
如果我在文件里就写一个0x90机器码,那么很遗憾,两个系统均无法执行!
这就是TMD门槛,将事情变成不再纯粹的门槛!
现在编程已经没有以前好玩了,现在的编程语言太丰富,现在的编程语言太繁琐,现在的编程环境太复杂,而这一切,都是旨在 最大程度的隐藏底层细节,让程序员将精力集中在关注业务逻辑上!
上面这段话讲得非常矛盾! 看你如何理解。
如果你把编程当成谋生之道,那么当然需要 集中精力于经理分配的任务,而不是纠结什么语言细节,底层原理。 反之,如果你只是觉得好玩,希望探究底层的秘密,那么 肯定不希望去处理什么业务逻辑,业务是需求驱动的,我只是玩玩而已! 然而现有的编程环境已经不适合去探究系统的秘密了。
你想让一段哪怕再简单的指令跑起来,额外的工作量已经超过了写这段指令本身,你要有编译器,要遵守该编程语言的语法规范,换句话说,你要花精力去搭建环境,以及调试程序本身。
现在的编程环境已经全部为业务程序员而优化了!和业务逻辑越来越关联的语言,库,中间件, 络协议…即便是一个写Apache,Nginx模块的 底层C/C++程序员 ,也至少要依赖操作系统,glibc这些,至少,你要 首先编译出一个Linux下可运行的ELF文件 吧。
举个例子,你能在Linux平台写一个非ELF的直接可执行的二进制文件吗最简单的,我们知道,0x90这个机器码代表 nop ,即 什么都不做 ,我能将0x90这个指令写入一个如下文件nop.exe:
然后,我执行nop.exe,然后 让CPU什么也不做 吗/p>
不能!!看看吧,一个程序员想 让CPU什么也不做 都不行!而且这个程序员写的还是超级牛逼的机器语言0x90指令!如此牛逼的底层技术,竟然跑不起来!
好吧!很惭愧!但是想让nop跑起来,系统程序员还是有办法的,写汇编呗。
然后 按照标准流程 编译之:
然后,看看编译好的nop.exe之细节:
一个简单的nop指令构成的可执行文件,竟然656字节!!
实际上起作用的只有1个字节,额外的655字节在我看来全是垃圾!有点极端,但是按照程序执行的视角来看,只要不涉及程序分发和交换,ELF这种标准化的约束就没有什么用!
我们看下纯粹的nop.exe应该是个什么样子:
看清楚了吗只有1个字节!!
遗憾的是,它跑不起来:
万事因知乎而起,知乎却往往解决不了问题:
C 如何编译出一个不需要操作系统的程序/strong> https://www.zhihu.com/question/49580321
在看到这个问题之前,正好纠结过另一个问题: 打造最小的ELF文件
关于这个话题,有篇文章非常好:
打造史上最小可执行 ELF 文件(45 字节,可打印字符串): https://www.kancloud.cn/kancloud/cbook/69003
我曾经是想试着破45字节记录的,然而考虑到 既然想要最小,为什么需要ELF头呢什么不直接只包含指令呢/strong>
马其顿的亚历山大曾经在面对 格尔迪奥斯绳结 时,选择了砍断绳子,绕过了问题,成为了亚洲的统治者。
以纯粹直接的nop指令为例,还是那个代码:
我们把它编译成:
如何能让这么直接的程序跑起来/p>
我不会选择使用裸机去跑,也不想使用单片机这种简易的玩意儿,因为这些设备上无法部署可用的分析调试工具,我选择在标准的Linux系统上去跑这个指令文件。
虽然我不怎么会编程,但是能用软件解决的问题就不用专用硬件设备,我不是说过吗,软件可以无限试错!
为了让这个指令文件像一个普通的二进制ELF可执行文件那样直接在命令行执行,我们其实要做的非常简单。
在 现代操作系统(拥有独立的进程虚拟地址空间)Linux 中,我们需要做的就是三件事:
- 开辟一个新的进程P;
- 将这个文件的内容载入到该新进程P的地址空间某个地址A;
- 将该进程P的IP寄存器指向地址A。
为了让上面的三件事变成事实,我们需要了解Linux的程序加载机制。我们需要先了解ELF文件是如何载入内存并跑起来的,然后删掉一些复杂的约束,就成了。
换句话说,我们只需要照着ELF的加载程序框架比葫芦画瓢整一个更简单的加载程序就好了。幸运的是,这种加载程序在Linux内核是模块化的,我们只需要注册一个新的加载程序结构体,然后实现一些回调函数即可。
我就直接给出代码吧:
就这么简单一个加载程序就完成了,将其编译成模块,载入内核:
OK!接下来可以写只包含指令的文件了。我们以刚刚制作好的 只有1个字节的nop.exe 为例,试试它直接执行的效果:
出错了!但是却是正确的!程序确实是执行了的,我们看看为什么出错:
声明:本站部分文章及图片源自用户投稿,如本站任何资料有侵权请您尽早请联系jinwei@zod.com.cn进行处理,非常感谢!