我正在编写一个程序,它从c aplication中的纯十六进制字符串生成一个shell。如果我运行生成十六进制字符串的shell可执行文件,程序将正常运行并启动会话。但是当我在这个c代码中运行它(我从stackoverflow中的另一个帖子中获取)在gdb中运行并且在shell执行开始之前中断时,我注意到指向第一条指令的指针正在指向第二条指令汇编代码,而不是第一个。 c代码是
#include <sys/mman.h>
#include <string.h>
int main ()
{
char code[] = {
0xe8, 0x0a, 0x00, 0x00, 0x00, 0x2f, 0x62,
0x69, 0x6e, 0x2f, 0x62, 0x61, 0x73, 0x68,
0x5f, 0xb0, 0x3b, 0x48, 0x31, 0xf6, 0x48,
0x31, 0xd2, 0x0f, 0x05
};
void *buf;
/* copy code to executable buffer */
buf = mmap (0,sizeof(code),PROT_READ|PROT_WRITE|PROT_EXEC,
MAP_PRIVATE|MAP_ANON,-1,0);
memcpy (buf, code, sizeof(code));
/* run code */
((void (*) (void))buf)();
return 0;
}
shell:
.globl _start
.text
_start:
call chamaexecve
variaveis:
.asciz "/bin/bash"
chamaexecve:
pop %rdi # first instruction of the call
mov $59, %al # second instruction of the call
xor %rsi, %rsi
xor %rdx, %rdx
syscall
在gdb中,disasembling main,指向启动shellcode的callq
0x0000000000400596 <+0>: push %rbp
0x0000000000400597 <+1>: mov %rsp,%rbp
0x000000000040059a <+4>: sub $0x40,%rsp
0x000000000040059e <+8>: mov %fs:0x28,%rax
0x00000000004005a7 <+17>: mov %rax,-0x8(%rbp)
0x00000000004005ab <+21>: xor %eax,%eax
0x00000000004005ad <+23>: movb $0xe8,-0x30(%rbp)
0x00000000004005b1 <+27>: movb $0xa,-0x2f(%rbp)
0x00000000004005b5 <+31>: movb $0x0,-0x2e(%rbp)
0x00000000004005b9 <+35>: movb $0x0,-0x2d(%rbp)
0x00000000004005bd <+39>: movb $0x0,-0x2c(%rbp)
0x00000000004005c1 <+43>: movb $0x2f,-0x2b(%rbp)
0x00000000004005c5 <+47>: movb $0x62,-0x2a(%rbp)
0x00000000004005c9 <+51>: movb $0x69,-0x29(%rbp)
0x00000000004005cd <+55>: movb $0x6e,-0x28(%rbp)
0x00000000004005d1 <+59>: movb $0x2f,-0x27(%rbp)
0x00000000004005d5 <+63>: movb $0x62,-0x26(%rbp)
0x00000000004005d9 <+67>: movb $0x61,-0x25(%rbp)
0x00000000004005dd <+71>: movb $0x73,-0x24(%rbp)
0x00000000004005e1 <+75>: movb $0x68,-0x23(%rbp)
0x00000000004005e5 <+79>: movb $0x5f,-0x22(%rbp)
0x00000000004005e9 <+83>: movb $0xb0,-0x21(%rbp)
0x00000000004005ed <+87>: movb $0x3b,-0x20(%rbp)
0x00000000004005f1 <+91>: movb $0x48,-0x1f(%rbp)
0x00000000004005f5 <+95>: movb $0x31,-0x1e(%rbp)
0x00000000004005f9 <+99>: movb $0xf6,-0x1d(%rbp)
0x00000000004005fd <+103>: movb $0x48,-0x1c(%rbp)
0x0000000000400601 <+107>: movb $0x31,-0x1b(%rbp)
0x0000000000400605 <+111>: movb $0xd2,-0x1a(%rbp)
0x0000000000400609 <+115>: movb $0xf,-0x19(%rbp)
0x000000000040060d <+119>: movb $0x5,-0x18(%rbp)
0x0000000000400611 <+123>: mov $0x0,%r9d
0x0000000000400617 <+129>: mov $0xffffffff,%r8d
0x000000000040061d <+135>: mov $0x22,%ecx
0x0000000000400622 <+140>: mov $0x7,%edx
0x0000000000400627 <+145>: mov $0x19,%esi
0x000000000040062c <+150>: mov $0x0,%edi
0x0000000000400631 <+155>: callq 0x400470 <mmap@plt>
0x0000000000400636 <+160>: mov %rax,-0x38(%rbp)
0x000000000040063a <+164>: mov -0x38(%rbp),%rax
0x000000000040063e <+168>: mov -0x30(%rbp),%rdx
0x0000000000400642 <+172>: mov %rdx,(%rax)
0x0000000000400645 <+175>: mov -0x28(%rbp),%rdx
0x0000000000400649 <+179>: mov %rdx,0x8(%rax)
0x000000000040064d <+183>: mov -0x20(%rbp),%rdx
0x0000000000400651 <+187>: mov %rdx,0x10(%rax)
0x0000000000400655 <+191>: movzbl -0x18(%rbp),%edx
0x0000000000400659 <+195>: mov %dl,0x18(%rax)
0x000000000040065c <+198>: mov -0x38(%rbp),%rax
**0x0000000000400660 <+202>: callq *%rax**
0x0000000000400662 <+204>: mov $0x0,%eax
0x0000000000400667 <+209>: mov -0x8(%rbp),%rcx
0x000000000040066b <+213>: xor %fs:0x28,%rcx
0x0000000000400674 <+222>: je 0x40067b <main+229>
0x0000000000400676 <+224>: callq 0x400460 <__stack_chk_fail@plt>
0x000000000040067b <+229>: leaveq
0x000000000040067c <+230>: retq
我将断点设置为运行tb * 0x0000000000400660
的此调用
在这个断点处打印rax给出:
(gdb)print / x $ rax
$ 2 = 0x7ffff7ff5000
和x/8i 0x7ffff7ff5000
:
0x7ffff7ff5000: callq 0x7ffff7ff500f
0x7ffff7ff5005: (bad)
0x7ffff7ff5006: (bad)
0x7ffff7ff5007: imul $0x68736162,0x2f(%rsi),%ebp
0x7ffff7ff500e: pop %rdi # first instruction of the call
0x7ffff7ff500f: mov $0x3b,%al # second instruction of the call
0x7ffff7ff5011: xor %rsi,%rsi
0x7ffff7ff5014: xor %rdx,%rdx
另外,如果我从这一点打印十六进制,它会显示对齐的shellcode:
x / 25xb 0x7ffff7ff5000
0x7ffff7ff5000:0xe8 0x0a 0x00 0x00 0x00 0x2f 0x62 0x69
0x7ffff7ff5008:0x6e 0x2f 0x62 0x61 0x73 0x68 0x5f 0xb0
0x7ffff7ff5010:0x3b 0x48 0x31 0xf6 0x48 0x31 0xd2 0x0f
0x7ffff7ff5018:0x05
c代码是使用$ gcc -ggdb -o executahex executahex.c
编译的,而shell是$ as -gstabs -o shellf-test.o shellf-test.s
$ ld -o shellf-test shellf-test.o