【安全学习之路】Day44
距离上次《逆向工程核心原理》隔得远了点,并不是没继续看下去,一直没什么时间写博客,读得一些章节没什么营养的我就跳过了,现在从x64处理器开始。
x64处理器
64位
64位系统当中的内存地址变为64位,使用64位大小的指针。如寄存器等基本单位也变成了64位的。
内存
虚拟内存的实际大小实际上是16TB,内核和用户空间各占8个TB。
其实2^64=16EB,这个是理论上支持16EB的内存寻址,但是如果调的这么大的话,会浪费大量资源在内存管理上面。
通用寄存器
x64以R开头,x86以E开头
CALL/JMP
相同在于都是使用FF15XXXXXXXX,不过在x64里面解析方法不同。
也可以看到本来在x86里面是4个字节,在x64当中变成了8个字节。然后x86FF15后面的8个字节应该是绝对地址VA。这样的话指令长度就增长了,为了防止增加指令长度,在后面仍然跟着4个字节的地址,只不过变成了相对地址,也就是RVA。可以看到有个FF15FA3F0000,也就是这个相对地址就是3FFA,再加上本来的字节数(6个字节)
有个值得琢磨的事情,就是这个6是啥东西。
问了问GPT,他告诉我这个加上6其实是因为,这个3FFA也就是相对地址,实际上从CALL的下一条指令开始到目标地址的偏移,所以是现在这个CALL的实际地址加上6,再加上RVA。
同时
- 如果RelativeOffset是有符号整数,则目标地址 = CurrentAddress + 5 + RelativeOffset(5是CALL指令的长度)。
- 如果RelativeOffset是无符号整数,则目标地址 = CurrentAddress + 6 + RelativeOffset(6是CALL指令的长度)。
看到目标地址的内容了,75CE1E12,所以上面那个CALL被解析为CALL 00000000‘75CE1E12
函数调用约定
64位当中把32位的多种传递规则统一称为一种变形的fastcall。这个fastcall中可以把最多函数的四个参数存储到寄存器当中传递
也就是第一个永远存在RCX或XMM0当中。
如果超过了4个,则与栈并用,也就是第五个参数存入栈来传递,此外函数返回时传递参数过程中所用的栈由调用者清理。需要注意的是虽然多的参数会用栈来传递,但是前面这四个参数还是会预留空间。
栈 栈帧
通过MOV指令操作寄存器与预定的栈来传递,使用VC++的程序代码中几乎看不到push/pop指令。
本文作者:Corax0o0
本文链接:https://www.cnblogs.com/Corax0o0/p/17756118.html
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步