【发布时间】:2017-10-12 07:03:56
【问题描述】:
我在exploit.courses linux 容器上学习x64 shellcode,我在运行我编写的 hello world x64 shellcode 时遇到问题。
我正在尝试将“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 似乎正常退出,但什么也没发生……有人能解释一下原因吗?
对不起,如果这个问题已经被问过。我试图寻找类似的,但找不到任何东西。
【问题讨论】:
-
使用
strace。当您将 rsi=NULL 作为缓冲区传递时,为什么希望它打印任何内容?rbx不是系统调用 arg 寄存器之一。见stackoverflow.com/questions/2535989/…。而且您总是需要为write()传递指向内存中数据的指针。另见stackoverflow.com/tags/x86/info -
@PeterCordes 抱歉,我现在才看到你的评论
-
@invictus1306:我确定这是重复的东西,但我没有花时间去寻找。即使已经有对答案的评论,您也无需为发布答案而道歉。所以想要真正的答案。唯一错误的是回答一个问题,该问题应该作为许多传递数据之一的副本而不是指针问题(除非这甚至不在正确的寄存器中,所以 IDK)。
-
@PeterCordes 我明白了,当然如果我以前看到你的评论,我永远不会发帖。我也认为在 SO 中,90% 的问题已经存在,这些可能会有点不同(就像在这种情况下(rbx/rsi)),但内容是一样的。
-
我 猜
lea rsi,[rip+2]就在前面mov rbx,'Hi there'会做(如果我对rip值的想法正确,我没有在调试器中验证,我希望它指向mov rbx,...,就像大小写相对跳转一样,但我通常在源代码中使用标签并让汇编程序对其进行排序)。将数据放入代码之后的代码段仍然更合理,以避免浪费mov rbx,操作码以节省2个字节,只需调整rsi加载与数据的适当偏移量,无论它们落在哪里。