我正在尝试编写ASM代码来生成一个shell。
我已经发现__execve
的系统呼叫号码是0x3b或59。
我需要将"/bin/sh"
作为第一个参数发送,将指向{"/bin/sh", NULL}
的指针作为第二个参数,NULL
作为第三个参数。
通过英特尔架构上的x86_64 ASM 的配置——第一个参数写入RDI
寄存器,第二个参数写入RSI
寄存器,最后一个参数写入RDX
寄存器。
这是我的代码:
global _start
section .text
_start:
jmp message
mystart:
xor rax, rax
push rax
push rax
pop rdx ; third parameter - NULL
pop rdi ; first parameter - "/bin/sh"
mov rax, rdi
push rax
push rsp
pop rsi ; second parameter - pointer to {"/bin/sh", NULL}
xor rax, rax
mov al, 0x3b
syscall
xor rax, rax
mov al, 0x3c
xor rdi, rdi
mov dil, 0x0a
syscall
message:
call mystart
db "/bin/sh"
section .data
我使用以下说明来编译和链接代码。
yasm -f elf64 shell.asm -o shell.o
ld -o shell.out shell.o
_start
函数的 GDB 转储如下所示:
Dump of assembler code for function _start:
0x0000000000400080 <+0>: jmp 0x4000a3 <_start+35>
0x0000000000400082 <+2>: xor rax,rax
0x0000000000400085 <+5>: push rax
0x0000000000400086 <+6>: push rax
0x0000000000400087 <+7>: pop rdx
0x0000000000400088 <+8>: pop rdi
0x0000000000400089 <+9>: mov rax,rdi
0x000000000040008c <+12>: push rax
0x000000000040008d <+13>: push rsp
0x000000000040008e <+14>: pop rsi
0x000000000040008f <+15>: xor rax,rax
0x0000000000400092 <+18>: mov al,0x3b
0x0000000000400094 <+20>: syscall
0x0000000000400096 <+22>: xor rax,rax
0x0000000000400099 <+25>: mov al,0x3c
0x000000000040009b <+27>: xor rdi,rdi
0x000000000040009e <+30>: mov dil,0xa
---Type <return> to continue, or q <return> to quit---
0x00000000004000a1 <+33>: syscall
0x00000000004000a3 <+35>: call 0x400082 <_start+2>
0x00000000004000a8 <+40>: pop rsp
0x00000000004000a9 <+41>: (bad)
0x00000000004000aa <+42>: (bad)
0x00000000004000ab <+43>: .byte 0x69
0x00000000004000ac <+44>: outs dx,BYTE PTR ds:[rsi]
0x00000000004000ad <+45>: pop rsp
0x00000000004000ae <+46>: (bad)
0x00000000004000af <+47>: jae 0x400119
如您所见,(bad)
指令是由db "/bin/sh"
引起的,这个字符串有什么问题?什么是(bad)
指令?将来如何调试此类问题?
(1) 不能将字符串加载到寄存器中,只能加载指向字符串的指针。
(2)你的堆栈魔法只是错误的。将其中一个双倍push rax
移动到pop rdi
下方,该程序对我有用。