2017-10-12 15 views
1

exploit.courses 리눅스 컨테이너에서 x64 shellcode을 배우고 있는데 필자가 작성한 hello world x64 쉘 코드를 실행하는 데 문제가 있습니다. .data 섹션을 사용하지 않으므로 "Hi there"버퍼를 레지스터로 직접 이동하려고합니다. 누군가 이유를 설명 할 수 ...x64 helloworld 쉘 코드 아무 것도 출력하지 않습니다

$nasm -f elf64 -o print2.o print2.asm 
$ld -o print2 print2.o    
$./print2 

을 그리고 print2이 정상적으로 종료 보이지만 아무 일도 발생하지 않습니다 :

section .data 

;msg db "Hi there" 

section .text 

global _start 
_start: 
;zeroed out these registers 
xor rax, rax 
xor rbx, rbx 
xor rsi, rsi 
xor rdi, rdi 
xor rdx, rdx 

;write (int fd, char *msg, unsigned int len); 
mov rax,1 ; syscall 1 is write in 64bit arch 
mov rdi,1 ; rdi is fd 
mov rbx, 0x6572656874206948 
mov rdx, 9; rdx is size (9 for null byte) 
syscall ; instead of int 0x80 for 32 bit architecture 

;exit (int ret) 
mov rax, 60 ; syscall 60 is exit in 64bit arch 
mov rdi, 0 ; rdi is error code 
syscall 

나는 코드를 조립하고 그것을 실행?

이 질문에 대한 답변을 이미 요청한 경우 죄송합니다. 비슷한 것을 찾으려고했지만 아무 것도 못 찾았습니다.

+2

사용'strace' 같은 것을해야한다. rsi = NULL을 버퍼로 전달할 때 무엇이 ​​출력되는지 왜 예상합니까? 'rbx'는 syscall arg 레지스터 중 하나가 아닙니다. https://stackoverflow.com/questions/2535989/what-are-the-calling-conventions-for-unix-linux-system-calls-on-x86-64를 참조하십시오. 그리고 항상'write()'를 위해 메모리에있는 데이터에 대한 포인터를 전달해야합니다. 또한 https://stackoverflow.com/tags/x86/info를 참조하십시오 –

+0

@PeterCordes 죄송합니다. 내 의견은 – invictus1306

+0

@ invictus1306 만 보입니다 : 이것은 뭔가 복제 된 것이라고 확신하지만 시간을 내주지 않았습니다. 찾고. 이미 답변에 대한 의견이있는 경우에도 답변 게시에 대해 사과하실 필요가 없습니다. 그래서 진짜 답을 원합니다. 잘못된 점은 포인터 질문 대신에 많은 데이터 중 하나의 중복으로 닫아야하는 질문에 답하는 것입니다 (올바른 IDK도 포함되지 않았 음을 제외하고 IDK). –

답변

1

첫 번째 단계는 writedocumentation

ssize_t write(int fd, const void *buf, size_t count); 

에서 보면 두 번째 인수는 const void *

수 그러나 호출 규칙을 리눅스입니다해야합니다

RDI, RSI, RDX, RCX, R8, R9, XMM0–7 

그런 다음 구현하지 않습니다 옳은.

는이

global _start 


_start: 

    jmp short msg 

    routine: 

    ... 
    pop rsi   ;address of the string from the stack 
    ... 


    msg: 
    call routine  
    db 'Hi here' 
+0

이것은 64 비트 코드입니다. 'jmp' /'call' 대신에 RIP- 상대'LEA rsi, [rel msg]'를 사용하십시오. 또는 rel32 변위의 기계어 코드에서 '00'을 피하려면 문자열을 건너 뛰고 'LEA' 오프셋은 음수가됩니다 (높은 바이트에서 00 대신 FF). 이것은'call'이'00' 바이트를 포함하지 않도록하는 것과 같은 것입니다. 또는 NOP 썰매 점프 대상 앞에'msg'를 놓으십시오. –