{"id":1670,"date":"2021-06-07T21:11:30","date_gmt":"2021-06-08T02:11:30","guid":{"rendered":"https:\/\/badecho.com\/?p=1670"},"modified":"2023-03-15T01:01:49","modified_gmt":"2023-03-15T06:01:49","slug":"how-to-push-sse-registers","status":"publish","type":"post","link":"https:\/\/badecho.com\/index.php\/2021\/06\/07\/how-to-push-sse-registers\/","title":{"rendered":"How To \u201cPush\u201d SSE (XMM) Registers"},"content":{"rendered":"\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-large\"><img loading=\"lazy\" width=\"891\" height=\"543\" src=\"https:\/\/badecho.com\/wp-content\/uploads\/2021\/06\/PushSSE.png\" alt=\"Let's figure out how to backup these gigantic 128-bit registers...\" class=\"wp-image-1675\" srcset=\"https:\/\/badecho.com\/wp-content\/uploads\/2021\/06\/PushSSE.png 891w, https:\/\/badecho.com\/wp-content\/uploads\/2021\/06\/PushSSE-300x183.png 300w, https:\/\/badecho.com\/wp-content\/uploads\/2021\/06\/PushSSE-768x468.png 768w, https:\/\/badecho.com\/wp-content\/uploads\/2021\/06\/PushSSE-480x293.png 480w\" sizes=\"(max-width: 891px) 100vw, 891px\" \/><\/figure><\/div>\n\n\n\n<p>Maintaining the integrity and state of the CPU and stack is always vital whenever we&#8217;re discussing <a href=\"https:\/\/badecho.com\/index.php\/what-is-omnified\/\" target=\"_blank\" rel=\"noreferrer noopener\">Omnified<\/a> processes, as these usually contain code concerned with the seamless overhaul of one gameplay system or another. Because this code gets injected into a running process&#8217;s memory, we need to make sure that anything we&#8217;re using for our own calculations is restored to how it was when we&#8217;re done doing our thing (save for the desired <em>outcome<\/em> or <em>affected part<\/em> of the injection, of course).<\/p>\n\n\n\n<p>This, seemingly neurotic, need to preserve CPU data integrity is, without a doubt, exacerbated <em>a<\/em> <em>bit <\/em>when we&#8217;re talking about injecting foreign code into a process (as is my wont when playing games on my <a href=\"https:\/\/twitch.tv\/omni\" target=\"_blank\" rel=\"noreferrer noopener\">streams<\/a>), since it is critical that everything is <em>identical<\/em> as to how it was prior to our code executing (lest a crash doth follow). But, code injection aside, when writing assembly, you&#8217;ll often need to temporarily store data in order to make use of whatever register said data was occupying.<\/p>\n\n\n\n<p>Most of the time, this is a simple affair. Well, it is when we&#8217;re talking about general-purpose registers. Backing up the &#8220;globs&#8221; of data found in 128-bit (or wider) <a href=\"https:\/\/en.wikipedia.org\/wiki\/Streaming_SIMD_Extensions\" target=\"_blank\" rel=\"noreferrer noopener\">SSE registers<\/a> however? Not as clear cut. Let me show you how I do it.<\/p>\n\n\n\n<p>But first, an overview!<\/p>\n\n\n\n<h2>Push it! Pop It!<\/h2>\n\n\n\n<p>As you may very well know, it&#8217;s easy to temporarily store data in a general-purpose register and then later restore it. We simply use the <code>push<\/code> instruction to <em>push <\/em>the data to the stack, and then later use the <code>pop<\/code> instruction to essentially <em>pop<\/em> said data off the stack.<\/p>\n\n\n\n<h3>Pushing and Popping Some Stuff<\/h3>\n\n\n<pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\n\/\/ We need to use rax, rbx, rcx. Back them up!\npush rax\npush rbx\npush rcx\n\/\/ rax, rbx, and rcx are essentially backed up.\nmov rax,[someAddress]\nmov rbx,[rax+20]\nmov rcx,[rbx+10]\nmovss xmm0,[rcx+4]\n\/\/ Do whatever we need with these registers...\npop rcx\npop rbx\npop rax\n\/\/ rax, rbx, and rcx should now have their original values.\n<\/pre>\n\n\n<p>Pretty simple. It happens all the time.<\/p>\n\n\n\n<p>Very often, however, we might want to back up some data from a register that isn&#8217;t so <em>general-purpose<\/em>, such as an SSE register. Perhaps we wanted to back up the <code>xmm0<\/code> used in the previous example before writing to it &#8212; something you&#8217;d always want to do if injecting code that makes use of SSE registers into a running process (unless you love those crashes baby).<\/p>\n\n\n\n<h3>Illegal Pushing and Popping!<\/h3>\n\n\n<pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\n\/\/ Same as before...\npush xmm0 \/\/ &lt;-- This will fail!\nmovss xmm0,[rcx+4]\n\/\/ Do whatever we need with xmm0...\npop xmm0 \/\/ &lt;-- This too! Fail!\n<\/pre>\n\n\n<p>That isn&#8217;t going to assemble buddy! You lose!<\/p>\n\n\n\n<p>I would be lying if I said I never tried the above before. Hey, I bet you may have too! The <code>push<\/code> instruction is just so convenient! Why can&#8217;t it work for <em>everything<\/em>! Sadly, attempting to back up a beefy SSE register in this fashion can only <em>fail horribly<\/em>.<\/p>\n\n\n\n<p><a href=\"https:\/\/www.felixcloutier.com\/x86\/push\" target=\"_blank\" rel=\"noreferrer noopener\">Looking at some documentation<\/a>, it&#8217;s clear, more or less, that we&#8217;re limited in what we can &#8220;push&#8221; using this instruction: general-purpose registers, memory locations, and an even more limited range of immediate values.<\/p>\n\n\n\n<h2>So How Can I Push an SSE Register?<\/h2>\n\n\n\n<p>If we understand the mechanics behind how the <code>push<\/code> and <code>pop<\/code> instructions actually work, then it becomes rather clear as to how we can back up the data in SSE registers such as <code>xmm0<\/code>, <code>xmm1<\/code>, or what have you. <\/p>\n\n\n\n<p>When we <code>push<\/code> a register, we&#8217;re taking what&#8217;s on that register and placing it on the stack, the place in memory that essentially acts as temporary storage and which is being pointed to by the <code>rsp<\/code> register. <\/p>\n\n\n\n<p>How does it place the register&#8217;s value on top of the stack? Typically, by subtracting a number of bytes from the stack pointer&#8217;s address, causing <code>rsp<\/code> to essentially point to the next piece of memory that&#8217;s not currently being occupied by data that may still be needed (and if it is needed, then someone screwed up bad). <\/p>\n\n\n\n<p>Business is then concluded by writing the value to where <code>rsp<\/code> now points to. When we <code>pop<\/code> the value back onto the register, we&#8217;re essentially doing what&#8217;s described above, but in reverse.<\/p>\n\n\n\n<p>So, if we want to back up one of our SSE registers, we need only do exactly what the <code>push<\/code> instruction itself does, bearing in mind the difference in the amount of memory required to store an SSE register&#8217;s value (sixteen bytes vs a general-purpose register&#8217;s eight bytes).<\/p>\n\n\n\n<h3>Backing Up an SSE Register<\/h3>\n\n\n<pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\n\/\/ We need 16 bytes of space to write to on the stack.\nsub rsp,0x10 \/\/ 0x10 = 16 of course.\n\/\/ And then we just dump our SSE register onto the stack.\nmovdqu [rsp],xmm0\n\/\/ Do what needs to be done with xmm0...\nmovdqu xmm0,[rsp]\nadd rsp,0x10\n\/\/ xmm0 now has its original value, and the stack pointer is pointing to\n\/\/ where it was. All is well.\n<\/pre>\n\n\n<p>You see me do this all the time in my <a href=\"https:\/\/github.com\/BadEcho\/omnified-hacks\" target=\"_blank\" rel=\"noreferrer noopener\">Omnified hacking framework<\/a>. <\/p>\n\n\n\n<p>Now: with this knowledge go forth and conquer the world, with the surety attainable only when one is confident in the integrity of those many SSE registers that helped them along in their journey.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Maintaining the integrity and state of the CPU and stack is always vital whenever we&#8217;re discussing Omnified processes, as these [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[10,16],"tags":[61],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v14.9 - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\r\n<title>How To \u201cPush\u201d SSE (XMM) Registers - omni&#039;s hackpad<\/title>\r\n<meta name=\"description\" content=\"Backing up general purpose registers is easy using &quot;push&quot;. This doesn&#039;t work with XMM registers, however. Read on to see what I do instead.\" \/>\r\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\r\n<link rel=\"canonical\" href=\"https:\/\/badecho.com\/index.php\/2021\/06\/07\/how-to-push-sse-registers\/\" \/>\r\n<meta property=\"og:locale\" content=\"en_US\" \/>\r\n<meta property=\"og:type\" content=\"article\" \/>\r\n<meta property=\"og:title\" content=\"How To \u201cPush\u201d SSE (XMM) Registers - omni&#039;s hackpad\" \/>\r\n<meta property=\"og:description\" content=\"Backing up general purpose registers is easy using &quot;push&quot;. This doesn&#039;t work with XMM registers, however. Read on to see what I do instead.\" \/>\r\n<meta property=\"og:url\" content=\"https:\/\/badecho.com\/index.php\/2021\/06\/07\/how-to-push-sse-registers\/\" \/>\r\n<meta property=\"og:site_name\" content=\"omni&#039;s hackpad\" \/>\r\n<meta property=\"article:published_time\" content=\"2021-06-08T02:11:30+00:00\" \/>\r\n<meta property=\"article:modified_time\" content=\"2023-03-15T06:01:49+00:00\" \/>\r\n<meta property=\"og:image\" content=\"https:\/\/badecho.com\/wp-content\/uploads\/2021\/06\/PushSSE.png\" \/>\r\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\r\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"WebSite\",\"@id\":\"https:\/\/badecho.com\/#website\",\"url\":\"https:\/\/badecho.com\/\",\"name\":\"omni&#039;s hackpad\",\"description\":\"Game Code Disassembly. Omnified Modification. Madness.\",\"publisher\":{\"@id\":\"https:\/\/badecho.com\/#\/schema\/person\/3de67496328be7ae6e1f52faf582e9d2\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":\"https:\/\/badecho.com\/?s={search_term_string}\",\"query-input\":\"required name=search_term_string\"}],\"inLanguage\":\"en-US\"},{\"@type\":\"ImageObject\",\"@id\":\"https:\/\/badecho.com\/index.php\/2021\/06\/07\/how-to-push-sse-registers\/#primaryimage\",\"inLanguage\":\"en-US\",\"url\":\"https:\/\/badecho.com\/wp-content\/uploads\/2021\/06\/PushSSE.png\",\"width\":891,\"height\":543,\"caption\":\"Let's figure out how to backup these gigantic 128-bit registers...\"},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/badecho.com\/index.php\/2021\/06\/07\/how-to-push-sse-registers\/#webpage\",\"url\":\"https:\/\/badecho.com\/index.php\/2021\/06\/07\/how-to-push-sse-registers\/\",\"name\":\"How To \\u201cPush\\u201d SSE (XMM) Registers - omni&#039;s hackpad\",\"isPartOf\":{\"@id\":\"https:\/\/badecho.com\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/badecho.com\/index.php\/2021\/06\/07\/how-to-push-sse-registers\/#primaryimage\"},\"datePublished\":\"2021-06-08T02:11:30+00:00\",\"dateModified\":\"2023-03-15T06:01:49+00:00\",\"description\":\"Backing up general purpose registers is easy using \\\"push\\\". This doesn't work with XMM registers, however. Read on to see what I do instead.\",\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/badecho.com\/index.php\/2021\/06\/07\/how-to-push-sse-registers\/\"]}]},{\"@type\":\"Article\",\"@id\":\"https:\/\/badecho.com\/index.php\/2021\/06\/07\/how-to-push-sse-registers\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/badecho.com\/index.php\/2021\/06\/07\/how-to-push-sse-registers\/#webpage\"},\"author\":{\"@id\":\"https:\/\/badecho.com\/#\/schema\/person\/3de67496328be7ae6e1f52faf582e9d2\"},\"headline\":\"How To \\u201cPush\\u201d SSE (XMM) Registers\",\"datePublished\":\"2021-06-08T02:11:30+00:00\",\"dateModified\":\"2023-03-15T06:01:49+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/badecho.com\/index.php\/2021\/06\/07\/how-to-push-sse-registers\/#webpage\"},\"publisher\":{\"@id\":\"https:\/\/badecho.com\/#\/schema\/person\/3de67496328be7ae6e1f52faf582e9d2\"},\"image\":{\"@id\":\"https:\/\/badecho.com\/index.php\/2021\/06\/07\/how-to-push-sse-registers\/#primaryimage\"},\"keywords\":\"assembly\",\"articleSection\":\"General Dev,Omnified Design\",\"inLanguage\":\"en-US\"},{\"@type\":[\"Person\",\"Organization\"],\"@id\":\"https:\/\/badecho.com\/#\/schema\/person\/3de67496328be7ae6e1f52faf582e9d2\",\"name\":\"Matt Weber\",\"image\":{\"@type\":\"ImageObject\",\"@id\":\"https:\/\/badecho.com\/#personlogo\",\"inLanguage\":\"en-US\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/7e345ac2708b3a41c7bd70a4a0440d41?s=96&d=mm&r=g\",\"caption\":\"Matt Weber\"},\"logo\":{\"@id\":\"https:\/\/badecho.com\/#personlogo\"}}]}<\/script>\r\n<!-- \/ Yoast SEO plugin. -->","_links":{"self":[{"href":"https:\/\/badecho.com\/index.php\/wp-json\/wp\/v2\/posts\/1670"}],"collection":[{"href":"https:\/\/badecho.com\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/badecho.com\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/badecho.com\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/badecho.com\/index.php\/wp-json\/wp\/v2\/comments?post=1670"}],"version-history":[{"count":10,"href":"https:\/\/badecho.com\/index.php\/wp-json\/wp\/v2\/posts\/1670\/revisions"}],"predecessor-version":[{"id":2676,"href":"https:\/\/badecho.com\/index.php\/wp-json\/wp\/v2\/posts\/1670\/revisions\/2676"}],"wp:attachment":[{"href":"https:\/\/badecho.com\/index.php\/wp-json\/wp\/v2\/media?parent=1670"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/badecho.com\/index.php\/wp-json\/wp\/v2\/categories?post=1670"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/badecho.com\/index.php\/wp-json\/wp\/v2\/tags?post=1670"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}