X86机器上的汇编语言,Windows与Linux对比

7

它们是相同的吗?

更长的版本:

假设我在Windows机器上用汇编语言写了一个小程序,它只是将1+1相加并将其存储在一个寄存器中。然后,我在Linux机器上编写完全相同的代码。它会工作吗?

我的想法是会,因为在硬件级别上,它是相同的机器,因此“硬件语言”(请原谅不精确)也将是相同的。

所以,我认为一个针对Windows的病毒,但用汇编语言编写的,不仅仅是一个Windows病毒。


3
有人在阅读尼尔·斯蒂芬森的作品! - chimeracoder
3
不,尼尔·斯蒂芬森可能会建议一种可以让你发烧的电脑病毒。 - tylerl
1
我从未听说过尼尔·斯蒂芬森,但下次去图书馆时会查一下。 - jason
后续问题:学习其中一个是否也会学到另一个(至少是高水平)?还是我们就像苹果和橙子一样不同?从迄今为止的答案来看,编译的行为产生了很大的差异。 - jason
@jason:是的,如果你学会了为Windows编写汇编代码,那么你就掌握了为任何平台编写汇编代码的很多技巧。但是,如果你打算编写一个更复杂的程序,你可能需要使用平台的API,而这些API可能会非常不同。 - Andreas Rejbrand
10个回答

11

病毒一定需要与操作系统交互,并使用其API,因此高度依赖平台。

此外,可执行文件也有一个头部,这取决于目标操作系统。如果在Windows中创建一个空的EXE文件,则该文件在Linux下无法运行(甚至无法启动)。


4
有人编写了概念证明蠕虫和病毒,可以跨平台运行,方法是利用一个被广泛应用的高级环境,或者通过平台检测并运行多平台负载的适当部分。《2600》杂志在10年前发表过一篇相关文章,此后我也看到过一份白皮书。 - dmckee --- ex-moderator kitten
2
1988年的莫里斯蠕虫最初是一款多平台的程序,可以在Vax BSD和Sun系统上运行。 - David Thornley

9
是的和不是。
将1+1相加并将其存储在寄存器中的小片段将是完全相同的机器代码--也就是说,无论操作系统如何,在处理器上运行的代码都是相同的。
然而,您需要用其他与操作系统交互的位来包围该代码,以使您的程序有意义--例如,如果它没有输出到某个地方,您永远不会知道您的代码实际上正确地将2存储在eax中。
有趣的是,像Wine这样的项目通过在Linux下提供与程序期望在Windows下找到的相同API调用以及提供适当的逻辑来允许Linux正确解码Windows可执行文件,从而实现跨平台互操作性。因此,有了Wine支持,一些Windows病毒实际上可以在Windows下运行。这可能需要一些工作,但您可以做到。
不,Wine不必重新编译Windows程序--事实上,它直接在处理器上运行存储在EXE中的机器代码。

多年前,我在Linux系统上使用Wine玩《魔兽世界》。它几乎完美地运行,但是角色的腿部动画出现了一些问题。 - Kalamane
@Kalamane,这可能是因为WoW调用了一些奇怪的Direct3D API来进行腿部渲染,而在OpenGL中没有任何等效项(Vulkan最初发布于2015年)。 - user97662

5
在Windows上编写的汇编程序与Linux不具有二进制兼容性... 您需要在Linux上重新编译(组装)它们,但请注意汇编器之间存在差异.. 例如,它们以不同方式处理声明代码、数据、BSS等部分。
在Linux上无法本地运行Windows可执行文件(您可以在Wine中运行它们,但它们将被沙盒化)。

3
语言本身基本相同,但操作指令不同。在http://asm.sourceforge.net/intro/hello.html网站上的教程对此有很好的解释。
section    .text
    global _start           ;必须为链接器(ld)声明
_start: ;告诉链接器入口点
mov edx,len ;消息长度 mov ecx,msg ;要写的消息 mov ebx,1 ;文件描述符(标准输出) mov eax,4 ;系统调用号(sys_write) int 0x80 ;调用内核
mov eax,1 ;系统调用号(sys_exit) int 0x80 ;调用内核
section .data
msg db 'Hello, world!',0xa ;我们亲爱的字符串 len equ $ - msg ;我们亲爱的字符串的长度
这与DOS的hello world程序不同,因为它涉及到特定于操作系统的内容(如int 0x80)。

“the operator instructions are different” 是什么意思? - stakx - no longer contributing
@stakx - 我认为他的意思是“操作系统指令”。 - Marcel Korpel

1

虽然您可能正在编写x86汇编语言,但根据您使用的操作系统,您仍将使用不同的汇编器,并且它们将具有不同的功能,因此在Windows上使用汇编语言编写的内容不一定与在Linux上编写的相同,尽管我认为它们应该是相当相似的。


汇编器的特性并不重要,因为从汇编语言到机器码的转换应该是相同的。而其他一些东西,比如文件格式和系统调用,才是会有所不同的。 - David Thornley

1
汇编语言在很大程度上是相同和相似的。然而,无论是Windows还是Linux都不会尝试执行任意文件。大多数现代操作系统拒绝执行程序,除非它们具有适当的可执行头(例如PE或ELF)。
在Windows中,文件需要具有正确的扩展名(例如.exe,.dll,.com),并且文件需要符合便携式可执行文件(PE)格式的布局,Windows才会尝试执行该文件。
在Linux中,文件需要符合ELF格式(可执行和可链接格式),并且具有执行权限位(可以使用chmod设置/取消设置)。
实际上,这意味着Windows不识别ELF格式将拒绝执行Linux程序;而Linux将拒绝执行PE / Windows程序,除非你有Wine。用汇编语言编写的病毒需要重新组装(通过汇编器运行)成正确的可执行格式(PE或ELF)以适应操作系统。

接下来,你将面临Windows和Linux之间(甚至是不同版本的Windows和Linux之间)不同的函数调用约定问题;还有不同的系统调用API集和不同的方法来执行最基本的系统调用。实际上,编写一个在Windows和Linux之间可移植的汇编代码几乎是不可能的,因为即使像打印输入/输出这样的基本操作也是不同的。


1

x86指令将执行相同的操作。

但是,内存中的位置以及代码可以访问的内容将有所不同。 操作系统服务也会因为调用方式的不同而有所不同。

因此,如果您可以在两者上获得相同的二进制代码,则可以编写代码来将1-100的所有数字相加,这将起作用,但打印输出的机制将大不相同。


0

以下是来自《Linux Intel汇编语言入门》的引用:

  • 在其他操作系统下情况类似。例如,使用Microsoft或Turbo编译器,汇编语言源文件的后缀名为.asm,目标文件的后缀名为.obj等。

  • NASM可用于Unix和MS Windows。事实上,甚至可以在Windows下使用as,因为它是gcc软件包的一部分,并且在cygwin下以该名称提供。


0

针对所有操作系统,汇编可以是相同的,只要有针对您支持的每个操作系统的可移植性层和实现即可。

但是,如果您计划创建类似于我一样的超级兼容二进制文件... ELF 和 PE 格式完全不同,这将防止相同的可执行文件在不同的操作系统上运行。但是,这可以通过编写便携式程序加载器来解决。


0

它是相同的处理器,因此执行加1+1的指令也是相同的。

而且很可能你可以使用相似的工具,至少对于那个指令来说,有相同的汇编源码。但可执行文件格式不同于操作系统之间包含的字节执行以及其他内容差异较大。不同的工具用于创建不同的可执行文件/容器。如果您尝试执行完整的程序,就会产生这种情况。如果您有病毒或其他恶意程序,利用操作系统中某些malloc的方式,在其中存在一种方法可以使操作系统执行代码,那么该代码字节将不包含此可执行包装器,这些字节只是要运行的指令。因此从这个意义上讲,它们将再次成为相同的字节,但用于进入操作系统(或驱动程序)的漏洞很可能依赖于操作系统,您的漏洞将依赖于操作系统。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接