pro*_*rsn 0 memory x86 assembly stack mov
我已经拆解了一个使用C 函数的x86 elf二进制文件scanf
.
以下是与以下内容相关的反汇编代码块scanf
:
0x0804857a 89442404 mov dword [esp + 0x4], eax
0x0804857e c70424b28604. mov dword [esp], 0x80486b2
0x08048585 e8eafdffff call sym.imp.scanf
Run Code Online (Sandbox Code Playgroud)
检查时gdb
,地址处的内存0x80486b2
包含数据0x7325
(ASCII代码中的" %s "字符串).
所以这段代码显然是在堆栈上以相反的顺序推送参数,以便用这两个参数调用.
这通常用C编码
scanf
scanf
scanf ("%s", &somevar);
在给定汇编代码的情况下,我所期望的是,常量的32位表示形式 0x80486b2
被加载到堆栈指针所指向的地址中 ......
但是,该mov
指令已经加载了32位表示的任何处于地址 0x80486b2
到堆栈指针指向的地址 ......是吗?
所以我们基本上得到的mov
只是将数据从内存位置转移到另一个内存位置,根据这个x86程序集介绍(在众多其他来源中)是非法的(重点是我的):
在需要存储器传输的情况下,必须首先将源存储器内容加载到寄存器中,然后将其存储到目标存储器地址.
此处没有注册用作中间人.
怎么可能?
如果我理解的话,
mov
这里的指令将地址为0x80486b2的32位表示加载到堆栈指针指向的地址中......是吗?
不.指令
mov dword [esp], 0x80486b2
Run Code Online (Sandbox Code Playgroud)
将立即值复制0x80486B2
到寄存器指向的地址ESP
.这个地方是传递给scanf
函数的第一个参数.
所以我们基本上得到的
mov
只是将数据从内存位置转移到另一个内存位置,[...]
否.指令将立即的32位值移动到存储位置.在这种情况下,MOV的指令签名是:
MOV r/m32, imm32 Move imm32 to r/m32.
Run Code Online (Sandbox Code Playgroud)
该值0x80486b2
将写入寄存器ESP指向的DWORD存储器地址.
指令mov dword [esp + 0x4], eax
并通过从所述第二参数EAX
来scanf
.