Get argv[2] address in assembler x64

前端 未结 1 904
长情又很酷
长情又很酷 2020-12-20 02:13

edi is argc, rsi is argv

   0x0000000000400535 <+8>: mov    %edi,-0x4(%rbp)
   0x0000000000400538 <+11>:    mov    %rsi,-0x10(%rbp)
相关标签:
1条回答
  • 2020-12-20 02:33

    Are you writing main() or _start?

    If you're writing main, it's a normal function with its args in rdi, rsi, following the normal calling convention. See x86 tag wiki for links to the x86-64 ABI.

    If you're writing _start, then data is on the stack, as documented in process startup section of the ABI: [rsp] = argc, and above that an array of pointers, char *arg[] starting at rsp+8. It's an actual array right there on the stack, not a pointer to an array like main gets.

    rbp is meaningless unless you initialize it. It has whatever the caller left in it.


    Your code fragment is silly, too: you never initialize rbp. You should assume it holds garbage on process entry. Only rsp is guaranteed to be useful.

    lea is just a shift & add instruction that uses effective-address syntax / encoding. mov is the mnemonic for load / store.

        ;; your code with comments, also assuming that RBP was initialized
        bits 64
        lea r8, [rbp-0x10]      ; r8 = rbp-0x10
        mov r9, [r8]            ; should have just done mov r9, [rbp-0x10]
        mov r10, [r9+0x10]
        jmp r10                 ; jump to argv[2]???
    

    Did you put machine code bytes in argv[2]? Jumping to a string is not normally useful.

    Of course, since rbp isn't initialized, it's not actually accessing argv[2].


    Working example

    single-step this in a debugger if you want to see what's going on.

    ; get argc and argv from the stack, for x86-64 SysV ABI
    global _start
    _start:
        mov   ecx,  [rsp]             ;   load argc (assuming it's smaller than 2^32)
    
        cmp   ecx, 3
        jb  .argc_below_3
                                      ;   argv[0] is at rsp+8
        mov   rsi,  [rsp+8 +  8*2]    ;   argv[2]  (the 3rd element)
        movzx eax,  byte [rsi]        ;   first char of argv[2]
    
        ; if you stop here in a debugger, you can see the character from the second arg.
    
        ; fall through and exit
    .argc_below_3:
        xor edi, edi
        mov eax, 231                  ;  exit_group(0)
        syscall
    
    0 讨论(0)
提交回复
热议问题