Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/assembly/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Assembly 在堆栈(组件)中打印某物_Assembly_Memory_Nasm_X86 64_System Calls - Fatal编程技术网

Assembly 在堆栈(组件)中打印某物

Assembly 在堆栈(组件)中打印某物,assembly,memory,nasm,x86-64,system-calls,Assembly,Memory,Nasm,X86 64,System Calls,在linux中,您可以使用系统调用号4打印某些内容: mov eax,4 ;system call number mov ebx,0 ;file descriptor mov ecx,msg ;adress of message in data segment mov edx,length ;length of message 但是,如何从堆栈段打印内容 我试过这个: push 'H' push 'e' push 'l' push 'l' push 'o' p

在linux中,您可以使用系统调用号4打印某些内容:

mov eax,4       ;system call number
mov ebx,0       ;file descriptor
mov ecx,msg     ;adress of message in data segment
mov edx,length  ;length of message
但是,如何从堆栈段打印内容

我试过这个:

push 'H'
push 'e'
push 'l'
push 'l'
push 'o'
push ' '
push 'w'
push 'o'
push 'r'
push 'l'
push 'd'
mov eax,4       ;system call number
mov ebx,0       ;file descriptor
mov ecx,ebp     ;adress of message
mov edx,11      ;length of message
但是没有打印任何东西

编辑:我对代码做了一些更改,现在是这样:

section .data
msg: db "Hola mundo",0Ah
ok: db "OK",0Ah

section .text
global _start
_start:
push 'leH'
push 'w ol'
push 'dlro'
mov eax,4       ;system call number
mov ebx,1       ;file descriptor
mov ecx,esp     ;adress of message in data segment
mov edx,11      ;length of message
mov eax,1
xor ebx,ebx     ;same as move ebx,0 but better
int 0x80
编辑2(仍不工作)

回应该评论,我用以下内容汇编和编译:

nasm -f elf64 hello.asm && ld hello.o && ./a.out

我在Ubuntu 64位Linux上工作。

这个问题最初缺少一条关键信息。您可以组装并链接到:

nasm -f elf64 hello.asm && ld hello.o && ./a.out
这将生成一个64位可执行文件
int 0x80
不应在64位可执行文件中使用。在64位程序中,堆栈指针不能仅在32位ESP寄存器中表示。使用64位指针的唯一方法是使用
syscall
指令。提供了有关通过
syscall
指令使用64位系统调用接口的详细信息

如果修改代码以符合该接口,则可能会出现以下情况:

section .text
global _start
_start:
    mov dword [rsp-4], `rld\n`
                    ; Use back ticks instead of single quotes
                    ; To parse the string like C. We can write safely
                    ; in the 128 bytes below RSP because of the
                    ; Linux red zone.
    mov dword [rsp-8], 'o Wo'
    mov dword [rsp-12],'Hell'
    mov eax,1       ;Write system call number
    mov edi,eax     ;file descriptor (1 = stdout)
    lea rsi,[rsp-12];address of message on the stack
    mov edx,12      ;length of message
    syscall
    mov eax,60      ;Exit system call
    xor edi,edi     ;RDI=0
    syscall
此代码将常量写入32位寄存器,因为它们零扩展到整个64位寄存器。我们不能推送64位立即数,但可以将字符串作为32位DWORD值直接写入堆栈。我们不需要调整RSP,因为Linux有一个128字节,可以防止异步事件和信号的破坏


如果要使用带有C转义字符的C样式字符串,请使用NASM而不是单引号来进行区分。这允许您使用类似于
\n
的内容作为表示新行字符的字符。我提到这一点是因为您似乎想在问题中发布的一些代码中添加换行符,这些代码后来被删除。

ebp
不是堆栈指针,
esp
是堆栈指针。也,
push
将使用每个字符4个字节,所以这不太管用。更不用说使用
push
将反转字符串。@Jester字符串的反转是我想测试的内容,Jester指出应该是ESP和EBP,如果要向后打印该字符串,可以用
push替换推“leH”
推“w-ol”
推“dlro”
。对于标准输出,EBX也应该是1而不是0。(0是标准输入)您是将其组装为64位程序还是32位程序?此代码无法作为64位代码正常运行,因为64位代码中的模拟无法处理使用堆栈时所需的64位地址。堆栈地址需要RSP中的完整64位地址。只有通过
syscall
指令使用64位System V Linux系统调用接口,才能完成此操作。关于使用它的信息可以在这里找到。对于代码密度,实际上可以混合使用
推送
mov
,例如
推送“地狱”
/
mov-dword[rsp+4],“o-Wo”
。作为奖励,您最终的rsp指向字符串的前面,因此您只需要
mov
而不是
lea
。这也是一种为
execve
获取以null结尾的字符串的简单方法,而无需在机器代码中使用文本0字节。但是+1是一个好的非
推送
示例,它更容易理解!(实际上,对于代码密度,您希望
push-imm32
推送字符串的末尾,然后
mov-reg,imm64
/
push-reg
推送接下来的8个字节。12个即时字节和2个操作码+1个前缀字节。您还可以
learsi,[rsp-8]
/syscall并在推送后使用虚拟
pop
)恢复rsp)
section .text
global _start
_start:
    mov dword [rsp-4], `rld\n`
                    ; Use back ticks instead of single quotes
                    ; To parse the string like C. We can write safely
                    ; in the 128 bytes below RSP because of the
                    ; Linux red zone.
    mov dword [rsp-8], 'o Wo'
    mov dword [rsp-12],'Hell'
    mov eax,1       ;Write system call number
    mov edi,eax     ;file descriptor (1 = stdout)
    lea rsi,[rsp-12];address of message on the stack
    mov edx,12      ;length of message
    syscall
    mov eax,60      ;Exit system call
    xor edi,edi     ;RDI=0
    syscall