0x01.寄存器与内存
寄存器与内存的区别:
1、寄存器位于CPU内部,执行速度快,但比较贵。
2、内存速度相对较慢,但成本较低,所以可以做的很大。
3、寄存器和内存没有本质区别,都是用于存储数据的容器,都是定宽的。
4、寄存器常用的有8个:EAX、ECX、EDX、EBX、ESP、EBP、ESI、EDI。
5、计算机中的几个常用计量单位:BYTE WORD DWORD
BYTE 字节 = 8(BIT)
WORD 字 = 16(BIT)
DWORD 双字 = 32(BIT)
1KB = 1024 BYTE
1MB = 1024 KB
1GB = 1024 MB
内存的数量特别庞大,无法每个内存单元都起一个名字,所以用编号来代替,我们称计算机CPU是32位或者64位,主要指的就是内存编号的宽度,而不是寄存器的宽度。
有很多书上说之所以叫32位计算机是因为寄存器的宽度是32位,是不准确的,因为还有很多寄存器是大于32位的。
32位计算机的编号最大是32位,也就是32个1 换成16进制为FFFFFFFF,也就是说,32位计算机内存寻址的最大范围是**FFFFFFFF+1 **
内存的单位是字节,那内存中能存储的信息最多为:FFFFFFFF+1 字节 即4G,这也是为什么我们在一个XP的系统上面如果物理内存超过4G是没有意义的原因。
0x02.内存编号
1、内存
2、从指定内存中写入/读取数据
mov dword ptr ds:[0x0012FF34],0x12345678
mov eax,dword ptr ds:[0x0012FF34]
dword :要读/写多少 此时是4字节 byte == 1字节 word == 2字节
ptr: Point 代表后面是一个指针 (指针的意思就是里面存的不是普通的值,而是个地址),也可以理解成强转,就是说把
ds:段寄存器 先不用管 记住就行
0x0012FF34:内存编号,必须是32位的 前面0可以省略
注意:地址编号不要随便写,因为内存是有保护的,并不是所有的内存都可以直接读写(需要特别处理)
建议地址编号写成esp的值
例子:随便使用c语言编写一个hello word程序,然后拉入od
我们以读取为例子,把栈的值读取到edx寄存器中
然后单步执行过去,会发现751D6359
这一串数据赋值给了edx中,把edx的值覆盖掉了
0x03.内存读写的五个公式
寻址公式一:[立即数]
读取内存的值:
mov eax,dword ptr ds:[0x13FFC4] //把地址0x13FFC4上的值给eax寄存器
mov eax,dword ptr ds:[0x13FFC8] //把地址0x13FFC8上的值给eax寄存器,在原来的地址上加4个字节,就是下一段数据的地址
内存中一般都是以dword为单位,也就是4个字节。4 * 8bit = 32,通过上面知道二进制的32位1其实就是8个F,其实宽度就是8位。
MOV DWORD PTR DS:[0x13FFC4],eax
MOV DWORD PTR DS:[0x13FFC8],ebx
获取内存编号:
LEA EAX,DWORD PTR DS:[0X13FFC4]
LEA EAX,DWORD PTR DS:[ESP+8]
lea exp1,exp2
汇编中lea就是把 exp2 的地址给 exp1
寻址公式二:[reg] reg代表寄存器 可以是8个通用寄存器中的任意一个
读取内存的值:
MOV ECX,0x13FFD0
MOV EAX,DWORD PTR DS:[ECX]
向内存中写入数据:
MOV EDX,0x13FFD8
MOV DWORD PTR DS:[EDX],0x87654321
获取内存编号:
LEA EAX,DWORD PTR DS:[EDX]
MOV EAX,DWORD PTR DS:[EDX]
寻址公式三:[reg+立即数]
读取内存的值:
MOV ECX,0x13FFD0
MOV EAX,DWORD PTR DS:[ECX+4]
向内存中写入数据:
MOV EDX,0x13FFD8
MOV DWORD PTR DS:[EDX+0xC],0x87654321
获取内存编号:
LEA EAX,DWORD PTR DS:[EDX+4]
MOV EAX,DWORD PTR DS:[EDX+4]
寻址公式四:[reg+reg*{1,2,4,8}]4
读取内存的值:
MOV EAX,13FFC4
MOV ECX,2
MOV EDX,DWORD PTR DS:[EAX+ECX*4]
向内存中写入数据:
MOV EAX,13FFC4
MOV ECX,2
MOV DWORD PTR DS:[EAX+ECX*4],87654321
获取内存编号:
LEA EAX,DWORD PTR DS:[EAX+ECX*4]
寻址公式五:[reg+reg*{1,2,4,8}+立即数]
读取内存的值:
MOV EAX,13FFC4
MOV ECX,2
MOV EDX,DWORD PTR DS:[EAX+ECX*4+4]
向内存中写入数据:
MOV EAX,13FFC4
MOV ECX,2
MOV DWORD PTR DS:[EAX+ECX*4+4],87654321
获取内存编号:
LEA EAX,DWORD PTR DS:[EAX+ECX*4+2]