{"id":4077,"date":"2024-09-25T09:49:00","date_gmt":"2024-09-25T07:49:00","guid":{"rendered":"https:\/\/security.humanativaspa.it\/?p=4077"},"modified":"2025-09-15T13:19:29","modified_gmt":"2025-09-15T13:19:29","slug":"exploiting-amd-atdcm64a-sys-arbitrary-pointer-dereference-part-1","status":"publish","type":"post","link":"https:\/\/hnsecurity.it\/it\/blog\/exploiting-amd-atdcm64a-sys-arbitrary-pointer-dereference-part-1\/","title":{"rendered":"Exploiting AMD atdcm64a.sys arbitrary pointer dereference &#8211; Part 1"},"content":{"rendered":"<div>\n<div>\n<p>After attending the <a href=\"https:\/\/apps.p.ost2.fyi\/learning\/course\/course-v1:OpenSecurityTraining2+Exp4011_Windows_Kernel_UAF_KTM+2023_v1\/home\">OST2 &#8211; Exp4011<\/a> course, taught by <a href=\"https:\/\/x.com\/saidelike\">Cedric Halbronn<\/a> (a <strong>free course<\/strong> that I <strong>really recommend to follow<\/strong> to anyone interested in the topic), I decided to start doing vulnerability research on <strong>third-party Windows drivers<\/strong>. I already had a bit of academic experience in <strong>kernel exploit development<\/strong> by crafting some exploits (<a href=\"https:\/\/github.com\/MrAle98\/HEVD-StackOverflow-x64-SMEPBypass\">stack overflow<\/a>, <a href=\"https:\/\/github.com\/MrAle98\/HEVD-ArbitraryWrite-Win10-x64\">arbitrary write<\/a>, <a href=\"https:\/\/github.com\/MrAle98\/HEVD-sessionPoolOverflow-win10-x64\">session pool overflow<\/a>) for the driver <a href=\"https:\/\/github.com\/hacksysteam\/HackSysExtremeVulnerableDriver\">HackSysExtremeVulnerableDriver<\/a>, so I decided to move on to real kernel drivers.<\/p>\n<p>In this <a href=\"https:\/\/hnsecurity.it\/tag\/atdcm64a\/\">series<\/a> of blog posts I&#8217;ll describe how I found <strong>two vulnerabilities<\/strong> in a <strong>Windows kernel driver<\/strong> part of an <strong>old AMD software package<\/strong> and how I exploited them in order to achieve <strong>local privilege escalation<\/strong>. Probably, this article won&#8217;t be very useful for experienced exploit developers\/vulnerability researchers, but I think it will be useful for <strong>red teamers<\/strong> that are <strong>looking for vulnerable drivers<\/strong> that are not blacklisted, in order to <strong>disable\/bypass EDRs<\/strong>. In addition, I&#8217;ll focus on how to use<strong> IDA Pro<\/strong>\u00a0to <strong>reverse and then debug drivers<\/strong> with the assistance of the pseudocode.<\/p>\n<\/div>\n<p>The series is divided in three parts as follows:<\/p>\n<ul class=\"postList\">\n<li class=\"graf graf--li\"><strong>Discovering the vulnerabilities<\/strong>\u00a0(<a href=\"https:\/\/hnsecurity.it\/exploiting-amd-atdcm64a-sys-arbitrary-pointer-dereference-part-1\/\">Part 1<\/a>) &#8211; This article<\/li>\n<li class=\"graf graf--li\"><strong>Confirming the vulnerabilities<\/strong>\u00a0(<a href=\"https:\/\/hnsecurity.it\/exploiting-amd-atdcm64a-sys-arbitrary-pointer-dereference-part-2\/\">Part 2<\/a>)<\/li>\n<li class=\"graf graf--li\"><strong>Exploitation<\/strong>\u00a0(<a href=\"https:\/\/hnsecurity.it\/exploiting-amd-atdcm64a-sys-arbitrary-pointer-dereference-part-3\/\">Part 3<\/a>)<\/li>\n<\/ul>\n<\/div>\n<div>\n<div>\n<p>I assume the reader already has <strong>basic knowledge about Windows kernel driver development\/exploitation<\/strong>. If that&#8217;s not the case, I suggest reading the following articles in order to gain a basic understanding of the <strong>interaction between user-mode processes and kernel-mode drivers<\/strong> and of protection mechanisms such as <strong>SMEP<\/strong>:<\/p>\n<\/div>\n<ul>\n<li><a href=\"https:\/\/connormcgarr.github.io\/Kernel-Exploitation-1\/\">https:\/\/connormcgarr.github.io\/Kernel-Exploitation-1\/<\/a><\/li>\n<li><a href=\"https:\/\/connormcgarr.github.io\/Kernel-Exploitation-2\/\">https:\/\/connormcgarr.github.io\/Kernel-Exploitation-2\/<\/a><\/li>\n<li><a href=\"https:\/\/connormcgarr.github.io\/x64-Kernel-Shellcode-Revisited-and-SMEP-Bypass\/\">https:\/\/connormcgarr.github.io\/x64-Kernel-Shellcode-Revisited-and-SMEP-Bypass\/<\/a><\/li>\n<li><a href=\"https:\/\/voidsec.com\/windows-drivers-reverse-engineering-methodology\/\">https:\/\/voidsec.com\/windows-drivers-reverse-engineering-methodology\/<\/a><\/li>\n<\/ul>\n<p>I also recommend following the <a href=\"https:\/\/apps.p.ost2.fyi\/learning\/course\/course-v1:OpenSecurityTraining2+Dbg3011_WinDbg3+2023_v1\/home\">OST2 &#8211; Dbg3011<\/a> course, again taught by Cedric Halbronn, in order to become familiar with <strong>WinDbg<\/strong>.<\/p>\n<\/div>\n<div><\/div>\n<div>\n<h2>Disclosure<\/h2>\n<\/div>\n<p>The vulnerabilities were reported directly to the <a href=\"https:\/\/www.amd.com\/en\/resources\/product-security.html\">AMD product security team<\/a> on July 26th, 2024.<\/p>\n<p>The AMD product security team replied the same day declaring that as the vulnerabilities affect an old software package that&#8217;s no longer maintained, <strong>they won&#8217;t be issuing a CVE ID or a security notice<\/strong>.<\/p>\n<h2>Setting up the environment<\/h2>\n<p>If you want to follow along I suggest you to create a <strong>Windows 11 VM<\/strong>.\u00a0 Specifically, I&#8217;m going to use the following build.<\/p>\n<div>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"raw\" data-enlighter-theme=\"monokai\" data-enlighter-highlight=\"3,4\">PS &gt; systeminfo\r\nHost Name: \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 WINDOWS11\r\nOS Name: \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 Microsoft Windows 11 Pro\r\nOS Version: \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a010.0.22631 N\/A Build 22631\r\nOS Manufacturer: \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 Microsoft Corporation\r\n[...]<\/pre>\n<\/div>\n<div>\n<div>\n<p>In addition, I provide here the <strong>hash of the ntoskrnl.exe<\/strong> file I have on my own Windows 11 VM.<\/p>\n<\/div>\n<div>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"raw\" data-enlighter-theme=\"monokai\">PS &gt; get-filehash C:\\Windows\\System32\\ntoskrnl.exe | select -expandProperty Hash \r\n0CE15480462E9CD3F7CBF2D44D2E393CF5674EE1D69A3459ADFA0E913A7A2AEB \r\nPS &gt;<\/pre>\n<p>In the Windows 11 VM, setup <strong>network kernel debugging as follows<\/strong> (run all commands as administrator).<\/p>\n<\/div>\n<\/div>\n<div>\n<div>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"raw\" data-enlighter-theme=\"monokai\">&gt; bcdedit \/debug on\r\n&gt; bcdedit \/dbgsettings net hostip:&lt;ip of your host machine&gt; port:&lt;port for example 50099&gt;<\/pre>\n<p>Take note of the <strong>key<\/strong> that the last command outputs. You can always get it back running the following command (again, as administrator).<\/p>\n<\/div>\n<div>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"raw\" data-enlighter-theme=\"monokai\">&gt; bcdedit \/dbgsettings\r\nkey \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 1dins0yu1y3cp.k42pkhb9dnua.1evtrhpv56ygd.349y5ok12c1ul\r\ndebugtype \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 NET\r\nhostip \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0192.168.157.1\r\nport \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a050001\r\ndhcp \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0Yes\r\nThe operation completed successfully.\r\n&gt;<\/pre>\n<p>Restart the VM so that changes will take effect.<\/p>\n<\/div>\n<\/div>\n<div>\n<h2>Analyzing the driver<\/h2>\n<\/div>\n<div>\n<h3>Reversing the driver<\/h3>\n<\/div>\n<div>\n<div>\n<p>The vulnerable driver can be obtained following these steps:<\/p>\n<ul>\n<li>Download this <a href=\"https:\/\/drivers.amd.com\/drivers\/beta\/win10-64bit-radeon-software-adrenalin-edition-18.12.1.1-dec5.exe\">software package<\/a><\/li>\n<li>Open the .exe with <strong>7zip<\/strong> and extract it. The driver is located at <strong>Packages\\Drivers\\Display\\WT6A_INF\\B336522\\atdcm64a.sys<\/strong><\/li>\n<li>Copy the driver both on your host machine (where you have IDA Pro or any other reversing framework) and on your VM<\/li>\n<\/ul>\n<\/div>\n<div>\n<p>If you are not able to download from the direct link, follow these steps:<\/p>\n<ul>\n<li>Navigate to this <a href=\"https:\/\/www.amd.com\/en\/support\/downloads\/previous-drivers.html\/graphics\/radeon-600-500-400\/radeon-rx-500-series\/radeon-rx-580.html\">link<\/a><\/li>\n<li>Expand the &#8220;Windows 10 &#8211; 64-bit Edition&#8221; tab<\/li>\n<li>Download the package <strong>Adrenalin Edition 18.12.1.1 Optional<\/strong> (Release date: 2018-12-05)<\/li>\n<\/ul>\n<figure id=\"attachment_4205\" aria-describedby=\"caption-attachment-4205\" style=\"width: 1403px\" class=\"wp-caption aligncenter\"><img decoding=\"async\" class=\"wp-image-4205 size-full\" src=\"https:\/\/hnsecurity.it\/wp-content\/uploads\/2024\/09\/2024-09-20-13_47_32-Clipboard-1.png\" alt=\"\" width=\"1403\" height=\"656\" srcset=\"https:\/\/hnsecurity.it\/wp-content\/uploads\/2024\/09\/2024-09-20-13_47_32-Clipboard-1.png 1403w, https:\/\/hnsecurity.it\/wp-content\/uploads\/2024\/09\/2024-09-20-13_47_32-Clipboard-1-300x140.png 300w, https:\/\/hnsecurity.it\/wp-content\/uploads\/2024\/09\/2024-09-20-13_47_32-Clipboard-1-1024x479.png 1024w, https:\/\/hnsecurity.it\/wp-content\/uploads\/2024\/09\/2024-09-20-13_47_32-Clipboard-1-768x359.png 768w, https:\/\/hnsecurity.it\/wp-content\/uploads\/2024\/09\/2024-09-20-13_47_32-Clipboard-1-350x164.png 350w\" sizes=\"(max-width: 1403px) 100vw, 1403px\" \/><figcaption id=\"caption-attachment-4205\" class=\"wp-caption-text\">Driver download page<\/figcaption><\/figure>\n<p>You can use <a href=\"https:\/\/www.osronline.com\/article.cfm%5Earticle=157.htm\">OSRLoader<\/a> to load the driver in the VM following the instructions\u00a0<a href=\"https:\/\/www.ired.team\/miscellaneous-reversing-forensics\/windows-kernel-internals\/loading-a-windows-kernel-driver-osr-driver-loader-debugging-with-source-code\">here<\/a> (just look at the animated GIF and ignore the other steps).<\/p>\n<\/div>\n<\/div>\n<div>\n<div>\n<p><em>Once the driver is loaded successfully in the VM, I suggest to create a <strong>snapshot of the VM<\/strong>. Usually the VM crashes many times especially during the exploit development phase. Having <strong>a snapshot allows to restart quickly<\/strong> from the point we want.<\/em><\/p>\n<\/div>\n<div>Now it is time to load the driver in <strong>IDA Pro<\/strong>. Once loaded, you are presented with the following interface:<\/div>\n<\/div>\n<div><\/div>\n<div>\n<figure id=\"attachment_3845\" aria-describedby=\"caption-attachment-3845\" style=\"width: 1915px\" class=\"wp-caption aligncenter\"><img decoding=\"async\" class=\"wp-image-3845 size-full\" src=\"https:\/\/hnsecurity.it\/wp-content\/uploads\/2024\/08\/image-53-1.png\" alt=\"\" width=\"1915\" height=\"831\" srcset=\"https:\/\/hnsecurity.it\/wp-content\/uploads\/2024\/08\/image-53-1.png 1915w, https:\/\/hnsecurity.it\/wp-content\/uploads\/2024\/08\/image-53-1-300x130.png 300w, https:\/\/hnsecurity.it\/wp-content\/uploads\/2024\/08\/image-53-1-1024x444.png 1024w, https:\/\/hnsecurity.it\/wp-content\/uploads\/2024\/08\/image-53-1-768x333.png 768w, https:\/\/hnsecurity.it\/wp-content\/uploads\/2024\/08\/image-53-1-1536x667.png 1536w, https:\/\/hnsecurity.it\/wp-content\/uploads\/2024\/08\/image-53-1-350x152.png 350w\" sizes=\"(max-width: 1915px) 100vw, 1915px\" \/><figcaption id=\"caption-attachment-3845\" class=\"wp-caption-text\">Initial view in IDA Pro<\/figcaption><\/figure>\n<\/div>\n<div>\n<div>\n<p>IDA Pro already shows the entry point: the DriverEntry routine.<\/p>\n<p>First thing I like to do is<strong> synchronize the decompiled View with the IDA View<\/strong>. Spawn the decompiled view with <code class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\">F5<\/code>, \u00a0right-click on the <strong>IDA View<\/strong> window and select <code class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\">Synchronize With -&gt; Pseudocode - A<\/code>.<\/p>\n<\/div>\n<div>\n<figure id=\"attachment_3787\" aria-describedby=\"caption-attachment-3787\" style=\"width: 1574px\" class=\"wp-caption aligncenter\"><img decoding=\"async\" class=\"wp-image-3787 size-full\" src=\"https:\/\/hnsecurity.it\/wp-content\/uploads\/2024\/08\/image-1-1.png\" alt=\"\" width=\"1574\" height=\"729\" srcset=\"https:\/\/hnsecurity.it\/wp-content\/uploads\/2024\/08\/image-1-1.png 1574w, https:\/\/hnsecurity.it\/wp-content\/uploads\/2024\/08\/image-1-1-300x139.png 300w, https:\/\/hnsecurity.it\/wp-content\/uploads\/2024\/08\/image-1-1-1024x474.png 1024w, https:\/\/hnsecurity.it\/wp-content\/uploads\/2024\/08\/image-1-1-768x356.png 768w, https:\/\/hnsecurity.it\/wp-content\/uploads\/2024\/08\/image-1-1-1536x711.png 1536w, https:\/\/hnsecurity.it\/wp-content\/uploads\/2024\/08\/image-1-1-350x162.png 350w\" sizes=\"(max-width: 1574px) 100vw, 1574px\" \/><figcaption id=\"caption-attachment-3787\" class=\"wp-caption-text\">Synchronizing views in IDA Pro<\/figcaption><\/figure>\n<div>\n<div><\/div>\n<div>From now on it will keep<strong> both cursors on the two windows synchronized<\/strong>. If you scroll one window, IDA Pro automatically scrolls on the other one as well.<\/div>\n<div>\n<p>If you want you can also further <strong>synchronize<\/strong> the <strong>Hex View with IDA View and Pseudocode<\/strong> windows using the same procedure. Right-click on the <strong>Hex View<\/strong> window and then select <code class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\">Synchronize With -&gt; IDA VIEW A - Pseudocode - A<\/code>.<\/p>\n<figure id=\"attachment_3788\" aria-describedby=\"caption-attachment-3788\" style=\"width: 1755px\" class=\"wp-caption aligncenter\"><img decoding=\"async\" class=\"wp-image-3788 size-full\" src=\"https:\/\/hnsecurity.it\/wp-content\/uploads\/2024\/08\/image-2-1.png\" alt=\"\" width=\"1755\" height=\"821\" srcset=\"https:\/\/hnsecurity.it\/wp-content\/uploads\/2024\/08\/image-2-1.png 1755w, https:\/\/hnsecurity.it\/wp-content\/uploads\/2024\/08\/image-2-1-300x140.png 300w, https:\/\/hnsecurity.it\/wp-content\/uploads\/2024\/08\/image-2-1-1024x479.png 1024w, https:\/\/hnsecurity.it\/wp-content\/uploads\/2024\/08\/image-2-1-768x359.png 768w, https:\/\/hnsecurity.it\/wp-content\/uploads\/2024\/08\/image-2-1-1536x719.png 1536w, https:\/\/hnsecurity.it\/wp-content\/uploads\/2024\/08\/image-2-1-350x164.png 350w\" sizes=\"(max-width: 1755px) 100vw, 1755px\" \/><figcaption id=\"caption-attachment-3788\" class=\"wp-caption-text\">Synchronizing Hex View with IDA View and Pseudocode<\/figcaption><\/figure>\n<\/div>\n<\/div>\n<div>\n<div>\n<p>The next steps here are:<\/p>\n<ol>\n<li>Identifying the <strong>symbolic link to the driver<\/strong> (so that we know <strong>how to get a handle<\/strong> to the driver <strong>from user-mode<\/strong>).<\/li>\n<li>Identifying <strong>driver dispatch routines handling IRPs<\/strong>.<\/li>\n<\/ol>\n<p><em>In this case we will focus only on the <strong>IRP_MJ_DEVICE_CONTROL<\/strong> major function code but typically he <strong>IRP_MJ_READ IRP_MJ_WRITE and IRP_MJ_CREATE<\/strong> major function codes are also of interest.<\/em><\/p>\n<div>\n<div>Usually, the <strong>symbolic link is created in the DriverEntry routine<\/strong>. Quickly inspecting the DriverEntry routine it in IDA Pro reveals the name <strong>AtiDCM<\/strong>:<\/div>\n<\/div>\n<figure id=\"attachment_3790\" aria-describedby=\"caption-attachment-3790\" style=\"width: 824px\" class=\"wp-caption aligncenter\"><img decoding=\"async\" class=\"size-full wp-image-3790\" src=\"https:\/\/hnsecurity.it\/wp-content\/uploads\/2024\/08\/image-4-1.png\" alt=\"\" width=\"824\" height=\"340\" srcset=\"https:\/\/hnsecurity.it\/wp-content\/uploads\/2024\/08\/image-4-1.png 824w, https:\/\/hnsecurity.it\/wp-content\/uploads\/2024\/08\/image-4-1-300x124.png 300w, https:\/\/hnsecurity.it\/wp-content\/uploads\/2024\/08\/image-4-1-768x317.png 768w, https:\/\/hnsecurity.it\/wp-content\/uploads\/2024\/08\/image-4-1-350x144.png 350w\" sizes=\"(max-width: 824px) 100vw, 824px\" \/><figcaption id=\"caption-attachment-3790\" class=\"wp-caption-text\">Symbolic link with name AtiDCM<\/figcaption><\/figure>\n<\/div>\n<div>\n<div><\/div>\n<div>Right after the creation of the symbolic link, we may notice the driver sets some dispatch routines in the <strong>MajorFunction array<\/strong> of the <strong>DriverObject<\/strong> struct:<\/div>\n<\/div>\n<\/div>\n<div>\n<figure id=\"attachment_3791\" aria-describedby=\"caption-attachment-3791\" style=\"width: 759px\" class=\"wp-caption aligncenter\"><img decoding=\"async\" class=\"wp-image-3791 size-full\" src=\"https:\/\/hnsecurity.it\/wp-content\/uploads\/2024\/08\/image-5-1.png\" alt=\"\" width=\"759\" height=\"391\" srcset=\"https:\/\/hnsecurity.it\/wp-content\/uploads\/2024\/08\/image-5-1.png 759w, https:\/\/hnsecurity.it\/wp-content\/uploads\/2024\/08\/image-5-1-300x155.png 300w, https:\/\/hnsecurity.it\/wp-content\/uploads\/2024\/08\/image-5-1-350x180.png 350w\" sizes=\"(max-width: 759px) 100vw, 759px\" \/><figcaption id=\"caption-attachment-3791\" class=\"wp-caption-text\">Definition of Dispatch routines in DriverObject<\/figcaption><\/figure>\n<\/div>\n<div>\n<div>\n<p>At this point I suggest to <strong>rename the indexes<\/strong> in the array with the corresponding <strong>IRP_MJ_XXX code<\/strong>. To do this you can:<\/p>\n<ol>\n<li>Click on the number and press <code class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\">m<\/code>.<\/li>\n<li>Select Yes in the popup.<\/li>\n<li>Then <code class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\">Ctrl-F<\/code> and type <strong>IRP_MJ<\/strong> in the search bar.<\/li>\n<li>Select the appropriate entry and press ok.<\/li>\n<\/ol>\n<\/div>\n<figure id=\"attachment_3792\" aria-describedby=\"caption-attachment-3792\" style=\"width: 439px\" class=\"wp-caption alignleft\"><img decoding=\"async\" class=\"wp-image-3792\" src=\"https:\/\/hnsecurity.it\/wp-content\/uploads\/2024\/08\/image-6-1.png\" alt=\"\" width=\"439\" height=\"171\" srcset=\"https:\/\/hnsecurity.it\/wp-content\/uploads\/2024\/08\/image-6-1.png 867w, https:\/\/hnsecurity.it\/wp-content\/uploads\/2024\/08\/image-6-1-300x117.png 300w, https:\/\/hnsecurity.it\/wp-content\/uploads\/2024\/08\/image-6-1-768x299.png 768w, https:\/\/hnsecurity.it\/wp-content\/uploads\/2024\/08\/image-6-1-350x136.png 350w\" sizes=\"(max-width: 439px) 100vw, 439px\" \/><figcaption id=\"caption-attachment-3792\" class=\"wp-caption-text\">Renaming index &#8211; Step 1-2<\/figcaption><\/figure>\n<figure id=\"attachment_3793\" aria-describedby=\"caption-attachment-3793\" style=\"width: 427px\" class=\"wp-caption alignright\"><img decoding=\"async\" class=\"wp-image-3793\" src=\"https:\/\/hnsecurity.it\/wp-content\/uploads\/2024\/08\/image-7-1.png\" alt=\"\" width=\"427\" height=\"156\" srcset=\"https:\/\/hnsecurity.it\/wp-content\/uploads\/2024\/08\/image-7-1.png 796w, https:\/\/hnsecurity.it\/wp-content\/uploads\/2024\/08\/image-7-1-300x110.png 300w, https:\/\/hnsecurity.it\/wp-content\/uploads\/2024\/08\/image-7-1-768x281.png 768w, https:\/\/hnsecurity.it\/wp-content\/uploads\/2024\/08\/image-7-1-350x128.png 350w\" sizes=\"(max-width: 427px) 100vw, 427px\" \/><figcaption id=\"caption-attachment-3793\" class=\"wp-caption-text\">Renaming index &#8211; Step 3-4<\/figcaption><\/figure>\n<figure id=\"attachment_3794\" aria-describedby=\"caption-attachment-3794\" style=\"width: 690px\" class=\"wp-caption aligncenter\"><img decoding=\"async\" class=\"wp-image-3794\" src=\"https:\/\/hnsecurity.it\/wp-content\/uploads\/2024\/08\/image-8-1.png\" alt=\"\" width=\"690\" height=\"216\" srcset=\"https:\/\/hnsecurity.it\/wp-content\/uploads\/2024\/08\/image-8-1.png 904w, https:\/\/hnsecurity.it\/wp-content\/uploads\/2024\/08\/image-8-1-300x94.png 300w, https:\/\/hnsecurity.it\/wp-content\/uploads\/2024\/08\/image-8-1-768x240.png 768w, https:\/\/hnsecurity.it\/wp-content\/uploads\/2024\/08\/image-8-1-350x110.png 350w\" sizes=\"(max-width: 690px) 100vw, 690px\" \/><figcaption id=\"caption-attachment-3794\" class=\"wp-caption-text\">Renaming index &#8211; result<\/figcaption><\/figure>\n<div>In addition to renaming all the indexes I like to rename the function names. You can do it by:<\/div>\n<div>\n<ol>\n<li>Clicking on the <strong>sub_XXXX<\/strong> you want to rename.<\/li>\n<li>Press <code class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\">n<\/code>.<\/li>\n<li>Change the name and press <code class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\">Enter<\/code>.<\/li>\n<\/ol>\n<\/div>\n<div>\n<figure id=\"attachment_3796\" aria-describedby=\"caption-attachment-3796\" style=\"width: 946px\" class=\"wp-caption aligncenter\"><img decoding=\"async\" class=\"wp-image-3796 size-full\" src=\"https:\/\/hnsecurity.it\/wp-content\/uploads\/2024\/08\/image-10-1.png\" alt=\"\" width=\"946\" height=\"281\" srcset=\"https:\/\/hnsecurity.it\/wp-content\/uploads\/2024\/08\/image-10-1.png 946w, https:\/\/hnsecurity.it\/wp-content\/uploads\/2024\/08\/image-10-1-300x89.png 300w, https:\/\/hnsecurity.it\/wp-content\/uploads\/2024\/08\/image-10-1-768x228.png 768w, https:\/\/hnsecurity.it\/wp-content\/uploads\/2024\/08\/image-10-1-350x104.png 350w\" sizes=\"(max-width: 946px) 100vw, 946px\" \/><figcaption id=\"caption-attachment-3796\" class=\"wp-caption-text\">Renaming the function to IrpDeviceIoControlHandler()<\/figcaption><\/figure>\n<\/div>\n<\/div>\n<div>\n<div>\n<p>After that I suggest to <strong>change the function signature <\/strong>to the appropriate one. Based on <a href=\"https:\/\/learn.microsoft.com\/en-us\/windows-hardware\/drivers\/ddi\/wdm\/nc-wdm-driver_dispatch\">MSDN<\/a>,\u00a0 the signature is the following:<\/p>\n<\/div>\n<div>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"c\" data-enlighter-theme=\"monokai\">NTSTATUS DriverDispatch(\r\n\u00a0 [in, out] _DEVICE_OBJECT *DeviceObject,\r\n\u00a0 [in, out] _IRP *Irp\r\n)<\/pre>\n<\/div>\n<div>\n<p>To change the function signature:<\/p>\n<ol>\n<li>Click on the target function name.<\/li>\n<li>Press <code class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\">y<\/code>.<\/li>\n<li>Insert the appropriate function signature.<\/li>\n<\/ol>\n<\/div>\n<p><em>It is advisable to keep the same calling convention you find in the original definition. In this case it is __fastcall.<\/em><\/p>\n<figure id=\"attachment_3797\" aria-describedby=\"caption-attachment-3797\" style=\"width: 1187px\" class=\"wp-caption aligncenter\"><img decoding=\"async\" class=\"wp-image-3797 size-full\" src=\"https:\/\/hnsecurity.it\/wp-content\/uploads\/2024\/08\/image-11-1.png\" alt=\"\" width=\"1187\" height=\"204\" srcset=\"https:\/\/hnsecurity.it\/wp-content\/uploads\/2024\/08\/image-11-1.png 1187w, https:\/\/hnsecurity.it\/wp-content\/uploads\/2024\/08\/image-11-1-300x52.png 300w, https:\/\/hnsecurity.it\/wp-content\/uploads\/2024\/08\/image-11-1-1024x176.png 1024w, https:\/\/hnsecurity.it\/wp-content\/uploads\/2024\/08\/image-11-1-768x132.png 768w, https:\/\/hnsecurity.it\/wp-content\/uploads\/2024\/08\/image-11-1-350x60.png 350w\" sizes=\"(max-width: 1187px) 100vw, 1187px\" \/><figcaption id=\"caption-attachment-3797\" class=\"wp-caption-text\">Redefining the function signature<\/figcaption><\/figure>\n<\/div>\n<div>\n<div><\/div>\n<div>Now we can move to our <strong>IrpDeviceIoControlHandler<\/strong> routine:<\/div>\n<div>\n<figure id=\"attachment_3798\" aria-describedby=\"caption-attachment-3798\" style=\"width: 916px\" class=\"wp-caption aligncenter\"><img decoding=\"async\" class=\"wp-image-3798 size-full\" src=\"https:\/\/hnsecurity.it\/wp-content\/uploads\/2024\/08\/image-12-1.png\" alt=\"\" width=\"916\" height=\"188\" srcset=\"https:\/\/hnsecurity.it\/wp-content\/uploads\/2024\/08\/image-12-1.png 916w, https:\/\/hnsecurity.it\/wp-content\/uploads\/2024\/08\/image-12-1-300x62.png 300w, https:\/\/hnsecurity.it\/wp-content\/uploads\/2024\/08\/image-12-1-768x158.png 768w, https:\/\/hnsecurity.it\/wp-content\/uploads\/2024\/08\/image-12-1-350x72.png 350w\" sizes=\"(max-width: 916px) 100vw, 916px\" \/><figcaption id=\"caption-attachment-3798\" class=\"wp-caption-text\">Pseudocode of IrpDeviceIoControlHandler()<\/figcaption><\/figure>\n<\/div>\n<\/div>\n<div>\n<div>If we inspect the first function we notice it actually returns a <strong>pointer in a global variable<\/strong> that points to a memory allocation obtained by calling <em>ExAllocatePoolWithTag()<\/em>:<\/div>\n<div>\n<figure id=\"attachment_3799\" aria-describedby=\"caption-attachment-3799\" style=\"width: 679px\" class=\"wp-caption aligncenter\"><img decoding=\"async\" class=\"wp-image-3799 size-full\" src=\"https:\/\/hnsecurity.it\/wp-content\/uploads\/2024\/08\/image-13-1.png\" alt=\"\" width=\"679\" height=\"576\" srcset=\"https:\/\/hnsecurity.it\/wp-content\/uploads\/2024\/08\/image-13-1.png 679w, https:\/\/hnsecurity.it\/wp-content\/uploads\/2024\/08\/image-13-1-300x254.png 300w, https:\/\/hnsecurity.it\/wp-content\/uploads\/2024\/08\/image-13-1-350x297.png 350w\" sizes=\"(max-width: 679px) 100vw, 679px\" \/><figcaption id=\"caption-attachment-3799\" class=\"wp-caption-text\">Pseudocode of sub_1400033e8()<\/figcaption><\/figure>\n<\/div>\n<div>When the driver returns from the first function, it passes the returned pointer to the next function along with the whole IRP. If we give a quick look at the <strong>second function<\/strong> we may notice It is a big function that <strong>handles the different IOCTLs<\/strong>.<\/div>\n<div><\/div>\n<div>I suggest to rename both functions and change their function signature:<\/div>\n<div>\n<figure id=\"attachment_3801\" aria-describedby=\"caption-attachment-3801\" style=\"width: 913px\" class=\"wp-caption aligncenter\"><img decoding=\"async\" class=\"wp-image-3801 size-full\" src=\"https:\/\/hnsecurity.it\/wp-content\/uploads\/2024\/08\/image-15-1.png\" alt=\"\" width=\"913\" height=\"181\" srcset=\"https:\/\/hnsecurity.it\/wp-content\/uploads\/2024\/08\/image-15-1.png 913w, https:\/\/hnsecurity.it\/wp-content\/uploads\/2024\/08\/image-15-1-300x59.png 300w, https:\/\/hnsecurity.it\/wp-content\/uploads\/2024\/08\/image-15-1-768x152.png 768w, https:\/\/hnsecurity.it\/wp-content\/uploads\/2024\/08\/image-15-1-350x69.png 350w\" sizes=\"(max-width: 913px) 100vw, 913px\" \/><figcaption id=\"caption-attachment-3801\" class=\"wp-caption-text\">Reversed IrpDeviceIoControlHandler()<\/figcaption><\/figure>\n<\/div>\n<div>Now let&#8217;s start inspecting <em>InnerIrpDeviceIoCtlHandler()<\/em>:<\/div>\n<div>\n<figure id=\"attachment_3802\" aria-describedby=\"caption-attachment-3802\" style=\"width: 848px\" class=\"wp-caption aligncenter\"><img decoding=\"async\" class=\"wp-image-3802 size-full\" src=\"https:\/\/hnsecurity.it\/wp-content\/uploads\/2024\/08\/image-16-1.png\" alt=\"\" width=\"848\" height=\"588\" srcset=\"https:\/\/hnsecurity.it\/wp-content\/uploads\/2024\/08\/image-16-1.png 848w, https:\/\/hnsecurity.it\/wp-content\/uploads\/2024\/08\/image-16-1-300x208.png 300w, https:\/\/hnsecurity.it\/wp-content\/uploads\/2024\/08\/image-16-1-768x533.png 768w, https:\/\/hnsecurity.it\/wp-content\/uploads\/2024\/08\/image-16-1-350x243.png 350w\" sizes=\"(max-width: 848px) 100vw, 848px\" \/><figcaption id=\"caption-attachment-3802\" class=\"wp-caption-text\">Initial pseudocode of InnerIrpDeviceIoCtlHandler()<\/figcaption><\/figure>\n<\/div>\n<div>\n<p>We can see it references multiple fields inside the IRP. If we give a look at the definition of the <a href=\"https:\/\/www.vergiliusproject.com\/kernels\/x64\/windows-11\/22h2\/_IRP\">IRP<\/a> and <a href=\"https:\/\/www.vergiliusproject.com\/kernels\/x64\/windows-11\/22h2\/_IO_STACK_LOCATION\">_IO_STACK_LOCATION<\/a>\u00a0 we can see the fields <em>CurrentStackLocation-&gt;Parameters<\/em> and <em>Irp-&gt;AssociatedIrp<\/em> are actually <strong>unions<\/strong>.<\/p>\n<\/div>\n<div>\n<p>Taking the <em>CurrentStackLocation-&gt;Parameters<\/em> we can see that it&#8217;s a union that <strong>changes based on the IRP Major Function Code<\/strong> handled. As the current function handles a <strong>IRP_MJ_DEVICE_CONTROL<\/strong> function code, we should use <em>CurrentStackLocation-&gt;Parameters.DeviceIoControl<\/em> in IDA Pro.<\/p>\n<\/div>\n<div>\n<p>To instruct IDA Pro to do so, you must:<\/p>\n<ol>\n<li>Click on the union field (<em>CurrentStackLication-&gt;Parameters<\/em>) press <code class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\">Alt + y<\/code>.<\/li>\n<li><code class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\">Ctrl + f<\/code> for searching for DeviceIoControl and then select the proper one (<em>Parameters.DeviceIoControl.IoControlCode <\/em>in this case).<\/li>\n<\/ol>\n<\/div>\n<\/div>\n<figure id=\"attachment_3805\" aria-describedby=\"caption-attachment-3805\" style=\"width: 498px\" class=\"wp-caption aligncenter\"><img decoding=\"async\" class=\"wp-image-3805\" src=\"https:\/\/hnsecurity.it\/wp-content\/uploads\/2024\/08\/image-19-1.png\" alt=\"\" width=\"498\" height=\"385\" srcset=\"https:\/\/hnsecurity.it\/wp-content\/uploads\/2024\/08\/image-19-1.png 751w, https:\/\/hnsecurity.it\/wp-content\/uploads\/2024\/08\/image-19-1-300x232.png 300w, https:\/\/hnsecurity.it\/wp-content\/uploads\/2024\/08\/image-19-1-350x271.png 350w\" sizes=\"(max-width: 498px) 100vw, 498px\" \/><figcaption id=\"caption-attachment-3805\" class=\"wp-caption-text\">Searching the proper union field<\/figcaption><\/figure>\n<div>\n<div>Now we know the function accesses the <em>IoControlCode<\/em> variable, provided as input from user mode, and based on that it handles the IRP differently. Let&#8217;s inspect the following piece of decompiled code:<\/div>\n<\/div>\n<div>\n<figure id=\"attachment_3807\" aria-describedby=\"caption-attachment-3807\" style=\"width: 848px\" class=\"wp-caption aligncenter\"><img decoding=\"async\" class=\"wp-image-3807 size-full\" src=\"https:\/\/hnsecurity.it\/wp-content\/uploads\/2024\/08\/image-21-1.png\" alt=\"\" width=\"848\" height=\"512\" srcset=\"https:\/\/hnsecurity.it\/wp-content\/uploads\/2024\/08\/image-21-1.png 848w, https:\/\/hnsecurity.it\/wp-content\/uploads\/2024\/08\/image-21-1-300x181.png 300w, https:\/\/hnsecurity.it\/wp-content\/uploads\/2024\/08\/image-21-1-768x464.png 768w, https:\/\/hnsecurity.it\/wp-content\/uploads\/2024\/08\/image-21-1-350x211.png 350w\" sizes=\"(max-width: 848px) 100vw, 848px\" \/><figcaption id=\"caption-attachment-3807\" class=\"wp-caption-text\">InnerIrpDeviceIoCtlHandler() before reversing<\/figcaption><\/figure>\n<\/div>\n<div>\n<div>Notice it references <em>IoControlCode variable <\/em>and subtract 0x22e084. If the result is zero, it calls a function (passing as input <em>Irp-&gt;AssociatedIrp.MasterIrp<\/em>). This means that <em>0x22e084<\/em> is a valid IOCTL. If we decode it, for example with <a href=\"https:\/\/www.osronline.com\/article.cfm%5Earticle=229.htm\">OSR Online IOCTL Decoder<\/a> we notice the info <strong>METHOD_BUFFERED<\/strong>:<\/div>\n<div>\n<figure id=\"attachment_3804\" aria-describedby=\"caption-attachment-3804\" style=\"width: 526px\" class=\"wp-caption aligncenter\"><img decoding=\"async\" class=\"wp-image-3804 size-full\" src=\"https:\/\/hnsecurity.it\/wp-content\/uploads\/2024\/08\/image-18-1.png\" alt=\"\" width=\"526\" height=\"459\" srcset=\"https:\/\/hnsecurity.it\/wp-content\/uploads\/2024\/08\/image-18-1.png 526w, https:\/\/hnsecurity.it\/wp-content\/uploads\/2024\/08\/image-18-1-300x262.png 300w, https:\/\/hnsecurity.it\/wp-content\/uploads\/2024\/08\/image-18-1-350x305.png 350w\" sizes=\"(max-width: 526px) 100vw, 526px\" \/><figcaption id=\"caption-attachment-3804\" class=\"wp-caption-text\">IOCTL decoded<\/figcaption><\/figure>\n<\/div>\n<div>Recalling <a href=\"https:\/\/learn.microsoft.com\/en-us\/windows-hardware\/drivers\/kernel\/buffer-descriptions-for-i-o-control-codes\">MSDN<\/a>, when using <strong>METHOD_BUFFERED<\/strong><em>,<\/em> the input and output buffer, passed from user mode, are represented by <em>Irp-&gt;AssociatedIrp.SystemBuffer<\/em>. At this point we are sure we can change the union <em>Irp-&gt;AssociatedIrp.MasterIrp<\/em> to be actually <em>Irp-&gt;AssociatedIrp.SystemBuffer<\/em>.<\/div>\n<div><\/div>\n<div>\n<figure id=\"attachment_3808\" aria-describedby=\"caption-attachment-3808\" style=\"width: 870px\" class=\"wp-caption aligncenter\"><img decoding=\"async\" class=\"wp-image-3808 size-full\" src=\"https:\/\/hnsecurity.it\/wp-content\/uploads\/2024\/08\/image-22-1.png\" alt=\"\" width=\"870\" height=\"540\" srcset=\"https:\/\/hnsecurity.it\/wp-content\/uploads\/2024\/08\/image-22-1.png 870w, https:\/\/hnsecurity.it\/wp-content\/uploads\/2024\/08\/image-22-1-300x186.png 300w, https:\/\/hnsecurity.it\/wp-content\/uploads\/2024\/08\/image-22-1-768x477.png 768w, https:\/\/hnsecurity.it\/wp-content\/uploads\/2024\/08\/image-22-1-350x217.png 350w\" sizes=\"(max-width: 870px) 100vw, 870px\" \/><figcaption id=\"caption-attachment-3808\" class=\"wp-caption-text\">InnerIrpDeviceIoCtlHandler() after reversing<\/figcaption><\/figure>\n<\/div>\n<\/div>\n<div>\n<div>\n<p>At this point we are interested in reversing and analyzing the code that handles our s<em>ystemBuffer<\/em> variable and see if there are any vulnerabilities.<\/p>\n<\/div>\n<\/div>\n<h3>Identifying an arbitrary MSR read<\/h3>\n<div>\n<div>Inside our <em>InnerIrpDeviceIoCtlHandler()<\/em> we notice a <code class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\">rdmsr<\/code> instruction (<em>__readmsr()<\/em> in the decompiled code).<\/div>\n<div><\/div>\n<div>\n<figure id=\"attachment_3809\" aria-describedby=\"caption-attachment-3809\" style=\"width: 641px\" class=\"wp-caption aligncenter\"><img decoding=\"async\" class=\"wp-image-3809 size-full\" src=\"https:\/\/hnsecurity.it\/wp-content\/uploads\/2024\/08\/image-23-1.png\" alt=\"\" width=\"641\" height=\"203\" srcset=\"https:\/\/hnsecurity.it\/wp-content\/uploads\/2024\/08\/image-23-1.png 641w, https:\/\/hnsecurity.it\/wp-content\/uploads\/2024\/08\/image-23-1-300x95.png 300w, https:\/\/hnsecurity.it\/wp-content\/uploads\/2024\/08\/image-23-1-350x111.png 350w\" sizes=\"(max-width: 641px) 100vw, 641px\" \/><figcaption id=\"caption-attachment-3809\" class=\"wp-caption-text\">Arbitrary MSR read<\/figcaption><\/figure>\n<\/div>\n<div>\n<p>As we can see from the snippet of code above, the routine takes the <strong>input<\/strong> for the <em>__readmsr<\/em> instruction from the <em><strong>systemBuffer<\/strong><\/em> (that we control) and returns the <strong>output<\/strong> again in <em><strong>systemBuffer<\/strong><\/em>. This grants us the ability to <strong>read arbitrary MSRs!<\/strong><\/p>\n<\/div>\n<\/div>\n<div>\n<h3>Identifying an arbitrary pointer dereference<\/h3>\n<div>After additional reversing of <em>InnerIrpIoCtlHandler()<\/em> and the functions called by <em>InnerIrpIoCtlHandler()<\/em> itself, we can see a call to <strong><em>callDriver()<\/em><\/strong> (a reversed function) passing as input multiple fields from <strong>s<\/strong><em><strong>ystemBuffer<\/strong><\/em>.<\/div>\n<div><\/div>\n<div>\n<figure id=\"attachment_3811\" aria-describedby=\"caption-attachment-3811\" style=\"width: 608px\" class=\"wp-caption aligncenter\"><img decoding=\"async\" class=\"wp-image-3811 size-full\" src=\"https:\/\/hnsecurity.it\/wp-content\/uploads\/2024\/08\/image-25-1.png\" alt=\"\" width=\"608\" height=\"666\" srcset=\"https:\/\/hnsecurity.it\/wp-content\/uploads\/2024\/08\/image-25-1.png 608w, https:\/\/hnsecurity.it\/wp-content\/uploads\/2024\/08\/image-25-1-274x300.png 274w, https:\/\/hnsecurity.it\/wp-content\/uploads\/2024\/08\/image-25-1-350x383.png 350w\" sizes=\"(max-width: 608px) 100vw, 608px\" \/><figcaption id=\"caption-attachment-3811\" class=\"wp-caption-text\">Call to callDriver()<\/figcaption><\/figure>\n<\/div>\n<div>Here&#8217;s the pseudocode of <strong><em>callDriver() <\/em><\/strong>after reversing:<\/div>\n<div><\/div>\n<div>\n<figure id=\"attachment_3812\" aria-describedby=\"caption-attachment-3812\" style=\"width: 1046px\" class=\"wp-caption aligncenter\"><img decoding=\"async\" class=\"wp-image-3812 size-full\" src=\"https:\/\/hnsecurity.it\/wp-content\/uploads\/2024\/08\/image-26-1.png\" alt=\"\" width=\"1046\" height=\"707\" srcset=\"https:\/\/hnsecurity.it\/wp-content\/uploads\/2024\/08\/image-26-1.png 1046w, https:\/\/hnsecurity.it\/wp-content\/uploads\/2024\/08\/image-26-1-300x203.png 300w, https:\/\/hnsecurity.it\/wp-content\/uploads\/2024\/08\/image-26-1-1024x692.png 1024w, https:\/\/hnsecurity.it\/wp-content\/uploads\/2024\/08\/image-26-1-768x519.png 768w, https:\/\/hnsecurity.it\/wp-content\/uploads\/2024\/08\/image-26-1-350x237.png 350w\" sizes=\"(max-width: 1046px) 100vw, 1046px\" \/><figcaption id=\"caption-attachment-3812\" class=\"wp-caption-text\">Pseudocode of callDriver()<\/figcaption><\/figure>\n<\/div>\n<div>\n<p>We can see it performs:<\/p>\n<ol>\n<li>A call to <strong><em>IoGetAttachedDeviceReference() <\/em><\/strong>passing as input the<strong> first parameter (that we fully control)<\/strong>.<\/li>\n<li>A call to <strong><em>IofCallDriver()<\/em><\/strong> passing as input the <strong>output of <em>IoGetAttachedDeviceReference()<\/em><\/strong>.<\/li>\n<\/ol>\n<\/div>\n<div>At this point we must reverse these two functions in order to understand what we are able to do.<\/div>\n<div>\n<p>Open another IDA Pro window and load the ntoskrnl.exe of the Windows 11 VM. After some reversing we get the shape of <em>IoGetAttachedDeviceReference()<\/em>:<\/p>\n<\/div>\n<div>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"c\" data-enlighter-highlight=\"16,17,37,20\" data-enlighter-theme=\"monokai\">PDEVICE_OBJECT __stdcall IoGetAttachedDeviceReference(PDEVICE_OBJECT DeviceObject)\r\n{\r\n\u00a0 unsigned __int8 CurrentIrql; \/\/ di\r\n\u00a0 char *v3; \/\/ rcx\r\n\u00a0 _DEVICE_OBJECT *i; \/\/ rax\r\n\u00a0 _DWORD *SchedulerAssist; \/\/ r8\r\n\u00a0 __int64 v7; \/\/ r9\r\n\u00a0 unsigned __int8 v8; \/\/ cl\r\n\u00a0 struct _KPRCB *CurrentPrcb; \/\/ r9\r\n\u00a0 _DWORD *v10; \/\/ r8\r\n\u00a0 int v11; \/\/ eax\r\n\u00a0 bool v12; \/\/ zf\r\n\r\n\r\n\u00a0[...]\r\n\u00a0 for ( i = DeviceObject-&gt;AttachedDevice; i; i = i-&gt;AttachedDevice )\r\n\u00a0 \u00a0 DeviceObject = i;\r\n\u00a0 if ( ObpTraceFlags )\r\n\u00a0 \u00a0 ObpPushStackInfo((__int64)&amp;DeviceObject[-1].DeviceLock.Header.WaitListHead, 1, 1u, 'tlfD');\r\n\u00a0 ObpIncrPointerCount((volatile signed __int64 *)&amp;DeviceObject[-1].DeviceLock.Header.WaitListHead);\r\n\u00a0 KxReleaseQueuedSpinLock((char *)KeGetPcr()-&gt;NtTib.ArbitraryUserPointer + 160);\r\n\u00a0 if ( KiIrqlFlags )\r\n\u00a0 {\r\n\u00a0 \u00a0 v8 = KeGetCurrentIrql();\r\n\u00a0 \u00a0 if ( (KiIrqlFlags &amp; 1) != 0 &amp;&amp; v8 &lt;= 0xFu &amp;&amp; CurrentIrql &lt;= 0xFu &amp;&amp; v8 &gt;= 2u )\r\n\u00a0 \u00a0 {\r\n\u00a0 \u00a0 \u00a0 CurrentPrcb = KeGetCurrentPrcb();\r\n\u00a0 \u00a0 \u00a0 v10 = CurrentPrcb-&gt;SchedulerAssist;\r\n\u00a0 \u00a0 \u00a0 v11 = ~(unsigned __int16)(-1LL &lt;&lt; (CurrentIrql + 1));\r\n\u00a0 \u00a0 \u00a0 v12 = (v11 &amp; v10[5]) == 0;\r\n\u00a0 \u00a0 \u00a0 v10[5] &amp;= v11;\r\n\u00a0 \u00a0 \u00a0 if ( v12 )\r\n\u00a0 \u00a0 \u00a0 \u00a0 KiRemoveSystemWorkPriorityKick(CurrentPrcb);\r\n\u00a0 \u00a0 }\r\n\u00a0 }\r\n\u00a0 __writecr8(CurrentIrql);\r\n\u00a0 return DeviceObject;\r\n}<\/pre>\n<div>\n<div>\n<p>We can see that basically it walks the <em><strong>DeviceObject-&gt;AttachedDevice<\/strong><\/em> linked list and then <strong>returns the last element<\/strong> in the list. In addition, before returning we can see a call to <strong><em>ObpIncrPointerCount()<\/em><\/strong> passing as input <code class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\">DeviceObject-0x30<\/code>. It is easier to see it in the disassembly listing (<code class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\">rbx<\/code>corresponds to <code class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\">DeviceObject<\/code>):<\/p>\n<\/div>\n<div><\/div>\n<div>\n<figure id=\"attachment_3813\" aria-describedby=\"caption-attachment-3813\" style=\"width: 1700px\" class=\"wp-caption aligncenter\"><img decoding=\"async\" class=\"wp-image-3813 size-full\" src=\"https:\/\/hnsecurity.it\/wp-content\/uploads\/2024\/08\/image-27-1.png\" alt=\"\" width=\"1700\" height=\"257\" srcset=\"https:\/\/hnsecurity.it\/wp-content\/uploads\/2024\/08\/image-27-1.png 1700w, https:\/\/hnsecurity.it\/wp-content\/uploads\/2024\/08\/image-27-1-300x45.png 300w, https:\/\/hnsecurity.it\/wp-content\/uploads\/2024\/08\/image-27-1-1024x155.png 1024w, https:\/\/hnsecurity.it\/wp-content\/uploads\/2024\/08\/image-27-1-768x116.png 768w, https:\/\/hnsecurity.it\/wp-content\/uploads\/2024\/08\/image-27-1-1536x232.png 1536w, https:\/\/hnsecurity.it\/wp-content\/uploads\/2024\/08\/image-27-1-350x53.png 350w\" sizes=\"(max-width: 1700px) 100vw, 1700px\" \/><figcaption id=\"caption-attachment-3813\" class=\"wp-caption-text\">call to ObpIncrPointerCount passing DdeviceObject-0x30<\/figcaption><\/figure>\n<\/div>\n<div><\/div>\n<div>\n<p>Here&#8217;s the reversed <em>ObpIncrPointerCount()<\/em> function:<\/p>\n<\/div>\n<div>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"c\" data-enlighter-highlight=\"4\" data-enlighter-theme=\"monokai\">signed __int64 __fastcall __spoils&lt;rax&gt; ObpIncrPointerCount(volatile signed __int64 *a1)\r\n{\r\n\u00a0 signed __int64 result; \/\/ rax\r\n\u00a0 result = _InterlockedIncrement64(a1);\r\n\u00a0 if ( result &lt;= 1 )\r\n\u00a0 \u00a0 KeBugCheckEx(0x18u, 0LL, (ULONG_PTR)(a1 + 6), 0x10uLL, result);\r\n\u00a0 return result;\r\n}<\/pre>\n<p>Notice the call to <strong><em>_InterlockedIncrement64()<\/em><\/strong>. This seems to grant us an <strong>arbitrary increment primitive<\/strong>. However, we have to consider that <em>callDriver()<\/em>, later on, calls <em><strong>ObfDereferenceObject()<\/strong><\/em> on the same <strong>AttachedDeviceReference<\/strong> variable.<\/p>\n<\/div>\n<div>\n<p>If we reverse <em>ObfDereferenceObject()<\/em> we can see that the function <strong>decrements the same field that was previously incremented<\/strong>. This <em>compensating action<\/em> is going to <strong>null out our arbitrary increment<\/strong> making it very <strong>likely<\/strong> <strong>unexploitable<\/strong>.<\/p>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<div>\n<div>\n<div>\n<p>Now let&#8217;s reverse <em>IofCallDriver()<\/em>:<\/p>\n<\/div>\n<\/div>\n<\/div>\n<div>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-highlight=\"24\" data-enlighter-theme=\"monokai\">NTSTATUS __stdcall IofCallDriver(PDEVICE_OBJECT DeviceObject, PIRP Irp)\r\n{\r\n  _IO_STACK_LOCATION *v2; \/\/ rax\r\n  __int64 MajorFunction; \/\/ r8\r\n\r\n  if ( IopDispatchCallDriver )\r\n  {\r\n    if ( IopDispatchCallDriver == 3 )\r\n      return IopPerfCallDriver((PADAPTER_OBJECT)DeviceObject);\r\n    else\r\n      return IovCallDriver(DeviceObject);\r\n  }\r\n  else\r\n  {\r\n    if ( --Irp-&gt;CurrentLocation &lt;= 0 )\r\n      KeBugCheckEx(0x35u, (ULONG_PTR)Irp, 0LL, 0LL, 0LL);\r\n    v2 = Irp-&gt;Tail.Overlay.CurrentStackLocation - 1;\r\n    Irp-&gt;Tail.Overlay.CurrentStackLocation = v2;\r\n    MajorFunction = v2-&gt;MajorFunction;\r\n    v2-&gt;DeviceObject = DeviceObject;\r\n    if ( (_BYTE)MajorFunction == 22 &amp;&amp; (unsigned __int8)(v2-&gt;MinorFunction - 2) &lt;= 1u )\r\n      return IopPoHandleIrp(Irp);\r\n    else\r\n      return ((__int64 (__fastcall *)(PDEVICE_OBJECT))DeviceObject-&gt;DriverObject-&gt;MajorFunction[MajorFunction])(DeviceObject);\r\n  }\r\n}<\/pre>\n<div>\n<p>The most interesting part of the function is the last line. It <strong>calls a function pointer<\/strong> inside the <strong>MajorFunction array<\/strong> part of <em><strong>DriverObject<\/strong><\/em> part of <em><strong>DeviceObject<\/strong><\/em>. Since <strong>we can control <em>DeviceObject<\/em><\/strong> then <strong>we can control the function pointer inside the MajorFunction array<\/strong>. This grants us the ability <strong>redirect the execution flow to an arbitrary location!<\/strong><\/p>\n<\/div>\n<h2>Wrapping up<\/h2>\n<\/div>\n<\/div>\n<\/div>\n<p>In this post we analyzed the driver EntryPoint with IDA Pro in order to retrieve the IOCTL handler. We analyzed the IOCTL handler, in order to retrieve the valid IoControlCodes and analyzed the functions in charge of handling the different IoControlCodes.<\/p>\n<p>Finally, we spotted two vulnerabilities: an <strong>arbitrary MSR read<\/strong> and an <strong>arbitrary pointer dereference.<\/strong><\/p>\n<p><em>You may have noticed that the <strong>driver analysis process<\/strong> (retrieving driver name, IOCTL dispatcher, IOCTL codes, &#8230;) can be quite tedious. If you want to <strong>automate the process<\/strong> I suggest you to give a look at the following <a href=\"https:\/\/github.com\/VoidSec\/DriverBuddyReloaded\">project<\/a> that directly integrates into IDA Pro.<\/em><\/p>\n<p>In <a href=\"https:\/\/hnsecurity.it\/exploiting-amd-atdcm64a-sys-arbitrary-pointer-dereference-part-2\/\">Part 2<\/a> we will confirm both vulnerabilities with the help of IDA Pro&#8217;s Debugger.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>After attending the OST2 &#8211; Exp4011 course, taught by Cedric Halbronn (a free course that I really recommend to follow [&hellip;]<\/p>\n","protected":false},"author":12,"featured_media":159895,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[78,81],"tags":[82,87,96,135,189,191,209,210,77,211],"class_list":["post-4077","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-exploits","category-vulnerabilities","tag-vulnerability-research","tag-reverse-engineering","tag-static-analysis","tag-windows","tag-tutorial","tag-red-teaming","tag-atdcm64a","tag-exploit-development","tag-exploit","tag-ida"],"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.2 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>HN Security Exploiting AMD atdcm64a.sys arbitrary pointer dereference - Part 1<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/hnsecurity.it\/it\/blog\/exploiting-amd-atdcm64a-sys-arbitrary-pointer-dereference-part-1\/\" \/>\n<meta property=\"og:locale\" content=\"it_IT\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"HN Security Exploiting AMD atdcm64a.sys arbitrary pointer dereference - Part 1\" \/>\n<meta property=\"og:description\" content=\"After attending the OST2 &#8211; Exp4011 course, taught by Cedric Halbronn (a free course that I really recommend to follow [&hellip;]\" \/>\n<meta property=\"og:url\" content=\"https:\/\/hnsecurity.it\/it\/blog\/exploiting-amd-atdcm64a-sys-arbitrary-pointer-dereference-part-1\/\" \/>\n<meta property=\"og:site_name\" content=\"HN Security\" \/>\n<meta property=\"article:published_time\" content=\"2024-09-25T07:49:00+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2025-09-15T13:19:29+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/hnsecurity.it\/wp-content\/uploads\/2025\/09\/AMD.jpg\" \/>\n\t<meta property=\"og:image:width\" content=\"1600\" \/>\n\t<meta property=\"og:image:height\" content=\"836\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/jpeg\" \/>\n<meta name=\"author\" content=\"Alessandro Iandoli\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@hnsec\" \/>\n<meta name=\"twitter:site\" content=\"@hnsec\" \/>\n<meta name=\"twitter:label1\" content=\"Scritto da\" \/>\n\t<meta name=\"twitter:data1\" content=\"Alessandro Iandoli\" \/>\n\t<meta name=\"twitter:label2\" content=\"Tempo di lettura stimato\" \/>\n\t<meta name=\"twitter:data2\" content=\"14 minuti\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/hnsecurity.it\/it\/blog\/exploiting-amd-atdcm64a-sys-arbitrary-pointer-dereference-part-1\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/hnsecurity.it\/it\/blog\/exploiting-amd-atdcm64a-sys-arbitrary-pointer-dereference-part-1\/\"},\"author\":{\"name\":\"Alessandro Iandoli\",\"@id\":\"https:\/\/hnsecurity.it\/it\/#\/schema\/person\/7883a9c36dac7694ca101137125d5fff\"},\"headline\":\"Exploiting AMD atdcm64a.sys arbitrary pointer dereference &#8211; Part 1\",\"datePublished\":\"2024-09-25T07:49:00+00:00\",\"dateModified\":\"2025-09-15T13:19:29+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/hnsecurity.it\/it\/blog\/exploiting-amd-atdcm64a-sys-arbitrary-pointer-dereference-part-1\/\"},\"wordCount\":2076,\"publisher\":{\"@id\":\"https:\/\/hnsecurity.it\/it\/#organization\"},\"image\":{\"@id\":\"https:\/\/hnsecurity.it\/it\/blog\/exploiting-amd-atdcm64a-sys-arbitrary-pointer-dereference-part-1\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/hnsecurity.it\/wp-content\/uploads\/2025\/09\/AMD.jpg\",\"keywords\":[\"vulnerability research\",\"reverse engineering\",\"static analysis\",\"windows\",\"Tutorial\",\"red teaming\",\"atdcm64a\",\"exploit development\",\"exploit\",\"ida\"],\"articleSection\":[\"Exploits\",\"Vulnerabilities\"],\"inLanguage\":\"it-IT\"},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/hnsecurity.it\/it\/blog\/exploiting-amd-atdcm64a-sys-arbitrary-pointer-dereference-part-1\/\",\"url\":\"https:\/\/hnsecurity.it\/it\/blog\/exploiting-amd-atdcm64a-sys-arbitrary-pointer-dereference-part-1\/\",\"name\":\"HN Security Exploiting AMD atdcm64a.sys arbitrary pointer dereference - Part 1\",\"isPartOf\":{\"@id\":\"https:\/\/hnsecurity.it\/it\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/hnsecurity.it\/it\/blog\/exploiting-amd-atdcm64a-sys-arbitrary-pointer-dereference-part-1\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/hnsecurity.it\/it\/blog\/exploiting-amd-atdcm64a-sys-arbitrary-pointer-dereference-part-1\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/hnsecurity.it\/wp-content\/uploads\/2025\/09\/AMD.jpg\",\"datePublished\":\"2024-09-25T07:49:00+00:00\",\"dateModified\":\"2025-09-15T13:19:29+00:00\",\"breadcrumb\":{\"@id\":\"https:\/\/hnsecurity.it\/it\/blog\/exploiting-amd-atdcm64a-sys-arbitrary-pointer-dereference-part-1\/#breadcrumb\"},\"inLanguage\":\"it-IT\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/hnsecurity.it\/it\/blog\/exploiting-amd-atdcm64a-sys-arbitrary-pointer-dereference-part-1\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"it-IT\",\"@id\":\"https:\/\/hnsecurity.it\/it\/blog\/exploiting-amd-atdcm64a-sys-arbitrary-pointer-dereference-part-1\/#primaryimage\",\"url\":\"https:\/\/hnsecurity.it\/wp-content\/uploads\/2025\/09\/AMD.jpg\",\"contentUrl\":\"https:\/\/hnsecurity.it\/wp-content\/uploads\/2025\/09\/AMD.jpg\",\"width\":1600,\"height\":836},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/hnsecurity.it\/it\/blog\/exploiting-amd-atdcm64a-sys-arbitrary-pointer-dereference-part-1\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/hnsecurity.it\/it\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Exploiting AMD atdcm64a.sys arbitrary pointer dereference &#8211; Part 1\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/hnsecurity.it\/it\/#website\",\"url\":\"https:\/\/hnsecurity.it\/it\/\",\"name\":\"HN Security\",\"description\":\"Offensive Security Specialists\",\"publisher\":{\"@id\":\"https:\/\/hnsecurity.it\/it\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/hnsecurity.it\/it\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"it-IT\"},{\"@type\":\"Organization\",\"@id\":\"https:\/\/hnsecurity.it\/it\/#organization\",\"name\":\"HN Security\",\"url\":\"https:\/\/hnsecurity.it\/it\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"it-IT\",\"@id\":\"https:\/\/hnsecurity.it\/it\/#\/schema\/logo\/image\/\",\"url\":\"https:\/\/hnsecurity.it\/wp-content\/uploads\/2026\/01\/hn-libellula.jpg\",\"contentUrl\":\"https:\/\/hnsecurity.it\/wp-content\/uploads\/2026\/01\/hn-libellula.jpg\",\"width\":696,\"height\":696,\"caption\":\"HN Security\"},\"image\":{\"@id\":\"https:\/\/hnsecurity.it\/it\/#\/schema\/logo\/image\/\"},\"sameAs\":[\"https:\/\/x.com\/hnsec\",\"https:\/\/www.linkedin.com\/company\/hnsecurity\/\",\"https:\/\/github.com\/hnsecurity\",\"https:\/\/infosec.exchange\/@hnsec\"]},{\"@type\":\"Person\",\"@id\":\"https:\/\/hnsecurity.it\/it\/#\/schema\/person\/7883a9c36dac7694ca101137125d5fff\",\"name\":\"Alessandro Iandoli\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"it-IT\",\"@id\":\"https:\/\/secure.gravatar.com\/avatar\/644822f5d8329ca419a50c1f39c97de5ccd163d1932e4cdc60a6cc8cb64ed29e?s=96&d=mm&r=g\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/644822f5d8329ca419a50c1f39c97de5ccd163d1932e4cdc60a6cc8cb64ed29e?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/644822f5d8329ca419a50c1f39c97de5ccd163d1932e4cdc60a6cc8cb64ed29e?s=96&d=mm&r=g\",\"caption\":\"Alessandro Iandoli\"},\"url\":\"https:\/\/hnsecurity.it\/it\/blog\/author\/ale98\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"HN Security Exploiting AMD atdcm64a.sys arbitrary pointer dereference - Part 1","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/hnsecurity.it\/it\/blog\/exploiting-amd-atdcm64a-sys-arbitrary-pointer-dereference-part-1\/","og_locale":"it_IT","og_type":"article","og_title":"HN Security Exploiting AMD atdcm64a.sys arbitrary pointer dereference - Part 1","og_description":"After attending the OST2 &#8211; Exp4011 course, taught by Cedric Halbronn (a free course that I really recommend to follow [&hellip;]","og_url":"https:\/\/hnsecurity.it\/it\/blog\/exploiting-amd-atdcm64a-sys-arbitrary-pointer-dereference-part-1\/","og_site_name":"HN Security","article_published_time":"2024-09-25T07:49:00+00:00","article_modified_time":"2025-09-15T13:19:29+00:00","og_image":[{"width":1600,"height":836,"url":"https:\/\/hnsecurity.it\/wp-content\/uploads\/2025\/09\/AMD.jpg","type":"image\/jpeg"}],"author":"Alessandro Iandoli","twitter_card":"summary_large_image","twitter_creator":"@hnsec","twitter_site":"@hnsec","twitter_misc":{"Scritto da":"Alessandro Iandoli","Tempo di lettura stimato":"14 minuti"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/hnsecurity.it\/it\/blog\/exploiting-amd-atdcm64a-sys-arbitrary-pointer-dereference-part-1\/#article","isPartOf":{"@id":"https:\/\/hnsecurity.it\/it\/blog\/exploiting-amd-atdcm64a-sys-arbitrary-pointer-dereference-part-1\/"},"author":{"name":"Alessandro Iandoli","@id":"https:\/\/hnsecurity.it\/it\/#\/schema\/person\/7883a9c36dac7694ca101137125d5fff"},"headline":"Exploiting AMD atdcm64a.sys arbitrary pointer dereference &#8211; Part 1","datePublished":"2024-09-25T07:49:00+00:00","dateModified":"2025-09-15T13:19:29+00:00","mainEntityOfPage":{"@id":"https:\/\/hnsecurity.it\/it\/blog\/exploiting-amd-atdcm64a-sys-arbitrary-pointer-dereference-part-1\/"},"wordCount":2076,"publisher":{"@id":"https:\/\/hnsecurity.it\/it\/#organization"},"image":{"@id":"https:\/\/hnsecurity.it\/it\/blog\/exploiting-amd-atdcm64a-sys-arbitrary-pointer-dereference-part-1\/#primaryimage"},"thumbnailUrl":"https:\/\/hnsecurity.it\/wp-content\/uploads\/2025\/09\/AMD.jpg","keywords":["vulnerability research","reverse engineering","static analysis","windows","Tutorial","red teaming","atdcm64a","exploit development","exploit","ida"],"articleSection":["Exploits","Vulnerabilities"],"inLanguage":"it-IT"},{"@type":"WebPage","@id":"https:\/\/hnsecurity.it\/it\/blog\/exploiting-amd-atdcm64a-sys-arbitrary-pointer-dereference-part-1\/","url":"https:\/\/hnsecurity.it\/it\/blog\/exploiting-amd-atdcm64a-sys-arbitrary-pointer-dereference-part-1\/","name":"HN Security Exploiting AMD atdcm64a.sys arbitrary pointer dereference - Part 1","isPartOf":{"@id":"https:\/\/hnsecurity.it\/it\/#website"},"primaryImageOfPage":{"@id":"https:\/\/hnsecurity.it\/it\/blog\/exploiting-amd-atdcm64a-sys-arbitrary-pointer-dereference-part-1\/#primaryimage"},"image":{"@id":"https:\/\/hnsecurity.it\/it\/blog\/exploiting-amd-atdcm64a-sys-arbitrary-pointer-dereference-part-1\/#primaryimage"},"thumbnailUrl":"https:\/\/hnsecurity.it\/wp-content\/uploads\/2025\/09\/AMD.jpg","datePublished":"2024-09-25T07:49:00+00:00","dateModified":"2025-09-15T13:19:29+00:00","breadcrumb":{"@id":"https:\/\/hnsecurity.it\/it\/blog\/exploiting-amd-atdcm64a-sys-arbitrary-pointer-dereference-part-1\/#breadcrumb"},"inLanguage":"it-IT","potentialAction":[{"@type":"ReadAction","target":["https:\/\/hnsecurity.it\/it\/blog\/exploiting-amd-atdcm64a-sys-arbitrary-pointer-dereference-part-1\/"]}]},{"@type":"ImageObject","inLanguage":"it-IT","@id":"https:\/\/hnsecurity.it\/it\/blog\/exploiting-amd-atdcm64a-sys-arbitrary-pointer-dereference-part-1\/#primaryimage","url":"https:\/\/hnsecurity.it\/wp-content\/uploads\/2025\/09\/AMD.jpg","contentUrl":"https:\/\/hnsecurity.it\/wp-content\/uploads\/2025\/09\/AMD.jpg","width":1600,"height":836},{"@type":"BreadcrumbList","@id":"https:\/\/hnsecurity.it\/it\/blog\/exploiting-amd-atdcm64a-sys-arbitrary-pointer-dereference-part-1\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/hnsecurity.it\/it\/"},{"@type":"ListItem","position":2,"name":"Exploiting AMD atdcm64a.sys arbitrary pointer dereference &#8211; Part 1"}]},{"@type":"WebSite","@id":"https:\/\/hnsecurity.it\/it\/#website","url":"https:\/\/hnsecurity.it\/it\/","name":"HN Security","description":"Offensive Security Specialists","publisher":{"@id":"https:\/\/hnsecurity.it\/it\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/hnsecurity.it\/it\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"it-IT"},{"@type":"Organization","@id":"https:\/\/hnsecurity.it\/it\/#organization","name":"HN Security","url":"https:\/\/hnsecurity.it\/it\/","logo":{"@type":"ImageObject","inLanguage":"it-IT","@id":"https:\/\/hnsecurity.it\/it\/#\/schema\/logo\/image\/","url":"https:\/\/hnsecurity.it\/wp-content\/uploads\/2026\/01\/hn-libellula.jpg","contentUrl":"https:\/\/hnsecurity.it\/wp-content\/uploads\/2026\/01\/hn-libellula.jpg","width":696,"height":696,"caption":"HN Security"},"image":{"@id":"https:\/\/hnsecurity.it\/it\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/x.com\/hnsec","https:\/\/www.linkedin.com\/company\/hnsecurity\/","https:\/\/github.com\/hnsecurity","https:\/\/infosec.exchange\/@hnsec"]},{"@type":"Person","@id":"https:\/\/hnsecurity.it\/it\/#\/schema\/person\/7883a9c36dac7694ca101137125d5fff","name":"Alessandro Iandoli","image":{"@type":"ImageObject","inLanguage":"it-IT","@id":"https:\/\/secure.gravatar.com\/avatar\/644822f5d8329ca419a50c1f39c97de5ccd163d1932e4cdc60a6cc8cb64ed29e?s=96&d=mm&r=g","url":"https:\/\/secure.gravatar.com\/avatar\/644822f5d8329ca419a50c1f39c97de5ccd163d1932e4cdc60a6cc8cb64ed29e?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/644822f5d8329ca419a50c1f39c97de5ccd163d1932e4cdc60a6cc8cb64ed29e?s=96&d=mm&r=g","caption":"Alessandro Iandoli"},"url":"https:\/\/hnsecurity.it\/it\/blog\/author\/ale98\/"}]}},"jetpack_featured_media_url":"https:\/\/hnsecurity.it\/wp-content\/uploads\/2025\/09\/AMD.jpg","_links":{"self":[{"href":"https:\/\/hnsecurity.it\/it\/wp-json\/wp\/v2\/posts\/4077","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/hnsecurity.it\/it\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/hnsecurity.it\/it\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/hnsecurity.it\/it\/wp-json\/wp\/v2\/users\/12"}],"replies":[{"embeddable":true,"href":"https:\/\/hnsecurity.it\/it\/wp-json\/wp\/v2\/comments?post=4077"}],"version-history":[{"count":1,"href":"https:\/\/hnsecurity.it\/it\/wp-json\/wp\/v2\/posts\/4077\/revisions"}],"predecessor-version":[{"id":160090,"href":"https:\/\/hnsecurity.it\/it\/wp-json\/wp\/v2\/posts\/4077\/revisions\/160090"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/hnsecurity.it\/it\/wp-json\/wp\/v2\/media\/159895"}],"wp:attachment":[{"href":"https:\/\/hnsecurity.it\/it\/wp-json\/wp\/v2\/media?parent=4077"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/hnsecurity.it\/it\/wp-json\/wp\/v2\/categories?post=4077"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/hnsecurity.it\/it\/wp-json\/wp\/v2\/tags?post=4077"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}