因为之前执行了PUSHAD,所以恢复的寄存器及其值和之前相同。
PUSHAD-POPAD指令经常被使用,例如:某个时刻你需要保存所有寄存器的内容,然后修改寄存器的值,或者进行堆栈的相关操作,然后使用POPAD恢复它们原来的状态。 也有以下的用法:
PUSHA 等价于 'PUSH AX, CX, DX, BX, SP, BP, SI, DI'。 POPA 等价于 'pop DI, SI, BP, SP, BX, DX, CX, AX'。
PUSHA,POPA和PUSHAD,POPAD就像姐妹一样,只不过它们在16位程序中使用,所以我们不感兴趣,OllyDbg是一个32位程序的调试器。 赋值指令的说明 MOV
该指令将第二个操作数赋值给第一个操作数,例如: MOV EAX, EBX
EBX值赋值给EAX。继续用OD载入CrueHead'а的CrackMe。
两个寄存器的值是不一样的,我们只是看寄存器:
11
在我的机器上,EAX为0,EBX为7FFD7000。这些初始值有可能与你机器上的不一样,我们只是看赋值的过程,按F7键,EBX的值就赋值给了EAX。
明白了吗?
MOV指令操作数有很多可以选择,例如: MOV AL, CL
这条指令时将CL的值赋值给AL。在OD中写上这句。
寄存器:
12
请记住,AL-是EAX的最后两位数字以及CL-是ECX的最后两位数字。按F7
可以看到只是将B0赋值给AL了,并不改变EAX和ECX的其他内容,即EAX的最后两位数字。
也可以给内存单元赋值,反之亦然一个寄存器的内容。
上图这种情况下,将要给EAX给的值是405000这个内存单元中的值,正如前面提到的,DWORD意味着你必须移动4个字节。如果该指令给出了一个不存在的内存单元可能会导致错误。我们可以用OD很容易的检查出来。
在数据窗口中右键单击选择Go to-Expression转到405000处.
可以看到内存中的内容是-00100000。由于内存中内容是倒序存放的,那么EAX中将被装入
13
00001000,按下F7键,看看会发生什么。
这里是1000,是从内存中读取出来的。现在,如果我们想写一个值到这个地址: MOV DWORD PTR DS:[400500],EAX 写入该指令。
在数据窗口中查看405000:
然后,按F7键发生异常:
注意异常的描述,是由于我们要写入400500这个内存地址导致的内存访问异常。 如果移动的是4个字节使用DWORD,移动两个字节的话使用WORD。 例如:
MOV AX,WORD PTR DS:[405008]
将405008内存单元中的两个字节赋值给AX。这种情况下,我们不能用EAX,这里移动的只有
14
两个字节,所以你必须使用一个16位的寄存器。 在数据窗口中查看405008.
按F7赋值给AX的只有两个字节。如下:
在AX中存放的是内存中相反的内容,EAX的其他部分并没有改变。 同理,一个字节使用BYTE。 MOV AL, BYTE PTR DS:[405008]
这种情况下,只有最后一个字节赋值给AL了,即08。
15