{"id":39,"date":"2006-08-14T07:00:24","date_gmt":"2006-08-14T12:00:24","guid":{"rendered":"http:\/\/www.nynaeve.net\/?p=39"},"modified":"2019-12-13T17:41:39","modified_gmt":"2019-12-13T22:41:39","slug":"win32-calling-conventions-concepts","status":"publish","type":"post","link":"http:\/\/www.nynaeve.net\/?p=39","title":{"rendered":"Win32 calling conventions: Concepts"},"content":{"rendered":"<p>If you have done debugging work on Win32 (x86)\u00c2\u00a0for any length of time, you probably know that there are many different calling conventions.\u00c2\u00a0 While I have already covered <a href=\"http:\/\/www.nynaeve.net\/?p=10\">the Win64 (X64) calling convention<\/a>, I haven&#8217;t yet gone into details about how to work with the various calling conventions present on x86 Windows.\u00c2\u00a0 This miniseries is going to go into some detail relating to how the calling conventions work from the perspective of debugging and reverse engineering.<\/p>\n<p>There are three major calling conventions in use in modern Win32 (on x86, anyway): __stdcall, __cdecl, and __fastcall.\u00c2\u00a0 All three have different characteristics that are important if you are debugging or reverse engineering something, and it is important to be able to recognize and work with functions written against all three calling conventions &#8211; even if you don&#8217;t have access to symbols.\u00c2\u00a0 To start off, it&#8217;s probably best to get a feel for what all of the different calling conventions do, how they work, and soforth.<\/p>\n<p>Most of the calling conventions have some things in common.\u00c2\u00a0 All of the calling conventions have the same set of\u00c2\u00a0<em>volatile <\/em>registers, which are not required to remain the same across a call site: eax, ecx, and edx.\u00c2\u00a0 Additionally, all three calling conventions use eax for 32-bit return values, and eax:edx for 64-bit return values (high 32 bits in edx).\u00c2\u00a0 For large return values (e.g. functions that return a structure, and not a pointer to a structure), a hidden argument is passed to a hidden local variable in the caller&#8217;s stack frame that represents the large return value, and the return value is filled in\u00c2\u00a0using the hidden argument\u00c2\u00a0(that is, large return values are actually implemented as a\u00c2\u00a0hidden\u00c2\u00a0pointer parameter).<\/p>\n<ul>\n<li>__cdecl is the default calling convention for the Microsoft C\/C++ compiler.\u00c2\u00a0 This is an entirely stack based calling convention for parameter passing; the caller cleans the arguments off of the stack when the call returns.<\/li>\n<li>__stdcall has the same semantics as __cdecl, except that the callee (target function) cleans the arguments off of the stack instead of the caller.<\/li>\n<li>__fastcall passes the first two register-sized arguments in ecx and edx, with the remaining arguments passed on the stack like __stdcall.\u00c2\u00a0 If any stack based arguments were present, the callee cleans them off of the stack.<\/li>\n<\/ul>\n<p>Additionally, there is a fourth calling convention implemented by CL, known as __thiscall, which is like __stdcall except that there is a hidden pointer argument representing a class object (&#8220;this&#8221; in C++) that is passed in\u00c2\u00a0ecx.\u00c2\u00a0 As you might imagine, __thiscall is used for non-static\u00c2\u00a0class member function calls (by default).\u00c2\u00a0 If you explicitly override the calling convention of member functions, then &#8220;this&#8221; becomes a hidden (first) argument that is passed according to the conventions of the overriding calling convention.\u00c2\u00a0 In general, __thiscall is not really used in the Windows API.<\/p>\n<p>That&#8217;s a general overview of the basic concepts behind all of the major Win32 x86 calling convention.\u00c2\u00a0 In some upcoming posts, I&#8217;ll explore the implications behind the different attributes of these calling conventions, their usage cases, and how they apply to you when you are debugging or reverse engineering something.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>If you have done debugging work on Win32 (x86)\u00c2\u00a0for any length of time, you probably know that there are many different calling conventions.\u00c2\u00a0 While I have already covered the Win64 (X64) calling convention, I haven&#8217;t yet gone into details about how to work with the various calling conventions present on x86 Windows.\u00c2\u00a0 This miniseries is [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":[],"categories":[2,8,5],"tags":[],"_links":{"self":[{"href":"http:\/\/www.nynaeve.net\/index.php?rest_route=\/wp\/v2\/posts\/39"}],"collection":[{"href":"http:\/\/www.nynaeve.net\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/www.nynaeve.net\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/www.nynaeve.net\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"http:\/\/www.nynaeve.net\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=39"}],"version-history":[{"count":1,"href":"http:\/\/www.nynaeve.net\/index.php?rest_route=\/wp\/v2\/posts\/39\/revisions"}],"predecessor-version":[{"id":653,"href":"http:\/\/www.nynaeve.net\/index.php?rest_route=\/wp\/v2\/posts\/39\/revisions\/653"}],"wp:attachment":[{"href":"http:\/\/www.nynaeve.net\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=39"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/www.nynaeve.net\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=39"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/www.nynaeve.net\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=39"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}