汇编x86代码和进程虚拟内存

时间:2018-04-22 09:33:19

标签: assembly x86 disassembly

我想了解下面的一段代码

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定义的地址?

有人可以指导我走向正确的方向吗?

谢谢!

1 个答案:

答案 0 :(得分:1)

  

...它是一个块,提供给我用于研究目的,可能来自IDA Pro,来自反汇编的PE,以了解此函数的作用以及对cpu寄存器的指令的影响

     

...我试图了解这些指令在执行时的作用

     

...遗憾的是,一旦ebp寄存器中的这一减法和加法发生,我仍然无法弄清楚寄存器的内容是什么

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

此代码实质上只是在[ebp-8][ebp-4]切换局部变量 它可以写成:

,而不是需要9条指令和3条寄存器
    mov edx, [ebp-8]
    mov eax, [ebp-4] 
    mov [ebp-4], edx
    mov [ebp-8], eax
lea eax, data
cmp eax, DWORD PTR [ebp-8]
jle SHORT L1
...
L1:
mov eax, DWORD PTR [ebp-8]

为了清晰起见,重新编写测试:

    cmp DWORD PTR [ebp-8], data
    jge SHORT L1
    ...
L1:
    mov eax, [ebp-8]

如果[ebp-8]处的局部变量大于或等于数组的起始地址,则它将成为EAX中的结果。

如果[ebp-8]处的局部变量小于数组的起始地址,则[ebp-4]的原始内容将成为EAX中的结果。

如果切换部分不重要,下一个代码将生成相同的EAX

    mov eax, [ebp-8]
    cmp eax, data
    jge SHORT L1
    mov eax, [ebp-4]
L1: