{"id":914,"date":"2020-12-27T23:59:33","date_gmt":"2020-12-28T04:59:33","guid":{"rendered":"https:\/\/badecho.com\/?p=914"},"modified":"2021-04-23T08:16:18","modified_gmt":"2021-04-23T13:16:18","slug":"hacking-ac-valhalla-part-4","status":"publish","type":"post","link":"https:\/\/badecho.com\/index.php\/2020\/12\/27\/hacking-ac-valhalla-part-4\/","title":{"rendered":"Hacking Assassin&#8217;s Creed: Valhalla &#8211; Part 4 (Abomnification System)"},"content":{"rendered":"\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\/2020\/12\/27\/hacking-ac-valhalla-part-4\/#Time_To_Add_Some_LSDFueled_Smooth_Morphing_Monsters\" title=\"Time To Add Some LSD-Fueled Smooth Morphing Monsters\">Time To Add Some LSD-Fueled Smooth Morphing Monsters<\/a><\/li><li class=\"ez-toc-page-1 ez-toc-heading-level-2\"><a class=\"ez-toc-link ez-toc-heading-2\" href=\"https:\/\/badecho.com\/index.php\/2020\/12\/27\/hacking-ac-valhalla-part-4\/#Is_Easy_Scaling_Support_BuiltIn\" title=\"Is Easy Scaling Support Built-In?\">Is Easy Scaling Support Built-In?<\/a><ul class=\"ez-toc-list-level-3\"><li class=\"ez-toc-heading-level-3\"><a class=\"ez-toc-link ez-toc-heading-3\" href=\"https:\/\/badecho.com\/index.php\/2020\/12\/27\/hacking-ac-valhalla-part-4\/#A_Crappy_Way_of_Finding_Easy_Scaling_Support\" title=\"A Crappy Way of Finding Easy Scaling Support\">A Crappy Way of Finding Easy Scaling Support<\/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\/2020\/12\/27\/hacking-ac-valhalla-part-4\/#Scanning_for_Contiguous_Dimensional_Scales\" title=\"Scanning for Contiguous Dimensional Scales\">Scanning for Contiguous Dimensional Scales<\/a><\/li><li class=\"ez-toc-page-1 ez-toc-heading-level-3\"><a class=\"ez-toc-link ez-toc-heading-5\" href=\"https:\/\/badecho.com\/index.php\/2020\/12\/27\/hacking-ac-valhalla-part-4\/#Some_Time_Passes%E2%80%A6\" title=\"Some Time Passes&#8230;\">Some Time Passes&#8230;<\/a><\/li><\/ul><\/li><li class=\"ez-toc-page-1 ez-toc-heading-level-2\"><a class=\"ez-toc-link ez-toc-heading-6\" href=\"https:\/\/badecho.com\/index.php\/2020\/12\/27\/hacking-ac-valhalla-part-4\/#Where,_Oh_Where,_is_the_Character_Model_Rendering_Code\" title=\"Where, Oh Where, is the Character Model Rendering Code?\">Where, Oh Where, is the Character Model Rendering Code?<\/a><ul class=\"ez-toc-list-level-3\"><li class=\"ez-toc-heading-level-3\"><a class=\"ez-toc-link ez-toc-heading-7\" href=\"https:\/\/badecho.com\/index.php\/2020\/12\/27\/hacking-ac-valhalla-part-4\/#Crouching_for_Success\" title=\"Crouching for Success\">Crouching for Success<\/a><ul class=\"ez-toc-list-level-4\"><li class=\"ez-toc-heading-level-4\"><a class=\"ez-toc-link ez-toc-heading-8\" href=\"https:\/\/badecho.com\/index.php\/2020\/12\/27\/hacking-ac-valhalla-part-4\/#PSA_A_Superior_Method_for_Searching_for_Changes\" title=\"PSA: A Superior Method for Searching for Changes\">PSA: A Superior Method for Searching for Changes<\/a><\/li><li class=\"ez-toc-page-1 ez-toc-heading-level-4\"><a class=\"ez-toc-link ez-toc-heading-9\" href=\"https:\/\/badecho.com\/index.php\/2020\/12\/27\/hacking-ac-valhalla-part-4\/#Back_to_the_Crouching_Search%E2%80%A6\" title=\"Back to the Crouching Search&#8230;\">Back to the Crouching Search&#8230;<\/a><\/li><\/ul><\/li><\/ul><\/li><li class=\"ez-toc-page-1 ez-toc-heading-level-2\"><a class=\"ez-toc-link ez-toc-heading-10\" href=\"https:\/\/badecho.com\/index.php\/2020\/12\/27\/hacking-ac-valhalla-part-4\/#Global_Scale_Multipliers\" title=\"Global Scale Multipliers\">Global Scale Multipliers<\/a><ul class=\"ez-toc-list-level-3\"><li class=\"ez-toc-heading-level-3\"><a class=\"ez-toc-link ez-toc-heading-11\" href=\"https:\/\/badecho.com\/index.php\/2020\/12\/27\/hacking-ac-valhalla-part-4\/#Consumers_of_the_Global_Scale_Multipliers\" title=\"Consumers of the Global Scale Multipliers\">Consumers of the Global Scale Multipliers<\/a><\/li><li class=\"ez-toc-page-1 ez-toc-heading-level-3\"><a class=\"ez-toc-link ez-toc-heading-12\" href=\"https:\/\/badecho.com\/index.php\/2020\/12\/27\/hacking-ac-valhalla-part-4\/#Testing_A_Custom_Scaling_Hook\" title=\"Testing A Custom Scaling Hook\">Testing A Custom Scaling Hook<\/a><\/li><\/ul><\/li><li class=\"ez-toc-page-1 ez-toc-heading-level-2\"><a class=\"ez-toc-link ez-toc-heading-13\" href=\"https:\/\/badecho.com\/index.php\/2020\/12\/27\/hacking-ac-valhalla-part-4\/#Retrieving_Character_Data_From_Rendering_Code\" title=\"Retrieving Character Data From Rendering Code\">Retrieving Character Data From Rendering Code<\/a><ul class=\"ez-toc-list-level-3\"><li class=\"ez-toc-heading-level-3\"><a class=\"ez-toc-link ez-toc-heading-14\" href=\"https:\/\/badecho.com\/index.php\/2020\/12\/27\/hacking-ac-valhalla-part-4\/#Finding_Some_Player_Data_Being_Rendered\" title=\"Finding Some Player Data Being Rendered\">Finding Some Player Data Being Rendered<\/a><\/li><li class=\"ez-toc-page-1 ez-toc-heading-level-3\"><a class=\"ez-toc-link ez-toc-heading-15\" href=\"https:\/\/badecho.com\/index.php\/2020\/12\/27\/hacking-ac-valhalla-part-4\/#Finding_the_Link_to_Known_Character_Data_Types\" title=\"Finding the Link to Known Character Data Types\">Finding the Link to Known Character Data Types<\/a><\/li><\/ul><\/li><li class=\"ez-toc-page-1 ez-toc-heading-level-2\"><a class=\"ez-toc-link ez-toc-heading-16\" href=\"https:\/\/badecho.com\/index.php\/2020\/12\/27\/hacking-ac-valhalla-part-4\/#Implementing_the_Abomnification_Initiation_Point_Code\" title=\"Implementing the Abomnification Initiation Point Code\">Implementing the Abomnification Initiation Point Code<\/a><ul class=\"ez-toc-list-level-3\"><li class=\"ez-toc-heading-level-3\"><a class=\"ez-toc-link ez-toc-heading-17\" href=\"https:\/\/badecho.com\/index.php\/2020\/12\/27\/hacking-ac-valhalla-part-4\/#Where_to_Initiate_the_Horror\" title=\"Where to Initiate the Horror?\">Where to Initiate the Horror?<\/a><\/li><li class=\"ez-toc-page-1 ez-toc-heading-level-3\"><a class=\"ez-toc-link ez-toc-heading-18\" href=\"https:\/\/badecho.com\/index.php\/2020\/12\/27\/hacking-ac-valhalla-part-4\/#Some_Time_Passes%E2%80%A6-2\" title=\"Some Time Passes&#8230;\">Some Time Passes&#8230;<\/a><\/li><li class=\"ez-toc-page-1 ez-toc-heading-level-3\"><a class=\"ez-toc-link ez-toc-heading-19\" href=\"https:\/\/badecho.com\/index.php\/2020\/12\/27\/hacking-ac-valhalla-part-4\/#Looking_at_the_Movement_Application_Code_for_Inspiration\" title=\"Looking at the Movement Application Code for Inspiration\">Looking at the Movement Application Code for Inspiration<\/a><\/li><li class=\"ez-toc-page-1 ez-toc-heading-level-3\"><a class=\"ez-toc-link ez-toc-heading-20\" href=\"https:\/\/badecho.com\/index.php\/2020\/12\/27\/hacking-ac-valhalla-part-4\/#Figuring_Out_Where_to_Store_the_Morph_Scale_ID\" title=\"Figuring Out Where to Store the Morph Scale ID\">Figuring Out Where to Store the Morph Scale ID<\/a><ul class=\"ez-toc-list-level-4\"><li class=\"ez-toc-heading-level-4\"><a class=\"ez-toc-link ez-toc-heading-21\" href=\"https:\/\/badecho.com\/index.php\/2020\/12\/27\/hacking-ac-valhalla-part-4\/#Morph_Scale_ID_Test_Hook\" title=\"Morph Scale ID Test Hook\">Morph Scale ID Test Hook<\/a><\/li><\/ul><\/li><li class=\"ez-toc-page-1 ez-toc-heading-level-3\"><a class=\"ez-toc-link ez-toc-heading-22\" href=\"https:\/\/badecho.com\/index.php\/2020\/12\/27\/hacking-ac-valhalla-part-4\/#Writing_the_Initiation_Point_Code\" title=\"Writing the Initiation Point Code\">Writing the Initiation Point Code<\/a><ul class=\"ez-toc-list-level-4\"><li class=\"ez-toc-heading-level-4\"><a class=\"ez-toc-link ez-toc-heading-23\" href=\"https:\/\/badecho.com\/index.php\/2020\/12\/27\/hacking-ac-valhalla-part-4\/#Abomnification_Initiation_Hook_%E2%80%93_Template\" title=\"Abomnification Initiation Hook &#8211; Template\">Abomnification Initiation Hook &#8211; Template<\/a><\/li><li class=\"ez-toc-page-1 ez-toc-heading-level-4\"><a class=\"ez-toc-link ez-toc-heading-24\" href=\"https:\/\/badecho.com\/index.php\/2020\/12\/27\/hacking-ac-valhalla-part-4\/#Parameters\" title=\"Parameters\">Parameters<\/a><\/li><li class=\"ez-toc-page-1 ez-toc-heading-level-4\"><a class=\"ez-toc-link ez-toc-heading-25\" href=\"https:\/\/badecho.com\/index.php\/2020\/12\/27\/hacking-ac-valhalla-part-4\/#Return_Values\" title=\"Return Values\">Return Values<\/a><\/li><li class=\"ez-toc-page-1 ez-toc-heading-level-4\"><a class=\"ez-toc-link ez-toc-heading-26\" href=\"https:\/\/badecho.com\/index.php\/2020\/12\/27\/hacking-ac-valhalla-part-4\/#Abomnification_Initiation_Hook_With_Morph_Scale_ID\" title=\"Abomnification Initiation Hook With Morph Scale ID\">Abomnification Initiation Hook With Morph Scale ID<\/a><\/li><li class=\"ez-toc-page-1 ez-toc-heading-level-4\"><a class=\"ez-toc-link ez-toc-heading-27\" href=\"https:\/\/badecho.com\/index.php\/2020\/12\/27\/hacking-ac-valhalla-part-4\/#External_Parameters\" title=\"External Parameters\">External Parameters<\/a><\/li><\/ul><\/li><li class=\"ez-toc-page-1 ez-toc-heading-level-3\"><a class=\"ez-toc-link ez-toc-heading-28\" href=\"https:\/\/badecho.com\/index.php\/2020\/12\/27\/hacking-ac-valhalla-part-4\/#4_Byte_Memory_Woes\" title=\"4 Byte Memory Woes\">4 Byte Memory Woes<\/a><ul class=\"ez-toc-list-level-4\"><li class=\"ez-toc-heading-level-4\"><a class=\"ez-toc-link ez-toc-heading-29\" href=\"https:\/\/badecho.com\/index.php\/2020\/12\/27\/hacking-ac-valhalla-part-4\/#Bad_Abomnification_Code\" title=\"Bad Abomnification Code\">Bad Abomnification Code<\/a><\/li><li class=\"ez-toc-page-1 ez-toc-heading-level-4\"><a class=\"ez-toc-link ez-toc-heading-30\" href=\"https:\/\/badecho.com\/index.php\/2020\/12\/27\/hacking-ac-valhalla-part-4\/#Good_Abomnification_Code\" title=\"Good Abomnification Code\">Good Abomnification Code<\/a><\/li><li class=\"ez-toc-page-1 ez-toc-heading-level-4\"><a class=\"ez-toc-link ez-toc-heading-31\" href=\"https:\/\/badecho.com\/index.php\/2020\/12\/27\/hacking-ac-valhalla-part-4\/#More_Bad_Abomnification_Code\" title=\"More Bad Abomnification Code\">More Bad Abomnification Code<\/a><\/li><li class=\"ez-toc-page-1 ez-toc-heading-level-4\"><a class=\"ez-toc-link ez-toc-heading-32\" href=\"https:\/\/badecho.com\/index.php\/2020\/12\/27\/hacking-ac-valhalla-part-4\/#More_Good_Abomnification_Code\" title=\"More Good Abomnification Code\">More Good Abomnification Code<\/a><\/li><\/ul><\/li><li class=\"ez-toc-page-1 ez-toc-heading-level-3\"><a class=\"ez-toc-link ez-toc-heading-33\" href=\"https:\/\/badecho.com\/index.php\/2020\/12\/27\/hacking-ac-valhalla-part-4\/#A_Better_Morph_Scale_ID_Location\" title=\"A Better Morph Scale ID Location\">A Better Morph Scale ID Location<\/a><\/li><li class=\"ez-toc-page-1 ez-toc-heading-level-3\"><a class=\"ez-toc-link ez-toc-heading-34\" href=\"https:\/\/badecho.com\/index.php\/2020\/12\/27\/hacking-ac-valhalla-part-4\/#Doing_Away_With_the_Morph_Scale_ID\" title=\"Doing Away With the Morph Scale ID\">Doing Away With the Morph Scale ID<\/a><ul class=\"ez-toc-list-level-4\"><li class=\"ez-toc-heading-level-4\"><a class=\"ez-toc-link ez-toc-heading-35\" href=\"https:\/\/badecho.com\/index.php\/2020\/12\/27\/hacking-ac-valhalla-part-4\/#Abomnification_Initiation_Hook_Without_Morph_Scale_ID\" title=\"Abomnification Initiation Hook Without Morph Scale ID\">Abomnification Initiation Hook Without Morph Scale ID<\/a><\/li><\/ul><\/li><\/ul><\/li><li class=\"ez-toc-page-1 ez-toc-heading-level-2\"><a class=\"ez-toc-link ez-toc-heading-36\" href=\"https:\/\/badecho.com\/index.php\/2020\/12\/27\/hacking-ac-valhalla-part-4\/#Implementing_the_Abomnification_Scale_Application_Code\" title=\"Implementing the Abomnification Scale Application Code\">Implementing the Abomnification Scale 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-37\" href=\"https:\/\/badecho.com\/index.php\/2020\/12\/27\/hacking-ac-valhalla-part-4\/#Abomnification_Scale_Application_Hook_%E2%80%93_Template\" title=\"Abomnification Scale Application Hook &#8211; Template\">Abomnification Scale Application Hook &#8211; Template<\/a><\/li><li class=\"ez-toc-page-1 ez-toc-heading-level-3\"><a class=\"ez-toc-link ez-toc-heading-38\" href=\"https:\/\/badecho.com\/index.php\/2020\/12\/27\/hacking-ac-valhalla-part-4\/#Abomnification_Scale_Application_Hook\" title=\"Abomnification Scale Application Hook\">Abomnification Scale Application Hook<\/a><\/li><\/ul><\/li><li class=\"ez-toc-page-1 ez-toc-heading-level-2\"><a class=\"ez-toc-link ez-toc-heading-39\" href=\"https:\/\/badecho.com\/index.php\/2020\/12\/27\/hacking-ac-valhalla-part-4\/#Is_AC_Valhalla_Abomnified\" title=\"Is AC: Valhalla Abomnified?\">Is AC: Valhalla Abomnified?<\/a><ul class=\"ez-toc-list-level-3\"><li class=\"ez-toc-heading-level-3\"><a class=\"ez-toc-link ez-toc-heading-40\" href=\"https:\/\/badecho.com\/index.php\/2020\/12\/27\/hacking-ac-valhalla-part-4\/#Abomnification_Implementation_%E2%80%93_Complete\" title=\"Abomnification Implementation &#8211; Complete\">Abomnification Implementation &#8211; Complete<\/a><\/li><\/ul><\/li><\/ul><\/nav><\/div>\r\n<h2><span class=\"ez-toc-section\" id=\"Time_To_Add_Some_LSDFueled_Smooth_Morphing_Monsters\"><\/span>Time To Add Some LSD-Fueled Smooth Morphing Monsters<span class=\"ez-toc-section-end\"><\/span><\/h2>\n\n\n\n<p>Good day to you. I&#8217;ve been busily hacking away at <em>Assassin&#8217;s Creed: Valhalla<\/em>, getting it to a state where we might be able to call it <a rel=\"noreferrer noopener\" href=\"https:\/\/badecho.com\/index.php\/what-is-omnified\/\" target=\"_blank\">Omnified<\/a>. I&#8217;ve provided several articles thus far covering <a rel=\"noreferrer noopener\" href=\"https:\/\/badecho.com\/index.php\/2020\/12\/07\/hacking-ac-valhalla-part-1\/\" target=\"_blank\">data structure analysis<\/a>, <a rel=\"noreferrer noopener\" href=\"https:\/\/badecho.com\/index.php\/2020\/12\/14\/hacking-ac-valhalla-part-2\/\" target=\"_blank\">overhaul of the damage system<\/a>, as well as <a rel=\"noreferrer noopener\" href=\"https:\/\/badecho.com\/index.php\/2020\/12\/20\/hacking-ac-valhalla-part-3\/\" target=\"_blank\">implementation of my intelligent speed booster for enemies<\/a>.<\/p>\n\n\n\n<p>So, we&#8217;ve got the <a rel=\"noreferrer noopener\" href=\"https:\/\/badecho.com\/index.php\/2020\/10\/19\/apocalypse-system\/\" target=\"_blank\">Apocalypse<\/a> and Predator systems down, only one left: the Abomnification system. This system causes enemies in the game to randomly change shape and size at randomly determined speeds accordingly to randomly determined morphing modes.<\/p>\n\n\n\n<p>It&#8217;s a pretty cool system that I plan on adding even more features to soon, and it will definitely have a detailed <a rel=\"noreferrer noopener\" href=\"https:\/\/badecho.com\/index.php\/category\/omnified-design\/\" target=\"_blank\">Omnified Design<\/a> article dedicated to it soon. Unfortunately, it does not have one yet. So, I hope you will bear with me if any gaps of knowledge remain in your brain even if you fully read this article (fat chance of that happening hahaha).<\/p>\n\n\n\n<p>One day, such an article will exist. Until that day, feel free to check out <a rel=\"noreferrer noopener\" href=\"https:\/\/badecho.com\/index.php\/tag\/abomnification\/\" target=\"_blank\">other Abomnification implementation articles<\/a> to gather more information on anything I forget to include in this one.<\/p>\n\n\n\n<h2><span class=\"ez-toc-section\" id=\"Is_Easy_Scaling_Support_BuiltIn\"><\/span>Is Easy Scaling Support Built-In?<span class=\"ez-toc-section-end\"><\/span><\/h2>\n\n\n\n<p>Implementation of the Abomnification system is a bit more complicated than the other systems. What actually needs to be done greatly depends on what the game makes available to us. Specifically, the first question we must answer is whether or not the game features built-in <em>easy scaling support<\/em>.<\/p>\n\n\n\n<p>Easy scaling support takes the form of three (typically) exposed floating point values, each of which acts as a multiplier for a particular dimension (width, height, or depth). The presence of these dimensional floats make the reshaping of creatures a simple affair; for example, doubling the height multiplier would cause the creature to become twice as tall.<\/p>\n\n\n\n<p>Ever since the creation of the Abomnification system, I&#8217;ve hoped to Omnify games with built-in scaling support, but the majority of the games that I&#8217;ve done since then (blame FromSoftware) lacked any. I hope this game has it, but I&#8217;m not holding my breath.<\/p>\n\n\n\n<h3><span class=\"ez-toc-section\" id=\"A_Crappy_Way_of_Finding_Easy_Scaling_Support\"><\/span>A Crappy Way of Finding Easy Scaling Support<span class=\"ez-toc-section-end\"><\/span><\/h3>\n\n\n\n<p>Many times a game will have easy scaling support if there is some sort of character creation process where the height or one of the other dimensions can be manipulated by the player. Another reason for easy scaling support to exist is if differently sized enemies of the same type is a gameplay element (i.e. Monster Hunter World). The last typical reason for built-in easy scaling support to exist is if the game is using an engine that supports such a thing out of the box.<\/p>\n\n\n\n<p>Some of the most prevalent (well, in the past at least) engines offer this, such as the Unreal engine I believe. Unfortunately, <em>Assassin&#8217;s Creed: Valhalla<\/em> is using the Ubisoft proprietary engine &#8220;AnvilNext&#8221;, and none of the other common reasons for having easy scaling apply here either. We&#8217;re most likely screwed, however I&#8217;m trying to be positive about things here OK!?<\/p>\n\n\n\n<p>The scale multipliers, at least for games powered by the Unreal engine, are usually found in the same data structure that houses the coordinates. So, we&#8217;re going to browse the memory region belonging to our location structure, looking for values that&#8230;appear to be scale multipliers.<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-large\"><img loading=\"lazy\" width=\"946\" height=\"533\" src=\"https:\/\/badecho.com\/wp-content\/uploads\/2020\/12\/LookingForScalingParameters.png\" alt=\"Shows us looking for scaling parameters.\" class=\"wp-image-918\" srcset=\"https:\/\/badecho.com\/wp-content\/uploads\/2020\/12\/LookingForScalingParameters.png 946w, https:\/\/badecho.com\/wp-content\/uploads\/2020\/12\/LookingForScalingParameters-300x169.png 300w, https:\/\/badecho.com\/wp-content\/uploads\/2020\/12\/LookingForScalingParameters-768x433.png 768w, https:\/\/badecho.com\/wp-content\/uploads\/2020\/12\/LookingForScalingParameters-480x270.png 480w\" sizes=\"(max-width: 946px) 100vw, 946px\" \/><figcaption>Hopefully we find some meaningful &#8220;1.00&#8221; values in the memory here&#8230;good luck hah.<\/figcaption><\/figure><\/div>\n\n\n\n<p>I have my memory browser loaded up so it is pointed right next to my coordinates. I&#8217;m going to look for floating points that are around <strong>1.0<\/strong>, and then see if I can tweak them. If the change holds, then we hope for a visual change in the character&#8217;s size.<\/p>\n\n\n\n<p>Yeah, this is a pretty primitive way to go about doing this. But, it actually ends up not taking too long to find the scale this way if standard easy scaling is present. <\/p>\n\n\n\n<p>Typically, we&#8217;re going to see three floating point values, one for each dimension, all contiguous to each other in memory. So three floating points at around <strong>1.0<\/strong>, as this is what the default for the player character is typically going to be&#8230;ya know, that only makes sense, right?<\/p>\n\n\n\n<p>But I don&#8217;t spend a ton of time looking for it in this fashion. I mean, we could waste hours pouring through the memory if we don&#8217;t hit our own STOP button. If I don&#8217;t see anything in a quick fashion related to scale nearby the location coordinates, it is time to move on frankly.<\/p>\n\n\n\n<h3><span class=\"ez-toc-section\" id=\"Scanning_for_Contiguous_Dimensional_Scales\"><\/span>Scanning for Contiguous Dimensional Scales<span class=\"ez-toc-section-end\"><\/span><\/h3>\n\n\n\n<p>As was stated before, often and especially for the player character, the dimensional scales will be stored in memory all next to each other, and typically all at the value <strong>1.0<\/strong>. Obviously, this will probably not be the case if there is any height\/width\/depth editing via character creation, but that&#8217;s not something we have to worry about here.<\/p>\n\n\n\n<p>So, why don&#8217;t we attempt to search memory for all sequences of three floating point values of <strong>1.0<\/strong>. We can do that if we search for a specific array of bytes. The 4 byte hex representation of a <strong>1.0<\/strong> is <code>0x3F800000<\/code>. Since we&#8217;re running on a little-endian system, that ends up looking like this in memory:<\/p>\n\n\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\">\n00 00 80 3F 00 00 80 3F 00 00 80 3F\n<\/pre>\n\n\n<p>So let&#8217;s search for this exact sequence, however let&#8217;s constrain the address range of the search results to be within the area of memory where we see our player&#8217;s health and location stored, which is between <code>0x2B450000000<\/code> and <code>0x2B460000000<\/code>.<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-large\"><img loading=\"lazy\" width=\"754\" height=\"749\" src=\"https:\/\/badecho.com\/wp-content\/uploads\/2020\/12\/ScaleSearchLittleEndian.png\" alt=\"Shows us searching for three contiguous 1.0 floating point values in memory.\" class=\"wp-image-920\" srcset=\"https:\/\/badecho.com\/wp-content\/uploads\/2020\/12\/ScaleSearchLittleEndian.png 754w, https:\/\/badecho.com\/wp-content\/uploads\/2020\/12\/ScaleSearchLittleEndian-300x298.png 300w, https:\/\/badecho.com\/wp-content\/uploads\/2020\/12\/ScaleSearchLittleEndian-150x150.png 150w, https:\/\/badecho.com\/wp-content\/uploads\/2020\/12\/ScaleSearchLittleEndian-480x477.png 480w\" sizes=\"(max-width: 754px) 100vw, 754px\" \/><figcaption>The results of our search for three contiguous 1.0 floating point values.<\/figcaption><\/figure><\/div>\n\n\n\n<p>Well we have some results. Looks like a little over <strong>16,000 <\/strong>of them. We probably should&#8217;ve constrained the results a bit more so the only results shown were closer to the location structure.<\/p>\n\n\n\n<h3><span class=\"ez-toc-section\" id=\"Some_Time_Passes%E2%80%A6\"><\/span>Some Time Passes&#8230;<span class=\"ez-toc-section-end\"><\/span><\/h3>\n\n\n\n<p>After checking out the results closest to the location structure, I could not pinpoint any sort of floating point sequence that could be manipulated in order to change the character&#8217;s shape and size. This doesn&#8217;t mean that there is no built-in scaling; the scale multipliers may be getting stored in a structure entirely independent from the location structure. I mean, who knows?<\/p>\n\n\n\n<p>But if such things do exist we are going to have a hell of a time finding them with just the information we currently have at hand. Every time I&#8217;ve found easy scaling support in a game, it has been located by the coordinates. And this has been across several different engines as well.<\/p>\n\n\n\n<p>We&#8217;re not seeing that here, so we must conclude, unfortunately, that easy scaling support does not exist in this game. This means we must implement own custom scaling code in order to be able to apply Abomnification-generated scale multipliers.<\/p>\n\n\n\n<h2><span class=\"ez-toc-section\" id=\"Where,_Oh_Where,_is_the_Character_Model_Rendering_Code\"><\/span>Where, Oh Where, is the Character Model Rendering Code?<span class=\"ez-toc-section-end\"><\/span><\/h2>\n\n\n\n<p>In order to be able to influence the size of a character&#8217;s model, we must locate the code responsible for calculating and storing the 3&#215;4 matrix values that essentially define the physical characteristics of the character in three dimensional space. We&#8217;re going to definitely have our work cut out for us. A game&#8217;s model rendering code is usually very deep down the rabbit hole as far as code goes, and it&#8217;s always very engine specific. <\/p>\n\n\n\n<p>Since creating the Abomnification engine, I&#8217;ve had to implement my own custom scaling code for five or six separate games. And, let me tell you, I&#8217;ve felt very fortunate each and every time I managed to crank one out. Sure, some might attribute it to &#8220;skill&#8221; or &#8220;deductive prowess&#8221;, but sometimes it seems like such a difficult task that it feels that I&#8217;d be lacking in humility if not attributing some of the success to luck.<\/p>\n\n\n\n<p>If I actually manage to achieve implementing custom scaling code in <em>this<\/em> game, then it will be the first game I&#8217;ve <em>ever<\/em> done such a thing in without the aid of <a rel=\"noreferrer noopener\" href=\"https:\/\/docs.microsoft.com\/en-us\/cpp\/cpp\/run-time-type-information?view=msvc-160#:~:text=Run%2Dtime%20type%20information%20(RTTI)%20is%20a%20mechanism%20that,were%20implementing%20this%20functionality%20themselves.\" target=\"_blank\">RTTI<\/a>. Real time type information gives us information about types and complex data structures, which <em>greatly<\/em> aids locating recognizable character data (which is where we store the character-specific Abomnification parameters) within the rendering functions (which are very removed from other parts of the code).<\/p>\n\n\n\n<p>The code which will be housing our custom scaler is where the mesh of polygons is being formed for a character through the processing of various edges and vertices. The data we&#8217;ll be manipulating are essentially vertex matrices, with each value basically representing the distance from some other point on the plane. <\/p>\n\n\n\n<p>So, as you can probably surmise from above, this is way beyond the difficulty levels presented by other areas such as character movement and health damage. In order to do this stuff, we got to git gud baby.<\/p>\n\n\n\n<h3><span class=\"ez-toc-section\" id=\"Crouching_for_Success\"><\/span>Crouching for Success<span class=\"ez-toc-section-end\"><\/span><\/h3>\n\n\n\n<p>To begin the search for our rendering function, we&#8217;ll be starting out in much the same way we initiate the disassembly of most things. We&#8217;ll locate the code of interest by searching for code involved in the manipulation of data isolated with controlled value changes. Of course, unlike the searches for more mundane things such as character location and health, it&#8217;s a bit less clear as to what to look for and how to look for it when we&#8217;re talking about the character&#8217;s model.<\/p>\n\n\n\n<p>Well, we are looking for code that processes vertex matrices for the polygonal mesh of our character&#8217;s body. All of them put together essentially forms the edges and shapes that compose the character&#8217;s model. So we basically just need to effectuate changes to all these vertex points in a consistent manner in order to isolate them. <\/p>\n\n\n\n<p>Lots of different actions change these vertex points; simply moving forward and\/or backward changes these particular points. But this is difficult to track. We have to perform our search using changes on the character&#8217;s model that are both quantifiable and easily repeatable. The easiest thing to do, at least for this game, is simply crouch up and down.<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-large\"><img loading=\"lazy\" width=\"665\" height=\"539\" src=\"https:\/\/badecho.com\/wp-content\/uploads\/2020\/12\/Crouching.png\" alt=\"Shows our character crouching pensively during our search for the rendering code.\" class=\"wp-image-930\" srcset=\"https:\/\/badecho.com\/wp-content\/uploads\/2020\/12\/Crouching.png 665w, https:\/\/badecho.com\/wp-content\/uploads\/2020\/12\/Crouching-300x243.png 300w, https:\/\/badecho.com\/wp-content\/uploads\/2020\/12\/Crouching-480x389.png 480w\" sizes=\"(max-width: 665px) 100vw, 665px\" \/><figcaption>Crouching folds up the polygonal plane nicely.<\/figcaption><\/figure><\/div>\n\n\n\n<p>When crouching, we&#8217;re basically folding up that mesh of polygons that makes up the character model; crumpling it up so it all fits in a small space. For the most part, we will have a decrease in values across the the character model as everything gets closer to each other. So, lets try an <strong>Unknown initial value<\/strong> search for floats, doing follow up searches for <strong>Decreased values<\/strong> when we crouch, and some follow up searches for <strong>Increased values<\/strong> when standing up.<\/p>\n\n\n\n<h4><span class=\"ez-toc-section\" id=\"PSA_A_Superior_Method_for_Searching_for_Changes\"><\/span>PSA: A Superior Method for Searching for Changes<span class=\"ez-toc-section-end\"><\/span><\/h4>\n\n\n\n<p>There will be millions of values at play here in memory. It will take awhile to narrow them all down, and we&#8217;ll still be flooded with many false positives at the end of it all. To increase precision, a breakpoint should be placed at code that is executing frequently, but not too frequently. We then set up a hotkey for <strong>Debug -&gt; Run<\/strong>, and then spam that key while trying to initiate a crouch. If we are unable to get in any user input, we&#8217;ll want to find a different spot.<\/p>\n\n\n\n<p>If everything is done correctly, we will get a few frames of animation every few clicks of the <strong>Debug -&gt; Run<\/strong> button, allowing for us to do very fine tuned <strong>Decreased values<\/strong> and <strong>Increased values<\/strong> searches. This will cause the number of results to very quickly get to a small number of accurate results. This is the <em>superior<\/em> way to search for changed values.<\/p>\n\n\n\n<h4><span class=\"ez-toc-section\" id=\"Back_to_the_Crouching_Search%E2%80%A6\"><\/span>Back to the Crouching Search&#8230;<span class=\"ez-toc-section-end\"><\/span><\/h4>\n\n\n\n<p>Starting at two billion or so results, we narrow them down in short order using the superior method described above. I ended up with a quite small (given what we&#8217;re searching for) set of only about <strong>800<\/strong> results. Not bad! Taking a look at a number of them, and seeing what was writing to them, I ended up in the following bit of code:<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-large\"><img loading=\"lazy\" width=\"946\" height=\"533\" src=\"https:\/\/badecho.com\/wp-content\/uploads\/2020\/12\/RenderingDrawingCodePrecursorCode.png\" alt=\"Shows a commonly executed instruction encountered when searching for changes in our character's model.\" class=\"wp-image-931\" srcset=\"https:\/\/badecho.com\/wp-content\/uploads\/2020\/12\/RenderingDrawingCodePrecursorCode.png 946w, https:\/\/badecho.com\/wp-content\/uploads\/2020\/12\/RenderingDrawingCodePrecursorCode-300x169.png 300w, https:\/\/badecho.com\/wp-content\/uploads\/2020\/12\/RenderingDrawingCodePrecursorCode-768x433.png 768w, https:\/\/badecho.com\/wp-content\/uploads\/2020\/12\/RenderingDrawingCodePrecursorCode-480x270.png 480w\" sizes=\"(max-width: 946px) 100vw, 946px\" \/><figcaption>This instruction is storing calculated values to a single matrix row.<\/figcaption><\/figure><\/div>\n\n\n\n<p>Interesting. This doesn&#8217;t look <em>exactly<\/em> like what I&#8217;m used to seeing, which is three separate <code>movups<\/code> or <code>movaps<\/code> instructions essentially resulting in a complete write to a 3&#215;4 matrix, but perhaps that is what it is going on here as well, given that everything is looped. Instead of each iteration writing to a separate 3&#215;4 matrix, maybe each iteration is writing to a particular row in a matrix. <\/p>\n\n\n\n<p>This is a bit of a complication, but let&#8217;s not worry about it until later. Let&#8217;s see what happens if we disable <code>movups [rax+rdi],xmm5<\/code> which is the instruction that&#8217;s writing to the data point we picked out of the search results earlier.<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-large\"><img loading=\"lazy\" width=\"753\" height=\"829\" src=\"https:\/\/badecho.com\/wp-content\/uploads\/2020\/12\/RenderingDrawingCodePrecursorDisabled.png\" alt=\"Shows the character missing an upper body after having removed the initially found rendering code.\" class=\"wp-image-932\" srcset=\"https:\/\/badecho.com\/wp-content\/uploads\/2020\/12\/RenderingDrawingCodePrecursorDisabled.png 753w, https:\/\/badecho.com\/wp-content\/uploads\/2020\/12\/RenderingDrawingCodePrecursorDisabled-272x300.png 272w, https:\/\/badecho.com\/wp-content\/uploads\/2020\/12\/RenderingDrawingCodePrecursorDisabled-480x528.png 480w\" sizes=\"(max-width: 753px) 100vw, 753px\" \/><figcaption>Hey, where&#8217;d our body go? We&#8217;re on the right track!<\/figcaption><\/figure><\/div>\n\n\n\n<p>Apparently disabling this instruction results in a large portion of our body disappearing. We&#8217;re actually looking for a function that, if disabled, results in the size of the model no longer updating when it should (i.e. getting smaller when crouching). While this isn&#8217;t exactly the rendering function we need, it still has to do with the character&#8217;s model, so we are actually on the right track.<\/p>\n\n\n\n<h2><span class=\"ez-toc-section\" id=\"Global_Scale_Multipliers\"><\/span>Global Scale Multipliers<span class=\"ez-toc-section-end\"><\/span><\/h2>\n\n\n\n<p>I was about to start going through the list of search results again, looking for more rendering-related code, when my eye caught on the instruction resting one line above the code we were just looking at: <code>mulps xmm5,[ACValhalla.exe+415A470]<\/code>. The product of this instruction is what is getting dumped into our data point. <\/p>\n\n\n\n<p>As you can tell by looking at the operand, this is multiplying some value by a multiplier stored in static memory. This is basically a compile-time constant. Browsing to the static memory in question, we see the following:<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-large\"><img loading=\"lazy\" width=\"946\" height=\"533\" src=\"https:\/\/badecho.com\/wp-content\/uploads\/2020\/12\/GlobalScaleMemory.png\" alt=\"Shows the contents of the global scale static memory.\" class=\"wp-image-945\" srcset=\"https:\/\/badecho.com\/wp-content\/uploads\/2020\/12\/GlobalScaleMemory.png 946w, https:\/\/badecho.com\/wp-content\/uploads\/2020\/12\/GlobalScaleMemory-300x169.png 300w, https:\/\/badecho.com\/wp-content\/uploads\/2020\/12\/GlobalScaleMemory-768x433.png 768w, https:\/\/badecho.com\/wp-content\/uploads\/2020\/12\/GlobalScaleMemory-480x270.png 480w\" sizes=\"(max-width: 946px) 100vw, 946px\" \/><figcaption>Three multipliers (2.0x) for each dimension.<\/figcaption><\/figure><\/div>\n\n\n\n<p>A floating pair triplet, all members set to <strong>2.0<\/strong>, with a bunch of boundary-forming zeroes following them. Very interesting. Could it be we are looking at a particular kind of global scale multiplier, with each value belonging to a separate dimension? After changing the values around myself, I observed that was indeed what it was; however, much more than just the character scale changed. Things such as the camera width, position, perspective, etc. changed.<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-large\"><img loading=\"lazy\" width=\"624\" height=\"793\" src=\"https:\/\/badecho.com\/wp-content\/uploads\/2020\/12\/OneHalfGlobalWidth.png\" alt=\"Shows the character being much skinnier after reducing the global width scaling.\" class=\"wp-image-946\" srcset=\"https:\/\/badecho.com\/wp-content\/uploads\/2020\/12\/OneHalfGlobalWidth.png 624w, https:\/\/badecho.com\/wp-content\/uploads\/2020\/12\/OneHalfGlobalWidth-236x300.png 236w, https:\/\/badecho.com\/wp-content\/uploads\/2020\/12\/OneHalfGlobalWidth-480x610.png 480w\" sizes=\"(max-width: 624px) 100vw, 624px\" \/><figcaption>Here&#8217;s our character, looking a bit skinnier after halving the first scaling multiplier, which is clearly for the width.<\/figcaption><\/figure><\/div>\n\n\n\n<p>We are <em>definitely<\/em> on the right track now. This only confirms it. Don&#8217;t start rejoicing too soon however, as just being able to tweak these global scale multipliers fails to give us what we need on a number of counts:<\/p>\n\n\n\n<ul><li>We need to be able to apply scale multipliers that are unique to each creature being scaled. The randomly selected morphing modes (which is per-creature) will be applying randomly determined target morphing dimensions independent of each and every other creature on the map.<\/li><li>Simply manipulating the global scale multipliers causes many things other than just the character model dimensions to change. The camera, its position and even angle, is affected.<\/li><\/ul>\n\n\n\n<p>All of that aside, I believe these global scale multipliers will lead us ultimately to where we need to be. Although they affect more than just the character model scales, by narrowing down where they&#8217;re actually used to influence said scales, we should be able to ultimately find the rendering code that we need.<\/p>\n\n\n\n<h3><span class=\"ez-toc-section\" id=\"Consumers_of_the_Global_Scale_Multipliers\"><\/span>Consumers of the Global Scale Multipliers<span class=\"ez-toc-section-end\"><\/span><\/h3>\n\n\n\n<p>Adding one of the global scale multipliers to our address list, lets now take a look at the sort of code that is accessing this bit (well bytes, bah&#8230;.puns bad) of static memory.<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-large\"><img loading=\"lazy\" width=\"946\" height=\"513\" src=\"https:\/\/badecho.com\/wp-content\/uploads\/2020\/12\/GlobalScaleUsers.png\" alt=\"Shows all the instructions accessing the global scale multiplier.\" class=\"wp-image-933\" srcset=\"https:\/\/badecho.com\/wp-content\/uploads\/2020\/12\/GlobalScaleUsers.png 946w, https:\/\/badecho.com\/wp-content\/uploads\/2020\/12\/GlobalScaleUsers-300x163.png 300w, https:\/\/badecho.com\/wp-content\/uploads\/2020\/12\/GlobalScaleUsers-768x416.png 768w, https:\/\/badecho.com\/wp-content\/uploads\/2020\/12\/GlobalScaleUsers-480x260.png 480w\" sizes=\"(max-width: 946px) 100vw, 946px\" \/><figcaption>The global scale multiplier is being accessed by a lot of different code.<\/figcaption><\/figure><\/div>\n\n\n\n<p>There&#8217;s a plethora (ah&#8230;Jefe) of code accessing these multipliers. Not surprising. We&#8217;re going to be interested in the code that is accessing the multipliers the most frequently, as that is indicative of character model matrix transformation scaling code. Just trust me OK. Highlighting the top instruction here, let&#8217;s hit that <strong>Show disassembler<\/strong> button and hope for the best.<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-large\"><img loading=\"lazy\" width=\"946\" height=\"533\" src=\"https:\/\/badecho.com\/wp-content\/uploads\/2020\/12\/ScalingMultiplierCode.png\" alt=\"Shows the most commonly executed consumption of the global scale multiplier.\" class=\"wp-image-934\" srcset=\"https:\/\/badecho.com\/wp-content\/uploads\/2020\/12\/ScalingMultiplierCode.png 946w, https:\/\/badecho.com\/wp-content\/uploads\/2020\/12\/ScalingMultiplierCode-300x169.png 300w, https:\/\/badecho.com\/wp-content\/uploads\/2020\/12\/ScalingMultiplierCode-768x433.png 768w, https:\/\/badecho.com\/wp-content\/uploads\/2020\/12\/ScalingMultiplierCode-480x270.png 480w\" sizes=\"(max-width: 946px) 100vw, 946px\" \/><figcaption>This is the most frequently executed usage of the global scale multipliers.<\/figcaption><\/figure><\/div>\n\n\n\n<p>The global scale multipliers are read by the highlighted instruction, whose product is then involved in many, many complex calculations and operations before being finally written to a matrix row. In order to see if this usage of the global  scale multiplier pertains to just the character&#8217;s model (and not other things like the camera), let&#8217;s replace this highlighted portion of code with a bunch of <code>nop<\/code> instructions.<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-large\"><img loading=\"lazy\" width=\"755\" height=\"635\" src=\"https:\/\/badecho.com\/wp-content\/uploads\/2020\/12\/DisablingGlobalScaleByPotential.png\" alt=\"Shows the character all scrunched up from disabling the most commonly executed use of the global scaling multiplier.\" class=\"wp-image-935\" srcset=\"https:\/\/badecho.com\/wp-content\/uploads\/2020\/12\/DisablingGlobalScaleByPotential.png 755w, https:\/\/badecho.com\/wp-content\/uploads\/2020\/12\/DisablingGlobalScaleByPotential-300x252.png 300w, https:\/\/badecho.com\/wp-content\/uploads\/2020\/12\/DisablingGlobalScaleByPotential-480x404.png 480w\" sizes=\"(max-width: 755px) 100vw, 755px\" \/><figcaption>When disabling the multiplier, we see a reduction in scale. Perfect.<\/figcaption><\/figure><\/div>\n\n\n\n<p>Excellent. When we remove the code that is applying the global scale multiplier (which will reduce the end product of all dimensions by half) we see the scale of our rendered character model change accordingly. That means this is the spot to effectuate scale changes! We can change the scale for whatever creature is being processed at the time of execution, without having to tamper with the global scale multiplier.<\/p>\n\n\n\n<h3><span class=\"ez-toc-section\" id=\"Testing_A_Custom_Scaling_Hook\"><\/span>Testing A Custom Scaling Hook<span class=\"ez-toc-section-end\"><\/span><\/h3>\n\n\n\n<p>Just to make sure that this is the proper place in the code to implement our Abomnification <em>scale application<\/em> hook, let&#8217;s create a quick and dirty hook into the <code>mulps xmm8,[ACValhalla.exe+415A470]<\/code> code. We&#8217;ll want to test out some different sample scales applied to just a single &#8220;column&#8221; of data at a time in <code>xmm8<\/code> in order to see if they all belong to different dimensions.<\/p>\n\n\n\n<p>In the past, games where I&#8217;ve had to hack into the rendering logic would dedicate entire rows of matrix data to each dimension. Typically, the first row (<code>[n]<\/code>) would be for the width, the second row (<code>[n+10]<\/code>) would be for the height, and the third row (<code>[n+20]<\/code>) would be for the depth. Each row would have a separate instruction writing independently calculated data into it.<\/p>\n\n\n\n<p>The rendering data structure is a bit more mysterious here. It seems to be 32-byte aligned, with the first 16 bytes containing three dimensional values (padded by 4 bytes of zeroes), and the last 16 bytes being for something else related to position. What it actually all is doesn&#8217;t matter right now; complete understanding is not required. I&#8217;m really only starting to understand what all the data I&#8217;ve previously worked with is. So, no need to do that here.<\/p>\n\n\n\n<p>Moving on, I create a simple hook that just multiplies the third floating point value in <code>xmm8<\/code> by <strong>1.5<\/strong>, and we get the following: <\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-large\"><img loading=\"lazy\" width=\"637\" height=\"1024\" src=\"https:\/\/badecho.com\/wp-content\/uploads\/2020\/12\/OnePointFiveThirdModelScale-637x1024.png\" alt=\"Shows a taller character when applying a 1.5x multiplier to the global scaling code at its most common usage point.\" class=\"wp-image-936\" srcset=\"https:\/\/badecho.com\/wp-content\/uploads\/2020\/12\/OnePointFiveThirdModelScale-637x1024.png 637w, https:\/\/badecho.com\/wp-content\/uploads\/2020\/12\/OnePointFiveThirdModelScale-187x300.png 187w, https:\/\/badecho.com\/wp-content\/uploads\/2020\/12\/OnePointFiveThirdModelScale-480x772.png 480w, https:\/\/badecho.com\/wp-content\/uploads\/2020\/12\/OnePointFiveThirdModelScale.png 655w\" sizes=\"(max-width: 637px) 100vw, 637px\" \/><figcaption>Multiplying one of the matrix values by 1.5 at this spot achieves our goal of scale manipulation.<\/figcaption><\/figure><\/div>\n\n\n\n<p>Hell yes! We&#8217;ve figured out how to change the scale of a character in this game! The only thing affected here is the character&#8217;s model; the camera and everything else is completely unaffected. Cool! Well, let&#8217;s see what happens when we screw with another matrix value (the first floating point). Let&#8217;s multiply that by&#8230;<strong>4<\/strong>?<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-large\"><img loading=\"lazy\" width=\"1001\" height=\"710\" src=\"https:\/\/badecho.com\/wp-content\/uploads\/2020\/12\/FourFirstModelScale.png\" alt=\"Shows the character's width increasing when multiplying one of the values by 4x at the most common usage point of the global scale multiplier.\" class=\"wp-image-937\" srcset=\"https:\/\/badecho.com\/wp-content\/uploads\/2020\/12\/FourFirstModelScale.png 1001w, https:\/\/badecho.com\/wp-content\/uploads\/2020\/12\/FourFirstModelScale-300x213.png 300w, https:\/\/badecho.com\/wp-content\/uploads\/2020\/12\/FourFirstModelScale-768x545.png 768w, https:\/\/badecho.com\/wp-content\/uploads\/2020\/12\/FourFirstModelScale-480x340.png 480w\" sizes=\"(max-width: 1001px) 100vw, 1001px\" \/><figcaption>Multiplying one of the other values by 4 increases width. Damn it looks creepy though. Perfect!<\/figcaption><\/figure><\/div>\n\n\n\n<p>Well hells yes again. The width has definitely increased greatly here, and while it looks freaking weird, that&#8217;s actually perfect. The point of the Abomnification system is not to create perfect scaling characters, but to create abominations!<\/p>\n\n\n\n<p>How would we go about creating perfect scaling? Well, because that&#8217;s completely outside of what I need to achieve here, I will have to leave that one to you. But, if you&#8217;re interested, I&#8217;d recommend taking a look at all the other consumers of the global scale parameter, some of which will be responsible for arranging the shape and size of different parts of the character, and then provide the necessary additional hooks in those places in order to the uniformly distribute the scaling change.<\/p>\n\n\n\n<p>Concerning what I&#8217;m trying to achieve, trying to do the above would just be something requiring loads of additional work for a more boring final product. Not going to happen. We will actually be able to prevent the most ridiculous of the potential visual aberrations from happening simply by our limits placed on the randomly generated dimensional maximums. <\/p>\n\n\n\n<p>So it looks like we&#8217;ve found the perfect spot to implement our custom scaling code. Here is where we&#8217;ll be placing an Abomnification scale application hook, which will be responsible for applying scale multipliers generated by the Abomnification system to data involved in the rendering of the character&#8217;s model. Are we out of the woods yet though? Not at all.<\/p>\n\n\n\n<h2><span class=\"ez-toc-section\" id=\"Retrieving_Character_Data_From_Rendering_Code\"><\/span>Retrieving Character Data From Rendering Code<span class=\"ez-toc-section-end\"><\/span><\/h2>\n\n\n\n<p>The primary functionality of the Abomnification system is the provisioning of what the scale multipliers should be for a particular character given the current step its on in its morphing journey to randomly determined morphing targets. If the previous sentence makes no sense to you, I am sad to say that it will have to remain nonsense until I get a detailed overview article on the Abomnification system published. Sorry!<\/p>\n\n\n\n<p>Assuming that you&#8217;re following along still (hello there you brave warrior), in order to do the above, we need to be able to store character specific data in memory easily reachable while operating within contexts specific to that character. This is typically not the most arduous of things to accomplish; when processing movement related functions, for example, we&#8217;ll typically have a location structure for the creature on hand.<\/p>\n\n\n\n<p>Not so in the dark, dank world of graphics rendering logic. This is typically far removed from other parts of code that manage more recognizable gameplay elements, and it also tends to be very generalized. This is code that needs to be highly performant, and essentially is just some sort of provider of math operations on matrices.<\/p>\n\n\n\n<p>From the place in code where we&#8217;ve decided to inject our custom scaling mechanism, we need to be able to retrieve known data structures pertaining to the character whose model is being rendered. With all the games I&#8217;ve done this for, this has been very difficult, as it is typically buried very deeply in loosely related data structures. <\/p>\n\n\n\n<p>This will be the very first time we try to accomplish such a thing without the presence of RTTI, so my skills are going to be tested here&#8230;and I&#8217;m a bit nervous about whether or not I&#8217;ll be able to do it. Let&#8217;s proceed.<\/p>\n\n\n\n<h3><span class=\"ez-toc-section\" id=\"Finding_Some_Player_Data_Being_Rendered\"><\/span>Finding Some Player Data Being Rendered<span class=\"ez-toc-section-end\"><\/span><\/h3>\n\n\n\n<p>We need to devise a method on how to retrieve useful character data from within the model rendering function. Here&#8217;s how we&#8217;re going to do it:<\/p>\n\n\n\n<ul><li>We&#8217;ll acquire some data that we know belongs to our player that is being rendered by the code.<\/li><li>A breakpoint will be placed on that code so that it is triggered when said data is being processed.<\/li><li>From there, we&#8217;ll figure out if we can dig up any data that links to instances of known data types for our player.<\/li><\/ul>\n\n\n\n<p>If we can provide a means of determining that it is our player who is being rendered, then we should be able to do the same for all characters that are not our player. So let&#8217;s get a hold of some data we know is tied to our player first. To do that, let&#8217;s take a look at the instruction that is actually writing out the processed rendering data.<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-large\"><img loading=\"lazy\" width=\"946\" height=\"533\" src=\"https:\/\/badecho.com\/wp-content\/uploads\/2020\/12\/PotentialRenderingDrawingCode.png\" alt=\"Shows the code ultimately making use of the global scaling multiplier at its most common usage point.\" class=\"wp-image-938\" srcset=\"https:\/\/badecho.com\/wp-content\/uploads\/2020\/12\/PotentialRenderingDrawingCode.png 946w, https:\/\/badecho.com\/wp-content\/uploads\/2020\/12\/PotentialRenderingDrawingCode-300x169.png 300w, https:\/\/badecho.com\/wp-content\/uploads\/2020\/12\/PotentialRenderingDrawingCode-768x433.png 768w, https:\/\/badecho.com\/wp-content\/uploads\/2020\/12\/PotentialRenderingDrawingCode-480x270.png 480w\" sizes=\"(max-width: 946px) 100vw, 946px\" \/><figcaption>This is where the calculated values based on the global scale multiplier are saved.<\/figcaption><\/figure><\/div>\n\n\n\n<p>Let&#8217;s right click on this instruction and choose to <strong>Find out what addresses this instruction accesses<\/strong>. This is going to pop up a window displaying just that, and we should expect there to be many, many addresses listed.<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-large\"><img loading=\"lazy\" width=\"483\" height=\"533\" src=\"https:\/\/badecho.com\/wp-content\/uploads\/2020\/12\/DataAccessByPotential.png\" alt=\"Shows the most accessed data points (in reverse order) by the previously shown code.\" class=\"wp-image-939\" srcset=\"https:\/\/badecho.com\/wp-content\/uploads\/2020\/12\/DataAccessByPotential.png 483w, https:\/\/badecho.com\/wp-content\/uploads\/2020\/12\/DataAccessByPotential-272x300.png 272w, https:\/\/badecho.com\/wp-content\/uploads\/2020\/12\/DataAccessByPotential-480x530.png 480w\" sizes=\"(max-width: 483px) 100vw, 483px\" \/><figcaption>Sorted in reverse order, the data with the highest count will be our own character&#8217;s data.<\/figcaption><\/figure><\/div>\n\n\n\n<p>As you can see from the image above, there are over 2000 different addresses being processed by this rendering function. The majority of these addresses have <em>nothing<\/em> to do with our player. Thankfully, we can easily determine which ones are related to our player by one principle in particular that rendering functions like this one tend to follow.<\/p>\n\n\n\n<p>Rendering code is <em>very<\/em> performance sensitive. We&#8217;re talking about graphics here, this kind of thing is the bread and butter of most games these days. While there are many different things on a screen that will require rendering at a given point in time, less priority will be given to character models that are further off in the distance than ones nearby. <\/p>\n\n\n\n<p>So, bearing that in mind, if our character is standing by himself in the snow, then we can conclude with certainty that the points of data receiving the greatest amount of attention are indeed the player character himself. By sorting the list of addresses by execution count (in reverse order in the image, sorry!) I can stake my life on the bet that the topmost (bottommost in the image, sorry!) address is indeed player related.<\/p>\n\n\n\n<h3><span class=\"ez-toc-section\" id=\"Finding_the_Link_to_Known_Character_Data_Types\"><\/span>Finding the Link to Known Character Data Types<span class=\"ez-toc-section-end\"><\/span><\/h3>\n\n\n\n<p>Now that we have a chosen player data point of <code>176D9026E60<\/code>, let&#8217;s wire up a breakpoint to go off when this particular address is being processed.<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-large\"><img loading=\"lazy\" width=\"946\" height=\"533\" src=\"https:\/\/badecho.com\/wp-content\/uploads\/2020\/12\/RenderingDataOnStack.png\" alt=\"Shows the state of the registers and stack when accessing our user data.\" class=\"wp-image-940\" srcset=\"https:\/\/badecho.com\/wp-content\/uploads\/2020\/12\/RenderingDataOnStack.png 946w, https:\/\/badecho.com\/wp-content\/uploads\/2020\/12\/RenderingDataOnStack-300x169.png 300w, https:\/\/badecho.com\/wp-content\/uploads\/2020\/12\/RenderingDataOnStack-768x433.png 768w, https:\/\/badecho.com\/wp-content\/uploads\/2020\/12\/RenderingDataOnStack-480x270.png 480w\" sizes=\"(max-width: 946px) 100vw, 946px\" \/><figcaption>The highlighted entry on the stack may lead to data we can identify ourselves with.<\/figcaption><\/figure><\/div>\n\n\n\n<p>Looking up, in memory, all the addresses stored in the various CPU registers, I saw nothing but unwieldy globs of rendering data. While some sort of link may have been able to have been discovered amongst all this, I highly doubt it. With the registers not giving us anything useful, there was only one place left to go: the stack.<\/p>\n\n\n\n<p>Glancing over at the stack, it didn&#8217;t take long until I noticed the address stored at <code>[rsp+40]<\/code>: <code>176D9DA56F0<\/code>. This looked very promising, as it was distinct from the other addresses stored in registers while also falling within the memory range of known player creature data. So, biting the bullet, I decided to grab the address and plop it into a <em>Structure dissect<\/em> window and see if we could discover any relations to useful bits of data.<\/p>\n\n\n\n<p>Not knowing what type of data this was, I dubbed the structure <strong>Rendering Data<\/strong> and then proceeded to click on <strong>Structure Options -&gt; Find relations<\/strong>. In the resulting pop up window, we made sure all of the other data types had valid addresses associated with them, and then hit OK, hoping for the best.<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-large\"><img loading=\"lazy\" width=\"946\" height=\"533\" src=\"https:\/\/badecho.com\/wp-content\/uploads\/2020\/12\/RenderingDataLink.png\" alt=\"Shows the structural contents of the data pointed to by the stack at the rendering code, along with a successful mapping to our Location structure!\" class=\"wp-image-941\" srcset=\"https:\/\/badecho.com\/wp-content\/uploads\/2020\/12\/RenderingDataLink.png 946w, https:\/\/badecho.com\/wp-content\/uploads\/2020\/12\/RenderingDataLink-300x169.png 300w, https:\/\/badecho.com\/wp-content\/uploads\/2020\/12\/RenderingDataLink-768x433.png 768w, https:\/\/badecho.com\/wp-content\/uploads\/2020\/12\/RenderingDataLink-480x270.png 480w\" sizes=\"(max-width: 946px) 100vw, 946px\" \/><figcaption>A successful link to our user&#8217;s data from the rendering code! Hooray!<\/figcaption><\/figure><\/div>\n\n\n\n<p>Holy shit. I can&#8217;t believe it, but we&#8217;ve found a linking data structure already! Just a little down the stack, we have a path that will lead us to the location structure of the character being rendered! Wow, we&#8217;re actually going to be able to do this.<\/p>\n\n\n\n<h2><span class=\"ez-toc-section\" id=\"Implementing_the_Abomnification_Initiation_Point_Code\"><\/span>Implementing the Abomnification Initiation Point Code<span class=\"ez-toc-section-end\"><\/span><\/h2>\n\n\n\n<p>Everything we&#8217;ve been talking about up until now has been about the Abomnification scale application code: the code that will be responsible for <em>applying<\/em> the scales generated by the Abomnification system. The reason why we had to spend time on that whole thing was because there is no easy scaling support built into the game&#8217;s engine. <\/p>\n\n\n\n<p>I wanted to focus on the custom scaling code first because, without it, what we hope to achieve is impossible. So, now that we know we can actually implement this system, we&#8217;re going to switch gears to the writing of the <em>initiation point<\/em> for the Abomnification system. This is what gives us the per-character scale multipliers that are going to be applied by our custom scaling function. We&#8217;ll get back to implementing the custom scale function later.<\/p>\n\n\n\n<h3><span class=\"ez-toc-section\" id=\"Where_to_Initiate_the_Horror\"><\/span>Where to Initiate the Horror?<span class=\"ez-toc-section-end\"><\/span><\/h3>\n\n\n\n<p>The first question we need to ask ourselves: where should the initiation point go? Well, we actually want it to be somewhere <em>other<\/em> than the rendering logic. For optimal results, we need scale generation to be frequent, yet not as frequent as the actual rendering of it. Otherwise, the smoothness of the morphing animation will suffer as not all generated scales will be caught by the naked eye.<\/p>\n\n\n\n<p>My favorite place to initiate the Abomnification system is in a coordinate polling function that is checking on coordinates of the various entities on a map at a high rate. Preferably, a coordinate polling function that is <em>only<\/em> polling NPCs and not all the rocks and bushes is ideal. Unless we want the bushes to be on acid too. Which sounds kind of fun&#8230;<\/p>\n\n\n\n<p>To start the search for the perfect place, let&#8217;s right click on one of our coordinates and choose <strong>Find out what accesses this address<\/strong> to get a list of all the coordinate polling functions.<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-large\"><img loading=\"lazy\" width=\"946\" height=\"533\" src=\"https:\/\/badecho.com\/wp-content\/uploads\/2020\/12\/FindingAGoodAbomInitiationPoint.png\" alt=\"Shows the coordinate polling functions polling for our player's coordinates. There's a lot of them.\" class=\"wp-image-951\" srcset=\"https:\/\/badecho.com\/wp-content\/uploads\/2020\/12\/FindingAGoodAbomInitiationPoint.png 946w, https:\/\/badecho.com\/wp-content\/uploads\/2020\/12\/FindingAGoodAbomInitiationPoint-300x169.png 300w, https:\/\/badecho.com\/wp-content\/uploads\/2020\/12\/FindingAGoodAbomInitiationPoint-768x433.png 768w, https:\/\/badecho.com\/wp-content\/uploads\/2020\/12\/FindingAGoodAbomInitiationPoint-480x270.png 480w\" sizes=\"(max-width: 946px) 100vw, 946px\" \/><figcaption>Quite a few functions are groping our player&#8217;s coordinates.<\/figcaption><\/figure><\/div>\n\n\n\n<p>I&#8217;ve said it before, but this game has way more coordinate polling functions than any other game I&#8217;ve hacked. Just an interesting little tidbit. I must assume there&#8217;s a lot of movement related code, or systems that respond to our player&#8217;s movement, and that&#8217;s not surprising at all given that this is <em>Assassin&#8217;s Creed<\/em>.<\/p>\n\n\n\n<p>Ideally, we want a coordinate polling function that is high up on the list in terms of execution rate, and one that is polling not just our player, but other NPCs as well. Let&#8217;s start off by disassembling the topmost called function and seeing what addresses that one is accessing.<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-large\"><img loading=\"lazy\" width=\"508\" height=\"533\" src=\"https:\/\/badecho.com\/wp-content\/uploads\/2020\/12\/FailAbomInitPoint.png\" alt=\"Shows that the most frequently executed coordinate polling function is only looking at our player's coordinate. Absolute failure.\" class=\"wp-image-952\" srcset=\"https:\/\/badecho.com\/wp-content\/uploads\/2020\/12\/FailAbomInitPoint.png 508w, https:\/\/badecho.com\/wp-content\/uploads\/2020\/12\/FailAbomInitPoint-286x300.png 286w, https:\/\/badecho.com\/wp-content\/uploads\/2020\/12\/FailAbomInitPoint-480x504.png 480w\" sizes=\"(max-width: 508px) 100vw, 508px\" \/><figcaption>Oops. This just looks at our own player&#8217;s coordinates. Pathetic.<\/figcaption><\/figure><\/div>\n\n\n\n<p>This is a shame, but not entirely surprising. Typically, from what I&#8217;ve seen, the coordinate polling functions that are most frequently executing tend to be just looking at the player, for reasons that should be obvious (there is usually a vested interested in knowing where the player is at all times right?).<\/p>\n\n\n\n<p>This function was executing too much anyway, using it might&#8217;ve resulted in animations that were moving too fast. Let&#8217;s go down the list then to the next one, and see if the second most commonly executed coordinate polling function is pinging entities other than just the player. If that doesn&#8217;t work either, then we&#8217;ll keep on going down the list until we get something that does.<\/p>\n\n\n\n<h3><span class=\"ez-toc-section\" id=\"Some_Time_Passes%E2%80%A6-2\"><\/span>Some Time Passes&#8230;<span class=\"ez-toc-section-end\"><\/span><\/h3>\n\n\n\n<p>We&#8217;re not getting anywhere looking down this list. I was under the impression that I would easily find something usable near the top. Wrong.<\/p>\n\n\n\n<p>Let&#8217;s pivot here a bit, and instead take a look at the location update code, which we worked with <a href=\"https:\/\/badecho.com\/index.php\/2020\/12\/20\/hacking-ac-valhalla-part-3\/\" target=\"_blank\" rel=\"noreferrer noopener\">during our implementation of the Predator system<\/a>, and get a list of all of the addresses whose locations are being updated.<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-large\"><img loading=\"lazy\" width=\"508\" height=\"623\" src=\"https:\/\/badecho.com\/wp-content\/uploads\/2020\/12\/LocationUpdateWrites.png\" alt=\"Shows that there are 177 different things moving on the map right now. Wowza!\" class=\"wp-image-953\" srcset=\"https:\/\/badecho.com\/wp-content\/uploads\/2020\/12\/LocationUpdateWrites.png 508w, https:\/\/badecho.com\/wp-content\/uploads\/2020\/12\/LocationUpdateWrites-245x300.png 245w, https:\/\/badecho.com\/wp-content\/uploads\/2020\/12\/LocationUpdateWrites-480x589.png 480w\" sizes=\"(max-width: 508px) 100vw, 508px\" \/><figcaption>There are a lot of moving parts on the map.<\/figcaption><\/figure><\/div>\n\n\n\n<p>There&#8217;s over 177 different entities moving on this map! My thoughts are that perhaps there are a separate class of polling functions dedicated to tracking non-player entities. So, let&#8217;s grab one of these non-player coordinates and see what code is accessing them.<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-large\"><img loading=\"lazy\" width=\"946\" height=\"513\" src=\"https:\/\/badecho.com\/wp-content\/uploads\/2020\/12\/EnemyCoordinatePollingFunctions.png\" alt=\"Shows the code accessing the enemy's coordinates.\" class=\"wp-image-954\" srcset=\"https:\/\/badecho.com\/wp-content\/uploads\/2020\/12\/EnemyCoordinatePollingFunctions.png 946w, https:\/\/badecho.com\/wp-content\/uploads\/2020\/12\/EnemyCoordinatePollingFunctions-300x163.png 300w, https:\/\/badecho.com\/wp-content\/uploads\/2020\/12\/EnemyCoordinatePollingFunctions-768x416.png 768w, https:\/\/badecho.com\/wp-content\/uploads\/2020\/12\/EnemyCoordinatePollingFunctions-480x260.png 480w\" sizes=\"(max-width: 946px) 100vw, 946px\" \/><figcaption>A much shorter list of instructions are accessing the entity&#8217;s coordinates, as opposed to the player&#8217;s.<\/figcaption><\/figure><\/div>\n\n\n\n<p>This is a much more useful list of instructions to look at. Whether or not these also show up on the list of player coordinate accessing instructions is something unknown to me at the moment, but something I also know that will be made abundantly clear later on. Let&#8217;s look at one of the three most commonly executing instructions and see what addresses that one is accessing.<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-large\"><img loading=\"lazy\" width=\"508\" height=\"656\" src=\"https:\/\/badecho.com\/wp-content\/uploads\/2020\/12\/EnemyCoordinatePollingAccesses.png\" alt=\"Shows all the addresses being accessed by the enemy coordinate polling function.\" class=\"wp-image-955\" srcset=\"https:\/\/badecho.com\/wp-content\/uploads\/2020\/12\/EnemyCoordinatePollingAccesses.png 508w, https:\/\/badecho.com\/wp-content\/uploads\/2020\/12\/EnemyCoordinatePollingAccesses-232x300.png 232w, https:\/\/badecho.com\/wp-content\/uploads\/2020\/12\/EnemyCoordinatePollingAccesses-480x620.png 480w\" sizes=\"(max-width: 508px) 100vw, 508px\" \/><figcaption>A very slowly growing list of non-player entity coordinates are being accessed here.<\/figcaption><\/figure><\/div>\n\n\n\n<p>Looks like our entity coordinate polling function is accessing a healthy number of non-player coordinates. Great. One worry I had, though, is that the list was consistently growing. This is indicative of temporary objects being introduced into existence for a brief amount of time so they can do what they have to do before they&#8217;re snuffed out of existence.<\/p>\n\n\n\n<p>Why are these temporary objects being accessed in a supposed NPC coordinate polling function? Do we actually know that the coordinates we were looking at originally belong to NPCs? Just because they were having their locations updated means little!<\/p>\n\n\n\n<h3><span class=\"ez-toc-section\" id=\"Looking_at_the_Movement_Application_Code_for_Inspiration\"><\/span>Looking at the Movement Application Code for Inspiration<span class=\"ez-toc-section-end\"><\/span><\/h3>\n\n\n\n<p>One of our achievements during the implementation of the Predator system was the locating of the <a href=\"https:\/\/badecho.com\/index.php\/2020\/12\/20\/hacking-ac-valhalla-part-3\/#movement-application-code\" target=\"_blank\" rel=\"noreferrer noopener\">movement application code in this game<\/a>. This is code purposed for facilitating changes to NPC coordinates in response to movement. We should make use of this code to get a good sampling of actual enemy NPC coordinates.<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-large\"><img loading=\"lazy\" width=\"946\" height=\"533\" src=\"https:\/\/badecho.com\/wp-content\/uploads\/2020\/12\/TemporaryChangeToGetEnemyCoords.png\" alt=\"Shows a temporary change made to the Predator system so we can log known NPC coordinates.\" class=\"wp-image-958\" srcset=\"https:\/\/badecho.com\/wp-content\/uploads\/2020\/12\/TemporaryChangeToGetEnemyCoords.png 946w, https:\/\/badecho.com\/wp-content\/uploads\/2020\/12\/TemporaryChangeToGetEnemyCoords-300x169.png 300w, https:\/\/badecho.com\/wp-content\/uploads\/2020\/12\/TemporaryChangeToGetEnemyCoords-768x433.png 768w, https:\/\/badecho.com\/wp-content\/uploads\/2020\/12\/TemporaryChangeToGetEnemyCoords-480x270.png 480w\" sizes=\"(max-width: 946px) 100vw, 946px\" \/><figcaption>I temporarily add an access to the X coordinate so I can log the NPC location structures nicely.<\/figcaption><\/figure><\/div>\n\n\n\n<p>I&#8217;m going to right click now on the new instruction here, buried deep within the game&#8217;s movement application code, and check out what addresses it is accessing. This will produce a list of coordinates that are most definitely NPC coordinates.<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-large\"><img loading=\"lazy\" width=\"508\" height=\"656\" src=\"https:\/\/badecho.com\/wp-content\/uploads\/2020\/12\/AbsolutelyNPCCoordsOK.png\" alt=\"Shows addresses being accessed by the movement application code. There are only 13 NPC actually it seems.\" class=\"wp-image-959\" srcset=\"https:\/\/badecho.com\/wp-content\/uploads\/2020\/12\/AbsolutelyNPCCoordsOK.png 508w, https:\/\/badecho.com\/wp-content\/uploads\/2020\/12\/AbsolutelyNPCCoordsOK-232x300.png 232w, https:\/\/badecho.com\/wp-content\/uploads\/2020\/12\/AbsolutelyNPCCoordsOK-480x620.png 480w\" sizes=\"(max-width: 508px) 100vw, 508px\" \/><figcaption>Only 13. Not 200 something. Wowza.<\/figcaption><\/figure><\/div>\n\n\n\n<p>This is a much smaller list of coordinates than what we were seeing from the more generalized location update function. Let&#8217;s take a few of these coordinates and check out what kind of polling functions they got.<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-large\"><img loading=\"lazy\" width=\"651\" height=\"812\" src=\"https:\/\/badecho.com\/wp-content\/uploads\/2020\/12\/TrueNPCPollingFunction.png\" alt=\"Shows a distinct list of NPC coordinate polling function. Around 20+ of them.\" class=\"wp-image-960\" srcset=\"https:\/\/badecho.com\/wp-content\/uploads\/2020\/12\/TrueNPCPollingFunction.png 651w, https:\/\/badecho.com\/wp-content\/uploads\/2020\/12\/TrueNPCPollingFunction-241x300.png 241w, https:\/\/badecho.com\/wp-content\/uploads\/2020\/12\/TrueNPCPollingFunction-480x599.png 480w\" sizes=\"(max-width: 651px) 100vw, 651px\" \/><figcaption>A more realistic number of functions is presented here. Progress.<\/figcaption><\/figure><\/div>\n\n\n\n<p>Not as many functions as the player had, but more than the previous coordinates we were looking at had. I must conclude that those other coordinates were most likely not NPC coordinates. Well, we all learned something today.<\/p>\n\n\n\n<p>Here we go again. Let&#8217;s go through these, starting at the most frequently executed and working our way down, and see if we can&#8217;t find one accessing around the same number of addresses as the movement application code was. We want something that&#8217;s precise and only looking at actual NPC coordinates.<\/p>\n\n\n\n<p>After reaching the fourth instruction on the list, we hit gold! The number of addresses being accessed was something much more inline with the number of NPC&#8217;s I imagined to actually be on the map. Note that the player&#8217;s coordinates do actually show up here if we make any kind of movement. Thankfully, the enemy coordinates are consistently polled even if they aren&#8217;t moving.<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-large\"><img loading=\"lazy\" width=\"483\" height=\"539\" src=\"https:\/\/badecho.com\/wp-content\/uploads\/2020\/12\/ExcellentNPCCoordinateAccesses.png\" alt=\"Shows a nice list of only 19 addresses being accessed by the NPC coordinate polling function.\" class=\"wp-image-961\" srcset=\"https:\/\/badecho.com\/wp-content\/uploads\/2020\/12\/ExcellentNPCCoordinateAccesses.png 483w, https:\/\/badecho.com\/wp-content\/uploads\/2020\/12\/ExcellentNPCCoordinateAccesses-269x300.png 269w, https:\/\/badecho.com\/wp-content\/uploads\/2020\/12\/ExcellentNPCCoordinateAccesses-480x536.png 480w\" sizes=\"(max-width: 483px) 100vw, 483px\" \/><figcaption>Excellent.<\/figcaption><\/figure><\/div>\n\n\n\n<p>This indicates to me, that this is a supremely perfect spot for the Abomnification initiation point hook. Here is where we&#8217;ll be injecting it in:<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-large\"><img loading=\"lazy\" width=\"946\" height=\"533\" src=\"https:\/\/badecho.com\/wp-content\/uploads\/2020\/12\/AbomnificationInitiationPointCode.png\" alt=\"Shows where we'll be implementing the Abomnification initiation point. A perfect NPC coordinate polling function.\" class=\"wp-image-962\" srcset=\"https:\/\/badecho.com\/wp-content\/uploads\/2020\/12\/AbomnificationInitiationPointCode.png 946w, https:\/\/badecho.com\/wp-content\/uploads\/2020\/12\/AbomnificationInitiationPointCode-300x169.png 300w, https:\/\/badecho.com\/wp-content\/uploads\/2020\/12\/AbomnificationInitiationPointCode-768x433.png 768w, https:\/\/badecho.com\/wp-content\/uploads\/2020\/12\/AbomnificationInitiationPointCode-480x270.png 480w\" sizes=\"(max-width: 946px) 100vw, 946px\" \/><figcaption>We spent some time finding it, but this is the perfect spot.<\/figcaption><\/figure><\/div>\n\n\n\n<p>Now that we know where to implement the call to the Abomnification system, we should be good to go right? Nope, there&#8217;s one more itsy bitsy thing we got to do.<\/p>\n\n\n\n<h3><span class=\"ez-toc-section\" id=\"Figuring_Out_Where_to_Store_the_Morph_Scale_ID\"><\/span>Figuring Out Where to Store the Morph Scale ID<span class=\"ez-toc-section-end\"><\/span><\/h3>\n\n\n\n<p>The morph scale ID basically acts as an index, used to access a particular character&#8217;s morphing data in our sandboxed morphing data blob. We maintain all of the various Abomnification characteristics in memory separated from the game&#8217;s own, however we still need to store the morph scale ID somewhere in the memory used by the game so a data association is persisted.<\/p>\n\n\n\n<p>This morph scale ID only requires 4 bytes of memory, and we want to store it in a commonly accessed type of character data, mainly for convenience&#8217;s sake. Because we know from earlier that the character location structure is accessible from within the rendering method we&#8217;ll be hooking into, we&#8217;re going to want to find 4 bytes of available data there to store it in.<\/p>\n\n\n\n<p>Naturally, just throwing bytes around in program memory being used by a program is a recipe for disaster. Nevertheless, we need to find an empty pocket, where it won&#8217;t cause a crash and where it won&#8217;t be overwritten.<\/p>\n\n\n\n<p>We&#8217;ll first want to get together some sample data to test it with, here&#8217;s how we&#8217;re going to do that:<\/p>\n\n\n\n<ol><li>Browse to the code we identified as the ideal location for our Abomnification initiation point hook. This part of the code just deals with non-player character location structures.<\/li><li>Right click on the instruction that is loading the location structure and then click <strong>Find out what addresses this instruction accesses<\/strong>.<\/li><li>Highlight all the addresses in the window that pops up, right click and select <strong>Open dissect data with selected addresses<\/strong>.<\/li><li>Name the structure anything you want, and then hit OK a bunch of times.<\/li><\/ol>\n\n\n\n<p>If we had a preexisting structure defined that would work with this data, you&#8217;d probably want to load up a Structure dissect window of that first, and then just use that window. However, while we do have a location structure defined, it is aligned slightly differently (X coordinate starts at <code>0x50<\/code>, not <code>0x30<\/code>).<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-large\"><img loading=\"lazy\" width=\"1024\" height=\"622\" src=\"https:\/\/badecho.com\/wp-content\/uploads\/2020\/12\/SampleDataForMorphScale-1024x622.png\" alt=\"Shows a structure dissect window full of sample enemy location data.\" class=\"wp-image-964\" srcset=\"https:\/\/badecho.com\/wp-content\/uploads\/2020\/12\/SampleDataForMorphScale-1024x622.png 1024w, https:\/\/badecho.com\/wp-content\/uploads\/2020\/12\/SampleDataForMorphScale-300x182.png 300w, https:\/\/badecho.com\/wp-content\/uploads\/2020\/12\/SampleDataForMorphScale-768x467.png 768w, https:\/\/badecho.com\/wp-content\/uploads\/2020\/12\/SampleDataForMorphScale-480x292.png 480w, https:\/\/badecho.com\/wp-content\/uploads\/2020\/12\/SampleDataForMorphScale.png 1117w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><figcaption>We can find pockets of usable data from here.<\/figcaption><\/figure><\/div>\n\n\n\n<p>Now that we have some sample data loaded up, we can look around the memory to find some empty pockets. We want to find green rows of 0&#8217;s, preferably one padded by a bunch of other rows of empty memory. There should be some somewhere, no program ever uses all the memory allocated to it. <\/p>\n\n\n\n<p>Once we find a row of data we want to try out, we write it down for later reference. We&#8217;re going to write some code now that will set our selected 4 bytes of memory to an arbitrary value. We will run the hook, and then disable the hook. The goal will be for the data to stick (not disappear) and for no crashes to happen.<\/p>\n\n\n\n<h4><span class=\"ez-toc-section\" id=\"Morph_Scale_ID_Test_Hook\"><\/span>Morph Scale ID Test Hook<span class=\"ez-toc-section-end\"><\/span><\/h4>\n\n\n<pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\ndefine(address,&quot;ACValhalla.exe&quot;+EC71DE)\ndefine(bytes,0F 58 49 30 0F C6 D2 00)\n\n[ENABLE]\n\nassert(address,bytes)\nalloc(newmem,$1000,&quot;ACValhalla.exe&quot;+EC71DE)\n\nlabel(code)\nlabel(return)\n\nnewmem:\n  mov [rcx+194],0x5\ncode:\n  addps xmm1,[rcx+30]\n  shufps xmm2,xmm2,00\n  jmp return\n\naddress:\n  jmp newmem\n  nop 3\nreturn:\n<\/pre>\n\n\n<p>This is just some brutally simple code which will try to set <code>[rcx+194]<\/code> to our arbitrary value. Let&#8217;s hook it into the code and&#8230;see if the game crashes.<\/p>\n\n\n\n<p>After running the hook and then disabling it (while holding my breath), it appears that most of the row got its value changed to our arbitrary value. Scrolling up on the column for which the data did not stick, I quickly saw that it had actually become recycled junk memory. So I removed it.<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-large\"><img loading=\"lazy\" width=\"1024\" height=\"622\" src=\"https:\/\/badecho.com\/wp-content\/uploads\/2020\/12\/GoodMorphScaleIDLocation-1024x622.png\" alt=\"Shows a green row of all 5's where we tested writing a fake morph scale ID.\" class=\"wp-image-965\" srcset=\"https:\/\/badecho.com\/wp-content\/uploads\/2020\/12\/GoodMorphScaleIDLocation-1024x622.png 1024w, https:\/\/badecho.com\/wp-content\/uploads\/2020\/12\/GoodMorphScaleIDLocation-300x182.png 300w, https:\/\/badecho.com\/wp-content\/uploads\/2020\/12\/GoodMorphScaleIDLocation-768x467.png 768w, https:\/\/badecho.com\/wp-content\/uploads\/2020\/12\/GoodMorphScaleIDLocation-480x292.png 480w, https:\/\/badecho.com\/wp-content\/uploads\/2020\/12\/GoodMorphScaleIDLocation.png 1117w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><figcaption>The 0x194 offset row is all nice and green. Perfect!<\/figcaption><\/figure><\/div>\n\n\n\n<p>That was fast! And lucky! Hmm&#8230;the fastest and luckiest I&#8217;ve ever been actually. Which leaves me with a sense of dread; a type of foreboding feeling permeating through my very soul. There are some additional things we probably want to do in order to ensure that this is a stable place to store our morph scale ID:<\/p>\n\n\n\n<ul><li>Run by one of the enemies whose coordinates belong to our sample data. See if the memory we&#8217;re using to store the morph scale ID doesn&#8217;t suddenly get overwritten by data that appears due to combat\/aggression code activating.<\/li><li>Walking some distance in order to recycle the creature data, see if that crashes the game.<\/li><li>Reload the game or even quit to the main menu, see if that crashes the game.<\/li><\/ul>\n\n\n\n<p>These are all things you probably want to do in order to ensure that we found the right place. I&#8217;m in a good mood though, and I&#8217;m feeling lucky, so I&#8217;m just going to get on with it and deal with the fallout later. I&#8217;m sure I won&#8217;t regret this.<\/p>\n\n\n\n<p>Well, we got everything we need. Everything! Not even lying. Let&#8217;s get to the code writing.<\/p>\n\n\n\n<h3><span class=\"ez-toc-section\" id=\"Writing_the_Initiation_Point_Code\"><\/span>Writing the Initiation Point Code<span class=\"ez-toc-section-end\"><\/span><\/h3>\n\n\n\n<p>We know where we&#8217;re going to store the morph scale ID, and we know where we&#8217;re going to hook our initiation point in. Let&#8217;s get it on then, and start with a barebones hook template that we&#8217;ll be filling in.<\/p>\n\n\n\n<h4><span class=\"ez-toc-section\" id=\"Abomnification_Initiation_Hook_%E2%80%93_Template\"><\/span>Abomnification Initiation Hook &#8211; Template<span class=\"ez-toc-section-end\"><\/span><\/h4>\n\n\n<pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\n\/\/ Initiates the Abomnification system.\n\/\/ UNIQUE AOB: 0F 58 49 30 0F C6 D2 00 0F\ndefine(omnifyAbomnificationHook, &quot;ACValhalla.exe&quot; + EC71DE)\n\nassert(omnifyAbomnificationHook, 0F 58 49 30 0F C6 D2 00)\nalloc(initiateAbomnification,$1000, omnifyAbomnificationHook)\n\nregistersymbol(omnifyAbomnificationHook)\n\ninitiateAbomnification:\n\ninitiateAbomnificationOriginalCode:\n  addps xmm1,[rcx+30]\n  shufps xmm2,xmm2,00\n  jmp initiateAbomnificationReturn\n\n\nomnifyAbomnificationHook:\n  jmp initiateAbomnification\n  nop 3\ninitiateAbomnificationReturn:\n<\/pre>\n\n\n<p>The Abomnification system must be executed so that the next scale multipliers for the creature are locked and loaded prior to execution reaching the <code>initiateAbomnificationOriginalCode<\/code> label. This is actually very simple. Trust me.<\/p>\n\n\n\n<p>The main Abomnification function is named <code>executeAbomnification<\/code>. As is tradition, I must apologize here for not having a dedicated <a href=\"https:\/\/badecho.com\/index.php\/category\/omnified-design\/\" target=\"_blank\" rel=\"noreferrer noopener\">Omnified Design<\/a> article on the Abomnification system yet, which would explain all of this. One day I shall have it though, and all wrongs will be righted.<\/p>\n\n\n\n<p>But we barely need any documentation, because this function is very simple. Here are the parameters and return values:<\/p>\n\n\n\n<h4><span class=\"ez-toc-section\" id=\"Parameters\"><\/span>Parameters<span class=\"ez-toc-section-end\"><\/span><\/h4>\n\n\n\n<ul><li>Address to memory holding the creature&#8217;s morph scale ID.<\/li><\/ul>\n\n\n\n<h4><span class=\"ez-toc-section\" id=\"Return_Values\"><\/span>Return Values<span class=\"ez-toc-section-end\"><\/span><\/h4>\n\n\n\n<ul><li><code>eax<\/code>: Set to the updated width scale.<\/li><li><code>ebx<\/code>: Set to the updated height scale.<\/li><li><code>ecx<\/code>: Set to the updated depth scale.<\/li><\/ul>\n\n\n\n<p>So, that&#8217;s not bad right? Usually I have at least four parameters required to call these fuckers. We don&#8217;t even need to use the return values, even though it would be nice if we could, as we don&#8217;t actually apply the scale here. That&#8217;s what the Abomnification scale application hook does (needed because this game has no built-in easy scaling).<\/p>\n\n\n\n<p>The only thing we need to bear in mind is to exclude the player&#8217;s own coordinates from being processed, as we don&#8217;t want the player to be morphing out of the box.<\/p>\n\n\n\n<p>Anyway, this is so simple I can just whip it out all at once, so here it is baby:<\/p>\n\n\n\n<h4><span class=\"ez-toc-section\" id=\"Abomnification_Initiation_Hook_With_Morph_Scale_ID\"><\/span>Abomnification Initiation Hook With Morph Scale ID<span class=\"ez-toc-section-end\"><\/span><\/h4>\n\n\n<pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\n\/\/ Initiates the Abomnification system.\n\/\/ UNIQUE AOB: 0F 58 49 30 0F C6 D2 00 0F\ndefine(omnifyAbomnificationHook, &quot;ACValhalla.exe&quot; + EC71DE)\n\nassert(omnifyAbomnificationHook, 0F 58 49 30 0F C6 D2 00)\nalloc(initiateAbomnification,$1000, omnifyAbomnificationHook)\n\nregistersymbol(omnifyAbomnificationHook)\n\ninitiateAbomnification:\n  pushf\n  \/\/ Ensure that the player location struct has been initialized.\n  push rax\n  mov rax,playerLocation\n  cmp [rax],0\n  pop rax\n  je initiateAbomnificationOriginalCode\n  \/\/ Ensure that the player isn't going to be Abomnified.\n  push rax\n  push rbx\n  mov rax,playerLocation\n  mov rbx,[rax]\n  \/\/ The addresses in this function are aligned so that the coordinates\n  \/\/ begin at 0x30, whereas with our pointer, the coordinates start at\n  \/\/ 0x50.\n  add rbx,20\n  cmp rbx,rcx\n  pop rbx\n  pop rax\n  je initiateAbomnificationOriginalCode\n  \/\/ Back up the registers used to hold return values.\n  push rax\n  push rbx\n  push rcx\n  \/\/ Load the address for where the morph scale ID is stored.\n  lea rax,[rcx+194]\n  \/\/ Push our sole parameter and call the Abomnification system.\n  push rax\n  call executeAbomnification  \n  \/\/ Restore the preserved values on the stack.\n  pop rcx\n  pop rbx\n  pop rax\ninitiateAbomnificationOriginalCode:\n  popf\n  addps xmm1,[rcx+30]\n  shufps xmm2,xmm2,00\n  jmp initiateAbomnificationReturn\n\n\nomnifyAbomnificationHook:\n  jmp initiateAbomnification\n  nop 3\ninitiateAbomnificationReturn:\n<\/pre>\n\n\n<p>In addition to this code, we&#8217;re going to make some initial tunings of the Abomnification system&#8217;s external parameters. We&#8217;ve gotten an idea of what we want our maximum dimensional values to be during our testing of the custom scaling function, but we won&#8217;t know what our desired morph step maximum is until we have everything setup.<\/p>\n\n\n\n<p>Here are my initial guesses on what some good tunings might be:<\/p>\n\n\n\n<h4><span class=\"ez-toc-section\" id=\"External_Parameters\"><\/span>External Parameters<span class=\"ez-toc-section-end\"><\/span><\/h4>\n\n\n<pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\nabomnifyWidthResultUpper:\n  dd #250\n  \nabomnifyHeightResultUpper:\n  dd #160\n  \nabomnifyDepthResultUpper:\n  dd #200\n<\/pre>\n\n\n<p>And that&#8217;s it! Because there is no built-in easy scaling, we simply disregard the return values here. We&#8217;ll be retrieving them later on in the Abomnification scale application hook to get them rendered.<\/p>\n\n\n\n<p>We can tell that everything is working by just taking a peek at the <code>morphScaleData<\/code> region of memory. If everything is all good, it&#8217;ll look <em>very<\/em> busy.<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-large\"><img loading=\"lazy\" width=\"946\" height=\"533\" src=\"https:\/\/badecho.com\/wp-content\/uploads\/2020\/12\/BusyMorphScaleData.png\" alt=\"Shows a busy looking morphScaleData region. A bunch of red memory indicating values being updated with generated scaling parameters.\" class=\"wp-image-966\" srcset=\"https:\/\/badecho.com\/wp-content\/uploads\/2020\/12\/BusyMorphScaleData.png 946w, https:\/\/badecho.com\/wp-content\/uploads\/2020\/12\/BusyMorphScaleData-300x169.png 300w, https:\/\/badecho.com\/wp-content\/uploads\/2020\/12\/BusyMorphScaleData-768x433.png 768w, https:\/\/badecho.com\/wp-content\/uploads\/2020\/12\/BusyMorphScaleData-480x270.png 480w\" sizes=\"(max-width: 946px) 100vw, 946px\" \/><figcaption>Our morph scale data region is busy at work.<\/figcaption><\/figure><\/div>\n\n\n\n<p>Since this code has been tested pretty heavily through its use with other games, normally it is expected that it will just work right off the bat. Not so in this case.<\/p>\n\n\n\n<h3><span class=\"ez-toc-section\" id=\"4_Byte_Memory_Woes\"><\/span>4 Byte Memory Woes<span class=\"ez-toc-section-end\"><\/span><\/h3>\n\n\n\n<p>Although it would appear that everything worked hunky-dory right from the get go, you would know that not to be the case if you were watching me write this article live on my <a href=\"https:\/\/twitch.tv\/omni\" target=\"_blank\" rel=\"noreferrer noopener\">stream<\/a>. In fact, the first time we tried running the code, the game crashed.<\/p>\n\n\n\n<p>Restarting the game, I added some thread isolation code so that I could monitor a single thread of execution at a time; needed since this area of the code was very multithreaded. I then monitored a single execution of the hook, and verified that the stack was uncorrupted with the correct address being pointed to by <code>rsp<\/code> at the hook&#8217;s completion.<\/p>\n\n\n\n<p>But it would still crash as soon as I hit <strong>Run<\/strong> after one successful execution of the new code. It had to be something to do with where or how we were storing the morph scale ID in the game&#8217;s memory.<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-large\"><img loading=\"lazy\" width=\"946\" height=\"533\" src=\"https:\/\/badecho.com\/wp-content\/uploads\/2020\/12\/MorphScaleIdNextToString.png\" alt=\"Shows the morph scale ID row highlighted, with the neighboring &quot;string&quot; value right below it.\" class=\"wp-image-967\" srcset=\"https:\/\/badecho.com\/wp-content\/uploads\/2020\/12\/MorphScaleIdNextToString.png 946w, https:\/\/badecho.com\/wp-content\/uploads\/2020\/12\/MorphScaleIdNextToString-300x169.png 300w, https:\/\/badecho.com\/wp-content\/uploads\/2020\/12\/MorphScaleIdNextToString-768x433.png 768w, https:\/\/badecho.com\/wp-content\/uploads\/2020\/12\/MorphScaleIdNextToString-480x270.png 480w\" sizes=\"(max-width: 946px) 100vw, 946px\" \/><figcaption>The highlighted row is the morph scale ID, with a &#8220;string&#8221; neighbor 4 bytes away.<\/figcaption><\/figure><\/div>\n\n\n\n<p>If you look at the image, you&#8217;ll notice that right underneath the morph scale ID row (which is highlighted) there is some &#8220;string&#8221; data being harbored. What was happening, before I fixed it, is that the string data (which is really probably not meant to be string data, but whatever) would disappear after our Abomnification system code committed a morph scale ID.<\/p>\n\n\n\n<p>Ahh. After seeing that, it became very clear: we were corrupting data that was used by the game for important things. This is a great illustration of the elusive nature of the many kinds of problems one gets when messing with the power of the GODS.<\/p>\n\n\n\n<p>As was mentioned before, and as it is shown in the structure dissect window, we only meant to dedicate 4 bytes of room for storing our morph scale ID. However, when we were saving it, we must&#8217;ve been writing 8 bytes at a time, screwing with the &#8220;string&#8221; value neighbor. Here is the Abomnification code (from the Omnified framework) responsible for that:<\/p>\n\n\n\n<h4><span class=\"ez-toc-section\" id=\"Bad_Abomnification_Code\"><\/span>Bad Abomnification Code<span class=\"ez-toc-section-end\"><\/span><\/h4>\n\n\n<pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\nincrementMorphDataIndex:\n  inc [morphScaleIndex]\n  mov rcx,[morphScaleIndex]\n  mov [rbx],rcx\n<\/pre>\n\n\n<p>In the final instruction, by moving the entire <code>rcx<\/code> register into the memory pointed to by the <code>rbx<\/code> register, we were overwriting 8 bytes of data. This was a no-no. To overwrite 4 bytes of data instead, we want to make use of the 32-bit form of the register.<\/p>\n\n\n\n<h4><span class=\"ez-toc-section\" id=\"Good_Abomnification_Code\"><\/span>Good Abomnification Code<span class=\"ez-toc-section-end\"><\/span><\/h4>\n\n\n<pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\nincrementMorphDataIndex:\n  inc [morphScaleIndex]\n  mov rcx,[morphScaleIndex]\n  mov [rbx],ecx\n<\/pre>\n\n\n<p>As you can see, we&#8217;re using the <code>ecx<\/code> register in the operand now as opposed to the <code>rcx<\/code> register. With this change committed, we no longer were guilty of overwriting important data used by the game! Yay!<\/p>\n\n\n\n<p>But problems still persisted. When looking at the <code>morphScaleData<\/code> region of code, I noticed that nothing was being written to it. Oops. Clearly some other part of the Abomnification code was continuing to have issues with the data neighboring our morph scale ID. In fact, it was the code right below where we just were.<\/p>\n\n\n\n<h4><span class=\"ez-toc-section\" id=\"More_Bad_Abomnification_Code\"><\/span>More Bad Abomnification Code<span class=\"ez-toc-section-end\"><\/span><\/h4>\n\n\n<pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\napplyMorphScaleFromData:  \n  mov rdx,morphScaleData\n  mov rcx,[rbx]   \n  cmp rcx,#999\n  ja executeAbomnificationCleanup\n  push rax  \n  push rdx\n  mov rax,rcx\n  mov rcx,#48\n  mul rcx\n  mov rcx,rax  \n  pop rdx\n  pop rax\n  add rdx,rcx  \n  cmp [rdx],0\n<\/pre>\n\n\n<p>There are two things wrong with the code above:<\/p>\n\n\n\n<ol><li>The entire 8 bytes of the <code>rcx<\/code> register is being compared in the <code>cmp rcx,#999<\/code> instruction. This will include the junk data from the morph scale ID&#8217;s neighbor, which will cause the comparison to always return false (even if the morph scale ID is way below 999).<\/li><li>The morph scale ID is being used as the multiplier in the <code>mul<\/code> instruction found halfway through the code. This resulted in the entire 8 bytes of data being multiplied and included in the product used as the ultimate address to the character&#8217;s morphing scale data. We have no control over the data widths used when something is the multiplicand, we instead need to use it as the multiplier so we can specify to only include the lower 4 bytes of data.<\/li><\/ol>\n\n\n\n<p>Taking all of that into account, we made the appropriate corrections to the code.<\/p>\n\n\n\n<h4><span class=\"ez-toc-section\" id=\"More_Good_Abomnification_Code\"><\/span>More Good Abomnification Code<span class=\"ez-toc-section-end\"><\/span><\/h4>\n\n\n<pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\nincrementMorphDataIndex:\n  inc [morphScaleIndex]\n  mov rcx,[morphScaleIndex]\n  mov [rbx],ecx\napplyMorphScaleFromData:  \n  mov rdx,morphScaleData\n  mov rcx,[rbx]   \n  cmp ecx,#999\n  ja executeAbomnificationCleanup\n  push rax  \n  push rdx\n  mov rax,#48\n  mul ecx\n  mov rcx,rax  \n  pop rdx\n  pop rax\n  add rdx,rcx  \n  cmp [rdx],0\n<\/pre>\n\n\n<p>And after that, everything worked beautifully! Hopefully this serves as a lesson to someone out there who runs into a similar problem.<\/p>\n\n\n\n<h3><span class=\"ez-toc-section\" id=\"A_Better_Morph_Scale_ID_Location\"><\/span>A Better Morph Scale ID Location<span class=\"ez-toc-section-end\"><\/span><\/h3>\n\n\n\n<p>As I feared earlier on in the article, our designated location of <code>0x194<\/code>, while appearing stable, ultimately was not. I noticed that the game began to crash upon dying, or when getting too close to enemies. I immediately recognized that as something symptomatic of data being in the wrong place at the wrong time; the bad data, in this case, being the morph scale ID.<\/p>\n\n\n\n<p>I loaded up a dissect structure window with a bunch of NPC location data again and proceeded to jot down all the empty memory. After trying a number of different ones, all leading to crashes, we finally settled on <code>0x178<\/code>, which was the first one for which values stuck and no crashes occurred.<\/p>\n\n\n\n<p>Hopefully it will hold true pending further testing. But, as it turns out&#8230;it did not.<\/p>\n\n\n\n<h3><span class=\"ez-toc-section\" id=\"Doing_Away_With_the_Morph_Scale_ID\"><\/span>Doing Away With the Morph Scale ID<span class=\"ez-toc-section-end\"><\/span><\/h3>\n\n\n\n<p>Nearly two days of stream time passed where I would make some kind of progress and then things would inevitably regress back to me having to fix something to do with the morph scale ID.<\/p>\n\n\n\n<p>Out of all the things required for the sometimes complicated implementation of the Abomnification system, the most problematic has always been the storage of the morph scale ID, used for looking up a creature&#8217;s morphing data. <\/p>\n\n\n\n<p>The idea of a morph scale ID itself was an improvement upon the original solution, which required storing 13 or so separate data points in creature data. That was a giant pain in the ass at the time, and I can&#8217;t believe I ever got that to work. But I did. You can call me a lot of things, but you can&#8217;t call me lazy!<\/p>\n\n\n\n<p>The placement of the morph scale ID into <em>Assassin&#8217;s Creed: Valhalla<\/em> was becoming too big of a problem, however. Having only a meager amount of data relations mapped out due to no RTTI (though, to be fair, we have the most data ever mapped without it), we consequently have limited mobility in terms of data placement. It essentially <em>has<\/em> to be somewhere nearby the location data.<\/p>\n\n\n\n<p>After ending the stream one night in a huff and puff, I finally did away with the morph scale ID requirement. It is no longer required in order to lookup a creature&#8217;s morphing data. Now, all we need is some sort of identifying address to do the lookup; in the case of <em>Assassin&#8217;s Creed: Valhalla<\/em>, we will be using the creature&#8217;s location structure address as the identifying address.<\/p>\n\n\n\n<p>Details on how I got this magic to work will be covered in the Abomnification design article. So, if you are curious about how I managed to do it, I hope you&#8217;re looking forward to reading that!<\/p>\n\n\n\n<p>Because we changed how we&#8217;re looking up morphing scale data, we need to redo our implementation of the initiation point hook. So, I now present to you the initiation point code, in its final form.<\/p>\n\n\n\n<h4><span class=\"ez-toc-section\" id=\"Abomnification_Initiation_Hook_Without_Morph_Scale_ID\"><\/span>Abomnification Initiation Hook Without Morph Scale ID<span class=\"ez-toc-section-end\"><\/span><\/h4>\n\n\n<pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\n\/\/ Initiates the Abomnification system.\n\/\/ UNIQUE AOB: 0F 58 49 30 0F C6 D2 00 0F\ndefine(omnifyAbomnificationHook, &quot;ACValhalla.exe&quot; + EC71DE)\n\nassert(omnifyAbomnificationHook, 0F 58 49 30 0F C6 D2 00)\nalloc(initiateAbomnification,$1000, omnifyAbomnificationHook)\n\nregistersymbol(omnifyAbomnificationHook)\n\ninitiateAbomnification:\n  pushf\n  \/\/ Ensure that the player location struct has been initialized.\n  push rax\n  mov rax,playerLocation\n  cmp [rax],0\n  pop rax\n  je initiateAbomnificationOriginalCode \n  \/\/ Back up the registers used to hold return values.\n  push rax\n  push rbx\n  push rcx\n  \/\/ The addresses in this function are aligned so that the coordinates\n  \/\/ begin at 0x30, whereas their alignment in most of the other places we \n  \/\/ work with them is such that the coordinates start at 0x50.\n  add rcx,-20\n  \/\/ Ensure that the player isn't going to be Abomnified.\n  mov rax,playerLocation\n  mov rbx,[rax]\n  cmp rbx,rcx\n  je initiateAbomnificationExit\n  \/\/ Push the identifying address parameter and call the Abomnification system.  \n  push rcx\n  call executeAbomnification    \ninitiateAbomnificationExit:\n  \/\/ Restore the preserved values on the stack.\n  pop rcx\n  pop rbx\n  pop rax\ninitiateAbomnificationOriginalCode:\n  popf\n  addps xmm1,[rcx+30]\n  shufps xmm2,xmm2,00\n  jmp initiateAbomnificationReturn\n\n\nomnifyAbomnificationHook:\n  jmp initiateAbomnification\n  nop 3\ninitiateAbomnificationReturn:\n<\/pre>\n\n\n<h2><span class=\"ez-toc-section\" id=\"Implementing_the_Abomnification_Scale_Application_Code\"><\/span>Implementing the Abomnification Scale Application Code<span class=\"ez-toc-section-end\"><\/span><\/h2>\n\n\n\n<p>As has been stated time and time again in this article, we were unable to find any sort of built-in easy scaling support in <em>Assassin&#8217;s Creed: Valhalla<\/em>. Therefore, we must provide our own scaling mechanism. We have already spent the time, sweated the sweat, and bled the blood required in order to find the primary character model rendering code. <\/p>\n\n\n\n<p>This rendering code will serve as an excellent home to our custom scaling function, and it is located at the lofty address of <code>ACValhalla.exe+E8F453<\/code>. Lets get going then, and whip up a template for injecting into this code, and work from there.<\/p>\n\n\n\n<h3><span class=\"ez-toc-section\" id=\"Abomnification_Scale_Application_Hook_%E2%80%93_Template\"><\/span>Abomnification Scale Application Hook &#8211; Template<span class=\"ez-toc-section-end\"><\/span><\/h3>\n\n\n<pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\n\/\/ Applies Abomnification generated scale multipliers.\n\/\/ Unique AOB: 44 0F 59 05 15 B0 2C 03\ndefine(omnifyApplyAbomnificationHook, &quot;ACValhalla.exe&quot; + E8F453)\n\nassert(omnifyApplyAbomnificationHook, 44 0F 59 05 15 B0 2C 03)\nalloc(applyAbomnification,$1000, omnifyApplyAbomnificationHook)\n\nregistersymbol(omnifyApplyAbomnificationHook)\n\napplyAbomnification:\n\napplyAbomnificationOriginalCode:\n  mulps xmm8,[ACValhalla.exe+415A470]\n  jmp applyAbomnificationReturn\n\n\nomnifyApplyAbomnificationHook:\n  jmp applyAbomnification\n  nop 3\napplyAbomnificationReturn:\n<\/pre>\n\n\n<p>Our goal here is to apply the Abomnification system&#8217;s generated scale multipliers for the character being rendered prior to the <code>applyAbomnificationOriginalCode<\/code> label being hit. The multipliers need to be applied to the contents of the <code>xmm8<\/code> register, whose values have the following characteristics:<\/p>\n\n\n\n<ul><li>The first floating point affects the width.<\/li><li>The second floating point affects the depth.<\/li><li>The third floating point affects the height.<\/li><li>The fourth floating point will be zeroed out later on. So it doesn&#8217;t matter.<\/li><\/ul>\n\n\n\n<p>In order to retrieve the multipliers we need to apply here, we&#8217;ll need to retrieve the identifying address of the character in question. As we noted in the previous section, we are using the location structure address for a character to identify said character. And, as we also figured out earlier, we&#8217;ll be able to get the location address by traversing the following path on the stack: <code>[[rsp+40]+18]<\/code>. <\/p>\n\n\n\n<p>If this data is not always present, we will need to do some pointer checks. Currently the only bad data we&#8217;re aware of is the address returned by <code>[[rsp+40]+18]<\/code>, which can sometimes be a bad pointer. So we&#8217;ll add a pointer check for that. <\/p>\n\n\n\n<p>Also, sometimes the data returned by <code>[rsp+40]<\/code> is a structure containing a pointer to a non-location structure at the same offset of <code>0x18<\/code>. A simple check for a <strong>0<\/strong> at offset <code>0x14<\/code> filters this problematic data out.<\/p>\n\n\n\n<p>Finally, one other thing we need to account for here is the shifting of the stack from the bit of data preservation we&#8217;ll be doing. The stack will be shifted by the following actions:<\/p>\n\n\n\n<ul><li>Conditional flags will be backed up, as is the norm for us. That&#8217;s <strong>2<\/strong> bytes.<\/li><li>We&#8217;ll be backing up the <code>rax<\/code>, <code>rbx<\/code>, and <code>rcx<\/code> registers, as these are used to hold the return values by <code>getAbomnifiedScales<\/code>. That&#8217;s three registers at <strong>8<\/strong> bytes each for a total of <strong>24<\/strong> bytes.<\/li><li>We&#8217;ll need to back up a SSE register to hold the multipliers we&#8217;ll be multiplying against <code>xmm8<\/code>. That&#8217;s <strong>16<\/strong> bytes.<\/li><\/ul>\n\n\n\n<p>Adding that all up, we get a total of <strong>42<\/strong> bytes. This means <code>[rsp+40]<\/code> will be shifting to <code>[rsp+6A]<\/code>.<\/p>\n\n\n\n<p>Once we have the location address, we&#8217;ll be executing the Abomnification system exported function <code>getAbomnifiedScales<\/code> (a new function I wrote while doing this) with the identifying address as the sole parameter to retrieve the scale multipliers for the character. <\/p>\n\n\n\n<p>Without further adieu, here is the complete Abomnification scale application code.<\/p>\n\n\n\n<h3><span class=\"ez-toc-section\" id=\"Abomnification_Scale_Application_Hook\"><\/span>Abomnification Scale Application Hook<span class=\"ez-toc-section-end\"><\/span><\/h3>\n\n\n<pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\n\/\/ Applies Abomnification generated scale multipliers.\n\/\/ Unique AOB: 44 0F 59 05 15 B0 2C 03\ndefine(omnifyApplyAbomnificationHook, &quot;ACValhalla.exe&quot; + E8F453)\n\nassert(omnifyApplyAbomnificationHook, 44 0F 59 05 15 B0 2C 03)\nalloc(applyAbomnification,$1000, omnifyApplyAbomnificationHook)\n\nregistersymbol(omnifyApplyAbomnificationHook)\n\napplyAbomnification:\n  pushf\n  \/\/ Ensure that the player location struct has been initialized.\n  push rax\n  mov rax,playerLocation\n  cmp [rax],0\n  pop rax\n  je applyAbomnificationOriginalCode\n  \/\/ Backing up an SSE register to hold our multiplier.\n  sub rsp,10\n  movdqu [rsp],xmm0  \n  \/\/ Backing up the registers used to hold return values by the\n  \/\/ Abomnification system.\n  push rax\n  push rbx\n  push rcx  \n  \/\/ A rendering supplementary data structure is stored on the stack.\n  mov rax,[rsp+6A]\n  \/\/ If the bytes at 0x14 are not zeroed, then the rendering data structure\n  \/\/ is not pointing to a location structure.\n  mov rbx,[rax+14]\n  cmp ebx,0\n  jne applyAbomnificationExit\n  \/\/ The location structure is found here, however we need to check that \n  \/\/ it's a valid pointer, as there is still a chance for some junk data here.\n  mov rbx,[rax+18]  \n  push rcx\n  lea rcx,[rbx]\n  call checkBadPointer\n  cmp ecx,0\n  pop rcx\n  jne applyAbomnificationExit    \n  \/\/ Ensure that the player isn't going to be Abomnified.\n  mov rax,playerLocation\n  cmp rbx,[rax]\n  je applyAbomnificationExit\n  \/\/ Push the identifying address parameter and get the Abomnified scales.  \n  push rbx\n  call getAbomnifiedScales\n  \/\/ Make some room on the stack so we can construct the multiplier SSE register.\n  sub rsp,10\n  movss xmm0,[identityValue]\n  shufps xmm0,xmm0,0\n  movups [rsp],xmm0\n  mov [rsp],eax\n  mov [rsp+4],ecx\n  mov [rsp+8],ebx\n  movups xmm0,[rsp]\n  add rsp,10\n  \/\/ Apply the Abomnified scale multipliers to the register that will be applied\n  \/\/ against the global scale parameters.\n  mulps xmm8,xmm0\napplyAbomnificationExit:\n  \/\/ Restore the preserved values on the stack.\n  pop rcx\n  pop rbx\n  pop rax\n  movdqu xmm0,[rsp]\n  add rsp,10\napplyAbomnificationOriginalCode:\n  popf \n  mulps xmm8,[ACValhalla.exe+415A470]\n  jmp applyAbomnificationReturn\n\n\nomnifyApplyAbomnificationHook:\n  jmp applyAbomnification\n  nop 3\napplyAbomnificationReturn:\n<\/pre>\n\n\n<p>And that&#8217;s the code.<\/p>\n\n\n\n<h2><span class=\"ez-toc-section\" id=\"Is_AC_Valhalla_Abomnified\"><\/span>Is AC: Valhalla Abomnified?<span class=\"ez-toc-section-end\"><\/span><\/h2>\n\n\n\n<p>Yes! Enemies morph randomly and present to the viewer an experience that is equal parts comical and horrific. I&#8217;m looking forward to playing this game! This article took a lot of work to produce, but we learned a lot from it that will make our endeavors in the future easier.<\/p>\n\n\n\n<p>I present to you, the patient reader, the complete implementation of the Abomnification system for <em>Assassin&#8217;s Creed: Valhalla<\/em>.<\/p>\n\n\n\n<h3><span class=\"ez-toc-section\" id=\"Abomnification_Implementation_%E2%80%93_Complete\"><\/span>Abomnification Implementation &#8211; Complete<span class=\"ez-toc-section-end\"><\/span><\/h3>\n\n\n<pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\n\/\/ Initiates the Abomnification system.\n\/\/ UNIQUE AOB: 0F 58 49 30 0F C6 D2 00 0F\ndefine(omnifyAbomnificationHook, &quot;ACValhalla.exe&quot; + EC71DE)\n\nassert(omnifyAbomnificationHook, 0F 58 49 30 0F C6 D2 00)\nalloc(initiateAbomnification,$1000, omnifyAbomnificationHook)\n\nregistersymbol(omnifyAbomnificationHook)\n\ninitiateAbomnification:\n  pushf\n  \/\/ Ensure that the player location struct has been initialized.\n  push rax\n  mov rax,playerLocation\n  cmp [rax],0\n  pop rax\n  je initiateAbomnificationOriginalCode \n  \/\/ Back up the registers used to hold return values.\n  push rax\n  push rbx\n  push rcx\n  \/\/ The addresses in this function are aligned so that the coordinates\n  \/\/ begin at 0x30, whereas their alignment in most of the other places we \n  \/\/ work with them is such that the coordinates start at 0x50.\n  add rcx,-20\n  \/\/ Ensure that the player isn't going to be Abomnified.\n  mov rax,playerLocation\n  mov rbx,[rax]\n  cmp rbx,rcx\n  je initiateAbomnificationExit\n  \/\/ Push the identifying address parameter and call the Abomnification system.  \n  push rcx\n  call executeAbomnification    \ninitiateAbomnificationExit:\n  \/\/ Restore the preserved values on the stack.\n  pop rcx\n  pop rbx\n  pop rax\ninitiateAbomnificationOriginalCode:\n  popf\n  addps xmm1,[rcx+30]\n  shufps xmm2,xmm2,00\n  jmp initiateAbomnificationReturn\n\n\nomnifyAbomnificationHook:\n  jmp initiateAbomnification\n  nop 3\ninitiateAbomnificationReturn:\n\n\nabominifyWidthResultUpper:\n  dd #250\n  \nabominifyHeightResultUpper:\n  dd #160\n  \nabominifyDepthResultUpper:\n  dd #200\n  \n\n\/\/ Applies Abomnification generated scale multipliers.\n\/\/ Unique AOB: 44 0F 59 05 15 B0 2C 03\ndefine(omnifyApplyAbomnificationHook, &quot;ACValhalla.exe&quot; + E8F453)\n\nassert(omnifyApplyAbomnificationHook, 44 0F 59 05 15 B0 2C 03)\nalloc(applyAbomnification,$1000, omnifyApplyAbomnificationHook)\n\nregistersymbol(omnifyApplyAbomnificationHook)\n\napplyAbomnification:\n  pushf\n  \/\/ Ensure that the player location struct has been initialized.\n  push rax\n  mov rax,playerLocation\n  cmp [rax],0\n  pop rax\n  je applyAbomnificationOriginalCode\n  \/\/ Backing up an SSE register to hold our multiplier.\n  sub rsp,10\n  movdqu [rsp],xmm0  \n  \/\/ Backing up the registers used to hold return values by the\n  \/\/ Abomnification system.\n  push rax\n  push rbx\n  push rcx  \n  \/\/ A rendering supplementary data structure is stored on the stack.\n  mov rax,[rsp+6A]\n  \/\/ If the bytes at 0x14 are not zeroed, then the rendering data structure\n  \/\/ is not pointing to a location structure.\n  mov rbx,[rax+14]\n  cmp ebx,0\n  jne applyAbomnificationExit\n  \/\/ The location structure is found here, however we need to check that \n  \/\/ it's a valid pointer, as there is still a chance for some junk data here.\n  mov rbx,[rax+18]  \n  push rcx\n  lea rcx,[rbx]\n  call checkBadPointer\n  cmp ecx,0\n  pop rcx\n  jne applyAbomnificationExit    \n  \/\/ Ensure that the player isn't going to be Abomnified.\n  mov rax,playerLocation\n  cmp rbx,[rax]\n  je applyAbomnificationExit\n  \/\/ Push the identifying address parameter and get the Abomnified scales.  \n  push rbx\n  call getAbomnifiedScales\n  \/\/ Make some room on the stack so we can construct the multiplier SSE register.\n  sub rsp,10\n  movss xmm0,[identityValue]\n  shufps xmm0,xmm0,0\n  movups [rsp],xmm0\n  mov [rsp],eax\n  mov [rsp+4],ecx\n  mov [rsp+8],ebx\n  movups xmm0,[rsp]\n  add rsp,10\n  \/\/ Apply the Abomnified scale multipliers to the register that will be applied\n  \/\/ against the global scale parameters.\n  mulps xmm8,xmm0\napplyAbomnificationExit:\n  \/\/ Restore the preserved values on the stack.\n  pop rcx\n  pop rbx\n  pop rax\n  movdqu xmm0,[rsp]\n  add rsp,10\napplyAbomnificationOriginalCode:\n  popf \n  mulps xmm8,[ACValhalla.exe+415A470]\n  jmp applyAbomnificationReturn\n\n\nomnifyApplyAbomnificationHook:\n  jmp applyAbomnification\n  nop 3\napplyAbomnificationReturn:\n<\/pre>\n\n\n<p>Some issues persist, such as a break in the morphing when the enemies switch to some particular animations, as well as the size of the player&#8217;s weapons being slightly reduced for some reason, except during some particular animation frames. However, these are very minor, and will be corrected in a follow up article if I deem it necessary.<\/p>\n\n\n\n<p>But whew, what an article! I hope this small contribution to science and reverse engineering benefits somebody, somewhere. But whether or not that happens, be sure to catch the live gameplay of Omnified <em>Assassin&#8217;s Creed: Valhalla<\/em> on my stream at: <a href=\"https:\/\/twitch.tv\/omni\" target=\"_blank\" rel=\"noreferrer noopener\">https:\/\/twitch.tv\/omni<\/a><\/p>\n\n\n\n<p>If you want to chat at all, say hello to me and my community on my Discord at: <a href=\"https:\/\/discord.gg\/omni\" target=\"_blank\" rel=\"noreferrer noopener\">https:\/\/discord.gg\/omni<\/a><\/p>\n\n\n\n<p>Keep it real folks, until next time.<\/p>\n\n\n\n<p><em>~Omni<\/em><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Table of Contents Time To Add Some LSD-Fueled Smooth Morphing MonstersIs Easy Scaling Support Built-In?A Crappy Way of Finding Easy [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[39,9],"tags":[27,24,22],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v14.9 - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\r\n<title>Hacking AC: Valhalla - Part 4 (Abomnification System) - omni&#039;s hackpad<\/title>\r\n<meta name=\"description\" content=\"The third of my game-neutral Omnified systems is hacked into Valhalla: the Abomnification system, which causes enemies to randomly morph.\" \/>\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\/2020\/12\/27\/hacking-ac-valhalla-part-4\/\" \/>\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 AC: Valhalla - Part 4 (Abomnification System) - omni&#039;s hackpad\" \/>\r\n<meta property=\"og:description\" content=\"The third of my game-neutral Omnified systems is hacked into Valhalla: the Abomnification system, which causes enemies to randomly morph.\" \/>\r\n<meta property=\"og:url\" content=\"https:\/\/badecho.com\/index.php\/2020\/12\/27\/hacking-ac-valhalla-part-4\/\" \/>\r\n<meta property=\"og:site_name\" content=\"omni&#039;s hackpad\" \/>\r\n<meta property=\"article:published_time\" content=\"2020-12-28T04:59:33+00:00\" \/>\r\n<meta property=\"article:modified_time\" content=\"2021-04-23T13:16:18+00:00\" \/>\r\n<meta property=\"og:image\" content=\"https:\/\/badecho.com\/wp-content\/uploads\/2020\/12\/LookingForScalingParameters.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\/2020\/12\/27\/hacking-ac-valhalla-part-4\/#primaryimage\",\"inLanguage\":\"en-US\",\"url\":\"https:\/\/badecho.com\/wp-content\/uploads\/2020\/12\/LookingForScalingParameters.png\",\"width\":946,\"height\":533,\"caption\":\"Hopefully we find some meaning \\\"1.00\\\" values in the memory here...good luck hah.\"},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/badecho.com\/index.php\/2020\/12\/27\/hacking-ac-valhalla-part-4\/#webpage\",\"url\":\"https:\/\/badecho.com\/index.php\/2020\/12\/27\/hacking-ac-valhalla-part-4\/\",\"name\":\"Hacking AC: Valhalla - Part 4 (Abomnification System) - omni&#039;s hackpad\",\"isPartOf\":{\"@id\":\"https:\/\/badecho.com\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/badecho.com\/index.php\/2020\/12\/27\/hacking-ac-valhalla-part-4\/#primaryimage\"},\"datePublished\":\"2020-12-28T04:59:33+00:00\",\"dateModified\":\"2021-04-23T13:16:18+00:00\",\"description\":\"The third of my game-neutral Omnified systems is hacked into Valhalla: the Abomnification system, which causes enemies to randomly morph.\",\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/badecho.com\/index.php\/2020\/12\/27\/hacking-ac-valhalla-part-4\/\"]}]},{\"@type\":\"Article\",\"@id\":\"https:\/\/badecho.com\/index.php\/2020\/12\/27\/hacking-ac-valhalla-part-4\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/badecho.com\/index.php\/2020\/12\/27\/hacking-ac-valhalla-part-4\/#webpage\"},\"author\":{\"@id\":\"https:\/\/badecho.com\/#\/schema\/person\/3de67496328be7ae6e1f52faf582e9d2\"},\"headline\":\"Hacking Assassin&#8217;s Creed: Valhalla &#8211; Part 4 (Abomnification System)\",\"datePublished\":\"2020-12-28T04:59:33+00:00\",\"dateModified\":\"2021-04-23T13:16:18+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/badecho.com\/index.php\/2020\/12\/27\/hacking-ac-valhalla-part-4\/#webpage\"},\"publisher\":{\"@id\":\"https:\/\/badecho.com\/#\/schema\/person\/3de67496328be7ae6e1f52faf582e9d2\"},\"image\":{\"@id\":\"https:\/\/badecho.com\/index.php\/2020\/12\/27\/hacking-ac-valhalla-part-4\/#primaryimage\"},\"keywords\":\"Abomnification,Hacking,Omnifying\",\"articleSection\":\"AC: Valhalla,Games\",\"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\/914"}],"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=914"}],"version-history":[{"count":27,"href":"https:\/\/badecho.com\/index.php\/wp-json\/wp\/v2\/posts\/914\/revisions"}],"predecessor-version":[{"id":975,"href":"https:\/\/badecho.com\/index.php\/wp-json\/wp\/v2\/posts\/914\/revisions\/975"}],"wp:attachment":[{"href":"https:\/\/badecho.com\/index.php\/wp-json\/wp\/v2\/media?parent=914"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/badecho.com\/index.php\/wp-json\/wp\/v2\/categories?post=914"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/badecho.com\/index.php\/wp-json\/wp\/v2\/tags?post=914"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}