执行十六进制字符串时,第一条指令跳过

时间:2017-02-17 21:28:12

标签: c assembly x86-64 linuxmint gas

我正在编写一个程序,它从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

0 个答案:

没有答案