OllyDBG调试-各寄存器作用

2012-07-02 08:26

OllyDBG调试-各寄存器作用

by xsky

at 2012-07-02 00:26:13

original http://www.udpwork.com/item/7601.html

eax, ebx, ecx, edx, esi, edi, ebp, esp 各寄存器作用

 eax, ebx, ecx, edx, esi, edi, ebp, esp等都是X86 汇编语言中CPU上的通用寄存器的名称,是32位的寄存器。如果用C语言来解释,可以把这些寄存器当作变量看待。

比方说:add eax,-2 ;   //可以认为是给变量eax加上-2这样的一个值。

这些32位寄存器有多种用途,但每一个都有“专长”,有各自的特别之处。

EAX 是”累加器”(accumulator), 它是很多加法乘法指令的缺省寄存器。

EBX 是”基地址”(base)寄存器, 在内存寻址时存放基地址。

ECX 是计数器(counter), 是重复(REP)前缀指令和LOOP指令的内定计数器。

EDX 则总是被用来放整数除法产生的余数。

ESI/EDI 分别叫做”源/目标索引寄存器”(source/destination index),因为在很多字符串操作指令中, DS:ESI指向源串,而ES:EDI指向目标串.

EBP 是”基址指针”(BASE POINTER), 它最经常被用作高级语言函数调用的”框架指针”(frame pointer). 在破解的时候,经常可以看见一个标准的函数起始代码:

push ebp ; 保存当前ebp
mov ebp,esp ; EBP设为当前堆栈指针
sub esp, xxx ; 预留xxx字节给函数临时变量.

这样一来,EBP 构成了该函数的一个框架, 在EBP上方分别是原来的EBP, 返回地址和参数. EBP下方则是临时变量. 函数返回时作 mov esp,ebp/pop ebp/ret 即可.

ESP 专门用作堆栈指针,被形象地称为栈顶指针,堆栈的顶部是地址小的区域,压入堆栈的数据越多,ESP也就越来越小。 在32位平台上,ESP每次减少4字节。

esp:寄存器存放当前线程的栈顶指针
ebp:寄存器存放当前线程的栈底指针
eip:寄存器存放下一个CPU指令存放的内存地址,当CPU执行完当前的指令后,从EIP寄存器中读取下一条指令的内存地址,然后继续执行。

 

附: 汇编指令

GAS中每个操作都是有一个字符的后缀,表明操作数的大小。

C声明 GAS后缀 大小(字节)
char b 1
short w 2
(unsigned) int / long / char* l 4
float s 4
double l 8
long double t 10/12

注意:GAL使用后缀“l”同时表示4字节整数和8字节双精度浮点数,这不会产生歧义因为浮点数使用的是完全不同的指令和寄存器。

操作数格式:

格式 操作数值 名称 样例(GAS = C语言)
$Imm Imm 立即数寻址 $1 = 1
Ea R[Ea] 寄存器寻址 %eax = eax
Imm M[Imm] 绝对寻址 0×104 = *0×104
(Ea) M[R[Ea]] 间接寻址 (%eax)= *eax
Imm(Ea) M[Imm+R[Ea]] (基址+偏移量)寻址 4(%eax) = *(4+eax)
(Ea,Eb) M[R[Ea]+R[Eb]] 变址 (%eax,%ebx) = *(eax+ebx)
Imm(Ea,Eb) M[Imm+R[Ea]+R[Eb]] 寻址 9(%eax,%ebx)= *(9+eax+ebx)
(,Ea,s) M[R[Ea]*s] 伸缩化变址寻址 (,%eax,4)= *(eax*4)
Imm(,Ea,s) M[Imm+R[Ea]*s] 伸缩化变址寻址 0xfc(,%eax,4)= *(0xfc+eax*4)
(Ea,Eb,s) M(R[Ea]+R[Eb]*s) 伸缩化变址寻址 (%eax,%ebx,4) = *(eax+ebx*4)
Imm(Ea,Eb,s) M(Imm+R[Ea]+R[Eb]*s) 伸缩化变址寻址 8(%eax,%ebx,4) = *(8+eax+ebx*4)

注:M[xx]表示在存储器中xx地址的值,R[xx]表示寄存器xx的值,这种表示方法将寄存器、内存都看出一个大数组的形式。

数据传送指令:

指令 效果 描述
movl S,D D <– S 传双字
movw S,D D <– S 传字
movb S,D D <– S 传字节
movsbl S,D D <– 符号扩展S 符号位填充(字节->双字)
movzbl S,D D <– 零扩展S 零填充(字节->双字)
pushl S R[%esp] <– R[%esp] – 4;

M[R[%esp]] <– S

压栈
popl D D <– M[R[%esp]];

R[%esp] <– R[%esp] + 4;

出栈

注:均假设栈往低地址扩展。

算数和逻辑操作地址:

指令 效果 描述
leal S,D D = &S movl地版,S地址入D,D仅能是寄存器
incl D D++ 加1
decl D D– 减1
negl D D = -D 取负
notl D D = ~D 取反
addl S,D D = D + S
subl S,D D = D – S
imull S,D D = D*S
xorl S,D D = D ^ S 异或
orl S,D D = D | S
andl S,D D = D & S
sall k,D D = D << k 左移
shll k,D D = D << k 左移(同sall)
sarl k,D D = D >> k 算数右移
shrl k,D D = D >> k 逻辑右移

特殊算术操作:

指令 效果 描述
imull S R[%edx]:R[%eax] = S * R[%eax] 无符号64位乘
mull S R[%edx]:R[%eax] = S * R[%eax] 有符号64位乘
cltd S R[%edx]:R[%eax] = 符号位扩展R[%eax] 转换为4字节
idivl S R[%edx] = R[%edx]:R[%eax] % S;

R[%eax] = R[%edx]:R[%eax] / S;

有符号除法,保存余数和商
divl S R[%edx] = R[%edx]:R[%eax] % S;

R[%eax] = R[%edx]:R[%eax] / S;

无符号除法,保存余数和商

注:64位数通常存储为,高32位放在edx,低32位放在eax。

条件码:

条件码寄存器描述了最近的算数或逻辑操作的属性。

CF:进位标志,最高位产生了进位,可用于检查无符号数溢出。

OF:溢出标志,二进制补码溢出——正溢出或负溢出。

ZF:零标志,结果为0。

SF:符号标志,操作结果为负。

比较指令:

指令 基于 描述
cmpb S2,S1 S1 – S2 比较字节,差关系
testb S2,S1 S1 & S2 测试字节,与关系
cmpw S2,S1 S1 – S2 比较字,差关系
testw S2,S1 S1 & S2 测试字,与关系
cmpl S2,S1 S1 – S2 比较双字,差关系
testl S2,S1 S1 & S2 测试双字,与关系

访问条件码指令:

指令 同义名 效果 设置条件
sete D setz D = ZF 相等/零
setne D setnz D = ~ZF 不等/非零
sets D   D = SF 负数
setns D   D = ~SF 非负数
setg D setnle D = ~(SF ^OF) & ZF 大于(有符号>)
setge D setnl D = ~(SF ^OF) 小于等于(有符号>=)
setl D setnge D = SF ^ OF 小于(有符号<)
setle D setng D = (SF ^ OF) | ZF 小于等于(有符号<=)
seta D setnbe D = ~CF & ~ZF 超过(无符号>)
setae D setnb D = ~CF 超过或等于(无符号>=)
setb D setnae D = CF 低于(无符号<)
setbe D setna D = CF | ZF 低于或等于(无符号<=)

跳转指令:

指令 同义名 跳转条件 描述
jmp   Label   1 直接跳转
jmp   *Operand   1 间接跳转
je     Label jz ZF 等于/零
jne    Label jnz ~ZF 不等/非零
js     Label   SF 负数
jnz    Label   ~SF 非负数
jg     Label jnle ~(SF^OF) & ~ZF 大于(有符号>)
jge    Label jnl ~(SF ^ OF) 大于等于(有符号>=)
jl     Label jnge SF ^ OF 小于(有符号<)
jle     Label jng (SF ^ OF) | ZF 小于等于(有符号<=)
ja     Label jnbe ~CF & ~ZF 超过(无符号>)
jae    Label jnb ~CF 超过或等于(无符号>=)
jb     Label jnae CF 低于(无符号<)
jbe    Label jna CF | ZF 低于或等于(无符号<=)

转移控制指令:(函数调用):

指令 描述
call    Label 过程调用,返回地址入栈,跳转到调用过程起始处,返回地址是call后面那条指令的地址
call    *Operand
leave 为返回准备好栈,为ret准备好栈,主要是弹出函数内的栈使用及%ebp
        <div style="margin-top:8px;padding:6px 0;border-top:1px solid #3cf">
            <div style="text-align:center;margin:16px 0;padding:6px;border:0px dashed #999;font-family:arial;font-size:26px;font-weight:bold">
<a href="http://www.udpwork.com/item/7601.html#review_form" title="不喜欢" style="text-decoration:none">
    <img src="http://www.udpwork.com//images/thumb_down24.gif" alt="">
    <span style="color:#f33">0</span>
</a>
   
<a href="http://www.udpwork.com/item/7601.html#review_form" title="喜欢" style="text-decoration:none">
    <img src="http://www.udpwork.com//images/thumb_up24.gif" alt="">
    <span style="color:#3c3">0</span>
</a>

IT 牛人博客聚合网站(udpwork.com) 聚合 | 评论: 0 | 10000+ 本编程/Linux PDF/CHM 电子书下载