【问题标题】:nasm 64 bit push qword?nasm 64位推送qword?
【发布时间】:2012-09-22 15:08:40
【问题描述】:

我似乎遇到了一个有趣的问题,尽管我可能做错了什么。

我的问题是我试图将 AAAABBBBCCCC 推入堆栈,然后通过标准输出打印它们。但是,在我的 x86_64 环境中,push 0x41414141 似乎会推送4141414100000000

所以下面的代码块:

    global _start
    section .text
    _start:
    push 0x43434343  ; CCCC
    push 0x42424242  ; BBBB
    push 0x41414141  ; AAAA
    xor rax,rax      ; Zero RAX
    mov byte al,0x1  ; 1 for sys_write
    mov rdi,rax      ; 1 for stdout
    mov rsi,rsp      ; RSP for source
    mov byte dl,0xC  ; 12
    syscall          

    xor rax,rax      ; Zero RAX
    mov al, 0x3C     ; 60 for sys_edxit
    cdq              ; 0 for clean exit.
    syscall

输出AAAABBBB,我认为只有 8 个字节,实际上是我要求的 12 个字节。当通过管道传输到输出文件并在 hexedit 中查看时,我注意到它显示的是414141410000000042424242

我认为push 指令会推送一个dword 值。到qword 大小的堆栈上?我这样想对吗?

考虑到额外的字节数,并将我的长度更改为 20,可以避免这种情况。但这会导致 sys_open 之类的问题。

所以我的问题是,我做错了什么?

【问题讨论】:

  • @DCoder:根据push指令上的操作伪代码,你是对的,操作数将被符号扩展。 --- 嗯...他刚刚删除了他的评论?

标签: assembly x86-64 nasm shellcode


【解决方案1】:

对于 64 位代码,堆栈 (RSP) 始终在 8 字节边界上对齐。也没有“push qword imm64”指令(见注)。

我的建议是将字符串“AAAABBBBCCCC”存储在它所属的数据部分(或“.rodata”)中,而不是弄乱堆栈。或者在 shellcode 中,

push   'CCCC'                  ; push qword, including 4 bytes of zeros
mov    rax, 'AAAABBBB'         ; mov reg, imm64; pick any register
push   rax                     ; push qword

保留您的变态的替代方法可能是:

sub rsp,16
mov dword [rsp],'AAAA'
mov dword [rsp+4],'BBBB'
mov dword [rsp+8],'CCCC'
....
add rsp,16

注意:AMD 的手册说有一个“push imm64”指令。 AMD 的手册是错误的——这条指令实际上推送了一个 32 位立即数(符号扩展为 64 位)。

英特尔的手册没有这个问题:https://www.felixcloutier.com/x86/push
也相关:How many bytes does the push instruction push onto the stack when I don't specify the operand size? - 你绝对不能在 64 位模式下进行双字推送。

【讨论】:

    猜你喜欢
    • 2013-05-30
    • 1970-01-01
    • 2012-02-10
    • 2011-11-19
    • 1970-01-01
    • 2012-11-01
    相关资源
    最近更新 更多