Assembly x64 helloworld外壳代码不打印任何内容
我正在linux容器上学习Assembly x64 helloworld外壳代码不打印任何内容,assembly,64-bit,shellcode,Assembly,64 Bit,Shellcode,我正在linux容器上学习x64外壳代码,运行我编写的hello world x64外壳代码时遇到问题。 我试图将“Hi there”缓冲区直接移动到寄存器中,因此我不使用.data部分 section .data ;msg db "Hi there" section .text global _start _start: ;zeroed out these registers xor rax, rax xor rbx, rbx xor rsi, rsi xor rdi
x64外壳代码
,运行我编写的hello world x64外壳代码时遇到问题。
我试图将“Hi there”缓冲区直接移动到寄存器中,因此我不使用.data
部分
section .data
;msg db "Hi there"
section .text
global _start
_start:
;zeroed out these registers
xor rax, rax
xor rbx, rbx
xor rsi, rsi
xor rdi, rdi
xor rdx, rdx
;write (int fd, char *msg, unsigned int len);
mov rax,1 ; syscall 1 is write in 64bit arch
mov rdi,1 ; rdi is fd
mov rbx, 0x6572656874206948
mov rdx, 9; rdx is size (9 for null byte)
syscall ; instead of int 0x80 for 32 bit architecture
;exit (int ret)
mov rax, 60 ; syscall 60 is exit in 64bit arch
mov rdi, 0 ; rdi is error code
syscall
我组装代码并运行它:
$nasm -f elf64 -o print2.o print2.asm
$ld -o print2 print2.o
$./print2
虽然print2似乎正常退出,但什么也没发生。。。有人能解释一下原因吗
对不起,如果这个问题已经被问过了。我试着寻找一个类似的,但什么也找不到。作为第一步,请查看
编写
第二个参数必须是常量void*
但对于linux,调用约定是:
RDI, RSI, RDX, RCX, R8, R9, XMM0–7
那么您的实现是不正确的
你应该这样做
global _start
_start:
jmp short msg
routine:
...
pop rsi ;address of the string from the stack
...
msg:
call routine
db 'Hi here'
使用strace
。当您将rsi=NULL作为缓冲区传递时,为什么希望它打印任何内容rbx
不是syscall arg寄存器之一。看见对于write()
,您始终需要传递指向内存中数据的指针。请看@PeterCordes抱歉,我现在才看到你的comment@invictus1306当前位置我肯定这是复制品,但我没有花时间去看。你不需要为发布答案而道歉,即使已经有了答案的评论。所以我想要真正的答案。唯一错误的是回答一个问题,这个问题应该作为许多传递数据中的一个问题的副本关闭,而不是指针问题(除了这个问题甚至不在正确的寄存器中,所以IDK)。@PeterCordes我知道了,如果我以前看到过你的评论,我肯定不会发布。我还认为,在这样的情况下,90%的问题已经存在,这些可能有点不同(比如在本例中(rbx/rsi)),但内容是相同的。我猜lea rsi,[rip+2]
就在前面mov rbx,'Hi here'
就可以了(没有在debugger中验证我是否正确理解了rip
值,我希望它指向mov rbx,…
作为相对跳跃,但我通常在源代码中使用标签,并让汇编程序对其进行排序)。更合理的做法是将数据放在代码后的代码段中,以避免浪费mov rbx,
opcode以节省2个字节,只需调整rsi
加载,并在数据到达的任何位置进行适当偏移。这是64位代码。使用RIP相对learsi,[rel msg]
而不是jmp
/call
。或者为了避免rel32位移的机器代码中出现00
,请跳过字符串,使LEA
偏移量为负(高字节中为FF而不是00)。这与使向后调用
不包含00
字节相同。或者将您的msg
放在您的NOP雪橇跳跃目标之前。
global _start
_start:
jmp short msg
routine:
...
pop rsi ;address of the string from the stack
...
msg:
call routine
db 'Hi here'