<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>sandboxteam &#8211; PT ESC</title>
	<atom:link href="/tag/sandboxteam/feed/index.xml" rel="self" type="application/rss+xml" />
	<link>/</link>
	<description></description>
	<lastBuildDate>Wed, 30 Sep 2026 19:20:56 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=7.1.3</generator>

<image>
	<url>/wp-content/uploads/2026/09/cropped-cropped-large_icon-32x32.png</url>
	<title>sandboxteam &#8211; PT ESC</title>
	<link>/</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>.NET Reactor: эволюция защиты с 6.7 до 7.0 и методы снятия обфускации</title>
		<link>/net-reactor-the-evolution-of-protection-from-6-7-to-7-0-and-methods-for-removing/</link>
		
		<dc:creator><![CDATA[global_author]]></dc:creator>
		<pubDate>Mon, 03 Mar 2025 18:06:33 +0000</pubDate>
				<category><![CDATA[Разное]]></category>
		<category><![CDATA[avlab]]></category>
		<category><![CDATA[dotnet]]></category>
		<category><![CDATA[obfuscation]]></category>
		<category><![CDATA[sandboxteam]]></category>
		<guid isPermaLink="false">/net-reactor-%d1%8d%d0%b2%d0%be%d0%bb%d1%8e%d1%86%d0%b8%d1%8f-%d0%b7%d0%b0%d1%89%d0%b8%d1%82%d1%8b-%d1%81-6-7-%d0%b4%d0%be-7-0-%d0%b8-%d0%bc%d0%b5%d1%82%d0%be%d0%b4%d1%8b-%d1%81%d0%bd%d1%8f%d1%82/</guid>

					<description><![CDATA[.NET Reactor: эволюция защиты с 6.7 до 7.0 и методы снятия обфускации 🔄 .NET Reactor — это мощный инструмент для защиты исполняемых файлов, написанных на С#, от декомпиляции и обратного инжиниринга. Он…]]></description>
										<content:encoded><![CDATA[<p><strong>.NET Reactor: эволюция защиты с 6.7 до 7.0 и методы снятия обфускации</strong> 🔄</p>
<p>.NET Reactor — это мощный инструмент для защиты исполняемых файлов, написанных на С#, от декомпиляции и обратного инжиниринга. Он предоставляет различные методы обфускации и лицензирования, обеспечивая безопасность интеллектуальной собственности разработчиков. </p>
<p>Но, как это обычно бывает, применяется он не только в благих целях: экспертам антивирусной лаборатории PT ESC часто попадаются вредоносные файлы, защищенные от анализа именно .Net Reactor.</p>
<p>🔓 <strong>Как защищен?</strong></p>
<p>.NET Reactor использует несколько уровней защиты для предотвращения декомпиляции и анализа кода:</p>
<p><strong>• NecroBit IL Code Protection:</strong> заменяет CIL-код методов на зашифрованный, делая невозможной декомпиляцию и восстановление исходного кода.</p>
<p><strong>• Виртуализация кода:</strong> преобразует исходный код в набор инструкций отличный от .NET IL, которые интерпретируются во время выполнения виртуальной машиной, что затрудняет анализ и восстановление оригинального кода.</p>
<p><strong>• Обфускация потока управления (Control Flow Obfuscation):</strong> преобразует код методов в запутанную структуру, усложняя понимание логики программы и затрудняя работу декомпиляторов (<em>пример — на скриншоте 1</em>).</p>
<p><strong>• Шифрование строк (String Encryption):</strong> шифрует строки в коде, предотвращая их чтение и анализ, что усложняет понимание функциональности приложения, как показано <em>на скриншоте 2</em>.</p>
<p><strong>• Антиотладочные механизмы (Anti Debug):</strong> внедряет проверки на наличие отладчиков, завершая процесс при их обнаружении, что препятствует динамическому анализу приложения. </p>
<p>🆕 <strong>Что нового?</strong></p>
<p>• Поддержка .NET 6.0: обеспечивает защиту для новейших приложений на этой платформе.</p>
<p>• Улучшения в виртуализации кода и Control Flow Obfuscation обеспечивают дальнейшее повышение надежности и сложности обфускации.</p>
<p>• Скрытие содержимого объединенных приложений .NET Core, 5.0, 6.0 предотвращает просмотр содержимого с помощью инструментов, таких как ILSpy / dnSpy.</p>
<p>🧐 <strong>Как анализировать?</strong></p>
<p>Несмотря на сложность защиты, существуют инструменты, которые облегчают жизнь реверсерам.<br />
NETReactorSlayer — мощный инструмент для реверса приложений, обфусцированных с помощью .NET Reactor. Его главные фишки:</p>
<p>• дешифровка NecroBit — восстанавливает CIL-код из зашифрованных методов;</p>
<p>• удаление прокси и оберток — очищает код от мусора, добавленного обфускатором (<em>смотрите на скриншоте 3</em>);</p>
<p>• декодирование строк и ресурсов — возвращает читаемые строки, зашифрованные в приложении;</p>
<p>• обход антиотладки и защиты от изменения кода.</p>
<p>Однако начиная с версии 6.9 изначальная версия Net Reactor Slayer перестала справляться с деобфускацией защиты даже с базовыми параметрами. Благодаря открытому исходному коду и довольно большому комьюнити, в pull requests можно найти исправленный код, который прекрасно отрабатывает даже на самой свежей версии обфускатора.</p>
<p>Но вот с виртуализированным кодом не все так гладко: Net Reactor Slayer с ним не справляется. Если вам повезло и файл был защищен версией <code>6.9.0.0</code>, то можно не тратить время на ручной анализ виртуальной машины, а применить VMAttack — инструмент для девиртуализации приложений .NET, в котором есть поддержка этой версии .NET Reactor. А если не повезло — проще всего проанализировать файл по его поведению, например с помощью PT Sandbox.</p>
<p>☝️ <strong>Вывод</strong></p>
<p>.NET Reactor остается одним из самых популярных обфускаторов для .NET. С каждой версией защита усложняется, особенно за счет виртуализации. Если собираетесь его анализировать — запасайтесь терпением и хорошими инструментами.</p>
<figure class="wp-block-image"><img width="1024" height="320" src="/wp-content/uploads/2025/03/photo_214@03-03-2025_18-06-33-1024x320.jpg" class="attachment-large size-large" alt="" decoding="async" loading="lazy" srcset="/wp-content/uploads/2025/03/photo_214@03-03-2025_18-06-33-1024x320.jpg 1024w, /wp-content/uploads/2025/03/photo_214@03-03-2025_18-06-33-300x94.jpg 300w, /wp-content/uploads/2025/03/photo_214@03-03-2025_18-06-33-768x240.jpg 768w, /wp-content/uploads/2025/03/photo_214@03-03-2025_18-06-33.jpg 1280w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>
<figure class="wp-block-image"><img width="1024" height="601" src="/wp-content/uploads/2025/03/photo_215@03-03-2025_18-06-33-1024x601.jpg" class="attachment-large size-large" alt="" decoding="async" loading="lazy" srcset="/wp-content/uploads/2025/03/photo_215@03-03-2025_18-06-33-1024x601.jpg 1024w, /wp-content/uploads/2025/03/photo_215@03-03-2025_18-06-33-300x176.jpg 300w, /wp-content/uploads/2025/03/photo_215@03-03-2025_18-06-33-768x451.jpg 768w, /wp-content/uploads/2025/03/photo_215@03-03-2025_18-06-33.jpg 1280w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>
<p><span class="hashtag">#avlab</span> <span class="hashtag">#sandboxteam</span> <span class="hashtag">#dotnet</span> <span class="hashtag">#obfuscation</span><br />
<a href="https://t.me/ptescalator" rel="noopener" target="_blank">@ptescalator</a></p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>А вы автоматизируете отладку?</title>
		<link>/do-you-automate-debugging/</link>
		
		<dc:creator><![CDATA[global_author]]></dc:creator>
		<pubDate>Fri, 21 Feb 2025 14:34:37 +0000</pubDate>
				<category><![CDATA[Разное]]></category>
		<category><![CDATA[avlab]]></category>
		<category><![CDATA[sandboxteam]]></category>
		<category><![CDATA[tips]]></category>
		<guid isPermaLink="false">http://localhost:8080/%d0%b0-%d0%b2%d1%8b-%d0%b0%d0%b2%d1%82%d0%be%d0%bc%d0%b0%d1%82%d0%b8%d0%b7%d0%b8%d1%80%d1%83%d0%b5%d1%82%d0%b5-%d0%be%d1%82%d0%bb%d0%b0%d0%b4%d0%ba%d1%83/</guid>

					<description><![CDATA[А вы автоматизируете отладку? 🧐 Команде экспертов PT Sandbox в работе часто приходится отлаживать различные компоненты ядра Windows, и без ядерного отладчика здесь не обойтись. Чем чаще мы этим занимаемся, тем больше…]]></description>
										<content:encoded><![CDATA[<strong>А вы автоматизируете отладку?</strong> 🧐<br />
<br />
Команде экспертов PT Sandbox в работе часто приходится отлаживать различные компоненты ядра Windows, и без ядерного отладчика здесь не обойтись. Чем чаще мы этим занимаемся, тем больше желание оптимизировать этот процесс.<br />
<br />
Часто при отладке хочется посмотреть изменение переменных, аргументов, различных значений рантайма. Этого можно добиться условными брейк-пойнтами и командами. Много лет назад в WinDbg появилась поддержка <a href="https://learn.microsoft.com/en-us/windows-hardware/drivers/debugger/using-linq-with-the-debugger-objects" rel="noopener" target="_blank">новой модели данных.</a> Командой <code>dx</code> можно объявлять свои переменные, структуры, вызывать JavaScript-функции и делать LINQ-запросы.<br />
<br />
Например, мы хотим зажурналировать все открытые файлы процессом <code>explorer.exe</code>:<br />
<br />
<pre class="wp-block-code"><span><code lang="powershell" class="hljs language-powershell language-powershell"><span class="hljs-number">0</span>: kd&gt; dx <span class="hljs-selector-tag">@</span><span class="hljs-variable">$explorer</span> = <span class="hljs-string">"explorer.exe"</span>
<span class="hljs-number">0</span>: kd&gt; bp /w <span class="hljs-string">"@<span class="hljs-variable">$curprocess</span>.Name.ToLower().StartsWith(@<span class="hljs-variable">$explorer</span>)"</span> nt!NtCreateFile <span class="hljs-string">"dx ((_OBJECT_ATTRIBUTES*)@r8)-&gt;ObjectName-&gt;Buffer; gc"</span>
</code></span></pre><br />
<br />
Если же условия или логика перехвата более сложная, без скрипта не обойтись. Рассмотрим пример.<br />
<br />
Допустим, мы хотим поймать и сохранить шеллкод, внедряемый в удаленный процесс. Для этого потребуется перехватить функцию <code>NtWriteVirtualMemory</code>, проверить, принадлежит ли описатель текущему процессу, и в противном случае сохранить регион памяти на диск. Как это выглядит в скрипте:<br />
<br />
<pre class="wp-block-code"><span><code lang="javascript" class="hljs language-javascript language-javascript"><span class="hljs-meta">"use strict"</span>;

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">WriteMemoryCallback</span>(<span class="hljs-params"></span>)
</span>{
    <span class="hljs-keyword">if</span>  (host.currentThread.Registers.User.rcx == <span class="hljs-number">-1</span>)
    {
        <span class="hljs-keyword">return</span>;
    }

    <span class="hljs-keyword">let</span> address = host.currentThread.Registers.User.rdx; 
    <span class="hljs-keyword">let</span> buffer  = host.currentThread.Registers.User.r8;
    <span class="hljs-keyword">let</span> length  = host.currentThread.Registers.User.r9;
    <span class="hljs-keyword">let</span> filename = ${host.currentProcess.Name}-${buffer.toString(<span class="hljs-number">16</span>)}.dmp;

    <span class="hljs-keyword">let</span> file = host.namespace.Debugger.Utility.FileSystem.TempDirectory.CreateFile(
        filename, <span class="hljs-string">'CreateNew'</span>);

    file.WriteBytes(host.memory.readMemoryValues(buffer, length, <span class="hljs-number">1</span>));
    host.diagnostics.debugLog(<span class="hljs-string">`dumped <span class="hljs-subst">${length}</span> bytes to <span class="hljs-subst">${filename}</span>\n`</span>);
    file.Close();
}

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">initializeScript</span>(<span class="hljs-params"></span>)
</span>{
    <span class="hljs-keyword">return</span> &#91;<span class="hljs-keyword">new</span> host.apiVersionSupport(<span class="hljs-number">1</span>, <span class="hljs-number">9</span>)];
}

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">invokeScript</span>(<span class="hljs-params"></span>)
</span>{
    <span class="hljs-keyword">let</span> bp = host.namespace.Debugger.Utility.Control.SetBreakpointAtOffset(<span class="hljs-string">"NtWriteVirtualMemory"</span>, <span class="hljs-number">0</span>, <span class="hljs-string">"nt"</span>);
    bp.Command = <span class="hljs-string">`dx @$scriptContents.WriteMemoryCallback(); gc`</span>;
}
</code></span></pre><br />
<br />
Иногда может не хватать набора API JavaScript-движка — с помощью <code>ExecuteCommand</code> можно вызвать любую команду отладчика, например чтобы удалить брейк-пойнт или поставить его по конкретному адресу:<br />
<br />
<pre class="wp-block-code"><span><code lang="javascript" class="hljs language-javascript language-javascript"><span class="hljs-keyword">let</span> exec = host.namespace.Debugger.Utility.Control.ExecuteCommand;
<span class="hljs-keyword">let</span> command = <span class="hljs-string">`dx @$scriptContents.BreakPointCallback(); gc`</span>;
exec(<span class="hljs-string">"bc *"</span>);
exec(<span class="hljs-string">`bp 0xfffffc024d546a88 "<span class="hljs-subst">${command}</span>"`</span>);
</code></span></pre><br />
<br />
Также JavaScript позволяет <a href="https://learn.microsoft.com/en-us/windows-hardware/drivers/debugger/using-linq-with-the-debugger-objects" rel="noopener" target="_blank">дополнять модель данных отладчика,</a> например добавлять инфу о секциях загруженных DLL или дополнительную команду, аналогичную <code>!handle</code>, <code>!address</code> и т. п.<br />
<br />
Допустим, мы хотим перечислить коллбэки на создание процесса, потока и загрузку DLL. Для этого нужно создать команду, например <code>!callbacks</code>:<br />
<br />
<pre class="wp-block-code"><span><code lang="javascript" class="hljs language-javascript language-javascript"><span class="hljs-keyword">const</span> log  = <span class="hljs-function"><span class="hljs-params">x</span> =&gt;</span> host.diagnostics.debugLog(x + <span class="hljs-string">'\n'</span>);
<span class="hljs-keyword">const</span> u64  = <span class="hljs-function"><span class="hljs-params">x</span> =&gt;</span> host.memory.readMemoryValues(x, <span class="hljs-number">1</span>, <span class="hljs-number">8</span>)&#91;<span class="hljs-number">0</span>];
<span class="hljs-keyword">const</span> exec = <span class="hljs-function"><span class="hljs-params">x</span> =&gt;</span> host.namespace.Debugger.Utility.Control.ExecuteCommand(x);

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">ParseCallbacks</span>(<span class="hljs-params">Symbol, Size</span>)
</span>{
    log(&#91;+] ${<span class="hljs-built_in">Symbol</span>}:);
    <span class="hljs-keyword">let</span> base = host.getModuleSymbolAddress(<span class="hljs-string">"nt"</span>, <span class="hljs-built_in">Symbol</span>);
    <span class="hljs-keyword">if</span> (base == <span class="hljs-literal">null</span>)
        <span class="hljs-keyword">return</span>;
    <span class="hljs-keyword">for</span> (<span class="hljs-keyword">let</span> i = <span class="hljs-number">0</span>; i &lt; Size; i++)
    {
        <span class="hljs-keyword">let</span> entry = u64(base.add(i * <span class="hljs-number">8</span>));
        <span class="hljs-keyword">if</span> (entry.compareTo(<span class="hljs-number">0</span>) != <span class="hljs-number">0</span>)
        {
            entry = entry.bitwiseAnd(<span class="hljs-number">-16</span>);
            <span class="hljs-keyword">let</span> callback = u64(entry.add(<span class="hljs-number">8</span>));
            log(\t${exec(.printf <span class="hljs-string">"%y"</span>, ${callback}).First()});
        }
    }
}

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">CallbackEnumerator</span>(<span class="hljs-params"></span>)
</span>{
    ParseCallbacks(<span class="hljs-string">"PspCreateProcessNotifyRoutine"</span>, <span class="hljs-number">64</span>);
    ParseCallbacks(<span class="hljs-string">"PspCreateThreadNotifyRoutine"</span>, <span class="hljs-number">64</span>);
    ParseCallbacks(<span class="hljs-string">"PspLoadImageNotifyRoutine"</span>, <span class="hljs-number">8</span>);
}

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">initializeScript</span>(<span class="hljs-params"></span>)
</span>{
    <span class="hljs-keyword">return</span> &#91;<span class="hljs-keyword">new</span> host.apiVersionSupport(<span class="hljs-number">1</span>, <span class="hljs-number">7</span>),
            <span class="hljs-keyword">new</span> host.functionAlias(CallbackEnumerator, <span class="hljs-string">"callbacks"</span>)];
}
</code></span></pre><br />
<br />
<strong>Результат на скрине. </strong>Современный WinDbg позволяет сильно автоматизировать процесс реверса, и у опытного аналитика наверняка есть комплект часто используемых скриптов.<em>
</em><br />
<span class="hashtag">#avlab</span> <span class="hashtag">#sandboxteam</span> <span class="hashtag">#tips</span><br />
<a href="https://t.me/ptescalator" rel="noopener" target="_blank">@ptescalator</a>]]></content:encoded>
					
		
		
			</item>
	</channel>
</rss>
