【reverse】逆向2 寄存器与内存
1、通用寄存器
主要用途其实没必要记下来,因为只是CPU建议你这么做。
寄存器需要按照顺序被下来
32位就是可以存32个0或1
所以存储范围就是0~0xFFFFFFFF
16位通用寄存器,名称就是32位通用寄存器少了一个E
8位寄存器AL CL DL BL AH CH DH BH 其中的L表示LOW,低位,H表示HIGH,高位
寄存器的样子长这样,AX本身就在EAX里面,CX本身就在ECX里面.....
AH是AX中的高位部分,AL是AX中低位部分.....
2、使用OD
认识界面
使用F3选择exe文件打开
可以看到四个窗口,左上方是反汇编窗口、右上方是寄存器窗口、左下方是数据窗口、右下方是堆栈窗口
mov指令
mov指令
我们选择当前指向的地址,也就是EIP指向的地址
双击,设计汇编指令
mov eax,0x1
这条指令就是让eax寄存器的值变为0x1
汇编完之后使用F8步入执行
这句指令的意思就是让0x1这个移动到eax中
未执行前
执行后
可以看到eax的值改变了
我们还可以是用
mov ecx,eax
这句话的意思就是将eax的值复制到ecx中
使用mov指令的前提是,后面两个容器(数据宽度)的大小需要一样
mov指令形式
注意:源操作数和目标操作数不能同时为内存单元
add指令
add就是加法
sub指令
sub就是减法
and指令
and指令就是 与 的运算
or指令
or指令就是 或 的运算
xor指令
xor指令就是 异或 的运算
not指令
not指令就是 非 的运算
3、认识内存
寄存器和内存的区别
-
寄存器位于CPU内部,执行速度快,但很贵
-
内存速度相对慢,但成本比较低,所以可以做的很大
-
寄存器和内存没有本质区,都是用于存储数据的容器,都是定宽的
-
寄存器常用的有8个
-
计算机中常用的计量单位:byte word dword
BYTE 字节 = 8bit
WORD 字 = 16bit
DWORD 双字 = 32bit
-
内存的数量特别庞大,无法每个内存单元都起名字,所以用编号来代替
计算机内存的每一个字节都会有一个编号(内存编号的单位是字节)
0x00000000
0x00000001
0x00000002
32位计算机的最大寻址编号是第32位,也就是32个1,换成16进制就是FFFFFFFF,也就是说,32位计算机内存寻址的最大范围是00000000~FFFFFFFF。内存的单位是字节,那么内存中存储的信息最多为FFFFFFFF+1字节,换算过来就是4G,这也是为什么我们在一个xp系统上面
-
32位的计算机寻址最大是4G吗?
不是,我们可以通过加内存条等方式
win2003是32位操作系统,但是看到这个内存通过扩展的方式到达了8G
内存格式
由图我们可以看到,内存单位为8位,就是1字节,所以我们操作内存的时候,最少就是操作8位。不管是读8位还是写8位,最少最少操作8位。这也是为什么最小的寄存器AH、AL之类的,最少操作8位。
从指定内存中写入/读取数据
为了区分立即数和内存编号,汇编通过打中括号的方式来区分
mov dword pte ds:[0x12345678],0x12345678
prt:表示后面是一个指针
ds:段寄存器
内存编号必须是32位的
注意:地址编号不要随便写,因为内存是有保护的,并不是所有的内存都可以之间诶读写(需要特别处理)
建议:地址编号写成esp的值
任何程序打开都有一个4G的空间(虚拟内存),即使有4G空间,但是有很多空间是不可以访问的
写内存
我们使用mov dword prt ds:[0x19FF74],0x12345678
将内存地址为0x19FF74写入了0x12345678这个数据,我们发现内存是4字节一起显示的,所以可以存储dword(4字节)的数据在里面。但是我们需要知道,内存的单位是1字节(8bit)
读内存
内存读取一定需要容器,我们用eax寄存器做容器
使用汇编指令
mov eax,dword ptr ds:[0x19FF78]
这样就可以将0x19FF78内存地址的值读到eax寄存器中
4、复习总结
-
32位 16位 8位通用寄存器
32 16 8 EAX AX AL ECX CX CL EDX DX DL EBX BX BL ESP SP AH EBP BP CH ESI SI DH EDI DI BH -
寄存器的结构:EAX-AX-AH-AL的关系
EAX(共32位)是AX(后16位)的拓展,AH是AX的高位(前8位),AL是AX的低位(后8位)
-
为什么8位寄存器只能放2个16进制数
因为16进制转成二进制就是4位 1111 = F
所以8位寄存器只能放2个16进制数 AH可以存放00~FF
-
内存单元:字节
每个字节都有编号,称为内存地址
内存地址在堆栈窗口是4字节一组
00000000
00000004
-
在反汇编和寄存器窗口,从左向右降位,但是在数据窗口是反过来的
我们使用db指令,以字节的形式来显示内存地址0x0019ff88开始的数据
发现数据窗口和堆栈窗口的数据是反着的
堆栈窗口中的HEX数据就是16进制数据,两位16进制就是8位也就是一字节,并且一字节就是一个内存地址
堆栈窗口中内存地址0x0019FF88~内存地址0x0019FF8B的数据为003E0000(高位向低位)
数据窗口中内存地址0x0019FF88~内存地址0x0019FF8B的数据是从右向左读的(高位向低位)
那么我们根据数据窗口来看,内存地址0x0019FF88上的数据就是00(左边的00),内存地址0x0019FF89上的数据就是30