常见的数据存放,内存结构、寄存器、标志位

堆内存(堆栈)

1、是自己向系统要的一片的空间
在这里插入图片描述

2、是反向增长,地址是从高位到地位,加到的时候是减小地位地址
3、堆栈数据是先进后出
在这里插入图片描述
4、如果函数有参数,参数由右往左逐个依次放入堆栈栈顶,通过PUSH指令
PUSH 指令可以拆解为下面两条指令
第一步 sub exp.0x4 //增加4个字节
mov [esp],数据
第二步 再call函数的时候
push 返回地址
jmp 到函数头部

5、进入函数后堆栈顶部会传入返回下一个执行代码的地址(32位程序和64位程序都是这样执行的)
6、x64 前四个参数分别是通过RCX,RDX,R8,R9四个寄存器传递的,后面的参数还是通过堆栈来传递,只不过不是用PUSH指令。

7、puSH 入栈,pop出栈,本质是在移动esp指针。

8、通过其他方式入栈,就可以不用PUSH入栈,不用POP出栈 , 起到隐藏函数入口的假象,增加别人逆向的难度·,代码如下两个图片:
在这里插入图片描述
在这里插入图片描述

虽然64位程序使用寄存器来传递参数,但是函数的调用者依旧会为被调用的函数开辟对应的参数栈空间,只不过没有使用PUSH指令,而是用MOV来转移

结论:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述


6、栈空间数据清理:
在这里插入图片描述
__fastcall

栈空间

1、局部变量存放在栈空间
在这里插入图片描述
2、当进行一个函数调用,刚进入函数的时候堆栈的栈顶存放的是返回值
在这里插入图片描述

数据段

编译器把字符默认存放在数据段,但是不一定放在数据段,也可以放在栈空间
idata 代码区
rdata 常量区
data 数据区–全局变量放在数据段

数据存放地址在: 0x7A7B30
在这里插入图片描述
存放在rdata常量区,常量区开始地址是007A7000
在这里插入图片描述

数据存放地址=常量区起始地址+便宜
0x7A7B30=007A7000+B30
在这里插入图片描述

寄存器ECX

1、在循环计数的时候一般是用ECX来保存循环计数器

寄存器EDI和ESI

1、在操作内存的时候,edi和esi一般是用来保存内存的起始地址

在这里插入图片描述

寄存器ESP

1、始终指向的是当前运行环境的栈顶

在这里插入图片描述
函数传一个参数,每次扩充了4个字节
ESP=0xDEF900 981248
ESP=0xDEF8FC ‭981244‬
ESP=0xDEF8F8 ‭ 981240‬

2、在这里插入图片描述

寄存器EBP (栈帧)

1、EBP代表局部变量的分界线,
栈帧EBP往高处走,也就是减少的方向放的是局部变量
在这里插入图片描述

栈帧EBP往底处走,也就是增加的方向放的是参数返回值
在这里插入图片描述2、x64位程序没有栈帧

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

标志寄存器(运算语句会修改标志寄存器,MOV语句不会修改标志寄存器)

在这里插入图片描述
在这里插入图片描述

C 最高位进位标志位

(最高位由数据的宽度决定 )
在这里插入图片描述

A 辅助中间位进位标志位

下图箭头位置 是 32位 的个情况
在这里插入图片描述

P标志位 ,奇偶标志位,只看最低有效字节,也就是最后一个字节的二进制1的个数,奇数个置0,偶数个置1

Z 零标志位

在这里插入图片描述

S标志位

最高位存的什么值S位里面存的就是什么值
在这里插入图片描述

溢出

在这里插入图片描述

D 方向标志位 决定了ESI EDI是增加还是减少

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/lygl35/article/details/112388043
今日推荐