在汇编程序x64中获取argv [2]地址

时间:2016-03-08 10:02:36

标签: assembly

edi是argc,rsi是argv

   0x0000000000400535 <+8>: mov    %edi,-0x4(%rbp)
   0x0000000000400538 <+11>:    mov    %rsi,-0x10(%rbp)

这里我得到了argv指针

(gdb) x/8x $rbp-0x10
0x7ffdb7cac380: 0xb7cac478  0x00007ffd  0x00000000  0x00000003
0x7ffdb7cac390: 0x00000000  0x00000000  0x1f130b45  0x00007ff3

指针0x7ffdb7cac478

所以我的argv [2]就在这里:

(gdb) x/8x 0x7ffdb7cac478+16
0x7ffdb7cac488: 0xb7cacd8a  0x00007ffd  0x00000000  0x00000000

地址0x7ffdb7cacd8a

我需要获取argv [2]的地址,所以我想写这个汇编代码:

伪代码:

x - 从地址$ rbp-0x10 //(指向argv的指针)

加载8个字节

y - 从x值加载8个字节+ 16 //(指向argv [2]的指针)

我稍后需要jmp到y。

如何用汇编程序x64编写?我可以使用哪个寄存器用于x和y?

我希望这是可以理解的。我是初学者。

我问这里,因为我不知道从哪里开始做研究。

更新

试过这个:

bits 64
ldr r8, rbp, #0x10
ldr r9, r8, #0x10
jmp r9

但它甚至没有编译....我正在使用nasm。

我猜以上是针对ARM arch,因为下面的amd64(x64)应该这样做。这是对的吗?

更新2:

bits 64
lea r8, [rbp-0x10]
lea r9, [r8+0x10]
jmp r9

更新3:

也不起作用......

bits 64
lea r8, [rbp-0x10]
mov r9, [r8]
mov r10, [r9+0x10]
jmp r10

1 个答案:

答案 0 :(得分:1)

您在撰写main()_start吗?

如果您正在编写main,那么它是rdirsi中的args的正常函数,遵循正常的调用约定。有关的链接,请参见wiki代码to the x86-64 ABI

如果您正在编写_start,那么数据就在堆栈中,如ABI的流程启动部分所述:[rsp] = argc,以及指针数组char *arg[]之上从rsp+8开始。它是堆栈上的实际数组,而不是指向类似main的数组的指针。

rbp除非您初始化它,否则毫无意义。它有来电者留下的任何东西。

您的代码片段也很愚蠢:您永远不会初始化rbp。您应该假设它在进程输入时保留垃圾。只有rsp才有用。

lea只是一个转变&amp;添加使用有效地址语法/编码的指令。 mov是加载/存储的助记符。

    ;; 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]???

您是否将机器代码字节放在argv[2]中?跳转到字符串通常不是很有用。

当然,由于rbp未初始化,因此实际上并未访问argv[2]

工作示例

如果你想看看发生了什么,

在调试器中单步执行此操作。

; 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
相关问题