【发布时间】:2018-04-22 09:33:18
【问题描述】:
我正在尝试理解下面的一段代码
data dd 1,2,3,4,5,6
myfunc:
lea eax, data
cmp eax, DWORD PTR [ebp-8]
jle SHORT L1
mov ecx, DWORD PTR [ebp-8]
add ecx, DWORD PTR [ebp-4]
mov DWORD PTR [ebp-4], ecx
mov edx, DWORD PTR [ebp-4]
sub edx, DWORD PTR [ebp-8]
mov DWORD PTR [ebp-8], edx
mov eax, DWORD PTR [ebp-4]
sub eax, DWORD PTR [ebp-8]
mov DWORD PTR [ebp-4], eax
L1:
mov eax, DWORD PTR [ebp-8]
第一行我知道它将被加载到进程虚拟内存中,因为dd 是用4 bytes 定义的,所以可能是这样的吗?
data dd 1,2,3,4,5,6
4004000 01 ; 1
4004001 00 ; 0
4004002 00 ; 0
4004003 00 ; 0
4004004 02 ; 2
4004005 00 ; 0
4004006 00 ; 0
4004007 00 ; 0
4004008 03 ; 3
4004009 00 ; 0
400400A 00 ; 0
400400B 00 ; 0
4004008 04 ; 4
4004009 00 ; 0
400400A 00 ; 0
400400B 00 ; 0
400400C 05 ; 5
400400D 00 ; 0
400400E 00 ; 0
400400F 00 ; 0
4004010 06 ; 6
4004011 00 ; 0
4004012 00 ; 0
4004013 00 ; 0
但是,在标签之后,它会将 var data 的内存地址加载到 eax 寄存器中,然后将 eax 的值与 [ebp-8] 处存在的 DWORD 进行比较
我不明白的是,我认为 ebp 中没有地址,所以可能是它丢失了mov ebp,esp?
即使我将 esp 移动到 ebp 我不明白的部分是代码说 ebp-8 应该是 ebp-4 可能指向定义的第一个 DWORD 的地址?
有人可以指导我正确的方向吗?
谢谢!
【问题讨论】:
-
是的,使用
[ebp-8]而不在函数顶部使用push ebp/mov ebp,esp很奇怪。但这将是一个本地的,而不是一个函数 arg,(因为它低于 EBP),所以它只是一个独立的函数是没有意义的。它可能是现有函数可以跳转到的块。顺便说一句,lea eax, data很傻;mov eax, OFFSET data更短更快,没有缺点。cmp eax, DWORD PTR [ebp-8]似乎将静态地址(eax)与局部变量进行比较。代码看起来很垃圾;是编译器生成的调试模式吗? -
嘿彼得,是的,它看起来很垃圾,它可能是 IDA Pro 提供给我的一个用于研究目的的块,从一个反汇编的 PE 中了解这个函数的作用以及指令对 cpu 寄存器的影响.因此,如果我在函数
myfunc之外执行push ebp和mov ebp,esp,我将在ebp 中有起始地址,但是当它尝试与eax进行比较时,它不会是invalid地址,因为ebp-4不存在?我试图了解这些指令在执行时会做什么 -
当然
ebp-4会存在。它甚至会被映射到您的进程的地址空间中。它将低于esp,因此会被异步破坏,除非您的函数也执行sub esp, 12。一个普通的函数会这样做来为当地人保留空间。 -
很明显这不是函数的开始,或者是使用父函数栈帧的私有辅助函数。标签不是真的
myfunc是吗?你只是猜测它是函数的开始而不是函数中的块吗? -
感谢@Peter Cordes,不幸的是,一旦
ebp寄存器发生减法和加法,我仍然无法弄清楚寄存器的内容是什么。我没有更多信息,它是函数中的一个块,它只是我所拥有的摘录。
标签: assembly x86 disassembly