首页
社区
课程
招聘
[求助]64位fastcall 栈回溯怎么实现
发表于: 2018-11-21 02:06 7731

[求助]64位fastcall 栈回溯怎么实现

2018-11-21 02:06
7731
[求助]64位fastcall栈回溯怎么实现
stdcall可以通过ebp但fastcall没有用辅助栈怎么回溯????????????????????????????/

[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

收藏
免费 0
支持
分享
最新回复 (8)
雪    币: 2473
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
reg
2018-11-21 04:39
0
雪    币: 1283
活跃值: (46)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
3
64位寄存器多,寄存器回溯试试
2018-11-21 08:07
0
雪    币: 914
活跃值: (2473)
能力值: ( LV5,RANK:68 )
在线值:
发帖
回帖
粉丝
4
RtlWalkFrameChain
2018-11-21 08:38
0
雪    币: 12848
活跃值: (9147)
能力值: ( LV9,RANK:280 )
在线值:
发帖
回帖
粉丝
5
RtlWalkFrameChain+1
原理自行阅读wrk源码
2018-11-21 08:50
0
雪    币: 689
活跃值: (422)
能力值: ( LV11,RANK:190 )
在线值:
发帖
回帖
粉丝
6
如果是编译器产生的代码,实际上在正式进入函数之前,是会有把寄存器保存到栈中的操作的(你可以F11跟一下汇编代码就明白了),栈帧从形式上来讲和32位没有区别。(我说的是VS,其他的编译器没有研究)
2018-11-21 09:43
0
雪    币: 1036
活跃值: (1311)
能力值: ( LV3,RANK:35 )
在线值:
发帖
回帖
粉丝
7
[rsp]啊 ,这不是一样的么。 64位 vs 编译的  fastcall只是把前4个参数用寄存器传了。 rcx rdx r8 r9
2018-11-21 11:35
0
雪    币: 688
活跃值: (204)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
8
fastcall其实就是thiscall+stdcall的变种版.....差别就是前4个参数分别会使用rcx,rdx,r8,r9,xmm0,xmm1,xmm2,xmm3中传递,当然如果是this调用的话,rcx就是保存对象自身的指针啦.
网上流传的文档描述大部分都是错误的,因为这个是微软专用的调用约定,所以看说明还是得看微软原版的说明:
https://msdn.microsoft.com/zh-cn/library/ms235286.aspx
网上的文档说明,往往都忽略了浮点数参数的传递和参数位置对齐的问题.
比如参数1和2是整数,参数3和4是浮点数,参数5是整数,那么他们对应的位置是rcx,rdx,xmm2,xmm3,[rsp+(5*0x8)](进入函数体后,rbp会被压入栈顶),坑就坑在这个栈上面,编译器优化的话,为了保存快速调用,被压入寄存器的参数,依然会霸占栈内存的,而某些情况下,也可能出现不霸占栈内存的情况,这个纯属看编译器优化了.
类似的调用约定,和clrcall差不多.clrcall更坑,分为32位clrcall和64位clrcall,而64位clrcall又很像fastcall....
之前我做JIT的时候,就被这些东西搞得晕坨坨的.
最后于 2018-11-26 22:45 被flarejune编辑 ,原因:
2018-11-26 22:36
0
雪    币: 181
活跃值: (131)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
9

面试遇到了这个问题,看了下wrk中的RtlWalkFrameChain 64位版本。基本原理就是,x64函数开头会有分配栈空间的指令,结尾有回收栈空间的指令,RtlWalkFrameChain 内部调用 RtlVirtualUnwind 去搜索栈空间相关的指令,可以得到当前函数的栈大小,然后通过 rsp+当前函数栈大小回推返回地址和父函数的rsp,最终完成栈回溯。具体细节参考 RtlWalkFrameChain 。

最后于 2020-9-18 11:01 被Private丶编辑 ,原因:
2020-9-18 11:00
1
游客
登录 | 注册 方可回帖
返回
//