滴水逆向学习笔记2
编辑
1是反汇编窗口;2是寄存器窗口;3是数据窗口;4是堆栈窗口
反汇编窗口和寄存器窗口顺序都是从高到低,而数据窗口里是倒过来的(高位在后低位在前)
编辑
运用db命令可以看到,在数据窗口里的数据是从低到高,而在堆栈窗口里是从高到低(就好比我们在纸上写的数据)(d是查看数据的意思,b(byte)就是字节,整体就是以字节的形式查看数据;当然也可以dd(dword)命令查看)
通过mov指令:MOV WORD PTR DS:[0xAFE3D0],1234,我们向AFE3D0这个内存里转移数据1234,而因为我们转的是两个字节,所以要用到word。每个内存编号对应一个字节的位置,但是我们却可以通过一个内存编号修改两个字节(如果是dword可以改四个,后面还可以改一堆)
寻址公式:
1、 [立即数] 2、[reg] 3、[reg+立即数] 4、[reg+reg*(1,2,4,8)]
5、[reg+reg*(1、2、4、8)+立即数] (reg代表寄存器,可以是8个通用寄存器中的任意一个)
如果[]里面计算的值超过了八个F,那么只取八个F,超过的丢弃了
读取内存的值:mov eax,dword ptr ds:[0x13ffc3]
向内存中写入数据:mov dword ptr ds:[0x12ffc3],eax
获取内存编号:lea eax,dword ptr ds:[0x12ffc3]
lea eax,dword ptr ds:[esp+9]
编辑
lea指令是获取内存编号,但是为什么我们都知道了内存编号还要去将它写入eax里呢,其实有的内存里的值是不断变化的,那时候我们通过数据去获取地址编号是很麻烦的,这时候lea指令就可以取到变量地址了。
mov eax,dword ptr ds:[ecx]:以ecx里的内容为地址编号然后读取这个地址编号的值
lea eax,dword ptr ds:[ecx]:让以ecx为地址编号的地址编号写入给eax(其实就是把ecx的值给eax)
堆栈:
1、base(栈底)、top(栈顶)是两个32位的通用寄存器,里面存储的是内存单元编号(内存地址)
2、base里面存储了一个地址,记录的起始地址。
3、top里面也存储了一个地址,记录的是结束的地址。
4、存入数据的时候,top的值减某个值
5、释放数据的时候,top的值加某个值
6、如果要读取中间的某个数据的时候可以通过top 或者 base加上偏移的方式去读取
7、这种内存的读取方式叫做:堆栈。
堆栈的优点:临时存储大量的数据,便于查找。
栈底的值不变,变的是栈顶
编辑 存入一个值top就会变
向栈顶里存储数据有两种方式:①先将数据存储到下一块内存里,然后再改变栈顶指向的内存编号。②先改变寄存器指向的内存,然后再往寄存器里存储数据。
①:首先先定义两个寄存器为栈底和栈顶,ebx为栈底,edx位栈顶
然后让栈顶和栈底都指向同一块内存编辑
然后让下一块内存存储数据,之后改变栈顶指向的内存编号
编辑
编辑 图示:编辑
②:先用lea指令将edx(栈顶)指向的地址编号变为下一个,然后往栈顶储存值即可
编辑
编辑
读取存储的数据:
①通过栈底加偏移的方式;②通过栈顶加偏移的方式
首先找一个寄存器用于读取存储的数据,然后用mov指令:
①:mov esi dword ptr ds:[ebx**-**(1,2,4,8)]
②:mov esi dword ptr ds:[edx**+**(1,2,4,8)]
弹出数据:
再另找一个寄存器,用于弹出数据。栈顶往后退(可以先让栈顶指向的内存后退,然后弹出之前的值;也可以先弹出当前的值,然后再让栈顶往后退)
编辑 编辑
栈顶往后退一块内存
编辑
push指令:将数据存入寄存器并且寄存器指向的内存上移一块内存(存入数据的二合一指令)
push 0x12345678;push reg
操作系统默认EBP栈底,ESP为栈顶
pop指令:将数据弹出到另一个寄存器然后下移一块内存。(弹出数据的二合一指令)
如pop eax;pop ebx