继我之前的问题之后,大多数评论都说“不要这样做,你处于一种不确定的状态,你必须杀死一切并重新开始”。还有一个“安全”的解决方法。
我不明白的是为什么分段错误本质上是不可恢复的。
写入受保护内存的时刻被捕获 - 否则,将SIGSEGV不会被发送。
如果可以捕获写入受保护内存的时刻,我不明白为什么 - 理论上 - 它不能在某个低级别上恢复,并且不能将 SIGSEGV 转换为标准软件异常。
请解释为什么在分段错误之后程序处于不确定状态,因为很明显,在内存实际更改之前抛出了错误(我可能是错的,不明白为什么)。如果它被抛出,人们可以创建一个程序来更改受保护的内存,一次一个字节,出现分段错误,并最终重新编程内核 - 这种安全风险并不存在,因为我们可以看到世界仍然存在。
SIGSEGV)?我正在尝试学习 x86_64 汇编,并使用 GCC 作为我的汇编程序。我正在使用的确切命令是:
gcc -nostdlib tapydn.S -D__ASSEMBLY__
Run Code Online (Sandbox Code Playgroud)
我主要使用 gcc 作为它的预处理器。这是tapydn.S:
.global _start
#include <asm-generic/unistd.h>
syscall=0x80
.text
_start:
movl $__NR_exit, %eax
movl $0x00, %ebx
int $syscall
Run Code Online (Sandbox Code Playgroud)
这会导致分段错误。我相信问题出在以下几行:
movl $__NR_exit, %eax
Run Code Online (Sandbox Code Playgroud)
我使用__NR_exit它是因为它比一些神奇的数字更具描述性。但是,我对它的使用似乎是不正确的。我相信情况确实如此,因为当我将有问题的行更改为以下内容时,它运行良好:
movl $0x01, %eax
Run Code Online (Sandbox Code Playgroud)
进一步支持这一思路的是以下内容usr/include/asm-generic/unistd.h:
#define __NR_exit 93
__SYSCALL(__NR_exit, sys_exit)
Run Code Online (Sandbox Code Playgroud)
我预计 __NR_exit 的值为 1,而不是 93!显然我误解了它的目的,因此误解了它的用法。据我所知,我很幸运能在$0x01案例中工作(很像 C++ 中的未定义行为),所以我一直在挖掘......
接下来,我寻找sys_exit. 我找不到。我尝试使用它如下(有和没有前面的 $):
movl $sys_exit, %eax
Run Code Online (Sandbox Code Playgroud)
这不会链接:
/tmp/cc7tEUtC.o: In function `_start':
(.text+0x1): undefined reference to `sys_exit'
collect2: error: ld returned 1 exit …Run Code Online (Sandbox Code Playgroud) 我想在C程序和要由nasm或yasm编译的程序集文件中包括很多魔术数字。
在纯C语言中,文件看起来像一系列定义,例如:
#define BLESS 55378008
#define ANSWER 42
...
Run Code Online (Sandbox Code Playgroud)
在nasm或yasm中,相同的include可以实现为:
%define BLESS 55378008
%define ANSWER 42
...
Run Code Online (Sandbox Code Playgroud)
唯一的不同是C和nasm 的define:前面的主角。#%
有什么办法可以编写一个polygot include,它可以让我将它同时包含在C和nasm中,并且只列出一次常量?
是的,我知道我可以使用sed或其他方法从另一个文件生成一个文件。
我很好奇如果我把db 0x41这个.text部分放在它通常所属的地方,而不是放在.data它通常所属的地方,会发生什么。它会出现段错误,但到底为什么呢?
下面的代码是在 Mint 19.1 中使用 和 进行编译、链接和执行nasm的ld。
无段错误:
global _start
section .data
db 0x41
section .text
_start:
mov rax, 60 ; Exit(0) syscall
xor rdi, rdi
syscall
Run Code Online (Sandbox Code Playgroud)
段错误:
global _start
section .text
_start:
db 0x41
mov rax, 60 ; Exit(0) syscall
xor rdi, rdi
syscall
Run Code Online (Sandbox Code Playgroud)
我使用以下命令来组装、链接和运行它:
global _start
section .data
db 0x41
section .text
_start:
mov rax, 60 ; Exit(0) syscall
xor rdi, rdi
syscall
Run Code Online (Sandbox Code Playgroud) 经过多年的 C++ 和 Python,我昨天决定学习汇编(NASM 语法),我已经对退出程序的方式感到困惑。它主要是关于 ret 因为它是 SASM IDE 上的建议指令。
我显然是在为主要说话。我不关心 x86 向后兼容性。只有 x64 Linux 的最佳方式。我很好奇。
对不起,我是汇编代码的新手.我编码这个线条
section .text
global _start
_start:
nop
main:
mov eax, 1
mov ebx, 2
xor eax, eax
ret
Run Code Online (Sandbox Code Playgroud)
我用这些命令编译:
nasm -f elf main.asm
ld -melf_i386 -o main main.o
Run Code Online (Sandbox Code Playgroud)
当我运行代码时,Linux抛出了分段错误错误(我正在使用Linux Mint Nadia 64位).为什么会产生这个错误?
提前致谢
首先,我不了解现代CPU和操作系统。为此,我将针对intel 8085处理器进行解释。当然,我希望你想象有一个操作系统可以在intel 8085上运行。
我们有这样的汇编代码:
MVI A,16
MVI B,16
ADD B
HLT
Run Code Online (Sandbox Code Playgroud)
这段代码非常简单。当此代码运行时,它会执行以下操作: 将数字 16 加载到 intel 8085 处理器的寄存器 a 和 b 中。然后将这两个寄存器的值相加。
当然,当我们尝试在操作系统中运行这段代码时,很可能什么也不会发生。
我想问的是:如何在操作系统上运行不包含任何系统调用(或任何特定于操作系统)的代码(绕过操作系统)?我不希望操作系统在执行此操作时崩溃。