2012-08-06 2 views
0
jmp 0x2a      # 3 bytes 
    popl %esi      # 1 byte 
    movl %esi,0x8(%esi)   # 3 bytes 
    movb $0x0,0x7(%esi)   # 4 bytes 
    movl $0x0,0xc(%esi)   # 7 bytes 
    movl $0xb,%eax    # 5 bytes 
    movl %esi,%ebx    # 2 bytes 
    leal 0x8(%esi),%ecx   # 3 bytes 
    leal 0xc(%esi),%edx   # 3 bytes 
    int $0x80     # 2 bytes 
    movl $0x1, %eax    # 5 bytes 
    movl $0x0, %ebx    # 5 bytes 
    int $0x80     # 2 bytes 
    call -0x2f     # 5 bytes 
    .string \"/bin/sh\"    # 8 bytes 

그래서 다음 전화를 점프 코드 실행 순서를 들어 "문자열은 로 스택에 리턴 어드레스를 추진 할 수있게됩니다." 이 주소가 esi에 저장되어있는 이유는 pop esi입니까?는 스매싱 스택 재미와 이익,

+1

이 질문의 핵심은 무엇입니까? –

답변

1

position-independent code (주소가 무엇이든 관계없이 성공적으로 실행할 수있는 코드)을 작성하는 일반적인 방법입니다.

  • 지정한 주소로 이동합니다 스택에

    1. 는 반환 주소 (즉시 호출 다음 명령어의 주소)를 넣습니다 :

      call 명령은 두 가지 작업을 수행합니다.

    그래서 호출 후 문자열 "/ bin/sh"의 주소가 스택에 있습니다. 다음 명령어 인 pop esi은 해당 주소를 스택에서 가져와 esi 레지스터에 저장하므로 사용할 수 있습니다.

  • 0

    글쎄, call이 실행되면 리턴 주소 (호출 opcode 다음의 주소)가 스택에 푸시되어 ret이 발생하면 (정상 작동시) 실행이 중단 된 지점에서 계속 실행됩니다. 이것이 표준 x86 호출 규칙입니다.

    코드에서 푸시 된 반송 주소는 "/ bin/sh"의 위치입니다. pop %esi은 그 값을 esi 레지스터에 넣습니다.이 값은 포인터로 사용되며 리눅스 시스템에서 이 execve 인 syscall에 전달되어 문자열에 지정된 명령을 실행합니다.

    x86 calling conventions에는 많은 좋은 자료가 있는데, 그 중 리눅스 x86이 특히 흥미로울 것으로 기대합니다.

    관련 문제