{"id":1319,"date":"2011-11-19T19:26:25","date_gmt":"2011-11-19T17:26:25","guid":{"rendered":"https:\/\/alax.info\/blog\/?p=1319"},"modified":"2011-11-19T19:30:13","modified_gmt":"2011-11-19T17:30:13","slug":"hardware-assisted-memory-corruption-detection","status":"publish","type":"post","link":"https:\/\/alax.info\/blog\/1319","title":{"rendered":"Hardware assisted memory corruption detection"},"content":{"rendered":"<p>So you got a memory corruption issue with a piece of software. It comes in a unique scenario along the line of having a huge pile of weird code running well most of the time and then, right out of the blue, a corruption takes place followed by unexpected code execution and unstable software state in general.<\/p>\n<p>The biggest problem with memory corruption is that a fragment of code is modifying a memory block which it does not own, and it has no idea who actually is the owner of the block, while the real owner has no timely way to detect the modification. You only face the consequences being unable to capture the modification moment in first place.<\/p>\n<p>To get back to the original cause, an engineer has to drop into a time machine, turn back time and step back to where the trouble took originally place. As developers are not actually given state-of-the-art time machines, the time turning step is speculative.<\/p>\n<h4>CVirtualHeapPtr Class: Memory with Exception-on-Write access mode<\/h4>\n<p>At the same time a Windows platform developer is or might be aware of <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/ms810627.aspx\">virtual memory API<\/a> which among other things provides user mode application with capabilities to define memory protection modes. Having this on hands opens unique opportunity to apply read-only protection (PAGE_READONLY) onto a memory block and have exception raised at the very moment of unexpected memory modification, having call stack showing up a source of the problem. I refer to this mode of operation as &#8220;hardware assisted&#8221; because the access violation exception\/condition would be generated purely in hardware without any need to additionally do any address comparison in code.<\/p>\n<p>Needless to say that this way is completely convenient for the developer as he does not need to patch the monstrous application all around in order to compare access addresses against read-only fragment. Instead, a block defined as read-only will be immediately available as such for the whole process almost without any performance overhead.<\/p>\n<p>As ATL provides a set of memory allocator templates (<a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/3by29yh0%28v=vs.80%29.aspx\">CHeapPtr<\/a> for heap backed memory blocks, allocated with <em>CCRTAllocator<\/em>, alternate options include <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/80zw33a6%28v=vs.80%29.aspx\">CComHeapPtr<\/a> with <em>CComAllocator<\/em> wrapping <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/windows\/desktop\/ms692727%28v=vs.85%29.aspx\">CoTaskMemAlloc<\/a>\/<em>CoTaskMemFree<\/em> API), let us make an alternate allocator option that mimic well-known class interface and would facilitate corruption detection.<\/p>\n<p>Because virtual memory allocation unit is a page, and protection mode is defined for the whole page, this would be the allocation granularity. For a single allocated byte we would need to request <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/windows\/desktop\/ms724958%28v=vs.85%29.aspx\">SYSTEM_INFO::dwPageSize<\/a> bytes of virtual memory. Unlike normal memory heap manager, we have no way to share pages between allocations as we would be unable to effectively apply protection modes. This would definitely increase application pressure onto virtual memory, but is still acceptable for the sacred task of troubleshooting.<\/p>\n<p>We define a <em>CVirtualAllocator<\/em> class to be compatible with ATL&#8217;s <em>CCRTAllocator<\/em>, however based on <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/windows\/desktop\/aa366887%28v=vs.85%29.aspx\">VirtualAlloc<\/a>\/<em>VirtualFree<\/em> API. The smart pointer class over memory pointer would be defined as follows:<\/p>\n<pre style=\"color: #000000; background: #ffffff;\"><span style=\"color: #800000; font-weight: bold;\">template<\/span> <span style=\"color: #800080;\">&lt;<\/span><span style=\"color: #800000; font-weight: bold;\">typename<\/span> T<span style=\"color: #800080;\">&gt;<\/span>\r\n<span style=\"color: #800000; font-weight: bold;\">class<\/span> CVirtualHeapPtr <span style=\"color: #800080;\">:<\/span>\r\n    <span style=\"color: #800000; font-weight: bold;\">public<\/span> CHeapPtr<span style=\"color: #800080;\">&lt;<\/span>T<span style=\"color: #808030;\">,<\/span> CVirtualAllocator<span style=\"color: #800080;\">&gt;<\/span>\r\n<span style=\"color: #800080;\">{<\/span>\r\n<span style=\"color: #800000; font-weight: bold;\">public<\/span><span style=\"color: #e34adc;\">:<\/span>\r\n<span style=\"color: #696969;\">\/\/ CVirtualHeapPtr<\/span>\r\n    CVirtualHeapPtr<span style=\"color: #808030;\">(<\/span><span style=\"color: #808030;\">)<\/span> <span style=\"color: #800000; font-weight: bold;\">throw<\/span><span style=\"color: #808030;\">(<\/span><span style=\"color: #808030;\">)<\/span><span style=\"color: #800080;\">;<\/span>\r\n    <span style=\"color: #800000; font-weight: bold;\">explicit<\/span> CVirtualHeapPtr<span style=\"color: #808030;\">(<\/span>_In_ T<span style=\"color: #808030;\">*<\/span> pData<span style=\"color: #808030;\">)<\/span> <span style=\"color: #800000; font-weight: bold;\">throw<\/span><span style=\"color: #808030;\">(<\/span><span style=\"color: #808030;\">)<\/span><span style=\"color: #800080;\">;<\/span>\r\n    <span style=\"color: #603000;\">VOID<\/span> SetProtection<span style=\"color: #808030;\">(<\/span><span style=\"color: #603000;\">DWORD<\/span> nProtection<span style=\"color: #808030;\">)<\/span>\r\n    <span style=\"color: #800080;\">{<\/span>\r\n        <span style=\"color: #696969;\">\/\/ <\/span><span style=\"color: #ffffff; background: #808000;\">TODO: ...<\/span>\r\n    <span style=\"color: #800080;\">}<\/span>\r\n<span style=\"color: #800080;\">}<\/span><span style=\"color: #800080;\">;<\/span><\/pre>\n<p>The <em>SetProtection<\/em> method is to define memory protection for the memory block. Full code for the classes <a href=\"https:\/\/www.alax.info\/trac\/public\/browser\/trunk\/Utilities\/VirtualHeapPtr\/VirtualHeapPtr.h#L9\">is available on Trac here<\/a> (lines 9-132):<\/p>\n<ul>\n<li><em>CGlobalVirtualAllocator<\/em> class is a singleton querying operating system for virtual memory page size, and provides alignment method<\/li>\n<li><em>CVirtualAllocator<\/em> class is a <em>CCRTAllocator<\/em>-compatible allocator class<\/li>\n<li><em>CVirtualHeapPtr<\/em> class is smart template class wrapping a pointer to allocated memory<\/li>\n<\/ul>\n<p>Use case code will be as follows. &#8220;SetProtection(PAGE_READONLY)&#8221; enables protection on memory block and turns on exception generation at the moment memory block modification attempt. &#8220;SetProtection(PAGE_READWRITE)&#8221; would restore normal mode of memory operation.<\/p>\n<pre style=\"color: #000000; background: #ffffff;\">CVirtualHeapPtr<span style=\"color: #800080;\">&lt;<\/span><span style=\"color: #603000;\">BYTE<\/span><span style=\"color: #800080;\">&gt;<\/span> p<span style=\"color: #800080;\">;<\/span>\r\np<span style=\"color: #808030;\">.<\/span>Allocate<span style=\"color: #808030;\">(<\/span><span style=\"color: #008c00;\">2<\/span><span style=\"color: #808030;\">)<\/span><span style=\"color: #800080;\">;<\/span>\r\np<span style=\"color: #808030;\">[<\/span><span style=\"color: #008c00;\">1<\/span><span style=\"color: #808030;\">]<\/span> <span style=\"color: #808030;\">=<\/span> <span style=\"color: #008000;\">0x01<\/span><span style=\"color: #800080;\">;<\/span>\r\np<span style=\"color: #808030;\">.<\/span>SetProtection<span style=\"color: #808030;\">(<\/span>PAGE_READONLY<span style=\"color: #808030;\">)<\/span><span style=\"color: #800080;\">;<\/span>\r\n<span style=\"color: #696969;\">\/\/ NOTE: Compile with \/EHa on order to catch the exception<\/span>\r\n_ATLTRY\r\n<span style=\"color: #800080;\">{<\/span>\r\n    p<span style=\"color: #808030;\">[<\/span><span style=\"color: #008c00;\">1<\/span><span style=\"color: #808030;\">]<\/span> <span style=\"color: #808030;\">=<\/span> <span style=\"color: #008000;\">0x02<\/span><span style=\"color: #800080;\">;<\/span>\r\n    <span style=\"color: #696969;\">\/\/ NOTE: We never reach here due to exception<\/span>\r\n<span style=\"color: #800080;\">}<\/span>\r\n_ATLCATCHALL<span style=\"color: #808030;\">(<\/span><span style=\"color: #808030;\">)<\/span>\r\n<span style=\"color: #800080;\">{<\/span>\r\n    <span style=\"color: #696969;\">\/\/ NOTE: Catching the access violation for now to be able to continue execution<\/span>\r\n<span style=\"color: #800080;\">}<\/span>\r\np<span style=\"color: #808030;\">.<\/span>SetProtection<span style=\"color: #808030;\">(<\/span>PAGE_READWRITE<span style=\"color: #808030;\">)<\/span><span style=\"color: #800080;\">;<\/span>\r\np<span style=\"color: #808030;\">[<\/span><span style=\"color: #008c00;\">1<\/span><span style=\"color: #808030;\">]<\/span> <span style=\"color: #808030;\">=<\/span> <span style=\"color: #008000;\">0x03<\/span><span style=\"color: #800080;\">;<\/span><\/pre>\n<p>Given the information what data gets corrupt, the pointer allocator provides an efficient opportunity to detect the violation attempt. The only thing remained is to keep memory read-only, and temporarily revert to write access when the &#8220;legal&#8221; memory modification code is about to be executed.<\/p>\n<p><!--more--><\/p>\n<h5>One-shot Read\/Write Protection with Guard Pages<\/h5>\n<p>Another option granted by memory protection modes is brought by PAGE_GUARD flag. MSDN says:<\/p>\n<blockquote><p>A guard page provides a one-shot alarm for memory page access. This can be useful for an application that needs to monitor the growth of large dynamic data structures. For example, there are operating systems that use guard pages to implement automatic stack checking.<\/p><\/blockquote>\n<p>Setting a guard page mode provides an additional option to trigger an exception with even read access to a protected memory block.<\/p>\n<pre style=\"color: #000000; background: #ffffff;\">p<span style=\"color: #808030;\">.<\/span>SetProtection<span style=\"color: #808030;\">(<\/span>PAGE_READWRITE <span style=\"color: #808030;\">|<\/span> PAGE_GUARD<span style=\"color: #808030;\">)<\/span><span style=\"color: #800080;\">;<\/span>\r\n<span style=\"color: #603000;\">BYTE<\/span> n <span style=\"color: #808030;\">=<\/span> p<span style=\"color: #808030;\">[<\/span><span style=\"color: #008c00;\">0<\/span><span style=\"color: #808030;\">]<\/span><span style=\"color: #800080;\">;<\/span><\/pre>\n<h4>CDebugHeapPtr Class: More Options to Catch Memory Corruption Conditions<\/h4>\n<p>While setting memory protection attributes on a memory block of interest provides unique troubleshooting opportunities, it still does not cover important typical problems with memory misuse scenarios. Those are writing immediately before the allocated block, and writing immediately after. Having array of N items, this would be writing to indices -1 and N respectively.<\/p>\n<p>To address this scenarios of misuse we can extend CVirtualHeapPtr class so that it could additionally provide &#8220;sanity pages&#8221; with PAGE_NOACCESS protection at the boundary of allocation. Because virtual memory allocation is granular, we will have to have padding bytes that extend our block to the page boundary, however we have an option to put the padding bytes before or after the payload data block in order to capture after or before memory block writes respectively.<\/p>\n<p>The figure below shows memory layout for the data:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-1320\" title=\"CDebugHeapPtr Memory Layout\" src=\"https:\/\/alax.info\/blog\/wp-content\/uploads\/2011\/11\/image.png\" alt=\"\" width=\"509\" height=\"541\" srcset=\"https:\/\/alax.info\/blog\/wp-content\/uploads\/2011\/11\/image.png 509w, https:\/\/alax.info\/blog\/wp-content\/uploads\/2011\/11\/image-301x320.png 301w\" sizes=\"auto, (max-width: 509px) 100vw, 509px\" \/><\/p>\n<p>Source code for the <em>CDebugHeapPtr<\/em> class <a href=\"https:\/\/www.alax.info\/trac\/public\/browser\/trunk\/Utilities\/VirtualHeapPtr\/VirtualHeapPtr.h#L155\">is available on Trac<\/a> (lines 155-). The sanity pages create a block of inaccessible addresses which immediately cause access violation exception on either read of write access attempt. Under debugger, those are shows with question marks:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-1321\" title=\"PAGE_NOACCESS Data\" src=\"https:\/\/alax.info\/blog\/wp-content\/uploads\/2011\/11\/Image0011.png\" alt=\"\" width=\"673\" height=\"288\" srcset=\"https:\/\/alax.info\/blog\/wp-content\/uploads\/2011\/11\/Image0011.png 673w, https:\/\/alax.info\/blog\/wp-content\/uploads\/2011\/11\/Image0011-320x136.png 320w\" sizes=\"auto, (max-width: 673px) 100vw, 673px\" \/><\/p>\n<p>The padding space is pre-initialized with hardcoded value 0x77, and the space is checked for integrity at release of memory block call.<\/p>\n<h4>Catching the Exceptions<\/h4>\n<p>Having the exceptions generated on run-time, they immediately alter application execution code path and are easy to track and catch. There is no need to bring the feature rich debugger, such as Visual Studio to the production site in order to catch the exception and environment, instead a way simpler tool such as <a href=\"https:\/\/alax.info\/blog\/1248\">LogProcessExceptions<\/a> would be able to create a minidump file and write the state of the application. The minidump can be transferred into debugger-enabled environment for detailed check.<\/p>\n<p>Visual C++ .NET 2010 <a href=\"https:\/\/www.alax.info\/trac\/public\/browser\/trunk\/Utilities\/VirtualHeapPtr\">source code<\/a> is available from SVN.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>So you got a memory corruption issue with a piece of software. It comes in a unique scenario along the line of having a huge pile of weird code running well most of the time and then, right out of the blue, a corruption takes place followed by unexpected code execution and unstable software state&hellip; <\/p>\n<p><a class=\"moretag\" href=\"https:\/\/alax.info\/blog\/1319\">Read the full article<\/a><\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[11,21,13],"tags":[487,388,218,389,161,390,217,267],"class_list":["post-1319","post","type-post","status-publish","format-standard","hentry","category-atl","category-seriously","category-source","tag-atl","tag-corruption","tag-debug","tag-detection","tag-exception","tag-hardware","tag-memory","tag-protection"],"_links":{"self":[{"href":"https:\/\/alax.info\/blog\/wp-json\/wp\/v2\/posts\/1319","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/alax.info\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/alax.info\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/alax.info\/blog\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/alax.info\/blog\/wp-json\/wp\/v2\/comments?post=1319"}],"version-history":[{"count":0,"href":"https:\/\/alax.info\/blog\/wp-json\/wp\/v2\/posts\/1319\/revisions"}],"wp:attachment":[{"href":"https:\/\/alax.info\/blog\/wp-json\/wp\/v2\/media?parent=1319"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/alax.info\/blog\/wp-json\/wp\/v2\/categories?post=1319"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/alax.info\/blog\/wp-json\/wp\/v2\/tags?post=1319"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}