我是装配新手。我试图通过引用一本名为“编写安全工具和漏洞利用”的书来学习。任何熟悉本书的人都知道汇编代码是为32位编写的,但我是在64位系统上构建的。
由于这个原因,我已经重写了在64位上运行的代码。成功编译代码后,当我尝试运行程序时,无法完成所需的输出。相反,我没有收到输出。
我在AMD64 Debian Linux系统上构建它。以下是我尝试从以下位置接收输出的代码:
global _start
_start:
xor rax,rax
jmp short string
code:
pop rsi
push byte 15
push rsi
push byte 1
mov al,4
push rax
int 0x80
xor rax,rax
push rax
push rax
mov al,1
int 0x80
string:
call code
db 'Hello, world !',0x0a
我使用以下命令编译它
$> nasm -f elf64 hello.asm $> ld -s -o hello hello.o
当我尝试运行时,没有输出。
关于我哪里出错的任何建议?
答案 0 :(得分:1)
您的代码中主要存在一个大问题,您似乎相信通过int 0x80
进行系统调用的调用约定(传递参数)是通过将其推送到堆栈来传递的。但实际上,您需要浏览寄存器eax
,ebx
和ecx
(有关详情,请参阅here)。
因此,编写代码的正确方法是:
global _start
_start:
xor rax,rax
jmp short string
code:
pop rsi
mov rdx, 15
mov rcx, rsi
mov rbx, 1
mov al,4
int 0x80
xor rax,rax
mov rbx, rax
mov al,1
int 0x80
string:
call code
db 'Hello, world !',0x0a
然后,就这样做:
$> nasm -f elf64 hello.asm
$> gcc -nostdlib -o hello hello.o