在汇编器x64中获取argv [2]地址 [英] Get argv[2] address in assembler x64
问题描述
edi是argc,rsi是argv
edi is argc, rsi is argv
0x0000000000400535 <+8>: mov %edi,-0x4(%rbp)
0x0000000000400538 <+11>: mov %rsi,-0x10(%rbp)
在这里我得到了argv指针
here I get argv pointer
(gdb) x/8x $rbp-0x10
0x7ffdb7cac380: 0xb7cac478 0x00007ffd 0x00000000 0x00000003
0x7ffdb7cac390: 0x00000000 0x00000000 0x1f130b45 0x00007ff3
指针0x7ffdb7cac478
Pointer 0x7ffdb7cac478
所以我的argv [2]在这里:
So my argv[2] is here:
(gdb) x/8x 0x7ffdb7cac478+16
0x7ffdb7cac488: 0xb7cacd8a 0x00007ffd 0x00000000 0x00000000
在地址0x7ffdb7cacd8a
At address 0x7ffdb7cacd8a
我需要获取argv [2]的地址,所以我想编写以下汇编代码:
I need to get the address of argv[2], so I want to write this assembler code:
伪代码:
x-从地址$ rbp-0x10//加载8个字节//(指向argv的指针)
x - load 8 bytes from address $rbp-0x10 // (pointer to argv)
y-从x值+16////(指向argv [2]的指针)加载8个字节
y - load 8 bytes from x value+16 // (pointer to argv[2])
我稍后需要跳转到y.
我如何用汇编程序x64编写?我可以将哪个寄存器用于x和y?
How do I write in assembler x64? Which register I can use to for x and y?
我希望这是可以理解的.我是初学者.
I hope it is understandable. I am a beginner.
我在这里问,因为我不知道从哪里开始进行研究.
I ask here since I don't know where to start doing my research.
更新:
尝试过:
bits 64
ldr r8, rbp, #0x10
ldr r9, r8, #0x10
jmp r9
但是它甚至无法编译....我正在使用nasm.
But it doesn't even compile .... I am using nasm.
我猜上面是针对ARM架构的,对于下面的amd64(x64)应该这样做.正确吗?
I guess above was for ARM arch, for amd64 (x64) below should do this. Is it correct?
更新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
推荐答案
您在写main()
还是_start
?
如果您正在编写main
,则它是一个正常函数,其args位于rdi
,rsi
中,遵循正常的调用约定.请参见 x86 标签的问题wiki 获取链接
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.
如果您正在编写_start
,那么数据就在堆栈上,如ABI的进程启动部分:[rsp] = argc
中所述,并且在其上方是指针数组,char *arg[]
从rsp+8
开始.这是堆栈上的实际数组,而不是指向像main
获取的数组的指针.
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
是没有意义的.它有呼叫者留下的任何东西.
rbp
is meaningless unless you initialize it. It has whatever the caller left in it.
您的代码片段也很愚蠢:您永远不会初始化rbp.您应该假定它在进程条目上保留了垃圾.保证只有rsp
有用.
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
只是移位&添加使用有效地址语法/编码的指令. mov
是用于加载/存储的助记符.
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]???
您是否将机器代码字节放入了argv[2]
中?跳转到字符串通常没有用.
Did you put machine code bytes in argv[2]
? Jumping to a string is not normally useful.
当然,由于未初始化rbp
,因此实际上并没有访问argv[2]
.
Of course, since rbp
isn't initialized, it's not actually accessing argv[2]
.
如果要查看发生了什么,请在调试器中单步执行该操作.
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
这篇关于在汇编器x64中获取argv [2]地址的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!