{"componentChunkName":"component---src-templates-post-template-js","path":"/amsi-create-interface-en","result":{"data":{"markdownRemark":{"id":"b3fc0779-0b56-5117-9673-a189302a9866","html":"<blockquote>\n<p>This page has been machine-translated from the <a href=\"/amsi-create-interface\">original page</a>.</p>\n</blockquote>\n<p>Following the previous post, <a href=\"/amsi-learn-en\">AMSI Overview and How It Works</a>, this time I will summarize an application that issues AMSI scan requests by using the AMSI COM interface, along with its implementation.</p>\n<!-- omit in toc -->\n<h2 id=\"table-of-contents\" style=\"position:relative;\"><a href=\"#table-of-contents\" aria-label=\"table of contents permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Table of Contents</h2>\n<ul>\n<li><a href=\"#issuing-amsi-scan-requests-from-a-custom-application\">Issuing AMSI Scan Requests from a Custom Application</a></li>\n<li><a href=\"#the-main-function\">The main Function</a></li>\n<li><a href=\"#calling-the-scanarguments-function\">Calling the ScanArguments Function</a></li>\n<li><a href=\"#initializing-the-cstreamscanner-class\">Initializing the CStreamScanner Class</a></li>\n<li>\n<p><a href=\"#scanning-a-memory-stream\">Scanning a Memory Stream</a></p>\n<ul>\n<li><a href=\"#the-camsimemorystream-class\">The CAmsiMemoryStream Class</a></li>\n<li><a href=\"#calling-the-scanstream-method\">Calling the ScanStream Method</a></li>\n</ul>\n</li>\n<li>\n<p><a href=\"#scanning-a-file-stream\">Scanning a File Stream</a></p>\n<ul>\n<li><a href=\"#the-camsifilestream-class\">The CAmsiFileStream Class</a></li>\n</ul>\n</li>\n<li><a href=\"#summary\">Summary</a></li>\n</ul>\n<h2 id=\"issuing-amsi-scan-requests-from-a-custom-application\" style=\"position:relative;\"><a href=\"#issuing-amsi-scan-requests-from-a-custom-application\" aria-label=\"issuing amsi scan requests from a custom application permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Issuing AMSI Scan Requests from a Custom Application</h2>\n<p>Broadly speaking, there seem to be two ways to integrate the AMSI interface into an application: using the AMSI Win32 API, or using the AMSI COM interface.</p>\n<p>Reference: <a href=\"https://learn.microsoft.com/ja-jp/windows/win32/amsi/dev-audience#third-party-creators-of-antimalware-products\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">Developer audience and sample code - Win32 apps | Microsoft Learn</a></p>\n<p>Since the PowerShell example examined in the previous article uses the AMSI Win32 API, this time I decided to try an implementation that uses the AMSI COM interface.</p>\n<p>The official sample code is a good reference for creating an application that uses the AMSI COM interface.</p>\n<p>You can obtain this sample code by downloading <code class=\"language-text\">amsistream-sample.zip</code> from the following repository.</p>\n<p>Reference: <a href=\"https://github.com/microsoft/Windows-classic-samples/releases/tag/MicrosoftDocs-Samples\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">Release MicrosoftDocs-Samples · microsoft/Windows-classic-samples</a></p>\n<p>This sample program scans in-memory data and file contents by using the AMSI COM interface.</p>\n<p><span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 960px; \"\n    >\n      <a\n    class=\"gatsby-resp-image-link\"\n    href=\"/static/1387b2217308b1568e3babae3c49aa57/6774c/image-20250628144633707.png\"\n    style=\"display: block\"\n    target=\"_blank\"\n    rel=\"noopener\"\n  >\n    <span\n    class=\"gatsby-resp-image-background-image\"\n    style=\"padding-bottom: 66.25%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAANCAYAAACpUE5eAAAACXBIWXMAAAsTAAALEwEAmpwYAAABT0lEQVQ4y5WT2XKCQBBFeTTsBAPIVoCyq2z//20ttytDhESSPHQNNRRnTk9fpLZt6X6/U9d1vNZ1TUEQkOu65HkenU4nXm37fV5tch2bDEMnRVFIVdVvJY3jSH3fMwiV5znD4zjmZxyCA3Rdp8PhjWRZXmA/QVfApmmoKAqaponSNKWyLGkYBoYbhrEC7Brio2cg9gCsqorfRVFEmqa9hKyA+GDbMvaSJGFDvAvD8P9A2Oy1bJrm6u5elXS73QgFM2EIO9/3eRiwA0wY/mYpwep6vbIlwJfLhYGwwppl2edeTEWezObhHJ0Pchx3jpTHByNWjuPQ8Xj8ahl5RKFlHAAgQHiGpWVZbKlp+m7bS2zEHaLl7R1iyoiNyOBe22yIVgETQ4Hp+Xxe2sVfs53yyxxupwwrGIrYiCn/OTawwz1hwgDAEGbiP0bht9uzeq4H7ARS1F824Q8AAAAASUVORK5CYII='); background-size: cover; display: block;\"\n  ></span>\n  <picture>\n          <source\n              srcset=\"/static/1387b2217308b1568e3babae3c49aa57/8ac56/image-20250628144633707.webp 240w,\n/static/1387b2217308b1568e3babae3c49aa57/d3be9/image-20250628144633707.webp 480w,\n/static/1387b2217308b1568e3babae3c49aa57/e46b2/image-20250628144633707.webp 960w,\n/static/1387b2217308b1568e3babae3c49aa57/b3ed6/image-20250628144633707.webp 1391w\"\n              sizes=\"(max-width: 960px) 100vw, 960px\"\n              type=\"image/webp\"\n            />\n          <source\n            srcset=\"/static/1387b2217308b1568e3babae3c49aa57/8ff5a/image-20250628144633707.png 240w,\n/static/1387b2217308b1568e3babae3c49aa57/e85cb/image-20250628144633707.png 480w,\n/static/1387b2217308b1568e3babae3c49aa57/d9199/image-20250628144633707.png 960w,\n/static/1387b2217308b1568e3babae3c49aa57/6774c/image-20250628144633707.png 1391w\"\n            sizes=\"(max-width: 960px) 100vw, 960px\"\n            type=\"image/png\"\n          />\n          <img\n            class=\"gatsby-resp-image-image\"\n            src=\"/static/1387b2217308b1568e3babae3c49aa57/d9199/image-20250628144633707.png\"\n            alt=\"image-20250628144633707\"\n            title=\"image-20250628144633707\"\n            loading=\"lazy\"\n            style=\"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;\"\n          />\n        </picture>\n  </a>\n    </span></p>\n<p>The code is implemented as a single file of about 300 lines, so I think it is comparatively easy to read.</p>\n<p>Reference: <a href=\"https://github.com/microsoft/Windows-classic-samples/blob/main/Samples/AmsiStream/AmsiStream.cpp\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">Windows-classic-samples/Samples/AmsiStream/AmsiStream.cpp at main · microsoft/Windows-classic-samples</a></p>\n<p>First, I will read through this sample code in order, starting from the <code class=\"language-text\">main</code> function.</p>\n<h2 id=\"the-main-function\" style=\"position:relative;\"><a href=\"#the-main-function\" aria-label=\"the main function permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>The main Function</h2>\n<div class=\"gatsby-highlight\" data-language=\"c\"><pre class=\"language-c\"><code class=\"language-c\"><span class=\"token keyword\">int</span> __cdecl <span class=\"token function\">wmain</span><span class=\"token punctuation\">(</span>_In_ <span class=\"token keyword\">int</span> argc<span class=\"token punctuation\">,</span> <span class=\"token function\">_In_reads_</span><span class=\"token punctuation\">(</span>argc<span class=\"token punctuation\">)</span> WCHAR <span class=\"token operator\">*</span><span class=\"token operator\">*</span>argv<span class=\"token punctuation\">)</span>\n<span class=\"token punctuation\">{</span>\n\nHRESULT hr <span class=\"token operator\">=</span> <span class=\"token function\">CoInitializeEx</span><span class=\"token punctuation\">(</span>nullptr<span class=\"token punctuation\">,</span> COINIT_MULTITHREADED<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n<span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span><span class=\"token function\">SUCCEEDED</span><span class=\"token punctuation\">(</span>hr<span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n        hr <span class=\"token operator\">=</span> <span class=\"token function\">ScanArguments</span><span class=\"token punctuation\">(</span>argc<span class=\"token punctuation\">,</span> argv<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n        <span class=\"token function\">CoUninitialize</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n<span class=\"token punctuation\">}</span>\n\n<span class=\"token function\">wprintf</span><span class=\"token punctuation\">(</span>L<span class=\"token string\">\"Leaving with hr = 0x%x\\n\"</span><span class=\"token punctuation\">,</span> hr<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n\n    <span class=\"token keyword\">return</span> <span class=\"token number\">0</span><span class=\"token punctuation\">;</span>\n<span class=\"token punctuation\">}</span></code></pre></div>\n<p>In the <code class=\"language-text\">main</code> function, the first thing done is initialization of the COM library with the <code class=\"language-text\">CoInitializeEx</code> function.</p>\n<p>Reference: <a href=\"https://learn.microsoft.com/ja-jp/windows/win32/learnwin32/initializing-the-com-library\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">Initializing the COM Library - Win32 apps | Microsoft Learn</a></p>\n<p>Reference: <a href=\"https://learn.microsoft.com/ja-jp/windows/win32/api/combaseapi/nf-combaseapi-coinitializeex\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">CoInitializeEx function (combaseapi.h) - Win32 apps | Microsoft Learn</a></p>\n<p>This function must be called to initialize the COM library in Windows programs that use COM, and it appears to be called only once per thread that uses the COM library.</p>\n<p>The first argument to <code class=\"language-text\">CoInitializeEx</code> is reserved and therefore must be <code class=\"language-text\">NULL</code>, and the second argument is used to specify the threading model the program uses (<code class=\"language-text\">apartment thread</code> or <code class=\"language-text\">multithreaded</code>).</p>\n<p>In this sample, the argument is <code class=\"language-text\">COINIT_MULTITHREADED</code>, which uses the multithreaded model.</p>\n<p>After the COM library is initialized, <code class=\"language-text\">CoUninitialize</code> is called after <code class=\"language-text\">ScanArguments(argc, argv)</code>.</p>\n<p>This function must be executed to uninitialize the thread before it exits.</p>\n<h2 id=\"calling-the-scanarguments-function\" style=\"position:relative;\"><a href=\"#calling-the-scanarguments-function\" aria-label=\"calling the scanarguments function permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Calling the ScanArguments Function</h2>\n<p>After initializing the COM library, the <code class=\"language-text\">ScanArguments</code> function is called with the command-line arguments.</p>\n<div class=\"gatsby-highlight\" data-language=\"c\"><pre class=\"language-c\"><code class=\"language-c\">HRESULT <span class=\"token function\">ScanArguments</span><span class=\"token punctuation\">(</span>_In_ <span class=\"token keyword\">int</span> argc<span class=\"token punctuation\">,</span> <span class=\"token function\">_In_reads_</span><span class=\"token punctuation\">(</span>argc<span class=\"token punctuation\">)</span> <span class=\"token class-name\">wchar_t</span><span class=\"token operator\">*</span><span class=\"token operator\">*</span> argv<span class=\"token punctuation\">)</span>\n<span class=\"token punctuation\">{</span>\n    CStreamScanner scanner<span class=\"token punctuation\">;</span>\n    HRESULT hr <span class=\"token operator\">=</span> scanner<span class=\"token punctuation\">.</span><span class=\"token function\">Initialize</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    <span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span><span class=\"token function\">FAILED</span><span class=\"token punctuation\">(</span>hr<span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span>\n    <span class=\"token punctuation\">{</span>\n        <span class=\"token keyword\">return</span> hr<span class=\"token punctuation\">;</span>\n    <span class=\"token punctuation\">}</span>\n\n    <span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span>argc <span class=\"token operator\">&lt;</span> <span class=\"token number\">2</span><span class=\"token punctuation\">)</span>\n    <span class=\"token punctuation\">{</span>\n        <span class=\"token comment\">// Scan a single memory stream.</span>\n        <span class=\"token function\">wprintf</span><span class=\"token punctuation\">(</span>L<span class=\"token string\">\"Creating memory stream object\\n\"</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n\n        ComPtr<span class=\"token operator\">&lt;</span>IAmsiStream<span class=\"token operator\">></span> stream<span class=\"token punctuation\">;</span>\n        hr <span class=\"token operator\">=</span> MakeAndInitialize<span class=\"token operator\">&lt;</span>CAmsiMemoryStream<span class=\"token operator\">></span><span class=\"token punctuation\">(</span><span class=\"token operator\">&amp;</span>stream<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n        <span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span><span class=\"token function\">FAILED</span><span class=\"token punctuation\">(</span>hr<span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n            <span class=\"token keyword\">return</span> hr<span class=\"token punctuation\">;</span>\n        <span class=\"token punctuation\">}</span>\n\n        hr <span class=\"token operator\">=</span> scanner<span class=\"token punctuation\">.</span><span class=\"token function\">ScanStream</span><span class=\"token punctuation\">(</span>stream<span class=\"token punctuation\">.</span><span class=\"token function\">Get</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n        <span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span><span class=\"token function\">FAILED</span><span class=\"token punctuation\">(</span>hr<span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span>\n        <span class=\"token punctuation\">{</span>\n            <span class=\"token keyword\">return</span> hr<span class=\"token punctuation\">;</span>\n        <span class=\"token punctuation\">}</span>\n    <span class=\"token punctuation\">}</span>\n    <span class=\"token keyword\">else</span>\n    <span class=\"token punctuation\">{</span>\n        <span class=\"token comment\">// Scan the files passed on the command line.</span>\n        <span class=\"token keyword\">for</span> <span class=\"token punctuation\">(</span><span class=\"token keyword\">int</span> i <span class=\"token operator\">=</span> <span class=\"token number\">1</span><span class=\"token punctuation\">;</span> i <span class=\"token operator\">&lt;</span> argc<span class=\"token punctuation\">;</span> i<span class=\"token operator\">++</span><span class=\"token punctuation\">)</span>\n        <span class=\"token punctuation\">{</span>\n            LPWSTR fileName <span class=\"token operator\">=</span> argv<span class=\"token punctuation\">[</span>i<span class=\"token punctuation\">]</span><span class=\"token punctuation\">;</span>\n\n            <span class=\"token function\">wprintf</span><span class=\"token punctuation\">(</span>L<span class=\"token string\">\"Creating stream object with file name: %s\\n\"</span><span class=\"token punctuation\">,</span> fileName<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n            ComPtr<span class=\"token operator\">&lt;</span>IAmsiStream<span class=\"token operator\">></span> stream<span class=\"token punctuation\">;</span>\n            hr <span class=\"token operator\">=</span> MakeAndInitialize<span class=\"token operator\">&lt;</span>CAmsiFileStream<span class=\"token operator\">></span><span class=\"token punctuation\">(</span><span class=\"token operator\">&amp;</span>stream<span class=\"token punctuation\">,</span> fileName<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n            <span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span><span class=\"token function\">FAILED</span><span class=\"token punctuation\">(</span>hr<span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n                <span class=\"token keyword\">return</span> hr<span class=\"token punctuation\">;</span>\n            <span class=\"token punctuation\">}</span>\n\n            hr <span class=\"token operator\">=</span> scanner<span class=\"token punctuation\">.</span><span class=\"token function\">ScanStream</span><span class=\"token punctuation\">(</span>stream<span class=\"token punctuation\">.</span><span class=\"token function\">Get</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n            <span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span><span class=\"token function\">FAILED</span><span class=\"token punctuation\">(</span>hr<span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span>\n            <span class=\"token punctuation\">{</span>\n                <span class=\"token keyword\">return</span> hr<span class=\"token punctuation\">;</span>\n            <span class=\"token punctuation\">}</span>\n        <span class=\"token punctuation\">}</span>\n    <span class=\"token punctuation\">}</span>\n\n    <span class=\"token keyword\">return</span> S_OK<span class=\"token punctuation\">;</span>\n<span class=\"token punctuation\">}</span></code></pre></div>\n<p>Inside this function, an instance named <code class=\"language-text\">scanner</code> of the <code class=\"language-text\">CStreamScanner</code> class is first defined, and then initialized by its <code class=\"language-text\">Initialize</code> method.</p>\n<div class=\"gatsby-highlight\" data-language=\"c\"><pre class=\"language-c\"><code class=\"language-c\">CStreamScanner scanner<span class=\"token punctuation\">;</span>\nHRESULT hr <span class=\"token operator\">=</span> scanner<span class=\"token punctuation\">.</span><span class=\"token function\">Initialize</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></code></pre></div>\n<h2 id=\"initializing-the-cstreamscanner-class\" style=\"position:relative;\"><a href=\"#initializing-the-cstreamscanner-class\" aria-label=\"initializing the cstreamscanner class permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Initializing the CStreamScanner Class</h2>\n<p>The <code class=\"language-text\">CStreamScanner</code> class is defined as follows, and its <code class=\"language-text\">Initialize</code> method initializes the object by calling <code class=\"language-text\">CoCreateInstance</code>.</p>\n<p>Reference: <a href=\"https://learn.microsoft.com/ja-jp/windows/win32/api/combaseapi/nf-combaseapi-cocreateinstance\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">CoCreateInstance function (combaseapi.h) - Win32 apps | Microsoft Learn</a></p>\n<p>For the CLSID that specifies the class of the object to create, it uses the value defined in <code class=\"language-text\">amsi.h</code> and passes <code class=\"language-text\">__uuidof(CAntimalware)</code> to the <code class=\"language-text\">CoCreateInstance</code> function.</p>\n<p>Also, the interface identifier (IID) used to communicate with the object is stored in the member defined as <code class=\"language-text\">ComPtr&lt;IAntimalware> m_antimalware;</code>.</p>\n<div class=\"gatsby-highlight\" data-language=\"c\"><pre class=\"language-c\"><code class=\"language-c\">class CStreamScanner\n<span class=\"token punctuation\">{</span>\npublic<span class=\"token operator\">:</span>\n    HRESULT <span class=\"token function\">Initialize</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span>\n    <span class=\"token punctuation\">{</span>\n        <span class=\"token keyword\">return</span> <span class=\"token function\">CoCreateInstance</span><span class=\"token punctuation\">(</span>\n            <span class=\"token function\">__uuidof</span><span class=\"token punctuation\">(</span>CAntimalware<span class=\"token punctuation\">)</span><span class=\"token punctuation\">,</span>\n            nullptr<span class=\"token punctuation\">,</span>\n            CLSCTX_INPROC_SERVER<span class=\"token punctuation\">,</span>\n            <span class=\"token function\">IID_PPV_ARGS</span><span class=\"token punctuation\">(</span><span class=\"token operator\">&amp;</span>m_antimalware<span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    <span class=\"token punctuation\">}</span>\n\n    <span class=\"token comment\">/* omitted */</span>\n\nprivate<span class=\"token operator\">:</span>\n    ComPtr<span class=\"token operator\">&lt;</span>IAntimalware<span class=\"token operator\">></span> m_antimalware<span class=\"token punctuation\">;</span>\n<span class=\"token punctuation\">}</span><span class=\"token punctuation\">;</span></code></pre></div>\n<h2 id=\"scanning-a-memory-stream\" style=\"position:relative;\"><a href=\"#scanning-a-memory-stream\" aria-label=\"scanning a memory stream permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Scanning a Memory Stream</h2>\n<p>After the <code class=\"language-text\">CStreamScanner</code> class is initialized, the <code class=\"language-text\">ScanArguments</code> function decides whether to scan a predefined memory stream or a file received as a command-line argument, depending on whether command-line arguments are present.</p>\n<p>If no command-line arguments are present, the following code is executed.</p>\n<div class=\"gatsby-highlight\" data-language=\"c\"><pre class=\"language-c\"><code class=\"language-c\"><span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span>argc <span class=\"token operator\">&lt;</span> <span class=\"token number\">2</span><span class=\"token punctuation\">)</span>\n<span class=\"token punctuation\">{</span>\n    <span class=\"token comment\">// Scan a single memory stream.</span>\n    <span class=\"token function\">wprintf</span><span class=\"token punctuation\">(</span>L<span class=\"token string\">\"Creating memory stream object\\n\"</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n\n    ComPtr<span class=\"token operator\">&lt;</span>IAmsiStream<span class=\"token operator\">></span> stream<span class=\"token punctuation\">;</span>\n    hr <span class=\"token operator\">=</span> MakeAndInitialize<span class=\"token operator\">&lt;</span>CAmsiMemoryStream<span class=\"token operator\">></span><span class=\"token punctuation\">(</span><span class=\"token operator\">&amp;</span>stream<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    <span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span><span class=\"token function\">FAILED</span><span class=\"token punctuation\">(</span>hr<span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n        <span class=\"token keyword\">return</span> hr<span class=\"token punctuation\">;</span>\n    <span class=\"token punctuation\">}</span>\n\n    hr <span class=\"token operator\">=</span> scanner<span class=\"token punctuation\">.</span><span class=\"token function\">ScanStream</span><span class=\"token punctuation\">(</span>stream<span class=\"token punctuation\">.</span><span class=\"token function\">Get</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    <span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span><span class=\"token function\">FAILED</span><span class=\"token punctuation\">(</span>hr<span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span>\n    <span class=\"token punctuation\">{</span>\n        <span class=\"token keyword\">return</span> hr<span class=\"token punctuation\">;</span>\n    <span class=\"token punctuation\">}</span>\n<span class=\"token punctuation\">}</span></code></pre></div>\n<p>In this code, an <code class=\"language-text\">IAmsiStream</code> interface pointer is first declared with <code class=\"language-text\">ComPtr&lt;IAmsiStream> stream;</code>.</p>\n<p>Reference: <a href=\"https://learn.microsoft.com/ja-jp/windows/win32/api/amsi/nn-amsi-iamsistream\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">IAmsiStream (amsi.h) - Win32 apps | Microsoft Learn</a></p>\n<p>Reference: <a href=\"https://learn.microsoft.com/ja-jp/cpp/cppcx/wrl/comptr-class?view=msvc-170\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">ComPtr Class | Microsoft Learn</a></p>\n<p>Next, <code class=\"language-text\">MakeAndInitialize&lt;CAmsiMemoryStream>(&amp;stream);</code> initializes <code class=\"language-text\">CAmsiMemoryStream</code>, which is a Windows Runtime C++ Template Library (WRL) class, by using the <code class=\"language-text\">MakeAndInitialize</code> function.</p>\n<p>Reference: <a href=\"https://learn.microsoft.com/ja-jp/cpp/cppcx/wrl/makeandinitialize-function?view=msvc-170\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">MakeAndInitialize function | Microsoft Learn</a></p>\n<p>Reference: <a href=\"https://learn.microsoft.com/ja-jp/cpp/cppcx/wrl/how-to-instantiate-wrl-components-directly?view=msvc-170\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">How to: Instantiate WRL Components Directly | Microsoft Learn</a></p>\n<p>To be honest, my understanding of WRL is still a bit vague, but in this sample <code class=\"language-text\">CAmsiMemoryStream</code> seems to be a WRL class implemented to create a classic COM component.</p>\n<p>Reference: <a href=\"https://learn.microsoft.com/ja-jp/cpp/cppcx/wrl/how-to-create-a-classic-com-component-using-wrl?view=msvc-170&#x26;utm_source=chatgpt.com\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">How to: Create a Classic COM Component Using WRL | Microsoft Learn</a></p>\n<h3 id=\"the-camsimemorystream-class\" style=\"position:relative;\"><a href=\"#the-camsimemorystream-class\" aria-label=\"the camsimemorystream class permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>The CAmsiMemoryStream Class</h3>\n<p>The WRL class <code class=\"language-text\">CAmsiMemoryStream</code> is used to implement the <code class=\"language-text\">IAmsiStream</code> interface.</p>\n<p>This class appears to create <code class=\"language-text\">IAmsiStream</code> and the corresponding interface by using WRL through <code class=\"language-text\">RuntimeClass&lt;RuntimeClassFlags&lt;ClassicCom>, IAmsiStream></code>.</p>\n<p>It also inherits from <code class=\"language-text\">CAmsiStreamBase</code>, a separately defined class that provides common processing.</p>\n<div class=\"gatsby-highlight\" data-language=\"c\"><pre class=\"language-c\"><code class=\"language-c\">class CAmsiMemoryStream <span class=\"token operator\">:</span> public RuntimeClass<span class=\"token operator\">&lt;</span>RuntimeClassFlags<span class=\"token operator\">&lt;</span>ClassicCom<span class=\"token operator\">></span><span class=\"token punctuation\">,</span> IAmsiStream<span class=\"token operator\">></span><span class=\"token punctuation\">,</span> CAmsiStreamBase\n<span class=\"token punctuation\">{</span>\npublic<span class=\"token operator\">:</span>\n    HRESULT <span class=\"token function\">RuntimeClassInitialize</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span>\n    <span class=\"token punctuation\">{</span>\n        m_contentSize <span class=\"token operator\">=</span> <span class=\"token keyword\">sizeof</span><span class=\"token punctuation\">(</span>SampleStream<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n        <span class=\"token keyword\">return</span> <span class=\"token function\">SetContentName</span><span class=\"token punctuation\">(</span>L<span class=\"token string\">\"Sample content.txt\"</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    <span class=\"token punctuation\">}</span>\n\n    <span class=\"token comment\">// IAmsiStream</span>\n\n    <span class=\"token function\">STDMETHOD</span><span class=\"token punctuation\">(</span>GetAttribute<span class=\"token punctuation\">)</span><span class=\"token punctuation\">(</span>\n        _In_ AMSI_ATTRIBUTE attribute<span class=\"token punctuation\">,</span>\n        _In_ ULONG bufferSize<span class=\"token punctuation\">,</span>\n        <span class=\"token function\">_Out_writes_bytes_to_</span><span class=\"token punctuation\">(</span>bufferSize<span class=\"token punctuation\">,</span> <span class=\"token operator\">*</span>actualSize<span class=\"token punctuation\">)</span> PBYTE buffer<span class=\"token punctuation\">,</span>\n        _Out_ ULONG<span class=\"token operator\">*</span> actualSize<span class=\"token punctuation\">)</span>\n    <span class=\"token punctuation\">{</span>\n        HRESULT hr <span class=\"token operator\">=</span> <span class=\"token function\">BaseGetAttribute</span><span class=\"token punctuation\">(</span>attribute<span class=\"token punctuation\">,</span> bufferSize<span class=\"token punctuation\">,</span> buffer<span class=\"token punctuation\">,</span> actualSize<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n        <span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span>hr <span class=\"token operator\">==</span> E_NOTIMPL<span class=\"token punctuation\">)</span>\n        <span class=\"token punctuation\">{</span>\n            <span class=\"token keyword\">switch</span> <span class=\"token punctuation\">(</span>attribute<span class=\"token punctuation\">)</span>\n            <span class=\"token punctuation\">{</span>\n            <span class=\"token keyword\">case</span> AMSI_ATTRIBUTE_CONTENT_ADDRESS<span class=\"token operator\">:</span>\n                <span class=\"token keyword\">const</span> <span class=\"token keyword\">void</span><span class=\"token operator\">*</span> contentAddress <span class=\"token operator\">=</span> SampleStream<span class=\"token punctuation\">;</span>\n                hr <span class=\"token operator\">=</span> <span class=\"token function\">CopyAttribute</span><span class=\"token punctuation\">(</span><span class=\"token operator\">&amp;</span>contentAddress<span class=\"token punctuation\">,</span> <span class=\"token keyword\">sizeof</span><span class=\"token punctuation\">(</span>contentAddress<span class=\"token punctuation\">)</span><span class=\"token punctuation\">,</span> bufferSize<span class=\"token punctuation\">,</span> buffer<span class=\"token punctuation\">,</span> actualSize<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n            <span class=\"token punctuation\">}</span>\n        <span class=\"token punctuation\">}</span>\n        <span class=\"token keyword\">return</span> hr<span class=\"token punctuation\">;</span>\n    <span class=\"token punctuation\">}</span>\n\n    <span class=\"token function\">STDMETHOD</span><span class=\"token punctuation\">(</span>Read<span class=\"token punctuation\">)</span><span class=\"token punctuation\">(</span>\n        _In_ ULONGLONG position<span class=\"token punctuation\">,</span>\n        _In_ ULONG size<span class=\"token punctuation\">,</span>\n        <span class=\"token function\">_Out_writes_bytes_to_</span><span class=\"token punctuation\">(</span>size<span class=\"token punctuation\">,</span> <span class=\"token operator\">*</span>readSize<span class=\"token punctuation\">)</span> PBYTE buffer<span class=\"token punctuation\">,</span>\n        _Out_ ULONG<span class=\"token operator\">*</span> readSize<span class=\"token punctuation\">)</span>\n    <span class=\"token punctuation\">{</span>\n        <span class=\"token function\">wprintf</span><span class=\"token punctuation\">(</span>L<span class=\"token string\">\"Read() called with: position = %I64u, size = %u\\n\"</span><span class=\"token punctuation\">,</span> position<span class=\"token punctuation\">,</span> size<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n\n        <span class=\"token operator\">*</span>readSize <span class=\"token operator\">=</span> <span class=\"token number\">0</span><span class=\"token punctuation\">;</span>\n        <span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span>position <span class=\"token operator\">>=</span> m_contentSize<span class=\"token punctuation\">)</span>\n        <span class=\"token punctuation\">{</span>\n            <span class=\"token function\">wprintf</span><span class=\"token punctuation\">(</span>L<span class=\"token string\">\"Reading beyond end of stream\\n\"</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n            <span class=\"token keyword\">return</span> <span class=\"token function\">HRESULT_FROM_WIN32</span><span class=\"token punctuation\">(</span>ERROR_HANDLE_EOF<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n        <span class=\"token punctuation\">}</span>\n\n        <span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span>size <span class=\"token operator\">></span> m_contentSize <span class=\"token operator\">-</span> position<span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n            size <span class=\"token operator\">=</span> static_cast<span class=\"token operator\">&lt;</span>ULONG<span class=\"token operator\">></span><span class=\"token punctuation\">(</span>m_contentSize <span class=\"token operator\">-</span> position<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n        <span class=\"token punctuation\">}</span>\n\n        <span class=\"token operator\">*</span>readSize <span class=\"token operator\">=</span> size<span class=\"token punctuation\">;</span>\n        <span class=\"token function\">memcpy_s</span><span class=\"token punctuation\">(</span>buffer<span class=\"token punctuation\">,</span> size<span class=\"token punctuation\">,</span> SampleStream <span class=\"token operator\">+</span> position<span class=\"token punctuation\">,</span> size<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n        <span class=\"token keyword\">return</span> S_OK<span class=\"token punctuation\">;</span>\n    <span class=\"token punctuation\">}</span>\n<span class=\"token punctuation\">}</span><span class=\"token punctuation\">;</span></code></pre></div>\n<p>First, the <code class=\"language-text\">RuntimeClassInitialize</code> function is said to be the function that performs initialization when creating an object by using the <code class=\"language-text\">MakeAndInitialize</code> function template.</p>\n<p>Reference: <a href=\"https://learn.microsoft.com/ja-jp/cpp/cppcx/wrl/runtimeclass-class?view=msvc-170\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">RuntimeClass Class | Microsoft Learn</a></p>\n<p>In this sample, the string <code class=\"language-text\">SampleStream</code>, defined as a global variable, is stored in memory, and <code class=\"language-text\">SetContentName</code>, which is defined separately in <code class=\"language-text\">CAmsiStreamBase</code>, is used in that process.</p>\n<div class=\"gatsby-highlight\" data-language=\"c\"><pre class=\"language-c\"><code class=\"language-c\"><span class=\"token keyword\">const</span> <span class=\"token keyword\">char</span> SampleStream<span class=\"token punctuation\">[</span><span class=\"token punctuation\">]</span> <span class=\"token operator\">=</span> <span class=\"token string\">\"Hello, world\"</span><span class=\"token punctuation\">;</span>\n\nHRESULT <span class=\"token function\">RuntimeClassInitialize</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span>\n<span class=\"token punctuation\">{</span>\n    m_contentSize <span class=\"token operator\">=</span> <span class=\"token keyword\">sizeof</span><span class=\"token punctuation\">(</span>SampleStream<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    <span class=\"token keyword\">return</span> <span class=\"token function\">SetContentName</span><span class=\"token punctuation\">(</span>L<span class=\"token string\">\"Sample content.txt\"</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n<span class=\"token punctuation\">}</span></code></pre></div>\n<p>The subsequent code implements the <code class=\"language-text\">IAmsiStream</code> interface.</p>\n<p><code class=\"language-text\">STDMETHOD</code> apparently is a macro used to define “a function that is <code class=\"language-text\">__stdcall</code>, virtual, and returns <code class=\"language-text\">HRESULT</code>.”</p>\n<p>Reference: <a href=\"https://learn.microsoft.com/ja-jp/windows/win32/api/amsi/nn-amsi-iamsistream\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">IAmsiStream (amsi.h) - Win32 apps | Microsoft Learn</a></p>\n<p>In the <code class=\"language-text\">CAmsiMemoryStream</code> class, the <code class=\"language-text\">GetAttribute</code> and <code class=\"language-text\">Read</code> methods are defined as shown above.</p>\n<p>The <code class=\"language-text\">GetAttribute</code> method uses <code class=\"language-text\">BaseGetAttribute</code> from the base class <code class=\"language-text\">CAmsiStreamBase</code> to handle attributes related to AMSI scanning.</p>\n<p>Inside it, after checking items such as <code class=\"language-text\">attribute</code> and <code class=\"language-text\">buffer</code>, it ultimately returns the result of the <code class=\"language-text\">CopyAttribute</code> method defined in the base class.</p>\n<div class=\"gatsby-highlight\" data-language=\"c\"><pre class=\"language-c\"><code class=\"language-c\"><span class=\"token function\">STDMETHOD</span><span class=\"token punctuation\">(</span>GetAttribute<span class=\"token punctuation\">)</span><span class=\"token punctuation\">(</span>\n    _In_ AMSI_ATTRIBUTE attribute<span class=\"token punctuation\">,</span>\n    _In_ ULONG bufferSize<span class=\"token punctuation\">,</span>\n    <span class=\"token function\">_Out_writes_bytes_to_</span><span class=\"token punctuation\">(</span>bufferSize<span class=\"token punctuation\">,</span> <span class=\"token operator\">*</span>actualSize<span class=\"token punctuation\">)</span> PBYTE buffer<span class=\"token punctuation\">,</span>\n    _Out_ ULONG<span class=\"token operator\">*</span> actualSize<span class=\"token punctuation\">)</span>\n<span class=\"token punctuation\">{</span>\n    HRESULT hr <span class=\"token operator\">=</span> <span class=\"token function\">BaseGetAttribute</span><span class=\"token punctuation\">(</span>attribute<span class=\"token punctuation\">,</span> bufferSize<span class=\"token punctuation\">,</span> buffer<span class=\"token punctuation\">,</span> actualSize<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    <span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span>hr <span class=\"token operator\">==</span> E_NOTIMPL<span class=\"token punctuation\">)</span>\n    <span class=\"token punctuation\">{</span>\n        <span class=\"token keyword\">switch</span> <span class=\"token punctuation\">(</span>attribute<span class=\"token punctuation\">)</span>\n        <span class=\"token punctuation\">{</span>\n        <span class=\"token keyword\">case</span> AMSI_ATTRIBUTE_CONTENT_ADDRESS<span class=\"token operator\">:</span>\n            <span class=\"token keyword\">const</span> <span class=\"token keyword\">void</span><span class=\"token operator\">*</span> contentAddress <span class=\"token operator\">=</span> SampleStream<span class=\"token punctuation\">;</span>\n            hr <span class=\"token operator\">=</span> <span class=\"token function\">CopyAttribute</span><span class=\"token punctuation\">(</span><span class=\"token operator\">&amp;</span>contentAddress<span class=\"token punctuation\">,</span> <span class=\"token keyword\">sizeof</span><span class=\"token punctuation\">(</span>contentAddress<span class=\"token punctuation\">)</span><span class=\"token punctuation\">,</span> bufferSize<span class=\"token punctuation\">,</span> buffer<span class=\"token punctuation\">,</span> actualSize<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n        <span class=\"token punctuation\">}</span>\n    <span class=\"token punctuation\">}</span>\n    <span class=\"token keyword\">return</span> hr<span class=\"token punctuation\">;</span>\n<span class=\"token punctuation\">}</span></code></pre></div>\n<p>The <code class=\"language-text\">CopyAttribute</code> method checks the buffer and size passed as arguments, then copies the received data by using the <code class=\"language-text\">memcpy_s</code> function.</p>\n<div class=\"gatsby-highlight\" data-language=\"c\"><pre class=\"language-c\"><code class=\"language-c\">HRESULT <span class=\"token function\">CopyAttribute</span><span class=\"token punctuation\">(</span>\n    _In_ <span class=\"token keyword\">const</span> <span class=\"token keyword\">void</span><span class=\"token operator\">*</span> resultData<span class=\"token punctuation\">,</span>\n    _In_ <span class=\"token class-name\">size_t</span> resultSize<span class=\"token punctuation\">,</span>\n    _In_ ULONG bufferSize<span class=\"token punctuation\">,</span>\n    <span class=\"token function\">_Out_writes_bytes_to_</span><span class=\"token punctuation\">(</span>bufferSize<span class=\"token punctuation\">,</span> <span class=\"token operator\">*</span>actualSize<span class=\"token punctuation\">)</span> PBYTE buffer<span class=\"token punctuation\">,</span>\n    _Out_ ULONG<span class=\"token operator\">*</span> actualSize<span class=\"token punctuation\">)</span>\n<span class=\"token punctuation\">{</span>\n    <span class=\"token operator\">*</span>actualSize <span class=\"token operator\">=</span> <span class=\"token punctuation\">(</span>ULONG<span class=\"token punctuation\">)</span>resultSize<span class=\"token punctuation\">;</span>\n    <span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span>bufferSize <span class=\"token operator\">&lt;</span> resultSize<span class=\"token punctuation\">)</span>\n    <span class=\"token punctuation\">{</span>\n        <span class=\"token keyword\">return</span> E_NOT_SUFFICIENT_BUFFER<span class=\"token punctuation\">;</span>\n    <span class=\"token punctuation\">}</span>\n    <span class=\"token function\">memcpy_s</span><span class=\"token punctuation\">(</span>buffer<span class=\"token punctuation\">,</span> bufferSize<span class=\"token punctuation\">,</span> resultData<span class=\"token punctuation\">,</span> resultSize<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    <span class=\"token keyword\">return</span> S_OK<span class=\"token punctuation\">;</span>\n<span class=\"token punctuation\">}</span></code></pre></div>\n<p>The other method defined in the <code class=\"language-text\">CAmsiMemoryStream</code> class is <code class=\"language-text\">Read</code>, shown below.</p>\n<p>Here, the data of the content to be read is copied into the received buffer.</p>\n<div class=\"gatsby-highlight\" data-language=\"c\"><pre class=\"language-c\"><code class=\"language-c\"><span class=\"token function\">STDMETHOD</span><span class=\"token punctuation\">(</span>Read<span class=\"token punctuation\">)</span><span class=\"token punctuation\">(</span>\n    _In_ ULONGLONG position<span class=\"token punctuation\">,</span>\n    _In_ ULONG size<span class=\"token punctuation\">,</span>\n    <span class=\"token function\">_Out_writes_bytes_to_</span><span class=\"token punctuation\">(</span>size<span class=\"token punctuation\">,</span> <span class=\"token operator\">*</span>readSize<span class=\"token punctuation\">)</span> PBYTE buffer<span class=\"token punctuation\">,</span>\n    _Out_ ULONG<span class=\"token operator\">*</span> readSize<span class=\"token punctuation\">)</span>\n<span class=\"token punctuation\">{</span>\n    <span class=\"token function\">wprintf</span><span class=\"token punctuation\">(</span>L<span class=\"token string\">\"Read() called with: position = %I64u, size = %u\\n\"</span><span class=\"token punctuation\">,</span> position<span class=\"token punctuation\">,</span> size<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n\n    <span class=\"token operator\">*</span>readSize <span class=\"token operator\">=</span> <span class=\"token number\">0</span><span class=\"token punctuation\">;</span>\n    <span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span>position <span class=\"token operator\">>=</span> m_contentSize<span class=\"token punctuation\">)</span>\n    <span class=\"token punctuation\">{</span>\n        <span class=\"token function\">wprintf</span><span class=\"token punctuation\">(</span>L<span class=\"token string\">\"Reading beyond end of stream\\n\"</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n        <span class=\"token keyword\">return</span> <span class=\"token function\">HRESULT_FROM_WIN32</span><span class=\"token punctuation\">(</span>ERROR_HANDLE_EOF<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    <span class=\"token punctuation\">}</span>\n\n    <span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span>size <span class=\"token operator\">></span> m_contentSize <span class=\"token operator\">-</span> position<span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n        size <span class=\"token operator\">=</span> static_cast<span class=\"token operator\">&lt;</span>ULONG<span class=\"token operator\">></span><span class=\"token punctuation\">(</span>m_contentSize <span class=\"token operator\">-</span> position<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    <span class=\"token punctuation\">}</span>\n\n    <span class=\"token operator\">*</span>readSize <span class=\"token operator\">=</span> size<span class=\"token punctuation\">;</span>\n    <span class=\"token function\">memcpy_s</span><span class=\"token punctuation\">(</span>buffer<span class=\"token punctuation\">,</span> size<span class=\"token punctuation\">,</span> SampleStream <span class=\"token operator\">+</span> position<span class=\"token punctuation\">,</span> size<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    <span class=\"token keyword\">return</span> S_OK<span class=\"token punctuation\">;</span>\n<span class=\"token punctuation\">}</span></code></pre></div>\n<h3 id=\"calling-the-scanstream-method\" style=\"position:relative;\"><a href=\"#calling-the-scanstream-method\" aria-label=\"calling the scanstream method permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Calling the ScanStream Method</h3>\n<p>After copying the content data, <code class=\"language-text\">scanner.ScanStream(stream.Get());</code> passes a pointer to the <code class=\"language-text\">IAmsiStream</code> instance obtained by <code class=\"language-text\">stream.Get()</code> to the <code class=\"language-text\">ScanStream</code> method of the <code class=\"language-text\">CStreamScanner</code> class.</p>\n<p>Inside it, the <code class=\"language-text\">Scan</code> method of the initialized <code class=\"language-text\">IAntimalware</code> interface is called.</p>\n<p>Reference: <a href=\"https://learn.microsoft.com/ja-jp/windows/win32/api/amsi/nf-amsi-iantimalware-scan\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">IAntimalware::Scan (amsi.h) - Win32 apps | Microsoft Learn</a></p>\n<div class=\"gatsby-highlight\" data-language=\"c\"><pre class=\"language-c\"><code class=\"language-c\">class CStreamScanner\n<span class=\"token punctuation\">{</span>\npublic<span class=\"token operator\">:</span>\n    HRESULT <span class=\"token function\">Initialize</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span>\n    <span class=\"token punctuation\">{</span>\n        <span class=\"token keyword\">return</span> <span class=\"token function\">CoCreateInstance</span><span class=\"token punctuation\">(</span>\n            <span class=\"token function\">__uuidof</span><span class=\"token punctuation\">(</span>CAntimalware<span class=\"token punctuation\">)</span><span class=\"token punctuation\">,</span>\n            nullptr<span class=\"token punctuation\">,</span>\n            CLSCTX_INPROC_SERVER<span class=\"token punctuation\">,</span>\n            <span class=\"token function\">IID_PPV_ARGS</span><span class=\"token punctuation\">(</span><span class=\"token operator\">&amp;</span>m_antimalware<span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    <span class=\"token punctuation\">}</span>\n\n    HRESULT <span class=\"token function\">ScanStream</span><span class=\"token punctuation\">(</span>_In_ IAmsiStream<span class=\"token operator\">*</span> stream<span class=\"token punctuation\">)</span>\n    <span class=\"token punctuation\">{</span>\n        <span class=\"token function\">wprintf</span><span class=\"token punctuation\">(</span>L<span class=\"token string\">\"Calling antimalware->Scan() ...\\n\"</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n        ComPtr<span class=\"token operator\">&lt;</span>IAntimalwareProvider<span class=\"token operator\">></span> provider<span class=\"token punctuation\">;</span>\n        AMSI_RESULT r<span class=\"token punctuation\">;</span>\n        HRESULT hr <span class=\"token operator\">=</span> m_antimalware<span class=\"token operator\">-></span><span class=\"token function\">Scan</span><span class=\"token punctuation\">(</span>stream<span class=\"token punctuation\">,</span> <span class=\"token operator\">&amp;</span>r<span class=\"token punctuation\">,</span> <span class=\"token operator\">&amp;</span>provider<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n        <span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span><span class=\"token function\">FAILED</span><span class=\"token punctuation\">(</span>hr<span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n            <span class=\"token keyword\">return</span> hr<span class=\"token punctuation\">;</span>\n        <span class=\"token punctuation\">}</span>\n\n        <span class=\"token function\">wprintf</span><span class=\"token punctuation\">(</span>L<span class=\"token string\">\"Scan result is %u. IsMalware: %d\\n\"</span><span class=\"token punctuation\">,</span> r<span class=\"token punctuation\">,</span> <span class=\"token function\">AmsiResultIsMalware</span><span class=\"token punctuation\">(</span>r<span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n\n        <span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span>provider<span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n            PWSTR name<span class=\"token punctuation\">;</span>\n            hr <span class=\"token operator\">=</span> provider<span class=\"token operator\">-></span><span class=\"token function\">DisplayName</span><span class=\"token punctuation\">(</span><span class=\"token operator\">&amp;</span>name<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n            <span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span><span class=\"token function\">SUCCEEDED</span><span class=\"token punctuation\">(</span>hr<span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n                <span class=\"token function\">wprintf</span><span class=\"token punctuation\">(</span>L<span class=\"token string\">\"Provider display name: %s\\n\"</span><span class=\"token punctuation\">,</span> name<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n                <span class=\"token function\">CoTaskMemFree</span><span class=\"token punctuation\">(</span>name<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n            <span class=\"token punctuation\">}</span>\n            <span class=\"token keyword\">else</span>\n            <span class=\"token punctuation\">{</span>\n                <span class=\"token function\">wprintf</span><span class=\"token punctuation\">(</span>L<span class=\"token string\">\"DisplayName failed with 0x%x\"</span><span class=\"token punctuation\">,</span> hr<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n            <span class=\"token punctuation\">}</span>\n        <span class=\"token punctuation\">}</span>\n\n        <span class=\"token keyword\">return</span> S_OK<span class=\"token punctuation\">;</span>\n    <span class=\"token punctuation\">}</span>\n\nprivate<span class=\"token operator\">:</span>\n    ComPtr<span class=\"token operator\">&lt;</span>IAntimalware<span class=\"token operator\">></span> m_antimalware<span class=\"token punctuation\">;</span>\n<span class=\"token punctuation\">}</span><span class=\"token punctuation\">;</span></code></pre></div>\n<p>The scan result is stored in the variable <code class=\"language-text\">r</code> of type <code class=\"language-text\">AMSI_RESULT</code>.</p>\n<p>Also, by passing this <code class=\"language-text\">AMSI_RESULT</code> variable to the <code class=\"language-text\">AmsiResultIsMalware</code> macro, you can determine whether the content needs to be blocked.</p>\n<p>Reference: <a href=\"https://learn.microsoft.com/ja-jp/windows/win32/api/amsi/nf-amsi-amsiresultismalware\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">AmsiResultIsMalware macro (amsi.h) - Win32 apps | Microsoft Learn</a></p>\n<p>In addition, the sample displays the antimalware provider name from <code class=\"language-text\">provider</code>, which is an instance of the <code class=\"language-text\">IAntimalwareProvider</code> interface returned by the <code class=\"language-text\">Scan</code> method of the <code class=\"language-text\">IAntimalware</code> interface.</p>\n<p>Reference: <a href=\"https://learn.microsoft.com/ja-jp/windows/win32/api/amsi/nf-amsi-iantimalwareprovider-displayname\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">IAntimalwareProvider::D isplayName (amsi.h) - Win32 apps | Microsoft Learn</a></p>\n<p>When malware is actually detected, you can confirm that the variable <code class=\"language-text\">name</code> contains the provider name <code class=\"language-text\">Microsoft Defender Antivirus</code>, and that the variable <code class=\"language-text\">r</code> contains the detection result <code class=\"language-text\">AMSI_RESULT_DETECTED</code>, as shown below.</p>\n<p><span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 960px; \"\n    >\n      <a\n    class=\"gatsby-resp-image-link\"\n    href=\"/static/ff05e920738fb9d7e31185abfecba288/3f20e/image-20250628173813251.png\"\n    style=\"display: block\"\n    target=\"_blank\"\n    rel=\"noopener\"\n  >\n    <span\n    class=\"gatsby-resp-image-background-image\"\n    style=\"padding-bottom: 20.416666666666668%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAECAYAAACOXx+WAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAyUlEQVQY0z1Py27DMAzLjzh+xM/Gs9Oky5YCOeyyAtv+/3c4SUN3IGiJBkUO6+sbjuPA5TIj5YyYMkIIyPT23mMcR2hthBlKMSuMWv/vBDRrYzFc9zvWdcPLsqI0Qm2IMYmp9xOcJ44Zzho51paraMYYWGsFhswCBykVw+PxiZ/vL7yfH3ClY+kNrTWUUpDSn/E8z3QkoveO8zxF45l1biJM0JR02Pcdd6rclg3aBan5/Oyck4qaEiilME0TttsNtVZJ+ATrrDH/AoMCdMeys1+FAAAAAElFTkSuQmCC'); background-size: cover; display: block;\"\n  ></span>\n  <picture>\n          <source\n              srcset=\"/static/ff05e920738fb9d7e31185abfecba288/8ac56/image-20250628173813251.webp 240w,\n/static/ff05e920738fb9d7e31185abfecba288/d3be9/image-20250628173813251.webp 480w,\n/static/ff05e920738fb9d7e31185abfecba288/e46b2/image-20250628173813251.webp 960w,\n/static/ff05e920738fb9d7e31185abfecba288/5e05a/image-20250628173813251.webp 1275w\"\n              sizes=\"(max-width: 960px) 100vw, 960px\"\n              type=\"image/webp\"\n            />\n          <source\n            srcset=\"/static/ff05e920738fb9d7e31185abfecba288/8ff5a/image-20250628173813251.png 240w,\n/static/ff05e920738fb9d7e31185abfecba288/e85cb/image-20250628173813251.png 480w,\n/static/ff05e920738fb9d7e31185abfecba288/d9199/image-20250628173813251.png 960w,\n/static/ff05e920738fb9d7e31185abfecba288/3f20e/image-20250628173813251.png 1275w\"\n            sizes=\"(max-width: 960px) 100vw, 960px\"\n            type=\"image/png\"\n          />\n          <img\n            class=\"gatsby-resp-image-image\"\n            src=\"/static/ff05e920738fb9d7e31185abfecba288/d9199/image-20250628173813251.png\"\n            alt=\"image-20250628173813251\"\n            title=\"image-20250628173813251\"\n            loading=\"lazy\"\n            style=\"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;\"\n          />\n        </picture>\n  </a>\n    </span></p>\n<h2 id=\"scanning-a-file-stream\" style=\"position:relative;\"><a href=\"#scanning-a-file-stream\" aria-label=\"scanning a file stream permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Scanning a File Stream</h2>\n<p>If the sample program is run without command-line arguments, the memory scan discussed in the previous section is performed.</p>\n<p>On the other hand, if a file path is included in the command-line arguments, the <code class=\"language-text\">CAmsiFileStream</code> class is initialized and the file is scanned.</p>\n<div class=\"gatsby-highlight\" data-language=\"c\"><pre class=\"language-c\"><code class=\"language-c\"><span class=\"token keyword\">else</span>\n<span class=\"token punctuation\">{</span>\n    <span class=\"token comment\">// Scan the files passed on the command line.</span>\n    <span class=\"token keyword\">for</span> <span class=\"token punctuation\">(</span><span class=\"token keyword\">int</span> i <span class=\"token operator\">=</span> <span class=\"token number\">1</span><span class=\"token punctuation\">;</span> i <span class=\"token operator\">&lt;</span> argc<span class=\"token punctuation\">;</span> i<span class=\"token operator\">++</span><span class=\"token punctuation\">)</span>\n    <span class=\"token punctuation\">{</span>\n        LPWSTR fileName <span class=\"token operator\">=</span> argv<span class=\"token punctuation\">[</span>i<span class=\"token punctuation\">]</span><span class=\"token punctuation\">;</span>\n\n        <span class=\"token function\">wprintf</span><span class=\"token punctuation\">(</span>L<span class=\"token string\">\"Creating stream object with file name: %s\\n\"</span><span class=\"token punctuation\">,</span> fileName<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n        ComPtr<span class=\"token operator\">&lt;</span>IAmsiStream<span class=\"token operator\">></span> stream<span class=\"token punctuation\">;</span>\n        hr <span class=\"token operator\">=</span> MakeAndInitialize<span class=\"token operator\">&lt;</span>CAmsiFileStream<span class=\"token operator\">></span><span class=\"token punctuation\">(</span><span class=\"token operator\">&amp;</span>stream<span class=\"token punctuation\">,</span> fileName<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n        <span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span><span class=\"token function\">FAILED</span><span class=\"token punctuation\">(</span>hr<span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n            <span class=\"token keyword\">return</span> hr<span class=\"token punctuation\">;</span>\n        <span class=\"token punctuation\">}</span>\n\n        hr <span class=\"token operator\">=</span> scanner<span class=\"token punctuation\">.</span><span class=\"token function\">ScanStream</span><span class=\"token punctuation\">(</span>stream<span class=\"token punctuation\">.</span><span class=\"token function\">Get</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n        <span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span><span class=\"token function\">FAILED</span><span class=\"token punctuation\">(</span>hr<span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span>\n        <span class=\"token punctuation\">{</span>\n            <span class=\"token keyword\">return</span> hr<span class=\"token punctuation\">;</span>\n        <span class=\"token punctuation\">}</span>\n    <span class=\"token punctuation\">}</span>\n<span class=\"token punctuation\">}</span></code></pre></div>\n<p>When the sample program is executed with the file path to be scanned specified, you can confirm in the debugger that the file path is obtained from the command-line arguments.</p>\n<p><span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 960px; \"\n    >\n      <a\n    class=\"gatsby-resp-image-link\"\n    href=\"/static/4e17b283f786826450590119c8bf7ebe/c3a47/image-20250628170200679.png\"\n    style=\"display: block\"\n    target=\"_blank\"\n    rel=\"noopener\"\n  >\n    <span\n    class=\"gatsby-resp-image-background-image\"\n    style=\"padding-bottom: 24.166666666666664%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAFCAYAAABFA8wzAAAACXBIWXMAAAsTAAALEwEAmpwYAAAA8klEQVQY022Qya6DMAxF+Q8GCQItJISEIWEoUNiwff3/n7kvTtVFpS6OrmI7vraD/flEPxiHhdItyrJEVVW/4QJlxd81ogbnHFwIr6KWEFIhuK4L43ZiXnec54llWTDPM6ZpgjEGwzB47fsedhyx7bvPP9YNUkrUde3RbQupNILX6w9mPdEOI+Zp9InWobV6F7sJPp+apkHXdT5/HIc3ozg11lqDuy0Cay06Y9G47jR6URRIswwsz5EXN0cBxhgyFyPSNPVKa1M9nYKU3lQXkEvnHJVS3l27O9J97pUAu3Nk+Q1JkiCO4y+iKEIYhl4/UPwf0h2YPHBC8hUAAAAASUVORK5CYII='); background-size: cover; display: block;\"\n  ></span>\n  <picture>\n          <source\n              srcset=\"/static/4e17b283f786826450590119c8bf7ebe/8ac56/image-20250628170200679.webp 240w,\n/static/4e17b283f786826450590119c8bf7ebe/d3be9/image-20250628170200679.webp 480w,\n/static/4e17b283f786826450590119c8bf7ebe/e46b2/image-20250628170200679.webp 960w,\n/static/4e17b283f786826450590119c8bf7ebe/f992d/image-20250628170200679.webp 1440w,\n/static/4e17b283f786826450590119c8bf7ebe/c53a6/image-20250628170200679.webp 1601w\"\n              sizes=\"(max-width: 960px) 100vw, 960px\"\n              type=\"image/webp\"\n            />\n          <source\n            srcset=\"/static/4e17b283f786826450590119c8bf7ebe/8ff5a/image-20250628170200679.png 240w,\n/static/4e17b283f786826450590119c8bf7ebe/e85cb/image-20250628170200679.png 480w,\n/static/4e17b283f786826450590119c8bf7ebe/d9199/image-20250628170200679.png 960w,\n/static/4e17b283f786826450590119c8bf7ebe/07a9c/image-20250628170200679.png 1440w,\n/static/4e17b283f786826450590119c8bf7ebe/c3a47/image-20250628170200679.png 1601w\"\n            sizes=\"(max-width: 960px) 100vw, 960px\"\n            type=\"image/png\"\n          />\n          <img\n            class=\"gatsby-resp-image-image\"\n            src=\"/static/4e17b283f786826450590119c8bf7ebe/d9199/image-20250628170200679.png\"\n            alt=\"image-20250628170200679\"\n            title=\"image-20250628170200679\"\n            loading=\"lazy\"\n            style=\"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;\"\n          />\n        </picture>\n  </a>\n    </span></p>\n<h3 id=\"the-camsifilestream-class\" style=\"position:relative;\"><a href=\"#the-camsifilestream-class\" aria-label=\"the camsifilestream class permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>The CAmsiFileStream Class</h3>\n<p>Like <code class=\"language-text\">CAmsiMemoryStream</code>, the <code class=\"language-text\">CAmsiFileStream</code> class creates <code class=\"language-text\">IAmsiStream</code> and the corresponding interface by using WRL with <code class=\"language-text\">RuntimeClass&lt;RuntimeClassFlags&lt;ClassicCom>, IAmsiStream></code>.</p>\n<p>It also inherits from the separately defined <code class=\"language-text\">CAmsiStreamBase</code> class, which provides common processing.</p>\n<p>In the <code class=\"language-text\">RuntimeClassInitialize</code> function, which performs initialization when creating an object by using the <code class=\"language-text\">MakeAndInitialize</code> function template, it is called with a file name as an argument, unlike the memory-scan case.</p>\n<p>Inside it, the file handle of the target file obtained by <code class=\"language-text\">CreateFileW</code> is stored in the WRL <code class=\"language-text\">FileHandle</code>-typed variable <code class=\"language-text\">m_fileHandle</code>.</p>\n<div class=\"gatsby-highlight\" data-language=\"c\"><pre class=\"language-c\"><code class=\"language-c\">m_fileHandle<span class=\"token punctuation\">.</span><span class=\"token function\">Attach</span><span class=\"token punctuation\">(</span><span class=\"token function\">CreateFileW</span><span class=\"token punctuation\">(</span>fileName<span class=\"token punctuation\">,</span>\n    GENERIC_READ<span class=\"token punctuation\">,</span>             <span class=\"token comment\">// dwDesiredAccess</span>\n    <span class=\"token number\">0</span><span class=\"token punctuation\">,</span>                        <span class=\"token comment\">// dwShareMode</span>\n    nullptr<span class=\"token punctuation\">,</span>                  <span class=\"token comment\">// lpSecurityAttributes</span>\n    OPEN_EXISTING<span class=\"token punctuation\">,</span>            <span class=\"token comment\">// dwCreationDisposition</span>\n    FILE_ATTRIBUTE_NORMAL<span class=\"token punctuation\">,</span>    <span class=\"token comment\">// dwFlagsAndAttributes</span>\n    nullptr<span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>                <span class=\"token comment\">// hTemplateFile</span>\n\n<span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span><span class=\"token operator\">!</span>m_fileHandle<span class=\"token punctuation\">.</span><span class=\"token function\">IsValid</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span>\n<span class=\"token punctuation\">{</span>\n    hr <span class=\"token operator\">=</span> <span class=\"token function\">HRESULT_FROM_WIN32</span><span class=\"token punctuation\">(</span><span class=\"token function\">GetLastError</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    <span class=\"token function\">wprintf</span><span class=\"token punctuation\">(</span>L<span class=\"token string\">\"Unable to open file %s, hr = 0x%x\\n\"</span><span class=\"token punctuation\">,</span> fileName<span class=\"token punctuation\">,</span> hr<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    <span class=\"token keyword\">return</span> hr<span class=\"token punctuation\">;</span>\n<span class=\"token punctuation\">}</span></code></pre></div>\n<p>It then obtains the file size of this file and completes initialization.</p>\n<div class=\"gatsby-highlight\" data-language=\"c\"><pre class=\"language-c\"><code class=\"language-c\">LARGE_INTEGER fileSize<span class=\"token punctuation\">;</span>\n<span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span><span class=\"token operator\">!</span><span class=\"token function\">GetFileSizeEx</span><span class=\"token punctuation\">(</span>m_fileHandle<span class=\"token punctuation\">.</span><span class=\"token function\">Get</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">,</span> <span class=\"token operator\">&amp;</span>fileSize<span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span>\n<span class=\"token punctuation\">{</span>\n    hr <span class=\"token operator\">=</span> <span class=\"token function\">HRESULT_FROM_WIN32</span><span class=\"token punctuation\">(</span><span class=\"token function\">GetLastError</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    <span class=\"token function\">wprintf</span><span class=\"token punctuation\">(</span>L<span class=\"token string\">\"GetFileSizeEx failed with 0x%x\\n\"</span><span class=\"token punctuation\">,</span> hr<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    <span class=\"token keyword\">return</span> hr<span class=\"token punctuation\">;</span>\n<span class=\"token punctuation\">}</span>\nm_contentSize <span class=\"token operator\">=</span> <span class=\"token punctuation\">(</span>ULONGLONG<span class=\"token punctuation\">)</span>fileSize<span class=\"token punctuation\">.</span>QuadPart<span class=\"token punctuation\">;</span></code></pre></div>\n<p>Once initialization of the <code class=\"language-text\">CAmsiFileStream</code> class is complete, you can confirm that the member holding the file path to be scanned is assigned to <code class=\"language-text\">m_contentName</code>, and the member holding that file’s handle is assigned to <code class=\"language-text\">m_fileHandle</code>.</p>\n<p><span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 960px; \"\n    >\n      <a\n    class=\"gatsby-resp-image-link\"\n    href=\"/static/d93aac8d83f14f67dd1c0f4e828b17be/2ba99/image-20250628170536314.png\"\n    style=\"display: block\"\n    target=\"_blank\"\n    rel=\"noopener\"\n  >\n    <span\n    class=\"gatsby-resp-image-background-image\"\n    style=\"padding-bottom: 18.333333333333336%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAECAYAAACOXx+WAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAwUlEQVQY02WPS47DIBBEfZvYQOMJcRy+gTGWo7E09z9OpUHKKoun172guhhijHDOIefc3XbvHeMRQoC1FooIUipIxdY/HcHzNE1fDC2oPUwpddpetor0zEi59APWR1xdgQ0Jt4cHmTskcagQXwzneeI4Duz7DiUlruaG8vrHI22Y1wDSM0jJ3lJrAkkBKUamNRoxjRfm4wuGWmtv1QJJ8bdIY8l/MHHH7DYYX7BGbveszNa9xl/cGb04UMOs3XrxeANkHYFDNj8TSQAAAABJRU5ErkJggg=='); background-size: cover; display: block;\"\n  ></span>\n  <picture>\n          <source\n              srcset=\"/static/d93aac8d83f14f67dd1c0f4e828b17be/8ac56/image-20250628170536314.webp 240w,\n/static/d93aac8d83f14f67dd1c0f4e828b17be/d3be9/image-20250628170536314.webp 480w,\n/static/d93aac8d83f14f67dd1c0f4e828b17be/e46b2/image-20250628170536314.webp 960w,\n/static/d93aac8d83f14f67dd1c0f4e828b17be/0fff5/image-20250628170536314.webp 1221w\"\n              sizes=\"(max-width: 960px) 100vw, 960px\"\n              type=\"image/webp\"\n            />\n          <source\n            srcset=\"/static/d93aac8d83f14f67dd1c0f4e828b17be/8ff5a/image-20250628170536314.png 240w,\n/static/d93aac8d83f14f67dd1c0f4e828b17be/e85cb/image-20250628170536314.png 480w,\n/static/d93aac8d83f14f67dd1c0f4e828b17be/d9199/image-20250628170536314.png 960w,\n/static/d93aac8d83f14f67dd1c0f4e828b17be/2ba99/image-20250628170536314.png 1221w\"\n            sizes=\"(max-width: 960px) 100vw, 960px\"\n            type=\"image/png\"\n          />\n          <img\n            class=\"gatsby-resp-image-image\"\n            src=\"/static/d93aac8d83f14f67dd1c0f4e828b17be/d9199/image-20250628170536314.png\"\n            alt=\"image-20250628170536314\"\n            title=\"image-20250628170536314\"\n            loading=\"lazy\"\n            style=\"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;\"\n          />\n        </picture>\n  </a>\n    </span></p>\n<p>Also, just like <code class=\"language-text\">CAmsiMemoryStream</code>, the <code class=\"language-text\">CAmsiFileStream</code> class defines <code class=\"language-text\">GetAttribute</code> and <code class=\"language-text\">Read</code> methods for the <code class=\"language-text\">IAmsiStream</code> interface.</p>\n<p>Unlike <code class=\"language-text\">CAmsiMemoryStream</code>, the <code class=\"language-text\">GetAttribute</code> method of the <code class=\"language-text\">CAmsiFileStream</code> class appears to simply call the <code class=\"language-text\">BaseGetAttribute</code> method of the base class.</p>\n<p>Also, in the <code class=\"language-text\">Read</code> method, the file data is stored into <code class=\"language-text\">buffer</code> by using the file handle obtained from <code class=\"language-text\">m_fileHandle</code>.</p>\n<div class=\"gatsby-highlight\" data-language=\"c\"><pre class=\"language-c\"><code class=\"language-c\"><span class=\"token comment\">// IAmsiStream</span>\n\n<span class=\"token function\">STDMETHOD</span><span class=\"token punctuation\">(</span>GetAttribute<span class=\"token punctuation\">)</span><span class=\"token punctuation\">(</span>\n    _In_ AMSI_ATTRIBUTE attribute<span class=\"token punctuation\">,</span>\n    _In_ ULONG bufferSize<span class=\"token punctuation\">,</span>\n    <span class=\"token function\">_Out_writes_bytes_to_</span><span class=\"token punctuation\">(</span>bufferSize<span class=\"token punctuation\">,</span> <span class=\"token operator\">*</span>actualSize<span class=\"token punctuation\">)</span> PBYTE buffer<span class=\"token punctuation\">,</span>\n    _Out_ ULONG<span class=\"token operator\">*</span> actualSize<span class=\"token punctuation\">)</span>\n<span class=\"token punctuation\">{</span>\n    <span class=\"token keyword\">return</span> <span class=\"token function\">BaseGetAttribute</span><span class=\"token punctuation\">(</span>attribute<span class=\"token punctuation\">,</span> bufferSize<span class=\"token punctuation\">,</span> buffer<span class=\"token punctuation\">,</span> actualSize<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n<span class=\"token punctuation\">}</span>\n\n<span class=\"token function\">STDMETHOD</span><span class=\"token punctuation\">(</span>Read<span class=\"token punctuation\">)</span><span class=\"token punctuation\">(</span>\n    _In_ ULONGLONG position<span class=\"token punctuation\">,</span>\n    _In_ ULONG size<span class=\"token punctuation\">,</span>\n    <span class=\"token function\">_Out_writes_bytes_to_</span><span class=\"token punctuation\">(</span>size<span class=\"token punctuation\">,</span> <span class=\"token operator\">*</span>readSize<span class=\"token punctuation\">)</span> PBYTE buffer<span class=\"token punctuation\">,</span>\n    _Out_ ULONG<span class=\"token operator\">*</span> readSize<span class=\"token punctuation\">)</span>\n<span class=\"token punctuation\">{</span>\n    <span class=\"token function\">wprintf</span><span class=\"token punctuation\">(</span>L<span class=\"token string\">\"Read() called with: position = %I64u, size = %u\\n\"</span><span class=\"token punctuation\">,</span> position<span class=\"token punctuation\">,</span> size<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n\n    OVERLAPPED o <span class=\"token operator\">=</span> <span class=\"token punctuation\">{</span><span class=\"token punctuation\">}</span><span class=\"token punctuation\">;</span>\n    o<span class=\"token punctuation\">.</span>Offset <span class=\"token operator\">=</span> <span class=\"token function\">LODWORD</span><span class=\"token punctuation\">(</span>position<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    o<span class=\"token punctuation\">.</span>OffsetHigh <span class=\"token operator\">=</span> <span class=\"token function\">HIDWORD</span><span class=\"token punctuation\">(</span>position<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n\n    <span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span><span class=\"token operator\">!</span><span class=\"token function\">ReadFile</span><span class=\"token punctuation\">(</span>m_fileHandle<span class=\"token punctuation\">.</span><span class=\"token function\">Get</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">,</span> buffer<span class=\"token punctuation\">,</span> size<span class=\"token punctuation\">,</span> readSize<span class=\"token punctuation\">,</span> <span class=\"token operator\">&amp;</span>o<span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span>\n    <span class=\"token punctuation\">{</span>\n        HRESULT hr <span class=\"token operator\">=</span> <span class=\"token function\">HRESULT_FROM_WIN32</span><span class=\"token punctuation\">(</span><span class=\"token function\">GetLastError</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n        <span class=\"token function\">wprintf</span><span class=\"token punctuation\">(</span>L<span class=\"token string\">\"ReadFile failed with 0x%x\\n\"</span><span class=\"token punctuation\">,</span> hr<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n        <span class=\"token keyword\">return</span> hr<span class=\"token punctuation\">;</span>\n    <span class=\"token punctuation\">}</span>\n\n    <span class=\"token keyword\">return</span> S_OK<span class=\"token punctuation\">;</span>\n<span class=\"token punctuation\">}</span></code></pre></div>\n<p>Finally, by calling the <code class=\"language-text\">ScanStream</code> method, the file contents are scanned just like in the memory-scan case.</p>\n<h2 id=\"summary\" style=\"position:relative;\"><a href=\"#summary\" aria-label=\"summary permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Summary</h2>\n<p>This time, I read through sample code for a custom application that issues scan requests by using the AMSI interface.</p>","fields":{"slug":"/amsi-create-interface-en","tagSlugs":["/tag/windows/","/tag/anti-virus/","/tag/amsi/","/tag/english/"]},"frontmatter":{"date":"2025-06-28","description":"This article summarizes how a custom application can issue AMSI scan requests.","tags":["Windows","AntiVirus","AMSI","English"],"title":"Issuing AMSI Scan Requests from a Custom Application","socialImage":{"publicURL":"/static/4c95aac07a4438cb8a911e06531b610c/amsi-create-interface.png"}}}},"pageContext":{"slug":"/amsi-create-interface-en"}},"staticQueryHashes":["251939775","401334301","825871152"]}