简单的asm for ptint字符串" / bin / sh"然后退出
global _start:
_start:
jmp what
are:
mov rbx,0x68732f6e69622fff
shr rbx,0x8
push rbx
mov rsi,rsp
mov dl,0x8
xor rax,rax
mov al,1
syscall
xor rax,rax
mov al,0x3c
syscall
what:
call are
nasm -f elf64 test.asm
ld -o test test.o
按预期运行。
但在shellcode中使用:
const char shellcode[] = "\x48\xbb\xff\x2f\x62\x69\x6e\x2f\x73\x68\x48\xc1\xeb\x08\x53\x48\x89\xe6\xb2\x08\x48\x31\xc0\xb0\x01\x0f\x05\x48\x31\xc0\xb0\x3c\x0f\x05";
int main(){
( (void (*)(void))&shellcode )();
return 0;
}
gcc -fno-stack-protector -z execstack -o test2 test.c
它什么都不打印。
答案 0 :(得分:2)
您的代码假设rdi
== 0,1或2,而rdx
的56位高位为零。在流程开始时,这恰好是正确的。在你调用shellcode的时候,它是不正确的。
要修复,您需要将rdi
设置为1(如果希望输出为标准输出)或2(输出设置为标准错误),并设置rdx
8。
Linux on x86-64上的系统调用ABI是
rax
char
,short
,int
,long
以及rdi
,rsi
,{{1}中的指针参数分别是},rdx
,r10
和r8
个寄存器
返回值将在r9
;如果发生错误,大多数系统调用都会返回rax
(实际的-errno
变量是一个C库构造,内核对它一无所知)
errno
和rcx
被破坏(可能被系统调用修改);保留所有其他寄存器
因此,对于r11
(write
== SYS_write
== 1),您设置__NR_write
== 1; rax
==描述符编号(rdi
== 1表示标准输出,STDOUT_FILENO
== 2表示标准错误); STDERR_FILENO
==指向要写入的数据的指针,rsi
==要写入的字符数。