2011-10-21 2 views
2

저는 실행 파일로 전달 된 파일 이름을 읽고 어셈블리를 사용하여 해당 파일에 쓰려고합니다. 오류없이 컴파일되지만 실행시 실패합니다. 내 코드가 정확히 무엇입니까?argv에서 x86 어셈블리를 통해 파일 이름 읽기

BITS 32 
segment .data 
text db "text" 

segment .text 

global main 

main: 
pop ebx 
pop ebx 
pop ebx ; pop pointer to filename into ebx 
mov eax,0x5 ;syscall open 
mov ecx,0x2 ;flag read/write 
int 0x80 ;call kernel 
mov ebx,eax ;save returned file descriptor 
mov eax,0x4 ; write syscall 
mov ecx,text ;mov pointer to text into ecx 
mov edx,0x4 ;string length 
int 0x80 ;exit syscall 
mov eax,0x1 
int 0x80 
+0

4 바이트 문자열 (문자열이 자동으로 어셈블리에서 0으로 종료되지 않음)에서 5 바이트를 쓰고 있습니다. – user786653

+0

코드를 게시하기 전에 해당 비트를 변경하는 것을 잊었습니다. 내 텍스트 문자열을 변경했습니다. – evanjs

+0

또 다른 것 : 파일 이름으로'argv [0]'에 해당하는 C를 사용하지 않습니까? – user786653

답변

5

libc에서 전화를 걸었으므로 반송 용 주소가 있다는 것을 기억해야합니다. 이것은 당신이 방금 조립품 프로그램을 가지고 있다면 (많은 튜토리얼처럼!) 얻는 것과는 다르다. 그것을 염두에 두십시오 :

pop ebx ;; pops return address to libc caller (_start usually) 
pop ebx ;; pops argc 
pop ebx ;; pops argv !!WAS!!: ; pop pointer to filename into ebx 

다음은 첫 번째 인수를 인쇄하는 방법입니다. 당신은 거기에서 갈 수 있어야한다 (주의 : 내가 만든 수있는 실수) : 기본 입장에

BITS 32 

    section .text 
    global main 
    extern strlen 

main: 
    pop ecx ; Return address 
    pop ecx ; argc 
    pop ecx ; argv 
    mov ecx, [ecx+4] ; argv[1] 

    push ecx 
    call strlen 
    mov edx, eax ; count 
    pop ecx ; buf 

    mov eax, 4 ; sys_write 
    mov ebx, 1 ; stdout 
    int 0x80 

    mov eax, 1 ; sys_exit 
    mov ebx, 0 ; status 
    int 0x80 
+0

감사합니다. 당신의 대답은 크게 감사드립니다. – evanjs

2

을 :

... 
*envp[] 
*argv[] 
argc 
return address 

당신은 세 번, 당신이 종료 pop ebx 경우 : 스택은 다음과 같은있다 up accesing argv, argv[1]이 아닙니다.

argv은 NULL로 끝나는 배열 char *에 대한 포인터이므로 @ user786653과 같이 간접 참조를 따라야합니다.