vc在x64体系的一般传参数方式
来源:互联网 发布:网络名词 编辑:程序博客网 时间:2024/05/29 21:30
http://www.cnblogs.com/bbqzsl/p/5082929.html
前篇分析过在objc中函数调用传参的一般方式,本篇分析vc在x64体系中的一般传参方式。手头上因为没有64位的vc编译器,只好用windbg看ms自身的函数是怎么样调用的。
首先看两个再熟悉不过的api,memset和CreateHeap。函数原型和使用像呼吸一样了,也不用多解释一看就明白。
调用memset(rcx, rdx, r8):
00000000`76df5f63 488b842480000000 mov rax,qword ptr [rsp+80h]00000000`76df5f6b 4889842498000000 mov qword ptr [rsp+98h],rax00000000`76df5f73 458bc5 mov r8d,r13d00000000`76df5f76 33d2 xor edx,edx00000000`76df5f78 488bc8 mov rcx,rax00000000`76df5f7b e810cfffff call ntdll!memset (00000000`76df2e90)
</pre><p style="line-height: 1.5; margin: 10px auto;">调用RtlCreateHeap(rcx, rdx, r8, r9, [rsp+20h], [rsp+28h]):</p><div class="cnblogs_code" style="border: 1px solid rgb(204, 204, 204); padding: 5px; overflow: auto; margin: 5px 0px; color: rgb(0, 0, 0); font-family: 'Courier New' !important; font-size: 12px !important; background-color: rgb(245, 245, 245);"><div class="cnblogs_code_toolbar" style="margin-top: 5px;"><span class="cnblogs_code_copy" style="padding-right: 5px; line-height: 1.5 !important;"><a target=_blank title="复制代码" style="color: rgb(26, 139, 200); border: none !important;"><img src="http://common.cnblogs.com/images/copycode.gif" alt="复制代码" style="border: none !important;" /></a></span></div><pre style="margin-top: 0px; margin-bottom: 0px; white-space: pre-wrap; word-wrap: break-word; font-family: 'Courier New' !important;"><span style="color: rgb(128, 0, 128); line-height: 1.5 !important;">00000000</span>`76de47a6 4c8b842498000000 <span style="color: rgb(0, 0, 255); line-height: 1.5 !important;">mov</span><span style="line-height: 1.5 !important;"> r8,qword ptr [rsp+98h]</span><span style="color: rgb(128, 0, 128); line-height: 1.5 !important;">00000000</span>`76de47ae 488d05ab200000 <span style="color: rgb(0, 0, 255); line-height: 1.5 !important;">lea</span> rax,[ntdll!RtlReleaseMemoryStream (<span style="color: rgb(128, 0, 128); line-height: 1.5 !important;">00000000</span><span style="line-height: 1.5 !important;">`76de6860)]</span><span style="color: rgb(128, 0, 128); line-height: 1.5 !important;">00000000</span>`76de47b5 448d4e01 <span style="color: rgb(0, 0, 255); line-height: 1.5 !important;">lea</span> r9d,[rsi+<span style="color: rgb(128, 0, 128); line-height: 1.5 !important;">1</span><span style="line-height: 1.5 !important;">]</span><span style="color: rgb(128, 0, 128); line-height: 1.5 !important;">00000000</span>`76de47b9 488bd7 <span style="color: rgb(0, 0, 255); line-height: 1.5 !important;">mov</span><span style="line-height: 1.5 !important;"> rdx,rdi</span><span style="color: rgb(128, 0, 128); line-height: 1.5 !important;">00000000</span>`76de47bc <span style="color: rgb(128, 0, 128); line-height: 1.5 !important;">4889842488010000</span> <span style="color: rgb(0, 0, 255); line-height: 1.5 !important;">mov</span><span style="line-height: 1.5 !important;"> qword ptr [rsp+188h],rax</span><span style="color: rgb(128, 0, 128); line-height: 1.5 !important;">00000000</span>`76de47c4 488d842440010000 <span style="color: rgb(0, 0, 255); line-height: 1.5 !important;">lea</span><span style="line-height: 1.5 !important;"> rax,[rsp+140h]</span><span style="color: rgb(128, 0, 128); line-height: 1.5 !important;">00000000</span>`76de47cc b900800000 <span style="color: rgb(0, 0, 255); line-height: 1.5 !important;">mov</span><span style="line-height: 1.5 !important;"> ecx,8000h</span><span style="color: rgb(128, 0, 128); line-height: 1.5 !important;">00000000</span>`76de47d1 <span style="color: rgb(128, 0, 128); line-height: 1.5 !important;">4889442428</span> <span style="color: rgb(0, 0, 255); line-height: 1.5 !important;">mov</span><span style="line-height: 1.5 !important;"> qword ptr [rsp+28h],rax</span><span style="color: rgb(128, 0, 128); line-height: 1.5 !important;">00000000</span>`76de47d6 c784244001000060000000 <span style="color: rgb(0, 0, 255); line-height: 1.5 !important;">mov</span><span style="line-height: 1.5 !important;"> dword ptr [rsp+140h],60h</span><span style="color: rgb(128, 0, 128); line-height: 1.5 !important;">00000000</span>`76de47e1 48c784247801000000100000 <span style="color: rgb(0, 0, 255); line-height: 1.5 !important;">mov</span><span style="line-height: 1.5 !important;"> qword ptr [rsp+178h],1000h</span><span style="color: rgb(128, 0, 128); line-height: 1.5 !important;">00000000</span>`76de47ed <span style="color: rgb(128, 0, 128); line-height: 1.5 !important;">4889742420</span> <span style="color: rgb(0, 0, 255); line-height: 1.5 !important;">mov</span><span style="line-height: 1.5 !important;"> qword ptr [rsp+20h],rsi</span><span style="color: rgb(128, 0, 128); line-height: 1.5 !important;">00000000</span>`76de47f2 4c89842480010000 <span style="color: rgb(0, 0, 255); line-height: 1.5 !important;">mov</span><span style="line-height: 1.5 !important;"> qword ptr [rsp+180h],r8</span><span style="color: rgb(128, 0, 128); line-height: 1.5 !important;">00000000</span>`76de47fa e8a18cffff <span style="color: rgb(0, 0, 255); line-height: 1.5 !important;">call</span> ntdll!RtlCreateHeap (<span style="color: rgb(128, 0, 128); line-height: 1.5 !important;">00000000</span>`76ddd4a0)
再来分析一下有多个参数的api函数。
00000000`74a4b6f9 4c8d5c2450 lea r11,[rsp+50h]00000000`74a4b6fe 488d442470 lea rax,[rsp+70h]00000000`74a4b703 4c895c2448 mov qword ptr [rsp+48h],r1100000000`74a4b708 4889442440 mov qword ptr [rsp+40h],rax00000000`74a4b70d 488d842480000000 lea rax,[rsp+80h]00000000`74a4b715 4889442438 mov qword ptr [rsp+38h],rax00000000`74a4b71a 488d842490000000 lea rax,[rsp+90h]00000000`74a4b722 4c8d8c24b0000000 lea r9,[rsp+0B0h]00000000`74a4b72a 4889442430 mov qword ptr [rsp+30h],rax00000000`74a4b72f 488d8424a0000000 lea rax,[rsp+0A0h]00000000`74a4b737 4c8d8424c0000000 lea r8,[rsp+0C0h]00000000`74a4b73f 488d542460 lea rdx,[rsp+60h]00000000`74a4b744 488d8c2400010000 lea rcx,[rsp+100h]00000000`74a4b74c 4c89742428 mov qword ptr [rsp+28h],r1400000000`74a4b751 4889442420 mov qword ptr [rsp+20h],rax00000000`74a4b756 ff153c5affff call qword ptr [wow64+0x1198 (00000000`74a41198)]
wow64经一些处理后跳转到ntdll!RtlCreateProcessParameters
ntdll!RtlCreateProcessParameters:00000000`76dede20 4883ec68 sub rsp,68h00000000`76dede24 488b8424b8000000 mov rax,qword ptr [rsp+0B8h]00000000`76dede2c c744245000000000 mov dword ptr [rsp+50h],000000000`76dede34 4889442448 mov qword ptr [rsp+48h],rax00000000`76dede39 488b8424b0000000 mov rax,qword ptr [rsp+0B0h]00000000`76dede41 4889442440 mov qword ptr [rsp+40h],rax00000000`76dede46 488b8424a8000000 mov rax,qword ptr [rsp+0A8h]00000000`76dede4e 4889442438 mov qword ptr [rsp+38h],rax00000000`76dede53 488b8424a0000000 mov rax,qword ptr [rsp+0A0h]00000000`76dede5b 4889442430 mov qword ptr [rsp+30h],rax00000000`76dede60 488b842498000000 mov rax,qword ptr [rsp+98h]00000000`76dede68 4889442428 mov qword ptr [rsp+28h],rax00000000`76dede6d 488b842490000000 mov rax,qword ptr [rsp+90h]00000000`76dede75 4889442420 mov qword ptr [rsp+20h],rax00000000`76dede7a e851b4feff call ntdll!RtlCreateProcessParametersEx (00000000`76dd92d0)
RtlCreateProcessParameters函数将上一层传入的参数原封不动,并在后面增加一个参数0,然用后调RtlCreateProcessParametersEx。
RtlCreateProcessParameters函数一共有10个参数,RtlCreateProcessParametersEx函数一共有11个参数。
前4个参数使用的寄存器rcx,rdx,r8和r9, 后6个参数用了入栈方式,虽然前4个参数作用了寄存器,但仍然在堆栈中空出了4个qword的位置。第五个参数起是由rsp+20h处开始放入(mov)堆栈(,入栈push是由最后一个开始)。
线程在调用RtlCreateProcessParameters前,准备调用栈过程中并没有往rsp~rsp+18h处写东西,而从寄存器的调配可以看出用了寄存器rcx,rdx,r8,r9。
线程在调用RtlCreateProcessParametersEx前,将上一层调用栈后面6个参数搬运了过来,并增加了一个参数放到rsp+50h处。
通过windbg浏览几处api函数调用,可以看出vc的__stdcall调用的传参方式。前4个参数使用rcx,rdx,r8,r9,之后的参数使用堆栈并且在调用栈中空出4个qword位置,第5个参数不是rsp-8而是rsp-28h在函数入口处时。如果参数数量不超过4个,不使用堆栈。反汇编代码也说明vc在传参数时没有使用到rdi,rsi。
下一篇分析gcc在x64的传参方式。
上一篇分析objc在x64的传参方式。
- vc在x64体系的一般传参数方式
- vc在x64体系的一般传参数方式
- gcc在x64体系中如何传递参数
- iOS objc在simulator-x86_64体系下一般传参方式
- gcc在x64体系中如何传递参数,linux,mac,iOS适用
- 深入理解 x86/x64 的中断体系
- 深入理解 x86/x64 的中断体系
- TCPServer 的一般参数
- TCPServer 的一般参数
- VS2008在WIN7 X64上不能编译VC++程序的解决方法
- vc++ 2015 RC x64在windows2008安装时提示没有权限的解决
- 匠心 x64 结构体系下的内存寻址
- 查询方式的一般使用
- 上下文的一般绘制方式
- X64对浮点参数的处理
- 在VC中创建和使用动态链接库(DLL)的一般方法
- 在vc中调用一般的.exe只需要一个函数
- rest API 里面GET方式不能传参数,但是可以在路径里的传参数。
- C++输出的精度控制
- Python---xml
- OpenGL基于帧缓存FBO的离屏渲染
- [Leetcode]Serialize and Deserialize Binary Tree
- 技术人如何才能不焦虑
- vc在x64体系的一般传参数方式
- objective-C基础----字典,集合
- iOS——TabelView
- C++本质:类的赋值运算符=的重载,以及深拷贝和浅拷贝
- 关于C中的内存分配问题
- 横向滑动加载更多的控件的实现
- 数字漩涡形输出
- 虚函数
- Oracle EBS 交叉币种(2)-应收交叉币种