{"componentChunkName":"component---src-templates-post-template-js","path":"/rust-winapi-usermode-apc-en","result":{"data":{"markdownRemark":{"id":"d51e07c0-21ba-558a-af53-c18253eb1e17","html":"<blockquote>\n<p>This page has been machine-translated from the <a href=\"/rust-winapi-usermode-apc\">original page</a>.</p>\n</blockquote>\n<p>Continuing from the <a href=\"/tag/rust-win-api\">previous articles</a>, I wanted to keep trying out various programs that call the Windows API from Rust.</p>\n<p>This time, I wrote a program in Rust that creates a thread and triggers an APC function registered to that thread.</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>\n<p><a href=\"#about-windows-asynchronous-procedure-calls-apc\">About Windows Asynchronous Procedure Calls (APC)</a></p>\n<ul>\n<li><a href=\"#types-of-apcs\">Types of APCs</a></li>\n<li><a href=\"#when-apcs-run\">When APCs run</a></li>\n<li><a href=\"#how-to-register-a-user-mode-apc\">How to register a user-mode APC</a></li>\n</ul>\n</li>\n<li>\n<p><a href=\"#code-for-registering-the-user-mode-apc-i-created\">Code for registering the user-mode APC I created</a></p>\n<ul>\n<li><a href=\"#loading-modules\">Loading modules</a></li>\n<li><a href=\"#implementing-alertable-functions\">Implementing alertable functions</a></li>\n<li><a href=\"#defining-the-apc-function\">Defining the APC function</a></li>\n<li><a href=\"#creating-the-thread-and-registering-the-apc-function\">Creating the thread and registering the APC function</a></li>\n</ul>\n</li>\n<li>\n<p><a href=\"#analyzing-the-rust-binary\">Analyzing the Rust binary</a></p>\n<ul>\n<li><a href=\"#finding-the-main-function\">Finding the main function</a></li>\n<li><a href=\"#creating-the-thread\">Creating the thread</a></li>\n</ul>\n</li>\n<li><a href=\"#summary\">Summary</a></li>\n</ul>\n<h2 id=\"about-windows-asynchronous-procedure-calls-apc\" style=\"position:relative;\"><a href=\"#about-windows-asynchronous-procedure-calls-apc\" aria-label=\"about windows asynchronous procedure calls apc 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>About Windows Asynchronous Procedure Calls (APC)</h2>\n<p>Windows Asynchronous Procedure Calls (APC) are one of the mechanisms that can execute work asynchronously on a specific thread.</p>\n<p>APCs are a mechanism that can run user-mode programs and system code in the context of a specific user thread (that is, within the execution address space of a particular process).</p>\n<p>Reference: <a href=\"https://learn.microsoft.com/en-us/windows/win32/sync/asynchronous-procedure-calls\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">Asynchronous Procedure Calls - Win32 apps | Microsoft Learn</a></p>\n<p>APCs are represented by kernel objects called APC objects, which are registered in one of the two APC queues that exist for each thread and wait there to be executed.</p>\n<p>Of the two APC queues that each thread maintains, one is a queue for kernel APCs and the other is a queue for user APCs.</p>\n<p>The APC objects registered in these queues wait to be executed via a software interrupt.</p>\n<h3 id=\"types-of-apcs\" style=\"position:relative;\"><a href=\"#types-of-apcs\" aria-label=\"types of apcs 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>Types of APCs</h3>\n<p>Broadly speaking, APCs come in two modes: user-mode APCs and kernel-mode APCs.</p>\n<p>A user-mode APC is an APC generated by an application, while a kernel-mode APC is an APC generated by the system.</p>\n<p>In addition, each mode has both Normal and Special APCs.</p>\n<p>The differences in behavior between each mode are described in considerable detail on pp. 67-69 of <em>Inside Windows</em>, 7th Edition, Part 2, but that is not the point I want to focus on here, so I will omit it.</p>\n<h3 id=\"when-apcs-run\" style=\"position:relative;\"><a href=\"#when-apcs-run\" aria-label=\"when apcs run 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>When APCs run</h3>\n<p>APCs are usually executed when a thread enters an Alertable state.</p>\n<p>In particular, for user-mode APCs, as described in the documentation below, the APC function runs when a call such as <code class=\"language-text\">SleepEx</code> moves the thread into an Alertable state.</p>\n<p>Reference: <a href=\"https://learn.microsoft.com/en-us/windows/win32/sync/asynchronous-procedure-calls\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">Asynchronous Procedure Calls - Win32 apps | Microsoft Learn</a></p>\n<p>This time, I will aim to implement a program in Rust that uses this user-mode APC mechanism.</p>\n<h3 id=\"how-to-register-a-user-mode-apc\" style=\"position:relative;\"><a href=\"#how-to-register-a-user-mode-apc\" aria-label=\"how to register a user mode apc 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>How to register a user-mode APC</h3>\n<p>Registering a user-mode APC is very simple: just call the <code class=\"language-text\">QueueUserAPC</code> API with a <code class=\"language-text\">PAPCFUNC</code>, which is a pointer to the APC function you want to execute, and a handle to the thread where you want to register the APC.</p>\n<p>Reference: <a href=\"https://learn.microsoft.com/ja-jp/windows/win32/api/processthreadsapi/nf-processthreadsapi-queueuserapc\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">QueueUserAPC function (processthreadsapi.h) - Win32 apps | Microsoft Learn</a></p>\n<p>This makes the APC function execute when the target thread changes to an Alertable state.</p>\n<h2 id=\"code-for-registering-the-user-mode-apc-i-created\" style=\"position:relative;\"><a href=\"#code-for-registering-the-user-mode-apc-i-created\" aria-label=\"code for registering the user mode apc i created 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>Code for registering the user-mode APC I created</h2>\n<p>To verify the behavior of a user-mode APC, I wrote the following code in Rust.</p>\n<div class=\"gatsby-highlight\" data-language=\"rust\"><pre class=\"language-rust\"><code class=\"language-rust\"><span class=\"token comment\">// cargo run --bin UserModeApc</span>\n\n<span class=\"token keyword\">use</span> <span class=\"token namespace\">std<span class=\"token punctuation\">::</span></span><span class=\"token punctuation\">{</span>thread<span class=\"token punctuation\">,</span> time<span class=\"token punctuation\">}</span><span class=\"token punctuation\">;</span>\n<span class=\"token keyword\">use</span> <span class=\"token namespace\">windows<span class=\"token punctuation\">::</span></span><span class=\"token class-name\">Win32</span><span class=\"token punctuation\">::</span><span class=\"token class-name\">System</span><span class=\"token punctuation\">::</span><span class=\"token class-name\">Threading</span><span class=\"token punctuation\">::</span><span class=\"token punctuation\">{</span><span class=\"token class-name\">GetCurrentThread</span><span class=\"token punctuation\">,</span> <span class=\"token class-name\">GetCurrentThreadId</span><span class=\"token punctuation\">,</span> <span class=\"token class-name\">QueueUserAPC</span><span class=\"token punctuation\">,</span> <span class=\"token class-name\">SleepEx</span><span class=\"token punctuation\">}</span><span class=\"token punctuation\">;</span>\n\n<span class=\"token keyword\">extern</span> <span class=\"token string\">\"system\"</span> <span class=\"token keyword\">fn</span> <span class=\"token function-definition function\">apc_func</span><span class=\"token punctuation\">(</span>_<span class=\"token punctuation\">:</span> <span class=\"token keyword\">usize</span><span class=\"token punctuation\">)</span>  <span class=\"token punctuation\">{</span>\n    <span class=\"token macro property\">println!</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"User mode APC triggered !!\"</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    <span class=\"token keyword\">return</span><span class=\"token punctuation\">;</span>\n<span class=\"token punctuation\">}</span>\n\n<span class=\"token keyword\">fn</span> <span class=\"token function-definition function\">non_alertable_func</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n\n    <span class=\"token keyword\">let</span> sleep_time<span class=\"token punctuation\">:</span> <span class=\"token namespace\">time<span class=\"token punctuation\">::</span></span><span class=\"token class-name\">Duration</span> <span class=\"token operator\">=</span> <span class=\"token namespace\">time<span class=\"token punctuation\">::</span></span><span class=\"token class-name\">Duration</span><span class=\"token punctuation\">::</span><span class=\"token function\">from_millis</span><span class=\"token punctuation\">(</span><span class=\"token number\">5000</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    <span class=\"token keyword\">let</span> now <span class=\"token operator\">=</span> <span class=\"token namespace\">time<span class=\"token punctuation\">::</span></span><span class=\"token class-name\">Instant</span><span class=\"token punctuation\">::</span><span class=\"token function\">now</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    \n    <span class=\"token macro property\">println!</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"Non alertable sleep started.\"</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    <span class=\"token namespace\">thread<span class=\"token punctuation\">::</span></span><span class=\"token function\">sleep</span><span class=\"token punctuation\">(</span>sleep_time<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    <span class=\"token macro property\">assert!</span><span class=\"token punctuation\">(</span>now<span class=\"token punctuation\">.</span><span class=\"token function\">elapsed</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">>=</span> sleep_time<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    <span class=\"token macro property\">println!</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"Non alertable sleep started.\"</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n\n    <span class=\"token keyword\">return</span><span class=\"token punctuation\">;</span>\n<span class=\"token punctuation\">}</span>\n\n<span class=\"token keyword\">fn</span> <span class=\"token function-definition function\">alertable_func</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n\n    <span class=\"token keyword\">let</span> now <span class=\"token operator\">=</span> <span class=\"token namespace\">time<span class=\"token punctuation\">::</span></span><span class=\"token class-name\">Instant</span><span class=\"token punctuation\">::</span><span class=\"token function\">now</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    \n    <span class=\"token comment\">// SleepEx による Alertable な Sleep</span>\n    <span class=\"token macro property\">println!</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"Alertable sleep started.\"</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    <span class=\"token keyword\">unsafe</span> <span class=\"token punctuation\">{</span>\n        <span class=\"token class-name\">SleepEx</span><span class=\"token punctuation\">(</span><span class=\"token number\">9999999</span><span class=\"token punctuation\">,</span> <span class=\"token boolean\">true</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    <span class=\"token punctuation\">}</span>\n    <span class=\"token comment\">// APC がコールさ SleepEx が中断されるので実際には長時間の Sleep は発生しない</span>\n    <span class=\"token macro property\">println!</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"Alertable sleep fineshed in {} nanos.\"</span><span class=\"token punctuation\">,</span> now<span class=\"token punctuation\">.</span><span class=\"token function\">elapsed</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">.</span><span class=\"token function\">as_nanos</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n\n    <span class=\"token keyword\">return</span><span class=\"token punctuation\">;</span>\n<span class=\"token punctuation\">}</span>\n\n\n<span class=\"token keyword\">fn</span> <span class=\"token function-definition function\">main</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n\n    <span class=\"token keyword\">let</span> non_alertable_thread_handle <span class=\"token operator\">=</span> <span class=\"token namespace\">thread<span class=\"token punctuation\">::</span></span><span class=\"token function\">spawn</span><span class=\"token punctuation\">(</span><span class=\"token closure-params\"><span class=\"token closure-punctuation punctuation\">|</span><span class=\"token closure-punctuation punctuation\">|</span></span> <span class=\"token punctuation\">{</span>\n\n        <span class=\"token keyword\">unsafe</span> <span class=\"token punctuation\">{</span>\n            <span class=\"token keyword\">let</span> h_spawned_thread <span class=\"token operator\">=</span> <span class=\"token class-name\">GetCurrentThread</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n            <span class=\"token keyword\">let</span> spawned_thread_id <span class=\"token operator\">=</span> <span class=\"token class-name\">GetCurrentThreadId</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n            <span class=\"token macro property\">println!</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"Thread id {} started.\"</span><span class=\"token punctuation\">,</span> spawned_thread_id<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n\n            <span class=\"token comment\">// Add User APC into queue</span>\n            <span class=\"token keyword\">if</span> <span class=\"token class-name\">QueueUserAPC</span><span class=\"token punctuation\">(</span><span class=\"token class-name\">Some</span><span class=\"token punctuation\">(</span>apc_func<span class=\"token punctuation\">)</span><span class=\"token punctuation\">,</span> h_spawned_thread<span class=\"token punctuation\">,</span> <span class=\"token number\">0</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">!=</span> <span class=\"token number\">0</span> <span class=\"token punctuation\">{</span>\n                <span class=\"token macro property\">println!</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"Add User mode APC into non alertable thread id {}.\"</span><span class=\"token punctuation\">,</span> spawned_thread_id<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 comment\">// Non alertable なスレッドを作成</span>\n        <span class=\"token function\">non_alertable_func</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    <span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n\n    non_alertable_thread_handle<span class=\"token punctuation\">.</span><span class=\"token function\">join</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">.</span><span class=\"token function\">unwrap</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n\n\n    <span class=\"token keyword\">let</span> alertable_thread_handle <span class=\"token operator\">=</span> <span class=\"token namespace\">thread<span class=\"token punctuation\">::</span></span><span class=\"token function\">spawn</span><span class=\"token punctuation\">(</span><span class=\"token closure-params\"><span class=\"token closure-punctuation punctuation\">|</span><span class=\"token closure-punctuation punctuation\">|</span></span> <span class=\"token punctuation\">{</span>\n\n        <span class=\"token keyword\">unsafe</span> <span class=\"token punctuation\">{</span>\n            <span class=\"token keyword\">let</span> h_spawned_thread <span class=\"token operator\">=</span> <span class=\"token class-name\">GetCurrentThread</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n            <span class=\"token keyword\">let</span> spawned_thread_id <span class=\"token operator\">=</span> <span class=\"token class-name\">GetCurrentThreadId</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n            <span class=\"token macro property\">println!</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"Thread id {} started.\"</span><span class=\"token punctuation\">,</span> spawned_thread_id<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n\n            <span class=\"token comment\">// Add User APC into queue</span>\n            <span class=\"token keyword\">if</span> <span class=\"token class-name\">QueueUserAPC</span><span class=\"token punctuation\">(</span><span class=\"token class-name\">Some</span><span class=\"token punctuation\">(</span>apc_func<span class=\"token punctuation\">)</span><span class=\"token punctuation\">,</span> h_spawned_thread<span class=\"token punctuation\">,</span> <span class=\"token number\">0</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">!=</span> <span class=\"token number\">0</span> <span class=\"token punctuation\">{</span>\n                <span class=\"token macro property\">println!</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"Add User mode APC into alertable thread id {}.\"</span><span class=\"token punctuation\">,</span> spawned_thread_id<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 comment\">// Alertable なスレッドを作成</span>\n        <span class=\"token function\">alertable_func</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    <span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n\n    alertable_thread_handle<span class=\"token punctuation\">.</span><span class=\"token function\">join</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">.</span><span class=\"token function\">unwrap</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    \n    <span class=\"token keyword\">return</span><span class=\"token punctuation\">;</span>\n\n<span class=\"token punctuation\">}</span></code></pre></div>\n<h3 id=\"loading-modules\" style=\"position:relative;\"><a href=\"#loading-modules\" aria-label=\"loading modules 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>Loading modules</h3>\n<p>This time I wanted to use the four API functions <code class=\"language-text\">GetCurrentThread</code>, <code class=\"language-text\">GetCurrentThreadId</code>, <code class=\"language-text\">QueueUserAPC</code>, and <code class=\"language-text\">SleepEx</code>, so I added <code class=\"language-text\">windows::Win32::System::Threading</code>, which includes all of them, as a dependency.</p>\n<div class=\"gatsby-highlight\" data-language=\"toml\"><pre class=\"language-toml\"><code class=\"language-toml\"><span class=\"token key property\">windows</span> <span class=\"token punctuation\">=</span> <span class=\"token punctuation\">{</span> <span class=\"token key property\">version</span> <span class=\"token punctuation\">=</span> <span class=\"token string\">\"0.60.0\"</span><span class=\"token punctuation\">,</span> <span class=\"token key property\">features</span> <span class=\"token punctuation\">=</span> <span class=\"token punctuation\">[</span>\n    <span class=\"token string\">\"Win32_System_Threading\"</span>\n<span class=\"token punctuation\">]</span> <span class=\"token punctuation\">}</span></code></pre></div>\n<p>Reference: <a href=\"https://microsoft.github.io/windows-docs-rs/doc/windows/Win32/System/Threading/index.html\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">windows::Win32::System::Threading - Rust</a></p>\n<p>Also, because I use <code class=\"language-text\">thread</code> and <code class=\"language-text\">time</code> from Rust’s standard library, I load the following modules.</p>\n<div class=\"gatsby-highlight\" data-language=\"rust\"><pre class=\"language-rust\"><code class=\"language-rust\"><span class=\"token keyword\">use</span> <span class=\"token namespace\">std<span class=\"token punctuation\">::</span></span><span class=\"token punctuation\">{</span>thread<span class=\"token punctuation\">,</span> time<span class=\"token punctuation\">}</span><span class=\"token punctuation\">;</span>\n<span class=\"token keyword\">use</span> <span class=\"token namespace\">windows<span class=\"token punctuation\">::</span></span><span class=\"token class-name\">Win32</span><span class=\"token punctuation\">::</span><span class=\"token class-name\">System</span><span class=\"token punctuation\">::</span><span class=\"token class-name\">Threading</span><span class=\"token punctuation\">::</span><span class=\"token punctuation\">{</span><span class=\"token class-name\">GetCurrentThread</span><span class=\"token punctuation\">,</span> <span class=\"token class-name\">GetCurrentThreadId</span><span class=\"token punctuation\">,</span> <span class=\"token class-name\">QueueUserAPC</span><span class=\"token punctuation\">,</span> <span class=\"token class-name\">SleepEx</span><span class=\"token punctuation\">}</span><span class=\"token punctuation\">;</span></code></pre></div>\n<h3 id=\"implementing-alertable-functions\" style=\"position:relative;\"><a href=\"#implementing-alertable-functions\" aria-label=\"implementing alertable functions 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>Implementing alertable functions</h3>\n<p>Next, I define two functions: <code class=\"language-text\">non_alertable_func</code> and <code class=\"language-text\">alertable_func</code>.</p>\n<p>Each of these functions is executed on a separate thread via <code class=\"language-text\">thread::spawn</code>.</p>\n<div class=\"gatsby-highlight\" data-language=\"rust\"><pre class=\"language-rust\"><code class=\"language-rust\"><span class=\"token keyword\">fn</span> <span class=\"token function-definition function\">non_alertable_func</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n\n    <span class=\"token keyword\">let</span> sleep_time<span class=\"token punctuation\">:</span> <span class=\"token namespace\">time<span class=\"token punctuation\">::</span></span><span class=\"token class-name\">Duration</span> <span class=\"token operator\">=</span> <span class=\"token namespace\">time<span class=\"token punctuation\">::</span></span><span class=\"token class-name\">Duration</span><span class=\"token punctuation\">::</span><span class=\"token function\">from_millis</span><span class=\"token punctuation\">(</span><span class=\"token number\">5000</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    <span class=\"token keyword\">let</span> now <span class=\"token operator\">=</span> <span class=\"token namespace\">time<span class=\"token punctuation\">::</span></span><span class=\"token class-name\">Instant</span><span class=\"token punctuation\">::</span><span class=\"token function\">now</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    \n    <span class=\"token macro property\">println!</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"Non alertable sleep started.\"</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    <span class=\"token namespace\">thread<span class=\"token punctuation\">::</span></span><span class=\"token function\">sleep</span><span class=\"token punctuation\">(</span>sleep_time<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    <span class=\"token macro property\">assert!</span><span class=\"token punctuation\">(</span>now<span class=\"token punctuation\">.</span><span class=\"token function\">elapsed</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">>=</span> sleep_time<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    <span class=\"token macro property\">println!</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"Non alertable sleep started.\"</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n\n    <span class=\"token keyword\">return</span><span class=\"token punctuation\">;</span>\n<span class=\"token punctuation\">}</span>\n\n\n<span class=\"token keyword\">fn</span> <span class=\"token function-definition function\">alertable_func</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n\n    <span class=\"token keyword\">let</span> now <span class=\"token operator\">=</span> <span class=\"token namespace\">time<span class=\"token punctuation\">::</span></span><span class=\"token class-name\">Instant</span><span class=\"token punctuation\">::</span><span class=\"token function\">now</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    \n    <span class=\"token comment\">// SleepEx による Alertable な Sleep</span>\n    <span class=\"token macro property\">println!</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"Alertable sleep started.\"</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    <span class=\"token keyword\">unsafe</span> <span class=\"token punctuation\">{</span>\n        <span class=\"token class-name\">SleepEx</span><span class=\"token punctuation\">(</span><span class=\"token number\">9999999</span><span class=\"token punctuation\">,</span> <span class=\"token boolean\">true</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    <span class=\"token punctuation\">}</span>\n    <span class=\"token comment\">// APC がコールされて SleepEx が中断されるので実際には長時間の Sleep は発生しない</span>\n    <span class=\"token macro property\">println!</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"Alertable sleep fineshed in {} nanos.\"</span><span class=\"token punctuation\">,</span> now<span class=\"token punctuation\">.</span><span class=\"token function\">elapsed</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">.</span><span class=\"token function\">as_nanos</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n\n    <span class=\"token keyword\">return</span><span class=\"token punctuation\">;</span>\n<span class=\"token punctuation\">}</span></code></pre></div>\n<p><code class=\"language-text\">non_alertable_func</code> uses the standard library’s <code class=\"language-text\">thread::sleep(sleep_time);</code> to sleep in a non-alertable way.</p>\n<p>By contrast, <code class=\"language-text\">alertable_func</code> performs its sleep with the Windows API <code class=\"language-text\">SleepEx</code>, which causes the thread to transition into an Alertable state.</p>\n<h3 id=\"defining-the-apc-function\" style=\"position:relative;\"><a href=\"#defining-the-apc-function\" aria-label=\"defining the apc 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>Defining the APC function</h3>\n<p>The following is the definition of the APC function that I want to execute via an APC.</p>\n<p>Because it is used as an argument to the Windows API, I use <code class=\"language-text\">extern \"system\"</code>.</p>\n<div class=\"gatsby-highlight\" data-language=\"rust\"><pre class=\"language-rust\"><code class=\"language-rust\"><span class=\"token keyword\">extern</span> <span class=\"token string\">\"system\"</span> <span class=\"token keyword\">fn</span> <span class=\"token function-definition function\">apc_func</span><span class=\"token punctuation\">(</span>_<span class=\"token punctuation\">:</span> <span class=\"token keyword\">usize</span><span class=\"token punctuation\">)</span>  <span class=\"token punctuation\">{</span>\n    <span class=\"token macro property\">println!</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"User mode APC triggered !!\"</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    <span class=\"token keyword\">return</span><span class=\"token punctuation\">;</span>\n<span class=\"token punctuation\">}</span></code></pre></div>\n<p>I also set the argument to match the definition of the <code class=\"language-text\">PAPCFUNC</code> type used as an argument to <code class=\"language-text\">QueueUserAPC</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/a9305b0ba77285631f51eeb7f5a29f39/2ba99/image-20250408213430392.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: 37.5%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAICAYAAAD5nd/tAAAACXBIWXMAAAsTAAALEwEAmpwYAAABCklEQVQoz4WQyWrEMBBE9TnebS2W5HUINoQYM4EEcsj//0elW7HCjA/O4dElqaSulvj+eMXX5xvW9wUv9wXuNsO2FqZt0V5gjEHf93DOwXsPay26roMYpxv6cYLsB8hhhKXNlsxa63DJPOhY+dyQXpYF8zxjIoZhwLquEEopMJ2zUFKi0AratqFjTMIpGnqAk/BeSR5eF0XxR1mWoQqOybCxoQdrJSGPJpJ0bMhnnJB1TTp46/qJqqogtm3Dvu8hMqfiFJ4SuRP+pP3xd2dEfEQ/jJDn+e8YB3Gk/wgjW+rEHxvHaZom6JJqRqacKjdIkgRpml7CHpFl2dPnxjQ5JyWyIzFfYO8V7PkBHob+e6bu2wYAAAAASUVORK5CYII='); background-size: cover; display: block;\"\n  ></span>\n  <picture>\n          <source\n              srcset=\"/static/a9305b0ba77285631f51eeb7f5a29f39/8ac56/image-20250408213430392.webp 240w,\n/static/a9305b0ba77285631f51eeb7f5a29f39/d3be9/image-20250408213430392.webp 480w,\n/static/a9305b0ba77285631f51eeb7f5a29f39/e46b2/image-20250408213430392.webp 960w,\n/static/a9305b0ba77285631f51eeb7f5a29f39/0fff5/image-20250408213430392.webp 1221w\"\n              sizes=\"(max-width: 960px) 100vw, 960px\"\n              type=\"image/webp\"\n            />\n          <source\n            srcset=\"/static/a9305b0ba77285631f51eeb7f5a29f39/8ff5a/image-20250408213430392.png 240w,\n/static/a9305b0ba77285631f51eeb7f5a29f39/e85cb/image-20250408213430392.png 480w,\n/static/a9305b0ba77285631f51eeb7f5a29f39/d9199/image-20250408213430392.png 960w,\n/static/a9305b0ba77285631f51eeb7f5a29f39/2ba99/image-20250408213430392.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/a9305b0ba77285631f51eeb7f5a29f39/d9199/image-20250408213430392.png\"\n            alt=\"image-20250408213430392\"\n            title=\"image-20250408213430392\"\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>Reference: <a href=\"https://microsoft.github.io/windows-docs-rs/doc/windows/Win32/Foundation/type.PAPCFUNC.html\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">PAPCFUNC in windows::Win32::Foundation - Rust</a></p>\n<h3 id=\"creating-the-thread-and-registering-the-apc-function\" style=\"position:relative;\"><a href=\"#creating-the-thread-and-registering-the-apc-function\" aria-label=\"creating the thread and registering the apc 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>Creating the thread and registering the APC function</h3>\n<p>Finally, I create the thread with Rust’s <code class=\"language-text\">thread::spawn</code> and register the APC function with <code class=\"language-text\">QueueUserAPC</code>.</p>\n<p>This time I also wanted more Rust practice, so I tried creating a thread using something other than the Windows API <code class=\"language-text\">CreateThread</code>.</p>\n<div class=\"gatsby-highlight\" data-language=\"rust\"><pre class=\"language-rust\"><code class=\"language-rust\"><span class=\"token keyword\">let</span> alertable_thread_handle <span class=\"token operator\">=</span> <span class=\"token namespace\">thread<span class=\"token punctuation\">::</span></span><span class=\"token function\">spawn</span><span class=\"token punctuation\">(</span><span class=\"token closure-params\"><span class=\"token closure-punctuation punctuation\">|</span><span class=\"token closure-punctuation punctuation\">|</span></span> <span class=\"token punctuation\">{</span>\n\n    <span class=\"token keyword\">unsafe</span> <span class=\"token punctuation\">{</span>\n        <span class=\"token keyword\">let</span> h_spawned_thread <span class=\"token operator\">=</span> <span class=\"token class-name\">GetCurrentThread</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n        <span class=\"token keyword\">let</span> spawned_thread_id <span class=\"token operator\">=</span> <span class=\"token class-name\">GetCurrentThreadId</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n        <span class=\"token macro property\">println!</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"Thread id {} started.\"</span><span class=\"token punctuation\">,</span> spawned_thread_id<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n\n        <span class=\"token comment\">// Add User APC into queue</span>\n        <span class=\"token keyword\">if</span> <span class=\"token class-name\">QueueUserAPC</span><span class=\"token punctuation\">(</span><span class=\"token class-name\">Some</span><span class=\"token punctuation\">(</span>apc_func<span class=\"token punctuation\">)</span><span class=\"token punctuation\">,</span> h_spawned_thread<span class=\"token punctuation\">,</span> <span class=\"token number\">0</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">!=</span> <span class=\"token number\">0</span> <span class=\"token punctuation\">{</span>\n            <span class=\"token macro property\">println!</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"Add User mode APC into alertable thread id {}.\"</span><span class=\"token punctuation\">,</span> spawned_thread_id<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 comment\">// Alertable なスレッドを作成</span>\n    <span class=\"token function\">alertable_func</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n<span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n\nalertable_thread_handle<span class=\"token punctuation\">.</span><span class=\"token function\">join</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">.</span><span class=\"token function\">unwrap</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></code></pre></div>\n<p>A thread created by <code class=\"language-text\">spawn</code> in Rust’s <code class=\"language-text\">thread</code> module returns an object called <code class=\"language-text\">JoinHandle</code>, so it seems that you can wait for the thread to finish by calling <code class=\"language-text\">.join()</code> on it.</p>\n<p>Because this <code class=\"language-text\">JoinHandle</code> is different from a Windows thread handle, I call the <code class=\"language-text\">GetCurrentThread</code> API inside the thread to obtain the thread handle needed to register the APC function with <code class=\"language-text\">QueueUserAPC</code>.</p>\n<p>Finally, I register the APC by calling <code class=\"language-text\">QueueUserAPC</code> with the APC function and the thread handle as arguments.</p>\n<p>At this point, the first argument to <code class=\"language-text\">QueueUserAPC</code> needs an <code class=\"language-text\">Option</code>-wrapped <code class=\"language-text\">PAPCFUNC</code>, so I wrap the <code class=\"language-text\">apc_func</code> function defined in the previous section in <code class=\"language-text\">Some</code>. (I still do not fully understand the concept of the <code class=\"language-text\">Option</code> enum and <code class=\"language-text\">Some</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/9c08a88f363cf20faef2abd80ca06423/85053/image-20250408213221842.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: 26.666666666666668%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAFCAYAAABFA8wzAAAACXBIWXMAAAsTAAALEwEAmpwYAAAArklEQVQY052OS2rEMBAFfRzL8shjfSy1LI2DNyHBEAK5/1UqsleBLIZkUfSDbqpf93G88vV5sL1V8vtKOTLyIsQl4oMnhPAL7z0xRvZ9R0QopVBrZV1XOuc8s3UNi53tla1zuCec4lLLJU4pkXMrIpnONpFkYUmR0GZqCzvPDMPwlL7vUUpdnHkcRzqtNdv2QFpl9SjoyaB+HP6FSziZCbssmPsdfbtxPvgvxhi+AQmZnTG6eTYEAAAAAElFTkSuQmCC'); background-size: cover; display: block;\"\n  ></span>\n  <picture>\n          <source\n              srcset=\"/static/9c08a88f363cf20faef2abd80ca06423/8ac56/image-20250408213221842.webp 240w,\n/static/9c08a88f363cf20faef2abd80ca06423/d3be9/image-20250408213221842.webp 480w,\n/static/9c08a88f363cf20faef2abd80ca06423/e46b2/image-20250408213221842.webp 960w,\n/static/9c08a88f363cf20faef2abd80ca06423/1d10f/image-20250408213221842.webp 1225w\"\n              sizes=\"(max-width: 960px) 100vw, 960px\"\n              type=\"image/webp\"\n            />\n          <source\n            srcset=\"/static/9c08a88f363cf20faef2abd80ca06423/8ff5a/image-20250408213221842.png 240w,\n/static/9c08a88f363cf20faef2abd80ca06423/e85cb/image-20250408213221842.png 480w,\n/static/9c08a88f363cf20faef2abd80ca06423/d9199/image-20250408213221842.png 960w,\n/static/9c08a88f363cf20faef2abd80ca06423/85053/image-20250408213221842.png 1225w\"\n            sizes=\"(max-width: 960px) 100vw, 960px\"\n            type=\"image/png\"\n          />\n          <img\n            class=\"gatsby-resp-image-image\"\n            src=\"/static/9c08a88f363cf20faef2abd80ca06423/d9199/image-20250408213221842.png\"\n            alt=\"image-20250408213221842\"\n            title=\"image-20250408213221842\"\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>Reference: <a href=\"https://microsoft.github.io/windows-docs-rs/doc/windows/Win32/System/Threading/fn.QueueUserAPC.html\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">QueueUserAPC in windows::Win32::System::Threading - Rust</a></p>\n<h2 id=\"analyzing-the-rust-binary\" style=\"position:relative;\"><a href=\"#analyzing-the-rust-binary\" aria-label=\"analyzing the rust binary 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>Analyzing the Rust binary</h2>\n<p>I had intended to analyze the binary I built at the same time as implementing the Windows API in Rust, but I completely forgot, so I will start doing that from this article onward.</p>\n<h3 id=\"finding-the-main-function\" style=\"position:relative;\"><a href=\"#finding-the-main-function\" aria-label=\"finding 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>Finding the main function</h3>\n<p>For now, when I decompiled without a PDB, the <code class=\"language-text\">main</code> function was output as follows (it clearly is not the actual implementation of <code class=\"language-text\">main</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/642738fa103230edcaf42cc18f53c9d0/76823/image-20250409002040916.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: 22.499999999999996%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAFCAYAAABFA8wzAAAACXBIWXMAAAsTAAALEwEAmpwYAAABJ0lEQVQY0yWQ6VLCQBCE8xgeWCoQAuQ+NllzExQjkYhX+f5P8jnGH129O7PV3dtGs3+kbNoJ1W5H2Qq3O7I85+LykkTnfL+PfI1H+tPA+TzycTrLeWR4e6d/PQlGnodXDscBo/sZ2O1bahHp+gNKhJQuiFTG9WzG0rQI0ohQR6y3W4LAwfcDvFDhRymOH+MGio3tyt7GyPqaVCuSTFOUNVlZkTxU8lhxfTPjfrHE8h2s0GFumv9YWSytDYuJLeHVJLZ1XIzq80BZ58Rphm460qoV90icfa4koe36lM8dxUs31VDUjdSyl3qeKKoanRfooiR9yMnlbsSNJlYxXhAQZApPJfKFUNwcSXjD3d0cW4d4dTKltWXuuB5bMfIjPfFfFeZqze39nF/bCqHYopxKrwAAAABJRU5ErkJggg=='); background-size: cover; display: block;\"\n  ></span>\n  <picture>\n          <source\n              srcset=\"/static/642738fa103230edcaf42cc18f53c9d0/8ac56/image-20250409002040916.webp 240w,\n/static/642738fa103230edcaf42cc18f53c9d0/d3be9/image-20250409002040916.webp 480w,\n/static/642738fa103230edcaf42cc18f53c9d0/e46b2/image-20250409002040916.webp 960w,\n/static/642738fa103230edcaf42cc18f53c9d0/6a022/image-20250409002040916.webp 1038w\"\n              sizes=\"(max-width: 960px) 100vw, 960px\"\n              type=\"image/webp\"\n            />\n          <source\n            srcset=\"/static/642738fa103230edcaf42cc18f53c9d0/8ff5a/image-20250409002040916.png 240w,\n/static/642738fa103230edcaf42cc18f53c9d0/e85cb/image-20250409002040916.png 480w,\n/static/642738fa103230edcaf42cc18f53c9d0/d9199/image-20250409002040916.png 960w,\n/static/642738fa103230edcaf42cc18f53c9d0/76823/image-20250409002040916.png 1038w\"\n            sizes=\"(max-width: 960px) 100vw, 960px\"\n            type=\"image/png\"\n          />\n          <img\n            class=\"gatsby-resp-image-image\"\n            src=\"/static/642738fa103230edcaf42cc18f53c9d0/d9199/image-20250409002040916.png\"\n            alt=\"image-20250409002040916\"\n            title=\"image-20250409002040916\"\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>In reality, the function loaded into <code class=\"language-text\">rcx</code> by <code class=\"language-text\">lea</code> seems to be the actual <code class=\"language-text\">main</code> function, and the function called with that as an argument (<code class=\"language-text\">0x2a90</code>) appears to be the <code class=\"language-text\">lang_start</code> function.</p>\n<p>Reference: <a href=\"https://users.rust-lang.org/t/who-calls-lang-start/51446\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">Who calls lang_start? - community - The Rust Programming Language Forum</a></p>\n<p>When I actually checked that function, there were places that looked like they used conditional branches and the <code class=\"language-text\">unwrap</code> function, so it seems reasonable to treat it as the <code class=\"language-text\">main</code> function.</p>\n<p><span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 862px; \"\n    >\n      <a\n    class=\"gatsby-resp-image-link\"\n    href=\"/static/df15cd525f94ccb8c7ae3ff9c9d5df43/f0551/image-20250409002637075.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: 77.5%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAQCAYAAAAWGF8bAAAACXBIWXMAAAsTAAALEwEAmpwYAAAB2klEQVQ4y51UW27bMBD0WWKLovgmJVly2iBNi16gSZAXgtz/FNPhyjYEFH24HwOJEjWzOzvU5v7jDY8vz3h8fcfD6wceXt5w//SMH/+JTb7dozUWxjlYX+HRWYe2M1C6uxibeDtiq1qEGLCfJ4zzZ5R+gCHp1a7BtlEXYZNY4a7VSNljmgv6/QGpH1mllyp3FLsEUmElNLa2HWBDIXoYH7n2lxOmuz0aErZdh1w8YnZw9FEbA02Ruqm2ftUskNZ2anlWLVmjtpy/zWi0FlIfE8owCfoyIKeCEBICq63XyPc+RChLMQ5SGwdFtOysteFY4ddJyCrqBh97OLbddbSgcwJrvKy1tsv0nZEkSBrotfYJ2sWFMJNw8dCQyNO/xI1WBNatLlB/b7l8P0hsch/x6WbG9c0dxmmmj/HigSwV0kPJYQrMX4KLBbFM8GngfRKvqvK/T/noYZ1yP2SEXEnjKqy/fvQnAcZmIVS6krYSl1OgVdudCdb4HdkSm+NQfLByWlIuHE4QeFZaybdKnUVPuTwLrAaymnLLUxGZvwPKeM389cj0siKFjMI8ppglh7ZEJoGCPqAjNJ+bMkp8lrP8hSfl+Kc4ZevUaqP0GWfvKH7KrYDfNdpIl/X9T+Dc5RVEZyUuAAAAAElFTkSuQmCC'); background-size: cover; display: block;\"\n  ></span>\n  <picture>\n          <source\n              srcset=\"/static/df15cd525f94ccb8c7ae3ff9c9d5df43/8ac56/image-20250409002637075.webp 240w,\n/static/df15cd525f94ccb8c7ae3ff9c9d5df43/d3be9/image-20250409002637075.webp 480w,\n/static/df15cd525f94ccb8c7ae3ff9c9d5df43/e32b8/image-20250409002637075.webp 862w\"\n              sizes=\"(max-width: 862px) 100vw, 862px\"\n              type=\"image/webp\"\n            />\n          <source\n            srcset=\"/static/df15cd525f94ccb8c7ae3ff9c9d5df43/8ff5a/image-20250409002637075.png 240w,\n/static/df15cd525f94ccb8c7ae3ff9c9d5df43/e85cb/image-20250409002637075.png 480w,\n/static/df15cd525f94ccb8c7ae3ff9c9d5df43/f0551/image-20250409002637075.png 862w\"\n            sizes=\"(max-width: 862px) 100vw, 862px\"\n            type=\"image/png\"\n          />\n          <img\n            class=\"gatsby-resp-image-image\"\n            src=\"/static/df15cd525f94ccb8c7ae3ff9c9d5df43/f0551/image-20250409002637075.png\"\n            alt=\"image-20250409002637075\"\n            title=\"image-20250409002637075\"\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>By the way, Binary Ninja has a pseudo-Rust decompiler mode, so I used it this time, but aside from replacing every variable declaration with <code class=\"language-text\">let</code>, I did not really feel much difference from the pseudo-C output.</p>\n<h3 id=\"creating-the-thread\" style=\"position:relative;\"><a href=\"#creating-the-thread\" aria-label=\"creating the thread 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>Creating the thread</h3>\n<p>If you check the function executed at the very beginning of the decompiled result, you notice that the text <code class=\"language-text\">failed to spawn thread</code> is embedded in it.</p>\n<p><span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 804px; \"\n    >\n      <a\n    class=\"gatsby-resp-image-link\"\n    href=\"/static/e5df5a0e745c681cc07d4303137259f9/27b7a/image-20250409002942619.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: 39.583333333333336%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAICAYAAAD5nd/tAAAACXBIWXMAAAsTAAALEwEAmpwYAAABOUlEQVQoz4WS21LCMBCG+yxCc27SNCmCoDJeeLhwCrQgo77/a/xuUrhwRvDin91JNt+eUnTHA7rvD3RDj81A/v4Tm8MXdocjtvsBu32Prh/I77GlmPftdRX61sOtZyilRMkFOFkuFbiQYEJAGwNF0qaie46baYlJyTBJ9g8VdhUR31YolYTSCrENaEKEdQ5S6QxLCQQpJUywKeMXVdglAV+XucIR6OGbgNr7DJNajxWddA02AqnC8HyXgZKAITg4X8P7BsZaMDpPrfwHOifLFYaXBBS5mtg2iLM5mtjmuTGapaDWz48u6Xxf2PvUMs2QFqCMxWzxgLh4QjtfwYeQwbUPcJWHVgbWOFSa5qsNhCNVNaRroJqWkqvTlh/HLXOpc2DKVDLxqx1GC0lLYXz8DUnTZKmDpOSn2B/SVvhhvcGANAAAAABJRU5ErkJggg=='); background-size: cover; display: block;\"\n  ></span>\n  <picture>\n          <source\n              srcset=\"/static/e5df5a0e745c681cc07d4303137259f9/8ac56/image-20250409002942619.webp 240w,\n/static/e5df5a0e745c681cc07d4303137259f9/d3be9/image-20250409002942619.webp 480w,\n/static/e5df5a0e745c681cc07d4303137259f9/95e88/image-20250409002942619.webp 804w\"\n              sizes=\"(max-width: 804px) 100vw, 804px\"\n              type=\"image/webp\"\n            />\n          <source\n            srcset=\"/static/e5df5a0e745c681cc07d4303137259f9/8ff5a/image-20250409002942619.png 240w,\n/static/e5df5a0e745c681cc07d4303137259f9/e85cb/image-20250409002942619.png 480w,\n/static/e5df5a0e745c681cc07d4303137259f9/27b7a/image-20250409002942619.png 804w\"\n            sizes=\"(max-width: 804px) 100vw, 804px\"\n            type=\"image/png\"\n          />\n          <img\n            class=\"gatsby-resp-image-image\"\n            src=\"/static/e5df5a0e745c681cc07d4303137259f9/27b7a/image-20250409002942619.png\"\n            alt=\"image-20250409002942619\"\n            title=\"image-20250409002942619\"\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>This text is likely part of the implementation of the <code class=\"language-text\">spawn</code> function used to create the thread.</p>\n<p><span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 907px; \"\n    >\n      <a\n    class=\"gatsby-resp-image-link\"\n    href=\"/static/ed7e747990bda12639149e33a784ec87/142fb/image-20250409003114648.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: 27.083333333333332%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAFCAYAAABFA8wzAAAACXBIWXMAAAsTAAALEwEAmpwYAAAA3ElEQVQY03WPS04DMQyGc4OeAYnHxEnsOC8YMVMJdhUrBFfoqgdgg7j6T2ZUSgGx+GT/tvz4jeWKzIoHiXhMCduouIuMMQdMUTBqQi6KkgWRBYEZIQSIMJj/YiwXxHiLpq0PZahqJ0H7sIqg1opSCrwPICI4507xKz/XxmuF8xHaP5vmGbVkZPEgRxiGAbazxMHaH9h/MBeXI25st9NtTvMWSQLulcDBn66Hvpz9N4te6vbYP8dsNjOurjNSktVaPtJaW3UqFfsd4eOV8PZMeH8hHJ5sP+jWj34v/ATsUZtA+YA5WwAAAABJRU5ErkJggg=='); background-size: cover; display: block;\"\n  ></span>\n  <picture>\n          <source\n              srcset=\"/static/ed7e747990bda12639149e33a784ec87/8ac56/image-20250409003114648.webp 240w,\n/static/ed7e747990bda12639149e33a784ec87/d3be9/image-20250409003114648.webp 480w,\n/static/ed7e747990bda12639149e33a784ec87/468b0/image-20250409003114648.webp 907w\"\n              sizes=\"(max-width: 907px) 100vw, 907px\"\n              type=\"image/webp\"\n            />\n          <source\n            srcset=\"/static/ed7e747990bda12639149e33a784ec87/8ff5a/image-20250409003114648.png 240w,\n/static/ed7e747990bda12639149e33a784ec87/e85cb/image-20250409003114648.png 480w,\n/static/ed7e747990bda12639149e33a784ec87/142fb/image-20250409003114648.png 907w\"\n            sizes=\"(max-width: 907px) 100vw, 907px\"\n            type=\"image/png\"\n          />\n          <img\n            class=\"gatsby-resp-image-image\"\n            src=\"/static/ed7e747990bda12639149e33a784ec87/142fb/image-20250409003114648.png\"\n            alt=\"image-20250409003114648\"\n            title=\"image-20250409003114648\"\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>Reference: <a href=\"https://doc.rust-lang.org/src/std/thread/mod.rs.html#721-735\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">mod.rs - source</a></p>\n<p>Honestly, it seemed impossible to determine from any other information that this function was <code class=\"language-text\">thread::spawn</code>. (Even looking at the disassembly results and the decompiled output, I could not make sense of it.)</p>\n<p>If I assume that up front, then if this function is <code class=\"language-text\">thread::spawn</code>, I can conclude that <code class=\"language-text\">var_90</code> stores a <code class=\"language-text\">JoinHandle</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: 248px; \"\n    >\n      <a\n    class=\"gatsby-resp-image-link\"\n    href=\"/static/c9053e146f1d9637a43819cbef2e9a3d/544ba/image-20250409003910439.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: 50.83333333333333%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAKCAYAAAC0VX7mAAAACXBIWXMAAAsTAAALEwEAmpwYAAAB9klEQVQoz3WT2W7TUBCG8yCgNpvt5Bw7thPbibM4zdYAooBoqZC4gEoRLYKUBuhGEYLCBbwANyAQiOf8mLgFqai5+DVnxp5/lv+cTEnZ1GoBynZS+NUaZqlMGEWUlUJphzAM0PLNtEqUlJZ/qhRNi3zRoGCYF5Ap24og8LAdTcWV5MiXJJUSK63xxMbNGEuKlMoKS6BtezGh65cZDRw8z6ST2AzlbJgmSW9AIJ01Ox2GwwF5w5IiPhXPI5svCNkZwf+kGUv7hPGIqDXGDxOC1oCWkDTiJp5fZXz9hnQZXdrRpR3qikfc7lJvdakGdUIZL2o0qMcxrnRTF2K/JvvUi8e8OHJVMepXcF0ZuePIyC5Fw6CdrJAkHXKFouw4oCFFbNndPGlOvJCwrE3qkRaFLVFbEdYVS0LihZGsIORqNocl4tieS840uJLNsiyx5Vz+H5ZS/yyWWRn22NgYs3qtz807qzzcHHN/0Gd7fV1wl3tDia3dFqzxYDzmlojV7vZoJl0RLEnR7Q9SP253yGw93mG2f8TT53tsbk04ebLH7+NTvu7O+Lb7gp9vPvPj5BPfD97x6/g9Xw4/Mn31mtnhES8P9tl+NuXt6Qd2pjMeTSbze+hgV1y0U6Eki3fE+iJUCkeu0/yy/42JdcXXjouSsz5H+ijO7R85p0naNhbOAAAAAABJRU5ErkJggg=='); background-size: cover; display: block;\"\n  ></span>\n  <picture>\n          <source\n              srcset=\"/static/c9053e146f1d9637a43819cbef2e9a3d/8ac56/image-20250409003910439.webp 240w,\n/static/c9053e146f1d9637a43819cbef2e9a3d/176e7/image-20250409003910439.webp 248w\"\n              sizes=\"(max-width: 248px) 100vw, 248px\"\n              type=\"image/webp\"\n            />\n          <source\n            srcset=\"/static/c9053e146f1d9637a43819cbef2e9a3d/8ff5a/image-20250409003910439.png 240w,\n/static/c9053e146f1d9637a43819cbef2e9a3d/544ba/image-20250409003910439.png 248w\"\n            sizes=\"(max-width: 248px) 100vw, 248px\"\n            type=\"image/png\"\n          />\n          <img\n            class=\"gatsby-resp-image-image\"\n            src=\"/static/c9053e146f1d9637a43819cbef2e9a3d/544ba/image-20250409003910439.png\"\n            alt=\"image-20250409003910439\"\n            title=\"image-20250409003910439\"\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>That means this function, which takes a <code class=\"language-text\">JoinHandle</code> as an argument, is probably <code class=\"language-text\">non_alertable_thread_handle.join().unwrap()</code> here.</p>\n<p>More precisely, because the string embedded when this function’s return value is not 0 is the error text used when <code class=\"language-text\">panic!</code> is called inside <code class=\"language-text\">unwrap</code>—<code class=\"language-text\">called Result::unwrap() on an Err</code>—it seems likely that the function above corresponds to <code class=\"language-text\">join()</code> up to that point, and that the contents of the following branch are <code class=\"language-text\">unwrap()</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: 716px; \"\n    >\n      <a\n    class=\"gatsby-resp-image-link\"\n    href=\"/static/a5e0427b72e46d0deb462ef12dbfdf47/6bbf7/image-20250409004043509.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: 21.25%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAECAYAAACOXx+WAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAuUlEQVQY03WQRw7CUAxEcxTSfsovgfAJa0JJLxvgAAjI/S8wOEFCKFIWTzO2LNljg0uOaK0gIo5QCHhBCMfzwfwAluNOmH+Mte2yRQwuFbZ6g2SvoXcJtNZIiDiOIWmB4AKKZpSUUEoh4HxatoRxynJcyhZ1f0PZX3GvOwx1i2fV4FWPtBjaDm/yD/LHqkBa5siKCueiJN8grajf9DhkBQxG8cZTXdIRi7w5i7myHeKrU2SH/d5hz/gAm/Z9+nqluicAAAAASUVORK5CYII='); background-size: cover; display: block;\"\n  ></span>\n  <picture>\n          <source\n              srcset=\"/static/a5e0427b72e46d0deb462ef12dbfdf47/8ac56/image-20250409004043509.webp 240w,\n/static/a5e0427b72e46d0deb462ef12dbfdf47/d3be9/image-20250409004043509.webp 480w,\n/static/a5e0427b72e46d0deb462ef12dbfdf47/d8378/image-20250409004043509.webp 716w\"\n              sizes=\"(max-width: 716px) 100vw, 716px\"\n              type=\"image/webp\"\n            />\n          <source\n            srcset=\"/static/a5e0427b72e46d0deb462ef12dbfdf47/8ff5a/image-20250409004043509.png 240w,\n/static/a5e0427b72e46d0deb462ef12dbfdf47/e85cb/image-20250409004043509.png 480w,\n/static/a5e0427b72e46d0deb462ef12dbfdf47/6bbf7/image-20250409004043509.png 716w\"\n            sizes=\"(max-width: 716px) 100vw, 716px\"\n            type=\"image/png\"\n          />\n          <img\n            class=\"gatsby-resp-image-image\"\n            src=\"/static/a5e0427b72e46d0deb462ef12dbfdf47/6bbf7/image-20250409004043509.png\"\n            alt=\"image-20250409004043509\"\n            title=\"image-20250409004043509\"\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>Incidentally, the code that should have been executed inside the thread created at this point was not included in the analysis results up to here.</p>\n<p>When I looked into where it was executed, I found that it was embedded among the objects referenced further down from the first <code class=\"language-text\">call</code> inside the following function that looked like <code class=\"language-text\">spawn</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: 804px; \"\n    >\n      <a\n    class=\"gatsby-resp-image-link\"\n    href=\"/static/e5df5a0e745c681cc07d4303137259f9/27b7a/image-20250409002942619.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: 39.583333333333336%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAICAYAAAD5nd/tAAAACXBIWXMAAAsTAAALEwEAmpwYAAABOUlEQVQoz4WS21LCMBCG+yxCc27SNCmCoDJeeLhwCrQgo77/a/xuUrhwRvDin91JNt+eUnTHA7rvD3RDj81A/v4Tm8MXdocjtvsBu32Prh/I77GlmPftdRX61sOtZyilRMkFOFkuFbiQYEJAGwNF0qaie46baYlJyTBJ9g8VdhUR31YolYTSCrENaEKEdQ5S6QxLCQQpJUywKeMXVdglAV+XucIR6OGbgNr7DJNajxWddA02AqnC8HyXgZKAITg4X8P7BsZaMDpPrfwHOifLFYaXBBS5mtg2iLM5mtjmuTGapaDWz48u6Xxf2PvUMs2QFqCMxWzxgLh4QjtfwYeQwbUPcJWHVgbWOFSa5qsNhCNVNaRroJqWkqvTlh/HLXOpc2DKVDLxqx1GC0lLYXz8DUnTZKmDpOSn2B/SVvhhvcGANAAAAABJRU5ErkJggg=='); background-size: cover; display: block;\"\n  ></span>\n  <picture>\n          <source\n              srcset=\"/static/e5df5a0e745c681cc07d4303137259f9/8ac56/image-20250409002942619.webp 240w,\n/static/e5df5a0e745c681cc07d4303137259f9/d3be9/image-20250409002942619.webp 480w,\n/static/e5df5a0e745c681cc07d4303137259f9/95e88/image-20250409002942619.webp 804w\"\n              sizes=\"(max-width: 804px) 100vw, 804px\"\n              type=\"image/webp\"\n            />\n          <source\n            srcset=\"/static/e5df5a0e745c681cc07d4303137259f9/8ff5a/image-20250409002942619.png 240w,\n/static/e5df5a0e745c681cc07d4303137259f9/e85cb/image-20250409002942619.png 480w,\n/static/e5df5a0e745c681cc07d4303137259f9/27b7a/image-20250409002942619.png 804w\"\n            sizes=\"(max-width: 804px) 100vw, 804px\"\n            type=\"image/png\"\n          />\n          <img\n            class=\"gatsby-resp-image-image\"\n            src=\"/static/e5df5a0e745c681cc07d4303137259f9/27b7a/image-20250409002942619.png\"\n            alt=\"image-20250409002942619\"\n            title=\"image-20250409002942619\"\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>However, understanding the details around this area was still difficult even when checking a binary with symbols, so I gave up for the time being.</p>\n<p>It probably means I need to read the implementation of Rust’s modules themselves.</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 wrote code in Rust that creates a thread and executes an arbitrary function with <code class=\"language-text\">QueueUserAPC</code>.</p>\n<p>I also tried analyzing the Rust binary with a decompiler, but even with symbols there were many parts that I could not make sense of, so my reaction was basically, “How are you supposed to analyze this?”</p>\n<p>I suspect that if I were more familiar with the implementation of Rust’s modules themselves, there would be a bit more room for informed guessing.</p>\n<p>Going forward, I would like to build up more know-how for analyzing Rust.</p>","fields":{"slug":"/rust-winapi-usermode-apc-en","tagSlugs":["/tag/rust/","/tag/windows/","/tag/rust-win-api/","/tag/english/"]},"frontmatter":{"date":"2025-04-09","description":"Using User-Mode APCs with the Windows API in Rust","tags":["Rust","Windows","Rust-WinAPI","English"],"title":"Using User-Mode APCs with the Windows API in Rust","socialImage":{"publicURL":"/static/ad0e43ca3b66023e796da62e26b76d4d/rust-winapi-usermode-apc.png"}}}},"pageContext":{"slug":"/rust-winapi-usermode-apc-en"}},"staticQueryHashes":["251939775","401334301","825871152"]}