{"id":1539,"date":"2021-04-21T12:31:07","date_gmt":"2021-04-21T17:31:07","guid":{"rendered":"https:\/\/badecho.com\/?p=1539"},"modified":"2021-06-06T21:36:21","modified_gmt":"2021-06-07T02:36:21","slug":"hacking-witcher-part-3","status":"publish","type":"post","link":"https:\/\/badecho.com\/index.php\/2021\/04\/21\/hacking-witcher-part-3\/","title":{"rendered":"Hacking the Witcher 3 &#8211; Part 3 (Predator System)"},"content":{"rendered":"\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-large\"><img loading=\"lazy\" width=\"366\" height=\"181\" src=\"https:\/\/badecho.com\/wp-content\/uploads\/2021\/04\/WitcherLogo-e1617575127960.png\" alt=\"\" class=\"wp-image-1444\" srcset=\"https:\/\/badecho.com\/wp-content\/uploads\/2021\/04\/WitcherLogo-e1617575127960.png 366w, https:\/\/badecho.com\/wp-content\/uploads\/2021\/04\/WitcherLogo-e1617575127960-300x148.png 300w\" sizes=\"(max-width: 366px) 100vw, 366px\" \/><\/figure><\/div>\n\n\n\n<p><em>The Witcher 3<\/em> is one of my favorite games to have come out in recent times. You won&#8217;t be surprised then to hear me say that my excitement towards the prospect of playing an <a href=\"https:\/\/badecho.com\/index.php\/what-is-omnified\/\" target=\"_blank\" rel=\"noreferrer noopener\">Omnified<\/a> version has increased with every new Omnified system I&#8217;ve implemented into it. Previously, we <a href=\"https:\/\/badecho.com\/index.php\/2021\/04\/12\/hacking-witcher-part-2\/\" target=\"_blank\" rel=\"noreferrer noopener\">implemented the damage overhauling Apocalypse system<\/a>; today, we implement the enemy speed boosting Predator system.<\/p>\n\n\n\n<p>Even though I should no longer be surprised when a new game throws unexpected things my way, <em>The Witcher 3<\/em> managed to throw me off balance (for just a few microseconds, mind you) with the manner in which creature locomotion is organized and managed. Despite this, implementation of the Predator system into the game was a relatively painless affair, and I will <em>try<\/em> to be brief.<\/p>\n\n\n\n<p>At the time of writing, a detailed design article providing an overview of the Predator system has not yet been published. I could swear I added an todo item to write such an article on my little todo app that resides on my phone, but I suppose it&#8217;s been buried by other things.<\/p>\n\n\n\n<p>For all those unversed in <em>Omnispeak<\/em>, the Predator system is a game-neutral overhaul to the game&#8217;s movement system that provides enemies with an intelligent speed boost based on their proximity to the player. Basically, it causes enemies to scare the crap out of me as they zoom in and end my existence.<\/p>\n\n\n\n<p>Although no design article exists yet, here&#8217;s a nice video for you:<\/p>\n\n\n\n<figure class=\"wp-block-embed aligncenter is-type-video is-provider-youtube wp-block-embed-youtube wp-embed-aspect-16-9 wp-has-aspect-ratio\"><div class=\"wp-block-embed__wrapper\">\n<iframe loading=\"lazy\" title=\"What is Predator?\" width=\"640\" height=\"360\" src=\"https:\/\/www.youtube.com\/embed\/W3bU01qxiBo?feature=oembed&amp;wmode=opaque\" frameborder=\"0\" allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture\" allowfullscreen><\/iframe>\n<\/div><figcaption>Listen to me prattle on about the Predator system. <\/figcaption><\/figure>\n\n\n\n<div id=\"ez-toc-container\" class=\"ez-toc-v2_0_11 counter-hierarchy counter-decimal ez-toc-grey\">\r\n<div class=\"ez-toc-title-container\">\r\n<p class=\"ez-toc-title\">Table of Contents<\/p>\r\n<span class=\"ez-toc-title-toggle\"><a class=\"ez-toc-pull-right ez-toc-btn ez-toc-btn-xs ez-toc-btn-default ez-toc-toggle\"><i class=\"ez-toc-glyphicon ez-toc-icon-toggle\"><\/i><\/a><\/span><\/div>\r\n<nav><ul class=\"ez-toc-list ez-toc-list-level-1\"><li class=\"ez-toc-page-1 ez-toc-heading-level-2\"><a class=\"ez-toc-link ez-toc-heading-1\" href=\"https:\/\/badecho.com\/index.php\/2021\/04\/21\/hacking-witcher-part-3\/#Where%E2%80%99s_the_Movement_Application_Code\" title=\"Where&#8217;s the Movement Application Code?\">Where&#8217;s the Movement Application Code?<\/a><ul class=\"ez-toc-list-level-3\"><li class=\"ez-toc-heading-level-3\"><a class=\"ez-toc-link ez-toc-heading-2\" href=\"https:\/\/badecho.com\/index.php\/2021\/04\/21\/hacking-witcher-part-3\/#Time_for_a_Dirty_Speed_Hack\" title=\"Time for a Dirty Speed Hack\">Time for a Dirty Speed Hack<\/a><\/li><li class=\"ez-toc-page-1 ez-toc-heading-level-3\"><a class=\"ez-toc-link ez-toc-heading-3\" href=\"https:\/\/badecho.com\/index.php\/2021\/04\/21\/hacking-witcher-part-3\/#Finding_the_Location_Update_Code\" title=\"Finding the Location Update Code\">Finding the Location Update Code<\/a><\/li><li class=\"ez-toc-page-1 ez-toc-heading-level-3\"><a class=\"ez-toc-link ez-toc-heading-4\" href=\"https:\/\/badecho.com\/index.php\/2021\/04\/21\/hacking-witcher-part-3\/#Finding_the_NPC_Location_Update_Code\" title=\"Finding the NPC Location Update Code\">Finding the NPC Location Update Code<\/a><\/li><\/ul><\/li><li class=\"ez-toc-page-1 ez-toc-heading-level-2\"><a class=\"ez-toc-link ez-toc-heading-5\" href=\"https:\/\/badecho.com\/index.php\/2021\/04\/21\/hacking-witcher-part-3\/#The_Predator_Initiation_Hook\" title=\"The Predator Initiation Hook\">The Predator Initiation Hook<\/a><ul class=\"ez-toc-list-level-3\"><li class=\"ez-toc-heading-level-3\"><a class=\"ez-toc-link ez-toc-heading-6\" href=\"https:\/\/badecho.com\/index.php\/2021\/04\/21\/hacking-witcher-part-3\/#Predator_Initiation_Hook_%E2%80%93_Template\" title=\"Predator Initiation Hook &#8211; Template\">Predator Initiation Hook &#8211; Template<\/a><\/li><li class=\"ez-toc-page-1 ez-toc-heading-level-3\"><a class=\"ez-toc-link ez-toc-heading-7\" href=\"https:\/\/badecho.com\/index.php\/2021\/04\/21\/hacking-witcher-part-3\/#Predator_Initiation_Hook_%E2%80%93_First_Steps\" title=\"Predator Initiation Hook &#8211; First Steps\">Predator Initiation Hook &#8211; First Steps<\/a><\/li><li class=\"ez-toc-page-1 ez-toc-heading-level-3\"><a class=\"ez-toc-link ez-toc-heading-8\" href=\"https:\/\/badecho.com\/index.php\/2021\/04\/21\/hacking-witcher-part-3\/#Predator_Initiation_Hook_%E2%80%93_Function_Execution\" title=\"Predator Initiation Hook &#8211; Function Execution\">Predator Initiation Hook &#8211; Function Execution<\/a><\/li><li class=\"ez-toc-page-1 ez-toc-heading-level-3\"><a class=\"ez-toc-link ez-toc-heading-9\" href=\"https:\/\/badecho.com\/index.php\/2021\/04\/21\/hacking-witcher-part-3\/#Predator_Initiation_Hook_%E2%80%93_Return_Value_Processing\" title=\"Predator Initiation Hook &#8211; Return Value Processing\">Predator Initiation Hook &#8211; Return Value Processing<\/a><\/li><li class=\"ez-toc-page-1 ez-toc-heading-level-3\"><a class=\"ez-toc-link ez-toc-heading-10\" href=\"https:\/\/badecho.com\/index.php\/2021\/04\/21\/hacking-witcher-part-3\/#Predator_Initiation_Hook_%E2%80%93_External_Parameters\" title=\"Predator Initiation Hook &#8211; External Parameters\">Predator Initiation Hook &#8211; External Parameters<\/a><\/li><\/ul><\/li><li class=\"ez-toc-page-1 ez-toc-heading-level-2\"><a class=\"ez-toc-link ez-toc-heading-11\" href=\"https:\/\/badecho.com\/index.php\/2021\/04\/21\/hacking-witcher-part-3\/#Is_The_Witcher_3_Zooming_Now\" title=\"Is The Witcher 3 Zooming Now?\">Is The Witcher 3 Zooming Now?<\/a><ul class=\"ez-toc-list-level-3\"><li class=\"ez-toc-heading-level-3\"><a class=\"ez-toc-link ez-toc-heading-12\" href=\"https:\/\/badecho.com\/index.php\/2021\/04\/21\/hacking-witcher-part-3\/#Predator_Initiation_Hook_%E2%80%93_Complete\" title=\"Predator Initiation Hook &#8211; Complete\">Predator Initiation Hook &#8211; Complete<\/a><\/li><\/ul><\/li><\/ul><\/nav><\/div>\r\n<h2><span class=\"ez-toc-section\" id=\"Where%E2%80%99s_the_Movement_Application_Code\"><\/span>Where&#8217;s the Movement Application Code?<span class=\"ez-toc-section-end\"><\/span><\/h2>\n\n\n\n<p>Well this is about the time in a <a href=\"https:\/\/badecho.com\/index.php\/tag\/predator\/\" target=\"_blank\" rel=\"noreferrer noopener\">Predator implementation article<\/a> where I take you through a very interesting and illuminating reverse engineering experience of finding the elusive <em>movement application<\/em> code for the game. This is the code that is responsible for calculating new coordinates for a creature in motion through the application of a set of movement offsets to the creature&#8217;s current coordinates.<\/p>\n\n\n\n<p>This is very distinct from the <em>location update<\/em> code, which is where new coordinate values are committed to the place in memory designated as the source-of-truth for a creature&#8217;s coordinates. Unlike the movement application code, this code is very easy to find. You would think that the movement application code would be nearby the location update code; however, because this is assembly we&#8217;re talking about, they can sometimes be literally hundreds of thousands of instructions apart.<\/p>\n\n\n\n<p>The movement application code is typically the ideal place to manipulate the movement of creatures as it allows all of the sometimes many systems dependent on changes to location coordinates to be updated properly. This increased stability is a result of our changes happening much further up the line in the processing of a creature&#8217;s locomotion than where it would occur if we simply tweaked the location update code.<\/p>\n\n\n\n<p>That&#8217;s all lovely, but it grieves me to inform you that finding it simply isn&#8217;t going to be happening with <em>The Witcher 3<\/em>. Are we screwed? No. While some games will definitely become completely unstable wrecks if we manipulate movement at the point of the location update code, not all games are so sensitive. I spent a bit of time looking for the movement application code, and was running into some really insane, very hard to navigate, clusters of physics-related instructions for every little movement update.<\/p>\n\n\n\n<p>So, I value my time, and decided to take a gamble and see if we could get by on a bit of a different approach&#8230;<\/p>\n\n\n\n<h3><span class=\"ez-toc-section\" id=\"Time_for_a_Dirty_Speed_Hack\"><\/span>Time for a Dirty Speed Hack<span class=\"ez-toc-section-end\"><\/span><\/h3>\n\n\n\n<p>When I affect changes to the movement of a creature at the place of a game&#8217;s location update code, I warmly refer to such a type of hook as a <em>dirty speed hack.<\/em> I call it such because, as I&#8217;ve gone on about in the previous paragraphs, depending on the composition of a game&#8217;s locational systems, implementing such a hack can cause the game to essentially blow up (creatures will phase out of existence, etc.).<\/p>\n\n\n\n<p>Typically, no movement offsets will be on hand when doing a dirty speed hack. That&#8217;s fine, as we can simply figure out what the offsets are by taking the difference between the new and current coordinates. And that&#8217;s what I decided to try out for <em>The Witcher 3<\/em>.<\/p>\n\n\n\n<p>And it worked out fine. No reason to bust our backs if we don&#8217;t need to.<\/p>\n\n\n\n<p>Time to get dirty!<\/p>\n\n\n\n<h3><span class=\"ez-toc-section\" id=\"Finding_the_Location_Update_Code\"><\/span>Finding the Location Update Code<span class=\"ez-toc-section-end\"><\/span><\/h3>\n\n\n\n<p>To do the dirty speed hack, we need to figure out where the location update code is. This is rather easy: we just need to see what code is writing to our character&#8217;s source-of-truth coordinate values. <\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-large\"><img loading=\"lazy\" width=\"819\" height=\"295\" src=\"https:\/\/badecho.com\/wp-content\/uploads\/2021\/04\/Pred1.png\" alt=\"Right click on our coordinates, and click here to see what is writing to them.\" class=\"wp-image-1544\" srcset=\"https:\/\/badecho.com\/wp-content\/uploads\/2021\/04\/Pred1.png 819w, https:\/\/badecho.com\/wp-content\/uploads\/2021\/04\/Pred1-300x108.png 300w, https:\/\/badecho.com\/wp-content\/uploads\/2021\/04\/Pred1-768x277.png 768w, https:\/\/badecho.com\/wp-content\/uploads\/2021\/04\/Pred1-480x173.png 480w\" sizes=\"(max-width: 819px) 100vw, 819px\" \/><figcaption>The location update code is essentially the code that write to this address.<\/figcaption><\/figure><\/div>\n\n\n\n<p>If we&#8217;re trying to hack a game that won&#8217;t make us pull out our hair, we shouldn&#8217;t see any instructions writing to our coordinates until we <em>actually move<\/em> our character in game. Luckily for us, that seems to be the case for <em>The Witcher 3<\/em>.<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-large\"><img loading=\"lazy\" width=\"799\" height=\"429\" src=\"https:\/\/badecho.com\/wp-content\/uploads\/2021\/04\/Pred2.png\" alt=\"One lonely location update code seems to be updating our coordinates.\" class=\"wp-image-1545\" srcset=\"https:\/\/badecho.com\/wp-content\/uploads\/2021\/04\/Pred2.png 799w, https:\/\/badecho.com\/wp-content\/uploads\/2021\/04\/Pred2-300x161.png 300w, https:\/\/badecho.com\/wp-content\/uploads\/2021\/04\/Pred2-768x412.png 768w, https:\/\/badecho.com\/wp-content\/uploads\/2021\/04\/Pred2-480x258.png 480w\" sizes=\"(max-width: 799px) 100vw, 799px\" \/><figcaption>One well behaving location update instruction: check.<\/figcaption><\/figure><\/div>\n\n\n\n<p>Alright. That was easy. Let&#8217;s get to implementing the <em>initiation point<\/em> for the Predator system then! Well, let&#8217;s hold up for <em>just<\/em> a second. Let&#8217;s make sure this is indeed the location code for not just the player, but for all creatures in the game. This is done by loading the disassembly window, right clicking on the instruction, and choosing <strong>Find out what addresses this instruction accesses<\/strong>.<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-large\"><img loading=\"lazy\" width=\"490\" height=\"470\" src=\"https:\/\/badecho.com\/wp-content\/uploads\/2021\/04\/Pred3.png\" alt=\"Shows only a single place in memory being accessed.\" class=\"wp-image-1546\" srcset=\"https:\/\/badecho.com\/wp-content\/uploads\/2021\/04\/Pred3.png 490w, https:\/\/badecho.com\/wp-content\/uploads\/2021\/04\/Pred3-300x288.png 300w, https:\/\/badecho.com\/wp-content\/uploads\/2021\/04\/Pred3-480x460.png 480w\" sizes=\"(max-width: 490px) 100vw, 490px\" \/><figcaption>Uh oh. Only our player&#8217;s coordinates are being updated by this.<\/figcaption><\/figure><\/div>\n\n\n\n<p>While doing this, I made sure I was nearby other NPCs that were also moving. And&#8230;unfortunately, as you can see, there&#8217;s only one place in memory that&#8217;s actually being updated by our location update code. This means that the code we&#8217;re looking at handles <em>exclusively<\/em> the player&#8217;s own movement.<\/p>\n\n\n\n<p>For the majority of games I&#8217;ve Omnified, both player and NPC coordinate updates were handled by the same piece of code. A separate system dedicated to managing the movement of just the player is something that I&#8217;ve found to actually be quite rare. Unfortunately, when a separate location update code exists for NPCs, it can be a bit troublesome to find.<\/p>\n\n\n\n<h3><span class=\"ez-toc-section\" id=\"Finding_the_NPC_Location_Update_Code\"><\/span>Finding the NPC Location Update Code<span class=\"ez-toc-section-end\"><\/span><\/h3>\n\n\n\n<p>How do we find the NPC location update code? The same way we found the player location update code: check for writes occurring to a particular set of coordinates. Of course, in this case the coordinates we need to look at are NPC coordinates, not our own. While we <a href=\"https:\/\/badecho.com\/index.php\/2021\/04\/04\/hacking-witcher-part-1\/\" target=\"_blank\" rel=\"noreferrer noopener\">wrote code previously that automatically hooks into our coordinates<\/a>, no such convenient feature exists for an NPC&#8217;s coordinates. So we&#8217;ll need to search for a pair.<\/p>\n\n\n\n<p>An easy way to do this is to look into various coordinate polling functions that are reading (not writing) from the coordinates. Often there will be system-wide functions that need to be kept apprised of the whereabouts of entities on the map, and these functions will be accessing the coordinates for every loaded creature in the game. This includes the player.<\/p>\n\n\n\n<p>So I started off the search for NPC coordinates by looking at what code was accessing my coordinates. Unfortunately, after looking through <em>all the accessing code<\/em>, I found that each and every one only was looking at the player&#8217;s coordinates. <\/p>\n\n\n\n<p>Wow. The movement systems for NPCs and the player are <em>very<\/em> separated. This is new for me &#8212; usually the movement mechanics for NPCs and players are at least somewhat related. Sadly this all means I was going to have to find the coordinates for an NPC the old fashioned way: by standing close to one and then doing an approximate value range search for the NPC&#8217;s location using my own as a reference.<\/p>\n\n\n\n<p>Unfortunately that yielded no results either. Argh. Eventually I found out it was due to even <em>greater<\/em> differences existing between the movement systems. If you recall, the value types for our player&#8217;s source-of-truth coordinates are <strong>doubles<\/strong>, which is definitely not the norm on its own. Well, as it turns out, NPCs actually use the more normal <strong>floats<\/strong> for the value types of their coordinates.<\/p>\n\n\n\n<p>I eventually figured this out simply by doing a new search for the NPC coordinate using <strong>float<\/strong> instead of <strong>double<\/strong>. I really need to stop doing value type-specific searches&#8230;<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-large\"><img loading=\"lazy\" width=\"865\" height=\"612\" src=\"https:\/\/badecho.com\/wp-content\/uploads\/2021\/04\/Pred4.png\" alt=\"Shows the NPC location update code.\" class=\"wp-image-1547\" srcset=\"https:\/\/badecho.com\/wp-content\/uploads\/2021\/04\/Pred4.png 865w, https:\/\/badecho.com\/wp-content\/uploads\/2021\/04\/Pred4-300x212.png 300w, https:\/\/badecho.com\/wp-content\/uploads\/2021\/04\/Pred4-768x543.png 768w, https:\/\/badecho.com\/wp-content\/uploads\/2021\/04\/Pred4-480x340.png 480w\" sizes=\"(max-width: 865px) 100vw, 865px\" \/><figcaption>Here it is. The (rather tiny) NPC location update code.<\/figcaption><\/figure><\/div>\n\n\n\n<h2><span class=\"ez-toc-section\" id=\"The_Predator_Initiation_Hook\"><\/span>The Predator Initiation Hook<span class=\"ez-toc-section-end\"><\/span><\/h2>\n\n\n\n<p>Well, at least we don&#8217;t have to deal with converting a bunch of doubles to floats, since NPCs don&#8217;t use doubles. We will still need to convert the player&#8217;s coordinates to floats, since the player&#8217;s location is a parameter to Predator technically.<\/p>\n\n\n\n<p>By the way, my theory as to why there is this strange separate movement system tacked onto the game that uses doubles is that perhaps it is the result of when CD Projekt had to hurriedly throw on an alternative movement system to the game (since the original movement\/controller system was very unpopular).<\/p>\n\n\n\n<p>Let&#8217;s whip up a starting template to work with.<\/p>\n\n\n\n<h3><span class=\"ez-toc-section\" id=\"Predator_Initiation_Hook_%E2%80%93_Template\"><\/span>Predator Initiation Hook &#8211; Template<span class=\"ez-toc-section-end\"><\/span><\/h3>\n\n\n<pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\n\/\/ Initiates the Predator system.\ndefine(omnifyPredatorHook,&quot;witcher3.exe&quot;+60E5C0)\n\nassert(omnifyPredatorHook,8B 02 89 41 70)\nalloc(initiatePredator,$1000,omnifyPredatorHook)\n\nregistersymbol(omnifyPredatorHook)\n\ninitiatePredator:\n\ninitiatePredatorOriginalCode:\n  mov eax,[rdx]\n  mov [rcx+70],eax\n  jmp initiatePredatorReturn\n\nomnifyPredatorHook:\n  jmp initiatePredator  \ninitiatePredatorReturn:\n<\/pre>\n\n\n<p>The updated coordinates, as a result of the NPC moving, are found in the <code>rdx<\/code> register; the current coordinates are found in <code>rcx<\/code>, starting at offset <code>0x70<\/code>. <\/p>\n\n\n\n<p>We&#8217;re going to need to calculate what the movement offsets are, and then pipe those values along with other required to the Predator system. When that returns, we&#8217;ll have updated movement offsets, which we&#8217;ll simply add back to the original coordinate values, storing the results in memory where the game expects the new coordinates (pointed to by the <code>rdx<\/code> register).<\/p>\n\n\n\n<p>I don&#8217;t need to read anything from the stack, so no need to worry about no stack math! Let&#8217;s go ahead then and start with prepping our data prior to Predator system execution.<\/p>\n\n\n\n<h3><span class=\"ez-toc-section\" id=\"Predator_Initiation_Hook_%E2%80%93_First_Steps\"><\/span>Predator Initiation Hook &#8211; First Steps<span class=\"ez-toc-section-end\"><\/span><\/h3>\n\n\n<pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\ninitiatePredator:\n  pushf \n  \/\/ An initialized playerLocation pointer is required prior to Predator execution.\n  push rax\n  mov rax,playerLocation\n  cmp rax,0\n  pop rax\n  je initiatePredatorOriginalCode\n  \/\/ We'll need a few SSE registers in order to do double-&gt;float conversion.\n  sub rsp,10\n  movdqu [rsp],xmm0\n  sub rsp,10\n  movdqu [rsp],xmm1\n  \/\/ We'll need to backup the registers used by Predator to store its return values.\n  push rax\n  push rbx\n  push rcx\n  \/\/ And another register to hold onto the current coordinates, since we'll need them to finish \n  \/\/ calculating what the new coordinates should be following Predator execution.\n  push rsi\n  mov rsi,rcx\n  mov rax,playerLocation\n  mov rbx,[rax]\n  \/\/ It is possible during a load screen following a death or area transition for a previously\n  \/\/ initialized player location pointer to no longer be pointing to a valid place in memory. \n  \/\/ We'll need to wait in that case. Eventually, our player hook will correct this.\n  lea rcx,[rbx+1B8]\n  call checkBadPointer\n  cmp ecx,0\n  jne initiatePredatorCleanup\n  \/\/ Our player's coordinates are stored as doubles. Predator expects them to be floats.\n  \/\/ A packed conversion to handle both X and Y at once...\n  cvtpd2ps xmm0,[rbx+1B8]\n  \/\/ And then a single conversion to take care of Z.\n  cvtsd2ss xmm1,[rbx+1C8]\n<\/pre>\n\n\n<p>Upon this code executing, the majority of the necessary preparations have been taken to ensure a successful Predator execution. We have our player&#8217;s coordinates converted, necessary data structures checked for, etc.<\/p>\n\n\n\n<p>Next, we&#8217;ll need to push required parameters to the stack and call <code>executePredator<\/code>.<\/p>\n\n\n\n<h3><span class=\"ez-toc-section\" id=\"Predator_Initiation_Hook_%E2%80%93_Function_Execution\"><\/span>Predator Initiation Hook &#8211; Function Execution<span class=\"ez-toc-section-end\"><\/span><\/h3>\n\n\n<pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\ninitiatePredatorExecute:\n  \/\/ With our player's coordinates converted, we'll push them as the first parameter to the stack.\n  \/\/ X and Y are pushed as quadwords first, followed by Z, as if they were pushed as two m64\n  \/\/ addresses.\n  sub rsp,8\n  movq [rsp],xmm0\n  sub rsp,8\n  movq [rsp],xmm1\n  \/\/ Next are the current coordinates for the target.\n  push [rsi+70]  \n  push [rsi+78]  \n  \/\/ An identity matrix is passed to represent the target's dimensional scales. True scaling is\n  \/\/ most likely not present in this game; the &quot;artificial&quot; size of the creature shouldn't \n  \/\/ impact movement.\n  movss xmm0,[identityValue]  \n  shufps xmm0,xmm0,0\n  sub rsp,10  \n  movdqu [rsp],xmm0  \n  \/\/ Time to produce the movement offsets, which act as the final parameter for the Predator system.\n  \/\/ Offsets are calculated as such: coordinatesNew - coordinatesCurrent = offsets.\n  movups xmm0,[rdx]\n  movups xmm1,[rsi+70]  \n  subps xmm0,xmm1\n  \/\/ The offsets are on xmm0, they are pushed to the stack as if we were pushing two m64 addresses \n  \/\/ in memory.\n  movhlps xmm1,xmm0\n  sub rsp,8\n  movq [rsp],xmm0\n  sub rsp,8\n  movq [rsp],xmm1\n  \/\/ All parameters have been provided. Execute the Predator!\n  call executePredator\n<\/pre>\n\n\n<p>All requirements are finally checked off; all parameters have been passed. Once all of the above code has finished executing, we will have updated movement offsets in <code>eax<\/code>, <code>ebx<\/code>, and <code>ecx<\/code>.<\/p>\n\n\n\n<p>All that remains is to reapply them to the current coordinates of the creature, and replace the target coordinates with these new values.<\/p>\n\n\n\n<h3><span class=\"ez-toc-section\" id=\"Predator_Initiation_Hook_%E2%80%93_Return_Value_Processing\"><\/span>Predator Initiation Hook &#8211; Return Value Processing<span class=\"ez-toc-section-end\"><\/span><\/h3>\n\n\n<pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\ninitializePredatorUpdateCoordinates:\n  \/\/ We make some room on the stack to help transfer updated offsets found in eax, ebx, and ecx\n  \/\/ to an SSE register.\n  sub rsp,10\n  mov [rsp],eax\n  mov [rsp+4],ebx\n  mov [rsp+8],ecx\n  movups xmm0,[rsp]\n  add rsp,10\n  \/\/ The updated offsets are then added to the current coordinates, giving us new target coordinates.\n  movups xmm1,[rsi+70]\n  addps xmm1,xmm0\n  movups [rdx],xmm1\ninitiatePredatorCleanup:\n  pop rsi\n  pop rcx\n  pop rbx\n  pop rax\n  movdqu xmm1,[rsp]\n  add rsp,10\n  movdqu xmm0,[rsp]\n  add rsp,10\ninitiatePredatorOriginalCode:\n  popf\n  mov eax,[rdx]\n  mov [rcx+70],eax\n  jmp initiatePredatorReturn\n\nomnifyPredatorHook:\n  jmp initiatePredator  \ninitiatePredatorReturn:\n<\/pre>\n\n\n<p>That&#8217;s all she wrote. Before we wrap up, however, we do need to tweak some external parameters.<\/p>\n\n\n\n<p>The vertical axis in <em>The Witcher 3<\/em> is the Z axis, not the typical Y axis. Also, coordinate values are somewhat non-granular, meaning that small changes to coordinate values cause bigger changes on screen than in some games.<\/p>\n\n\n\n<h3><span class=\"ez-toc-section\" id=\"Predator_Initiation_Hook_%E2%80%93_External_Parameters\"><\/span>Predator Initiation Hook &#8211; External Parameters<span class=\"ez-toc-section-end\"><\/span><\/h3>\n\n\n<pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\nthreatDistance:\n  dd (float)2.0\n\naggroDistance:\n  dd (float)6.0\n\nskipBoostY:\n  dd 0\n\nskipBoostZ:\n  dd 1\n<\/pre>\n\n\n<h2><span class=\"ez-toc-section\" id=\"Is_The_Witcher_3_Zooming_Now\"><\/span>Is The Witcher 3 Zooming Now?<span class=\"ez-toc-section-end\"><\/span><\/h2>\n\n\n\n<p>Zooming and booming. I&#8217;d create some nice GIFs for ya&#8217;ll showing the difference, but why settle for GIFs when you can just watch the live gameplay of an Omnified Witcher on my <a href=\"https:\/\/twitch.tv\/omni\" target=\"_blank\" rel=\"noreferrer noopener\">stream<\/a>?<\/p>\n\n\n\n<p>The speed boost to enemies is freaking excellent, increasing the excitement I have towards the otherwise sometimes rather droll gameplay offered by the game. It also seems to be quite stable! Speed boosts are smooth, no extreme jankiness has been detected. The &#8220;dirty speed hack&#8221; approach is a success! I can&#8217;t wait to play it! And for you to watch me play it! Check out the stream and say hello!<\/p>\n\n\n\n<p>Here&#8217;s the complete code; also, don&#8217;t forget that my hacking workspace is now <a href=\"https:\/\/badecho.com\/index.php\/2021\/04\/14\/omnified-hacks-published\/\" target=\"_blank\" rel=\"noreferrer noopener\">published live to my source code repository<\/a>. For the latest versions of my hacks, always be sure to check out what&#8217;s on the <a href=\"https:\/\/github.com\/BadEcho\/core\">Bad Echo technologies source control<\/a>!<\/p>\n\n\n\n<h3><span class=\"ez-toc-section\" id=\"Predator_Initiation_Hook_%E2%80%93_Complete\"><\/span>Predator Initiation Hook &#8211; Complete<span class=\"ez-toc-section-end\"><\/span><\/h3>\n\n\n<pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\n\/\/ Initiates the Predator system.\ndefine(omnifyPredatorHook,&quot;witcher3.exe&quot;+60E5C0)\n\nassert(omnifyPredatorHook,8B 02 89 41 70)\nalloc(initiatePredator,$1000,omnifyPredatorHook)\n\nregistersymbol(omnifyPredatorHook)\n\ninitiatePredator:\n  pushf \n  \/\/ An initialized playerLocation pointer is required prior to Predator execution.\n  push rax\n  mov rax,playerLocation\n  cmp rax,0\n  pop rax\n  je initiatePredatorOriginalCode\n  \/\/ We'll need a few SSE registers in order to do double-&gt;float conversion.\n  sub rsp,10\n  movdqu [rsp],xmm0\n  sub rsp,10\n  movdqu [rsp],xmm1\n  \/\/ We'll need to backup the registers used by Predator to store its return values.\n  push rax\n  push rbx\n  push rcx\n  \/\/ And another register to hold onto the current coordinates, since we'll need them to finish \n  \/\/ calculating what the new coordinates should be following Predator execution.\n  push rsi\n  mov rsi,rcx\n  mov rax,playerLocation\n  mov rbx,[rax]\n  \/\/ It is possible during a load screen following a death or area transition for a previously\n  \/\/ initialized player location pointer to no longer be pointing to a valid place in memory. \n  \/\/ We'll need to wait in that case. Eventually, our player hook will correct this.\n  lea rcx,[rbx+1B8]\n  call checkBadPointer\n  cmp ecx,0\n  jne initiatePredatorCleanup\n  \/\/ Our player's coordinates are stored as doubles. Predator expects them to be floats.\n  \/\/ A packed conversion to handle both X and Y at once...\n  cvtpd2ps xmm0,[rbx+1B8]\n  \/\/ And then a single conversion to take care of Z.\n  cvtsd2ss xmm1,[rbx+1C8]\ninitiatePredatorExecute:\n  \/\/ With our player's coordinates converted, we'll push them as the first parameter to the stack.\n  \/\/ X and Y are pushed as quadwords first, followed by Z, as if they were pushed as two m64\n  \/\/ addresses.\n  sub rsp,8\n  movq [rsp],xmm0\n  sub rsp,8\n  movq [rsp],xmm1\n  \/\/ Next are the current coordinates for the target.\n  push [rsi+70]  \n  push [rsi+78]  \n  \/\/ An identity matrix is passed to represent the target's dimensional scales. True scaling is\n  \/\/ most likely not present in this game; the &quot;artificial&quot; size of the creature shouldn't \n  \/\/ impact movement.\n  movss xmm0,[identityValue]  \n  shufps xmm0,xmm0,0\n  sub rsp,10  \n  movdqu [rsp],xmm0  \n  \/\/ Time to produce the movement offsets, which act as the final parameter for the Predator system.\n  \/\/ Offsets are calculated as such: coordinatesNew - coordinatesCurrent = offsets.\n  movups xmm0,[rdx]\n  movups xmm1,[rsi+70]  \n  subps xmm0,xmm1\n  \/\/ The offsets are on xmm0, they are pushed to the stack as if we were pushing two m64 addresses \n  \/\/ in memory.\n  movhlps xmm1,xmm0\n  sub rsp,8\n  movq [rsp],xmm0\n  sub rsp,8\n  movq [rsp],xmm1\n  \/\/ All parameters have been provided. Execute the Predator!\n  call executePredator\ninitializePredatorUpdateCoordinates:\n  \/\/ We make some room on the stack to help transfer updated offsets found in eax, ebx, and ecx\n  \/\/ to an SSE register.\n  sub rsp,10\n  mov [rsp],eax\n  mov [rsp+4],ebx\n  mov [rsp+8],ecx\n  movups xmm0,[rsp]\n  add rsp,10\n  \/\/ The updated offsets are then added to the current coordinates, giving us new target\n  \/\/ coordinates.\n  movups xmm1,[rsi+70]\n  addps xmm1,xmm0\n  movups [rdx],xmm1\ninitiatePredatorCleanup:\n  pop rsi\n  pop rcx\n  pop rbx\n  pop rax\n  movdqu xmm1,[rsp]\n  add rsp,10\n  movdqu xmm0,[rsp]\n  add rsp,10\ninitiatePredatorOriginalCode:\n  popf\n  mov eax,[rdx]\n  mov [rcx+70],eax\n  jmp initiatePredatorReturn\n\nomnifyPredatorHook:\n  jmp initiatePredator  \ninitiatePredatorReturn:\n\nthreatDistance:\n  dd (float)2.0\n\naggroDistance:\n  dd (float)6.0\n\nskipBoostY:\n  dd 0\n\nskipBoostZ:\n  dd 1\n<\/pre>\n\n\n<p>As always, thanks for reading, and thanks for your interest! Check out Omnified gameplay in action on my <a href=\"https:\/\/twitch.tv\/omni\" target=\"_blank\" rel=\"noreferrer noopener\">Twitch stream<\/a>, and drop by my <a href=\"https:\/\/discord.gg\/omni\" target=\"_blank\" rel=\"noreferrer noopener\">Discord server<\/a> to say hello, if you please.<\/p>\n\n\n\n<p>Otherwise, have a fabulous day my friends.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>The Witcher 3 is one of my favorite games to have come out in recent times. You won&#8217;t be surprised [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[9,60],"tags":[24,22,25],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v14.9 - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\r\n<title>Hacking the Witcher 3 - Part 3 (Predator System) - omni&#039;s hackpad<\/title>\r\n<meta name=\"description\" content=\"The Predator system, a game-neutral modification that intelligently boosts the speed of enemies, is implemented into The Witcher 3.\" \/>\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\/04\/21\/hacking-witcher-part-3\/\" \/>\r\n<meta property=\"og:locale\" content=\"en_US\" \/>\r\n<meta property=\"og:type\" content=\"article\" \/>\r\n<meta property=\"og:title\" content=\"Hacking the Witcher 3 - Part 3 (Predator System) - omni&#039;s hackpad\" \/>\r\n<meta property=\"og:description\" content=\"The Predator system, a game-neutral modification that intelligently boosts the speed of enemies, is implemented into The Witcher 3.\" \/>\r\n<meta property=\"og:url\" content=\"https:\/\/badecho.com\/index.php\/2021\/04\/21\/hacking-witcher-part-3\/\" \/>\r\n<meta property=\"og:site_name\" content=\"omni&#039;s hackpad\" \/>\r\n<meta property=\"article:published_time\" content=\"2021-04-21T17:31:07+00:00\" \/>\r\n<meta property=\"article:modified_time\" content=\"2021-06-07T02:36:21+00:00\" \/>\r\n<meta property=\"og:image\" content=\"https:\/\/badecho.com\/wp-content\/uploads\/2021\/04\/WitcherLogo-e1617575127960.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\/04\/21\/hacking-witcher-part-3\/#primaryimage\",\"inLanguage\":\"en-US\",\"url\":\"https:\/\/badecho.com\/wp-content\/uploads\/2021\/04\/WitcherLogo-e1617575127960.png\",\"width\":366,\"height\":181},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/badecho.com\/index.php\/2021\/04\/21\/hacking-witcher-part-3\/#webpage\",\"url\":\"https:\/\/badecho.com\/index.php\/2021\/04\/21\/hacking-witcher-part-3\/\",\"name\":\"Hacking the Witcher 3 - Part 3 (Predator System) - omni&#039;s hackpad\",\"isPartOf\":{\"@id\":\"https:\/\/badecho.com\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/badecho.com\/index.php\/2021\/04\/21\/hacking-witcher-part-3\/#primaryimage\"},\"datePublished\":\"2021-04-21T17:31:07+00:00\",\"dateModified\":\"2021-06-07T02:36:21+00:00\",\"description\":\"The Predator system, a game-neutral modification that intelligently boosts the speed of enemies, is implemented into The Witcher 3.\",\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/badecho.com\/index.php\/2021\/04\/21\/hacking-witcher-part-3\/\"]}]},{\"@type\":\"Article\",\"@id\":\"https:\/\/badecho.com\/index.php\/2021\/04\/21\/hacking-witcher-part-3\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/badecho.com\/index.php\/2021\/04\/21\/hacking-witcher-part-3\/#webpage\"},\"author\":{\"@id\":\"https:\/\/badecho.com\/#\/schema\/person\/3de67496328be7ae6e1f52faf582e9d2\"},\"headline\":\"Hacking the Witcher 3 &#8211; Part 3 (Predator System)\",\"datePublished\":\"2021-04-21T17:31:07+00:00\",\"dateModified\":\"2021-06-07T02:36:21+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/badecho.com\/index.php\/2021\/04\/21\/hacking-witcher-part-3\/#webpage\"},\"publisher\":{\"@id\":\"https:\/\/badecho.com\/#\/schema\/person\/3de67496328be7ae6e1f52faf582e9d2\"},\"image\":{\"@id\":\"https:\/\/badecho.com\/index.php\/2021\/04\/21\/hacking-witcher-part-3\/#primaryimage\"},\"keywords\":\"Hacking,Omnifying,Predator\",\"articleSection\":\"Games,Witcher 3\",\"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\/1539"}],"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=1539"}],"version-history":[{"count":6,"href":"https:\/\/badecho.com\/index.php\/wp-json\/wp\/v2\/posts\/1539\/revisions"}],"predecessor-version":[{"id":1551,"href":"https:\/\/badecho.com\/index.php\/wp-json\/wp\/v2\/posts\/1539\/revisions\/1551"}],"wp:attachment":[{"href":"https:\/\/badecho.com\/index.php\/wp-json\/wp\/v2\/media?parent=1539"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/badecho.com\/index.php\/wp-json\/wp\/v2\/categories?post=1539"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/badecho.com\/index.php\/wp-json\/wp\/v2\/tags?post=1539"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}