Assembly 汇编程序中的低级网络(与x86兼容)

Assembly 汇编程序中的低级网络(与x86兼容),assembly,networking,raw-sockets,Assembly,Networking,Raw Sockets,我希望用汇编语言编写一个能够发送和接收网络数据包的可引导程序。我不想使用任何库,我想自己创建它(并且在这样做的同时学习)。不幸的是,我找不到与最低级别的网卡(发送原始套接字)通信有关的任何信息。我认为有必要使用OUT和IN指令,尽管我找不到有关分配给网卡的端口的任何信息(或者如何查找,如果不总是相同的话)。有人能给我指出正确的方向吗?;-) 不同的网卡有不同的硬件接口(这就是为什么它们有不同的设备驱动程序) 您可能会从设备制造商那里获得有关硬件的信息(也可能不会:他们可能会将此视为专有信息,并编

我希望用汇编语言编写一个能够发送和接收网络数据包的可引导程序。我不想使用任何库,我想自己创建它(并且在这样做的同时学习)。不幸的是,我找不到与最低级别的网卡(发送原始套接字)通信有关的任何信息。我认为有必要使用
OUT
IN
指令,尽管我找不到有关分配给网卡的端口的任何信息(或者如何查找,如果不总是相同的话)。有人能给我指出正确的方向吗?;-)

不同的网卡有不同的硬件接口(这就是为什么它们有不同的设备驱动程序)

您可能会从设备制造商那里获得有关硬件的信息(也可能不会:他们可能会将此视为专有信息,并编写自己的设备驱动程序)


您还可以通过查看开放源代码网卡的源代码来获得这些信息:例如,我猜,Linux;或者,这是一个需要解决的相当大的问题。即使是达到“原始套接字”的程度也将是一项相当艰巨的工作

首先,使用现代BIOS,您的网卡通常不会在默认情况下进行配置,因此您需要将其配置为具有处理器可见的一些端口。这将为您提供让CPU实际与网卡对话的基本功能

第二,您必须找到它使用的特定芯片组的一些文档,以便了解如何读取和写入网络数据。对于一些较旧的卡,这相当容易,但大多数较新的卡充当具有分散/聚集硬件的总线主控器。对它们进行编程,即使是一个简单的传输,也可能非常繁琐。但这完全取决于硬件

第三,您需要开发IP堆栈的大部分,以便能够使用原始套接字。在硬件级别上,您基本上有两种功能:接收碰巧到达的任何数据包,并将数据包发送到指定的MAC地址——或者其他硬件地址,如果您的卡不是(并且看起来/行为不像)以太网


在上面的下两层将是一个(允许您使用IP地址而不是MAC地址)和一个DNS客户端(因此,您可以使用普通地址名,而不是虚线四元组。除此之外,您可能还希望构建知道如何创建/理解的软件。

在x86-64 Linux中,您可以使用原始套接字进行系统调用

global _start

section .text:
_start:
    ;sys_socket: rax, 41
    mov rax,41 

    ;sys_socket inputs:
    ;%rdi    %rsi  %rdx
    ;family  type  protocol

    mov rdi,2  ;AF_INET 
    mov rsi,2  ;DGRAM Socket
    mov rdx,0  ;protocol
    syscall

    ;sys_sendto: rax, 44
    ; I will do this later because rax holds the file desc 

    ;sys_sendto inputs:
    ;%rdi       %rsi  %rdx    %r10   %r8   %r9
    ;file desc  buff  lenght  flags  addr  addr-lenght
    mov rdi,rax  ;file desc
    mov rax,44   ;sys_sendto
    mov rsi,msg  ;buff
    mov rdx,msgl ;length
    mov r8,addr  ;addr
    mov r9,16    ;remember htons()??? that's why 16
    syscall


section .data:
    msg: db "hello"
    msgl: equ $-msg
    ;addr
    addr: dw 2
      db 10h,00h  ;htons()
      db 7fh,0h,0h,01h
      db 0,0,0,0,0,0,0,0
从教程视频:

那么,你是说所有不需要为网卡安装驱动程序的操作系统都已经拥有所有现有网卡的所有驱动程序了吗?这些驱动程序有很多;例如,我在购买这台计算机时购买了预装Windows的20页英特尔驱动程序。计算机制造商(“OEM”),谁安装了O/S,知道他们在这台机器上放了什么样的网卡,因此能够安装正确的驱动程序。否则,如果你买了一张网卡作为售后附加组件,那么我想你会发现它的盒子里包含了各种O/S的特定于网卡的设备驱动程序。有一些“通用”API,或多或少是旧的(现在可能已经过时),任何给定的卡都可能支持,也可能不支持:例如,如果您正在编写自己的操作系统,请参阅。否则,请在现有操作系统上进行系统调用,如Linux上的原始套接字。这看起来完全像垃圾邮件,因为您甚至没有提及视频的标题或作者。但无论如何,即使此视频是某种指南或教程,也只能链接到WER与堆栈溢出无关。如果您写了一个描述您必须做什么和/或包含一些代码的答案,可以将其他内容链接为“查看更多”,但链接不能是您答案中的唯一内容。如果您只想发布相关链接,例如,使用注释。(这需要一些代表,显然是出于垃圾邮件过滤的原因。)我很快就会更新。我不知道,抱歉!!!在64位代码中使用
int 0x80
不是一个好主意,特别是对于带有指针参数的系统调用:@PeterCordes抱歉,但问题提到了
x86
是的,这段代码是针对x86的64位长模式的:您可以从
r
寄存器名和
r8
r9
。看起来您使用了视频中的代码,并将
syscall
替换为
int 0x80
,而不更改32位呼叫号码或移植到32位ABI的不同呼叫约定(EBX、ECX、EDX…按该顺序,而不是RDI、RSI、RDX…按该顺序)。简而言之,您应该将其更改回
syscall
,以便在64位x86系统上使用。您应该尝试使用
strace./a.out
组装并运行它,以查看它进行的系统调用。