能力值:
( LV3,RANK:20 )
|
-
-
2 楼
我也碰到过这个问题,把我的HOOK堆栈搞得乱七八糟..... 观察了下,应该是为了给参数保留相应的堆栈。64位调用约定虽然优先使用寄存器传参,但还是会给参数留有相应的堆栈空间。比如我的GetStringVal函数有三个参数,根据调用约定使用了rcx rdx r8三个寄存器传参,但是在函数头还是将这三个寄存器的内容以从右到左的参数顺序保存到了堆栈中。 bool GetStringVal(HKEY hKey, LPCTSTR lpValue, LPCWSTR lpszContent) { 000000013F811100 mov qword ptr [rsp+18h],r8 000000013F811105 mov qword ptr [rsp+10h],rdx 000000013F81110A mov qword ptr [rsp+8],rcx 000000013F81110F push rdi 000000013F811110 sub rsp,80h 000000013F811117 mov rdi,rsp
|
能力值:
( LV2,RANK:10 )
|
-
-
3 楼
你那种情况都是3个参数 还好一点 那个flush 只有一个参数, 但是它写了两个位置的数据, 而且从源码来看是绝对看不出来的
|
能力值:
( LV2,RANK:10 )
|
-
-
4 楼
因为Debug版本. 会把参数写回栈 Release就没有 Release 不是参数的 就是保存非易失寄存器的... 这个基本常识吧...
|
能力值:
( LV2,RANK:10 )
|
-
-
5 楼
@syser, 你没认真看啊, 一个参数, 它要写回也是只写一个吧, 为什么写两个甚至三个? 其次, 我用的是 msvcr120.dll 后面不带d说明不是debug版本
|
能力值:
( LV9,RANK:140 )
|
-
-
6 楼
https://docs.microsoft.com/en-us/cpp/build/prolog-and-epilog?view=vs-2019这不懂是不是你想找的
|
能力值:
( LV4,RANK:50 )
|
-
-
7 楼
x64编译器默认fastcall, 当你使用&var1这种方式去访问参数地址的时候, 因为rcx是没有地址的所以编译器需要一个栈上的地址来存储数据,使逻辑不会出错,这也是fastcall为啥要有20h个(rcx, rdx, r8, r9)保留堆栈的原因, 当没有这种方式的访问时,一般是用来保存易失性的数据,节省栈的开销.
|
能力值:
( LV2,RANK:10 )
|
-
-
8 楼
frdGo
@syser, 你没认真看啊, 一个参数, 它要写回也是只写一个吧, 为什么写两个甚至三个?
其次, 我用的是 msvcr120.dll 后面不带d说明不是debug版本
...我说的还不够详细么.,. 相当于Push 非易失寄存器...
|
能力值:
( LV2,RANK:10 )
|
-
-
9 楼
谢谢各位, 搞明白了
|
|
|