【问题标题】:x64 helloworld shellcode not printing anythingx64 helloworld shellcode 不打印任何内容
【发布时间】: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加载与数据的适当偏移量,无论它们落在哪里。

标签: assembly 64-bit shellcode


【解决方案1】:

作为第一步,请查看write documentation

   ssize_t write(int fd, const void *buf, size_t count);

第二个参数必须是const 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' 

【讨论】:

  • 这是 64 位代码。使用相对于 RIP 的 LEA rsi, [rel msg] 而不是 jmp / call。或者为了避免在 rel32 位移的机器代码中出现00,跳过字符串,使LEA 偏移量为负数(FF 而不是高字节中的 00)。这与使向后 call 不包含 00 字节的原因相同。或者将您的msg 放在您的 NOP 雪橇跳跃目标之前。
猜你喜欢
  • 2019-05-26
  • 2021-02-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-03-02
相关资源
最近更新 更多