﻿<?xml version="1.0" encoding="utf-8"?>
<rss xmlns:a10="http://www.w3.org/2005/Atom" version="2.0">
  <channel>
    <title>Gapotchenko Blog</title>
    <link>https://blog.gapotchenko.com/</link>
    <description>Announcements, thoughts, insights and tricks for Gapotchenko products. Flavored with computer science and entrepreneurial spirit</description>
    <lastBuildDate>Wed, 08 Apr 2026 11:00:21 Z</lastBuildDate>
    <a10:id>urn:uuid:b58ef83f-f5c1-4df2-b5f1-dc53d8bfd595</a10:id>
    <a10:link rel="self" type="application/rss+xml" href="https://blog.gapotchenko.com/syndication/feed" />
    <a10:link rel="first" href="https://blog.gapotchenko.com/syndication/feed" />
    <a10:link rel="next" href="https://blog.gapotchenko.com/syndication/feed/page/2" />
    <a10:link rel="last" href="https://blog.gapotchenko.com/syndication/feed/page/4" />
    <item>
      <guid isPermaLink="false">84a10b9c-b9b4-4ce2-b2c5-737347c9f4a7</guid>
      <link>https://blog.gapotchenko.com/eazfuscator.net/on-benefits-of-obfuscation</link>
      <category>Eazfuscator.NET</category>
      <category>Business</category>
      <category>Benefits</category>
      <title>On Benefits of Obfuscation</title>
      <description>&lt;p&gt;&lt;img src="https://cdn.gapotchenko.com/website/blog/2021/09/intellectual-property-scene.png" alt="Intellectual Property Situation" /&gt;&lt;/p&gt;

&lt;p&gt;Your application's code is your intellectual property (IP) that comes with costs of time and money to develop. Therefore, protecting the code before distributing it is integral to the security of your business. &lt;/p&gt;

&lt;!-- more --&gt;

&lt;p&gt;If the code gets leaked or stolen, your company may face a spectrum of adverse effects, including loss of competitive edge, exposure of your innovations, and other serious consequences. Protecting that edge had become for the companies with intellectual property less of an option and more of a norm.&lt;/p&gt;

&lt;h2 id="whatiscodeobfuscation"&gt;What is code obfuscation?&lt;/h2&gt;

&lt;p&gt;Software protection is gaining more importance in this present digital era. You can protect against intellectual property theft, unauthorized access, and vulnerability discovery by making an application much more difficult to reverse-engineer. And obfuscation is one of the main approaches to achieve that. &lt;/p&gt;

&lt;p&gt;Code obfuscation is the technique of deliberately obscuring a code to make it much more difficult for humans to understand and useless to hackers who may have ulterior motives. Obfuscation uses several tricks to make the code irritating as hell to read and debug.&lt;/p&gt;

&lt;h2 id="reasonstouseobfuscation"&gt;Reasons to use obfuscation&lt;/h2&gt;

&lt;p&gt;Lack of protection may cause significant damage to a business owner. Cybercriminals may steal intellectual property, benefit from sensitive information, identify vulnerabilities, or add malicious code to apps. &lt;/p&gt;

&lt;p&gt;The idea moved towards obfuscation because of the following reasons:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Intellectual Property theft might quickly cost customers and brand reputation. Losing IP means losing of the first-to-market advantage or loss of profitability, or — in the worst case — losing entire lines of business to competitors.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Intellectual property is rapidly becoming a fundamental basis of wealth representing the most valuable asset. However, IP risk poses a threat to your intellectual capital and your financial success. In particular, to trade secrets, know-hows, lifestyle, salaries, and profits.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;It is believed that IP rights stimulate investment (time and money) and lead to innovation. As global IP theft increases, people invest less in new technology and products when they know their software will be stolen. This affects both inventors and investors.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h2 id="advantagesofobfuscation"&gt;Advantages of obfuscation&lt;/h2&gt;

&lt;p&gt;Obfuscation gives us a lot of benefits:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Cost-effectiveness.&lt;/strong&gt; While protection is core to any IP strategy, it can also have a significant capital value for any business. As the obfuscated code becomes much more challenging to analyze, this will reduce the possible hacker attacks. And your intellectual property won't be out in the open. So, your return on investments will definitely increase.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Safety.&lt;/strong&gt; Obfuscation is an integral method, referred to as application's self-defense. Considering the untrusted environment, it is always better to deploy an obfuscated application. This makes it much harder for attackers to decompile it and extract the intellectual property.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Performance.&lt;/strong&gt; Obfuscation also optimizes the code by removing not-so-useful metadata, unused code, or duplicate code. This, in turn, speeds up code execution, thus upping application performance.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Reliability.&lt;/strong&gt; Code obfuscation hides the implementation of a program while still allowing users to run it. Hiding business logic and valuable information in the obfuscated code makes it harder for attackers to access and reverse-engineer your application.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h2 id="conclusion"&gt;Conclusion&lt;/h2&gt;

&lt;p&gt;Software is a valuable type of intellectual property that can be challenging to secure. Therefore, protecting it should be among your priorities if it isn't already. The first line of defense against IP theft is often the existence of a well-implemented protection strategy.&lt;/p&gt;

&lt;p&gt;When properly implemented, code obfuscation is an effective approach for protecting your business assets. It isn't a way out, but it significally lowers the risks associated with IP leaks.&lt;/p&gt;</description>
      <pubDate>Wed, 08 Sep 2021 13:31:17 Z</pubDate>
    </item>
    <item>
      <guid isPermaLink="false">c0e41ee3-9cb2-49aa-bce4-922bf3983971</guid>
      <link>https://blog.gapotchenko.com/eazfuscator.net/deterministic-obfuscation</link>
      <category>Eazfuscator.NET</category>
      <category>Features</category>
      <title>Deterministic Obfuscation</title>
      <description>&lt;p&gt;&lt;img src="https://cdn.gapotchenko.com/website/blog/2021/05/deterministic-system.png" alt="Deterministic system" /&gt;&lt;/p&gt;

&lt;p&gt;Eazfuscator.NET gained the ability to perform deterministic obfuscation since version 2021.1.&lt;/p&gt;

&lt;!-- more --&gt;

&lt;p&gt;Deterministic obfuscation allows to produce an assembly whose binary content is identical across obfuscations for identical inputs.&lt;/p&gt;

&lt;p&gt;By default, obfuscator output from a given set of inputs is unique, since the obfuscator uses randomly generated cryptographic material for every obfuscation, which is a good thing.&lt;/p&gt;

&lt;p&gt;But sometimes, you may want to perform deterministic obfuscation. In that case, the obfuscator will produce a &lt;em&gt;deterministic&lt;/em&gt; assembly, the one whose binary content is identical across obfuscations as long as the input remains the same.&lt;/p&gt;

&lt;p&gt;Here is a bit more information from Eazfuscator.NET documentation: &lt;a href="https://learn.gapotchenko.com/eazfuscator.net/docs/sensei-features/deterministic-obfuscation"&gt;learn.gapotchenko.com/eazfuscator.net/docs/sensei-features/deterministic-obfuscation&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Deterministic obfuscation is a complementary feature to &lt;a href="https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/compiler-options/code-generation#deterministic"&gt;deterministic compilation&lt;/a&gt; provided by some .NET languages. Deterministic obfuscation is solely an industrial feature, the one that allows you to inspect the results with the finest precision.&lt;/p&gt;

&lt;p&gt;The areas of possible use are shaped by your needs and imagination. From what we have heard from the users, this is mainly a quality assurance (QA). For example, deterministic compilation and obfuscation allow to ensure that two separate build servers produce identical outputs, thus rulling out non-deterministic behaviors such as &lt;a href="https://en.wikipedia.org/wiki/Soft_error"&gt;soft errors&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;But the deterministic mode is not designed exclusively for QA. For example, one can imagine a deployment model that relies on changes in modules. If the source code of a module has no changes then why the compiled/obfuscated module should change? This approach can considerably simplify the patch review process for software manufacturers.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.gapotchenko.com/eazfuscator.net/download"&gt;Give Eazfuscator.NET a try&lt;/a&gt;&lt;/p&gt;</description>
      <pubDate>Tue, 18 May 2021 14:14:29 Z</pubDate>
    </item>
    <item>
      <guid isPermaLink="false">34e33fb7-a5a0-4fda-b2ec-9996674dfa22</guid>
      <link>https://blog.gapotchenko.com/eazfuscator.net/sdk-nuget-package-availability</link>
      <category>Eazfuscator.NET</category>
      <category>Features</category>
      <category>SDK</category>
      <title>Availability of Eazfuscator.NET SDK NuGet Package</title>
      <description>&lt;p&gt;&lt;img src="https://cdn.gapotchenko.com/website/blog/2021/05/sdk.png" alt="Software Development Kit" /&gt;
Starting with Eazfuscator.NET version 2021.1, the Software Development Kit (SDK) for .NET is available as a public NuGet package.&lt;/p&gt;

&lt;!-- more --&gt;

&lt;p&gt;SDK provides programmatic access to some specific features of Eazfuscator.NET. The most prominent one is stack trace decoding.&lt;/p&gt;

&lt;p&gt;Say you have an obfuscated stack trace or a log file and want to "deobfuscate" it, provided that you have the proper secret knowledge (password) at hand. All you need for that to work is to reference the official &lt;a href="https://www.nuget.org/packages/Gapotchenko.Eazfuscator.NET.SDK"&gt;Eazfuscator.NET SDK NuGet package&lt;/a&gt;. Here is how it can be achieved in code:&lt;/p&gt;

&lt;pre&gt;&lt;code class="csharp"&gt;using Gapotchenko.Eazfuscator.NET.SDK;

string stackTrace = SymbolDecoder.Decode("&amp;lt;obfuscated stack trace&amp;gt;", "secret-password");  
Console.WriteLine(stackTrace);  
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;code&gt;SymbolDecoder.Decode&lt;/code&gt; is a static function that covers the most common usage scenario. It is simple but you may need more. For example, stack trace decoding does take some time and you may prefer to use the cancellable variant:&lt;/p&gt;

&lt;pre&gt;&lt;code class="csharp"&gt;stackTrace = SymbolDecoder.Decode("&amp;lt;obfuscated stack trace&amp;gt;", "secret-password", cancellationToken);  
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Or if you need to decode a multitude of stacks/files with the same password, the simplest variant of &lt;code&gt;SymbolDecoder.Decode&lt;/code&gt; may put you into trouble because it performs key derivation operation each and every time the function is called. And it tends to be relatively slow, as the key derivation function has to be computationally intensive to deter brute-force attacks on a password.&lt;/p&gt;

&lt;p&gt;To overcome that inherent performance bottleneck, symbol decoder can be created beforehand and then reused multiple times with a great efficiency:&lt;/p&gt;

&lt;pre&gt;&lt;code class="csharp"&gt;using Gapotchenko.Eazfuscator.NET.SDK;

// Create symbol decoder beforehand. The creation operation is on a slower side.
var decoder = SymbolDecoder.Create("secret-password");

// Reuse the decoder multiple times. Consequent decoding operations are fast.
stackTrace = decoder.Decode("&amp;lt;obfuscated stack trace 1&amp;gt;");  
stackTrace = decoder.Decode("&amp;lt;obfuscated stack trace 2&amp;gt;");  
// ...
stackTrace = decoder.Decode("&amp;lt;obfuscated stack trace N&amp;gt;");

// Once you finish with symbol decoder, it is a good practice to dispose it to clean up the remnants of cryptographic material from memory.
decoder.Dispose();  
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Eazfuscator.NET SDK can be employed for various applications such as logging, diagnostics, data collection, automated error reporting et cetera. It is all up to your needs and imagination!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.gapotchenko.com/eazfuscator.net/download"&gt;Give Eazfuscator.NET a try&lt;/a&gt;&lt;/p&gt;</description>
      <pubDate>Mon, 17 May 2021 17:49:04 Z</pubDate>
    </item>
    <item>
      <guid isPermaLink="false">be2b0cc0-c782-45b5-89bb-7c50b161179d</guid>
      <link>https://blog.gapotchenko.com/eazfuscator.net/managing-stack-trace-passwords</link>
      <category>Eazfuscator.NET</category>
      <category>Features</category>
      <title>Managing Stack Trace Passwords</title>
      <description>&lt;p&gt;Since its inception, Eazfuscator.NET has offered the ability to encrypt the names of types, members, and other assembly symbols with a secret password.&lt;/p&gt;

&lt;p&gt;Once encryption is applied, the assembly remains obfuscated but the original symbol names can be retrieved back whenever such neccessity arises.&lt;/p&gt;

&lt;p&gt;The most common usage scenario is to decode an obfuscated stack trace back to its original form:&lt;/p&gt;

&lt;p&gt;&lt;img src="https://cdn.gapotchenko.com/website/blog/2020/12/eazfuscator.net-stack-trace-decoder.png" alt="Eazfuscator.NET Stack Trace Decoder" /&gt;&lt;/p&gt;

&lt;p&gt;Hence the umbrella name of that feature: &lt;em&gt;stack trace decoding&lt;/em&gt;. It allows to decode a stack trace using a piece of prior knowledge such as &lt;em&gt;stack trace password&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;In contrast to its numerous rivals, Eazfuscator.NET neither uses database nor mapping files. This signigicantly simplifies the handling of obfuscated assemblies as there is no separate state to store or manage. Instead, there is a password and that's all it takes.&lt;/p&gt;

&lt;p&gt;From security standpoint, you may prefer to use several stack trace passwords. One password per product is a good general approach. Naturally, you have to remember which password corresponds to which product; thus switching between products may take some extra time and effort.&lt;/p&gt;

&lt;p&gt;To make this process easier, &lt;strong&gt;Eazfuscator.NET 2020.4&lt;/strong&gt; offers a built-in management of stack trace passwords:&lt;/p&gt;

&lt;p&gt;&lt;img src="https://cdn.gapotchenko.com/website/blog/2020/12/eazfuscator.net-stack-trace-passwords-management-1.png?v=2" alt="Eazfuscator.NET Stack Trace Password Management 1 of 2" /&gt;&lt;/p&gt;

&lt;p&gt;The list of predefined passwords is the basis of the password management:&lt;/p&gt;

&lt;p&gt;&lt;img src="https://cdn.gapotchenko.com/website/blog/2020/12/eazfuscator.net-stack-trace-passwords-management-2.png" alt="Eazfuscator.NET Stack Trace Password Management 2 of 2" /&gt;&lt;/p&gt;

&lt;p&gt;The dialog allows to manipulate the predefined passwords in every conceivable way. Once defined, passwords can be quickly reused in the password text box.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.gapotchenko.com/eazfuscator.net/download"&gt;Give Eazfuscator.NET a try&lt;/a&gt;&lt;/p&gt;</description>
      <pubDate>Mon, 28 Dec 2020 13:31:00 Z</pubDate>
    </item>
    <item>
      <guid isPermaLink="false">2d86e39b-5681-417d-925c-f053fb4bacaf</guid>
      <link>https://blog.gapotchenko.com/eazfuscator.net/clearing-the-fog-obfuscators-vs-protectors</link>
      <category>Eazfuscator.NET</category>
      <category>Computer Science</category>
      <category>History</category>
      <title>Clearing the Fog: Obfuscators vs Protectors</title>
      <description>&lt;p&gt;Eazfuscator.NET is an obfuscator for .NET platform designed to protect .NET software from reverse-engineering and intellectual property theft. It belongs to the category of obfuscators.&lt;/p&gt;

&lt;p&gt;There is another tool category that claims to be as useful as obfuscation: protectors.&lt;/p&gt;

&lt;p&gt;While both obfuscators and protectors promise the same benefits, they are very different in instrumental parts of the implementation.&lt;/p&gt;

&lt;!-- more --&gt;

&lt;p&gt;Obfuscation is all about mathematics. It produces &lt;strong&gt;computational challenges&lt;/strong&gt; to make it hard for an observer to interpret the meaning of inner parts of a program. In best case scenario, an observer cannot grasp the inner workings of an obuscated program at all.&lt;/p&gt;

&lt;p&gt;In contrast, protectors rely on a more down-to-earth strategy of &lt;strong&gt;sneaking&lt;/strong&gt; a program from an observer with some purely technical tricks. For example, a protector can pack a program in an encrypted binary blob which then gets decrypted to the memory just before execution in run time.&lt;/p&gt;

&lt;p&gt;Today I want to show you a good example of that difference, seasoned with a pinch of nostalgia.&lt;/p&gt;

&lt;p&gt;Let's take a look at now a historical piece of software called &lt;strong&gt;NetWinProtector&lt;/strong&gt; by Safe Lion:&lt;/p&gt;

&lt;p&gt;&lt;img src="https://cdn.gapotchenko.com/website/blog/2019/12/NetWinProtector-scene.png" alt="NetWinProtector by Safe Lion" title="" /&gt; &lt;/p&gt;

&lt;p&gt;Note a distinctive look of that program. The design is a bit harsh and weird. However it seams to have a long-standing effect on human memory, as I vividly remember how I could not get it out of my head once I saw it back in 2015. It is weird and attractive, in a way.&lt;/p&gt;

&lt;p&gt;If you click that &lt;strong&gt;Buy&lt;/strong&gt; button you get directed to a now defunct website, but you can still &lt;a rel="nofollow noopener" href="https://web.archive.org/web/20170430035315/http://safe-lion.com"&gt;enjoy it via Internet Archive&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;To get another portion of a weird nostalgia, we can press &lt;strong&gt;Register&lt;/strong&gt; button:&lt;/p&gt;

&lt;p&gt;&lt;img src="https://cdn.gapotchenko.com/website/blog/2019/12/NetWinProtector-register-scene.png" alt="NetWinProtector Register" title="" /&gt; &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Register online&lt;/strong&gt; is expectedly defunct too, as it tries to access &lt;code&gt;http://safe-lion.com/Reg.asmx&lt;/code&gt;. Whatever amount of customers this product had, they all are left in the cold now.&lt;/p&gt;

&lt;p&gt;So what about protection? A product documentation provides the following overview:&lt;/p&gt;

&lt;p&gt;&lt;img src="https://cdn.gapotchenko.com/website/blog/2019/12/NetWinProtector-overview.png" alt="NetWinProtector Overview" title="" /&gt; &lt;/p&gt;

&lt;p&gt;"Your program is encrypted, wrapped into a manageable wrapper loader [sic]" - sounds like a typical protector. Before we even run it on a real app let's see if the product passes a smoke test.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;.NET Generic Unpacker&lt;/strong&gt; &lt;a href="http://www.ntcore.com/netunpack.php"&gt;tool&lt;/a&gt; by Daniel Pistelli is an instrument we will use for testing. All it does is scans the memory of a running process trying to find the boundaries of executable modules, then saves them to disk. So let's try to extract the modules of a running NetWinProtector instance which was handily protected by itself.&lt;/p&gt;

&lt;p&gt;As soon as we run &lt;code&gt;NETUnpack.exe&lt;/code&gt; tool we see something sneaky is going on. NetWinProtector shuts itself down! Probably this is what "Anti Memory Dump protection" feature is about.&lt;/p&gt;

&lt;p&gt;Let's do a dumb change by renaming &lt;code&gt;NETUnpack.exe&lt;/code&gt; file to &lt;code&gt;123NETUnpack.exe&lt;/code&gt;. Once that is done, NetWinProtector process does not exit anymore, so we can scan and grab all of its supposedly protected modules from the process memory:&lt;/p&gt;

&lt;p&gt;&lt;img src="https://cdn.gapotchenko.com/website/blog/2019/12/NetWinProtector-NETUnpack-unpack.png" alt="" title="" /&gt; &lt;/p&gt;

&lt;p&gt;Once unpacking is done, we get a bunch of files. And sure enough, NetWinProtector .NET assemblies are there, fully intact and ready for open observation:&lt;/p&gt;

&lt;p&gt;&lt;img src="https://cdn.gapotchenko.com/website/blog/2019/12/NetWinProtector-dotPeek.png" alt="NetWinProtector assembly viewed in JetBrains dotPeek decompiler" title="" /&gt; &lt;/p&gt;

&lt;p&gt;This is underwhelming result if you ask me. Reliance on technical trickery puts protectors and software protected by them to assailable position.&lt;/p&gt;

&lt;p&gt;In contrast, obfuscation makes a bet on computational hardness. This characterizes obfuscation as a new but relatively established branch of cryptography, which is in turn a prominent branch of mathematics intersected with other disciplines.&lt;/p&gt;

&lt;p&gt;To give a practical analogy: once attackers meet a 2&lt;sup&gt;n&lt;/sup&gt; combinatorial complexity where n &gt; 80, there is no &lt;code&gt;NETUnpack&lt;/code&gt; tool to rely on. They have to descend into realm of guessing and brute forcing, but due to the laws of computational complexity their chances are neglectably dim. This is what's called a &lt;strong&gt;cryptographical obfuscation&lt;/strong&gt; and this is the future we are heading to.&lt;/p&gt;

&lt;p&gt;Regarding NetWinProtector. Despite its short lifespan, it became a weird piece of nostalgia to me. The website, slogan, funky registration window, pricing. All those commercial aspirations whirled in the sands of time...&lt;/p&gt;</description>
      <pubDate>Thu, 26 Dec 2019 13:25:44 Z</pubDate>
    </item>
    <item>
      <guid isPermaLink="false">271b76aa-f5ac-41e3-95e8-904616f11155</guid>
      <link>https://blog.gapotchenko.com/eazfuscator.net/homomorphic-encryption-of-code</link>
      <category>Cryptography</category>
      <category>Research</category>
      <category>Eazfuscator.NET</category>
      <category>Features</category>
      <category>Homomorphic Encryption</category>
      <title>Homomorphic Encryption of Code</title>
      <description>&lt;p&gt;Previously we announced that we discovered a novel way of cryptographically secure obfuscation of software. This article gives a brief illustrated overview of discovery. It also provides some practical examples based on existing implementation of technology in Eazfuscator.NET obfuscator for .NET platform.&lt;/p&gt;

&lt;h2 id="introduction"&gt;Introduction&lt;/h2&gt;

&lt;p&gt;Obfuscation is relatively new field of cryptography and it often falls behind its older and bigger sibling - the data encryption. It's all about guarantees.&lt;/p&gt;

&lt;p&gt;The data encryption guarantees that data remains &lt;strong&gt;unobservable&lt;/strong&gt; unless an observer knows &lt;strong&gt;the key&lt;/strong&gt;. The key is selected to be a large enough number (or blob of data) that is extremely hard (i.e. impossible) to brute force.&lt;/p&gt;

&lt;p&gt;It's different when it comes to the code of a program. The code must remain observable in order to be executed by CPU. At the same time, a cryptographically secure obfuscation should make the code unobservable to an attacker.&lt;/p&gt;

&lt;p&gt;What some obfuscators (specifically protectors) do is they encrypt the code and put the key right into resulting executable file. This serves the purpose only until the key is discovered by a decompiler or memory dumper. After that, the game is over - the full code becomes observable by an attacker. As you can see, not a whole lot of guarantees at all.&lt;/p&gt;

&lt;p&gt;Extracting a key from executable file is billion of billions times simpler than brute forcing a 80 bit key used for encryption. An attacker wins by choosing the cheapest method.&lt;/p&gt;

&lt;p&gt;The only technique contemporary obfuscators are good at is &lt;strong&gt;concealing&lt;/strong&gt; the information. For example, Eazfuscator.NET does a good job on symbols by irreversibly renaming them. Removing the essential information is a great security measure. But the code is still there and it remains observable.&lt;/p&gt;

&lt;p&gt;Another neat trick some obfuscators employ is code &lt;strong&gt;virtualization&lt;/strong&gt;. It's achieved by translating the instructions of a target platform to instructions of a custom virtual machine. This gives solid results at the expense of code speed, but still the virtualized code remains somewhat observable. It is humanely possible to build a so-called devirtualizer that would obtain the original code of a program.&lt;/p&gt;

&lt;h2 id="indistinguishabilityobfuscation"&gt;Indistinguishability Obfuscation&lt;/h2&gt;

&lt;p&gt;Indistinguishability obfuscation (IO) is a cryptographic primitive that provides a formal notion of program obfuscation. Informally, &lt;em&gt;indistinguishability obfuscation hides the implementation of a program while still allowing users to run it&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;That's exactly what we need in order to make the code unobservable by an attacker.&lt;/p&gt;

&lt;p&gt;The definition of indistinguishability obfuscation has its roots at the notion of ciphertext indistinguishability which was later extended to a more general computational indistinguishability.&lt;/p&gt;

&lt;h2 id="homomorphicencryption"&gt;Homomorphic Encryption&lt;/h2&gt;

&lt;p&gt;At first, let's introduce a notion of program:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;O = P(I)  
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;where &lt;code&gt;P&lt;/code&gt; denotes a program, &lt;code&gt;I&lt;/code&gt; denotes its input and &lt;code&gt;O&lt;/code&gt; stands for output.&lt;/p&gt;

&lt;p&gt;The easiest way to look at this notion is to imagine that a program &lt;code&gt;P&lt;/code&gt; is a Unix-like command line tool with input &lt;code&gt;I&lt;/code&gt; in a form of &lt;code&gt;stdin&lt;/code&gt; and output &lt;code&gt;O&lt;/code&gt; in form of &lt;code&gt;stdout&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;In mathematical sense, program &lt;code&gt;P&lt;/code&gt; may be much simpler than a full-blown application. For example, it can be just a single operation like multiplication. &lt;/p&gt;

&lt;p&gt;The most intriguing candidate for indistinguishability obfuscation is  &lt;a href="https://en.wikipedia.org/wiki/Homomorphic_encryption"&gt;Homomorphic Encryption (HE)&lt;/a&gt;. Let's see how it works:&lt;/p&gt;

&lt;p&gt;&lt;img src="https://cdn.gapotchenko.com/website/blog/2019/10/homomorphic-encryption.png?v=2" alt="Homomorphic Encryption" /&gt;
Figure 1. Homomorphic encryption&lt;/p&gt;

&lt;p&gt;Homomorphic encryption (HE) uses a public-key cryptosystem that provides &lt;code&gt;E&lt;/code&gt; and &lt;code&gt;D&lt;/code&gt; functions. Function &lt;code&gt;E&lt;/code&gt; encrypts the data while &lt;code&gt;D&lt;/code&gt; performs the inverse operation of decryption.&lt;/p&gt;

&lt;p&gt;Now having those two functions we can write the program equation in homomorphically encrypted form by applying &lt;code&gt;E&lt;/code&gt; to both sides of equation:&lt;/p&gt;

&lt;pre&gt;
E(O) = E(P(E(I)))
&lt;/pre&gt;

&lt;p&gt;Let's introduce three shortcut symbols to better understand what's going on:&lt;/p&gt;

&lt;pre&gt;
P&lt;sub&gt;E&lt;/sub&gt; = E(P);  // encrypted program
I&lt;sub&gt;E&lt;/sub&gt; = E(I);  // encrypted input
O&lt;sub&gt;E&lt;/sub&gt; = E(O);  // encrypted output
&lt;/pre&gt;

&lt;p&gt;This gives us a more concise view of HE program equation:&lt;/p&gt;

&lt;pre&gt;
O&lt;sub&gt;E&lt;/sub&gt; = P&lt;sub&gt;E&lt;/sub&gt;(I&lt;sub&gt;E&lt;/sub&gt;)
&lt;/pre&gt;

&lt;p&gt;As you can see, the HE program &lt;tt&gt;P&lt;sub&gt;E&lt;/sub&gt;&lt;/tt&gt; solely works in encrypted domain, consuming encrypted input &lt;tt&gt;I&lt;sub&gt;E&lt;/sub&gt;&lt;/tt&gt; and producing encrypted output &lt;tt&gt;O&lt;sub&gt;E&lt;/sub&gt;&lt;/tt&gt;.&lt;/p&gt;

&lt;p&gt;In this way, the homomorphic encryption can be used to move a computationally extensive work &lt;tt&gt;P&lt;sub&gt;E&lt;/sub&gt;&lt;/tt&gt; to an untrusted party through a remote communication channel. Since the untrusted party never receives the private key of asymmetric cryptosystem, it never knows what program or data are being evaluated.&lt;/p&gt;

&lt;p&gt;This fact is denoted by the presence of a &lt;code&gt;Security Barrier&lt;/code&gt; in the figure above. The whole HE scheme is secure as long as &lt;code&gt;Encrypted Domain&lt;/code&gt; and &lt;code&gt;Plain Domain&lt;/code&gt; are kept separated by the barrier.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;But in software obfuscation, the security barrier is missing&lt;/strong&gt; and &lt;tt&gt;P&lt;sub&gt;E&lt;/sub&gt;&lt;/tt&gt; should be able to work on unencrypted &lt;code&gt;I&lt;/code&gt; and &lt;code&gt;O&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Let's write down a corresponding program equation that reflects that:&lt;/p&gt;

&lt;pre&gt;
O = D(P&lt;sub&gt;E&lt;/sub&gt;(E(I)))
&lt;/pre&gt;

&lt;p&gt;It goes just fine until &lt;code&gt;D&lt;/code&gt; function is used to decrypt the output. &lt;strong&gt;This poses a fatal problem&lt;/strong&gt; as function &lt;code&gt;D&lt;/code&gt; can be used not only to decrypt the output, it can also be used to decrypt the encrypted program &lt;tt&gt;P&lt;sub&gt;E&lt;/sub&gt;&lt;/tt&gt;:&lt;/p&gt;

&lt;pre&gt;
P = D(P&lt;sub&gt;E&lt;/sub&gt;);  // game over
&lt;/pre&gt;

&lt;p&gt;In this way, the obfuscation of &lt;tt&gt;P&lt;sub&gt;E&lt;/sub&gt;&lt;/tt&gt; is getting thwarted, rendering the whole HE scheme without a security barrier useless.&lt;/p&gt;

&lt;h2 id="aseeminglyunsolvabledilemma"&gt;A Seemingly Unsolvable Dilemma&lt;/h2&gt;

&lt;p&gt;The impossibility to build an indistinguishability obfuscation based on a general notion of homomorphic encryption that would be able to produce  &lt;em&gt;unencrypted&lt;/em&gt; output leads us to the root of a problem.&lt;/p&gt;

&lt;p&gt;In data communication, participants are separated by natural barriers:&lt;/p&gt;

&lt;p&gt;&lt;img src="https://cdn.gapotchenko.com/website/blog/2019/10/data-encryption.png?v=4" alt="Data encryption" /&gt;
Figure 2. Encrypted data communication&lt;/p&gt;

&lt;p&gt;The presence of barriers is what makes data encryption feasible: an attacker is physically unable to retrieve the key and thus cannot decrypt the information.&lt;/p&gt;

&lt;p&gt;In software obfuscation, all participants are located at the same security zone and every one of them has a physical access to an encryption key that is stored in software:&lt;/p&gt;

&lt;p&gt;&lt;img src="https://cdn.gapotchenko.com/website/blog/2019/10/software-obfuscation-dilemma.png?v=5" alt="Software obfuscation dilemma" /&gt;
Figure 3. The software obfuscation dilemma&lt;/p&gt;

&lt;p&gt;The absence of security barrier between Mallory and an encryption key embedded in software renders all program obfuscation attempts useless as Mallory will always be able to decrypt it.&lt;/p&gt;

&lt;p&gt;If we cease to embed a program encryption key in software, then we are safe from Mallory but CPU is not able to execute the program.&lt;/p&gt;

&lt;p&gt;This represents a seemingly unsolvable dilemma of indistinguishability obfuscation of software.&lt;/p&gt;

&lt;p&gt;Another name of this model is Virtual Black Box (VBB) obfuscation which was proven to be impossible by Barak et al. [Barak01]. The impossibility of VBB obfuscation means that we need to find a more relaxed model of obfuscation.&lt;/p&gt;

&lt;h2 id="ahintfromthebook"&gt;A Hint From The Book&lt;/h2&gt;

&lt;p&gt;On a cold fall of 2015, we stumbled upon important observation by Kris Kaspersky [Kris03, p. 567]:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;The analysis of code can be thwarted successfully only by encrypting the program. However, the processor cannot directly execute the encrypted code. Therefore, it must be decrypted before control is passed to the program. If the key is contained within the program, the reliability of the protection is close to zero. ...&lt;/p&gt;
  
  &lt;p&gt;In general, protection consists of implementing a certain mathematical model in a program that is used to generate the key. Different branches of the program are encrypted using various keys. To work out the keys, it is necessary to know the state of the model at the moment control is passed to the corresponding branch of the program. The code is dynamically decrypted at run time. To decrypt it entirely, all possible states of the model need to be tried sequentially. If there are lots of them, which is easy to achieve, the reconstruction of all code will be practically impossible.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Kaspersky suggested a plausible obfuscation model. Let's call it a &lt;strong&gt;Conditional Indistinguishability Obfuscation (CiO)&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The CiO model implies that  conditional parts of a program remain indistinguishable until they are executed. Once they hit the execution path, they become uncovered by decryption and thus become observable to CPU (and to Mallory).&lt;/p&gt;

&lt;p&gt;Since then, that brilliant idea never left our heads. It felt so powerful yet unreachable. &lt;strong&gt;An attacker cannot reconstruct the whole program as he only has access to the parts he can observe.&lt;/strong&gt; And intuitively he cannot observe all the parts but... how to achieve that?&lt;/p&gt;

&lt;p&gt;Kaspersky suggested to use "machine state" as the source of key material but it would be an inherently weak source due to the lack of entropy.&lt;/p&gt;

&lt;h2 id="indistinguishableassociativearray"&gt;Indistinguishable Associative Array&lt;/h2&gt;

&lt;p&gt;Three years later, at fall of 2018, we became involved in construction of indistinguishable associative array. We needed it in order to protect the dispatch table of Eazfuscator.NET virtual machine from attacks based on static analysis.&lt;/p&gt;

&lt;p&gt;Imagine a class &lt;code&gt;IndistinguishableDictionary&amp;lt;long, long&amp;gt;&lt;/code&gt; that behaves just like the ordinary &lt;code&gt;Dictionary&amp;lt;long, long&amp;gt;&lt;/code&gt; but with a twist: nobody is able to tell beforehand what association a dictionary holds unless they have a corresponding lookup key.&lt;/p&gt;

&lt;p&gt;Ordinary &lt;code&gt;Dictionary&amp;lt;long, long&amp;gt;&lt;/code&gt; can be enumerated, so all associations held by dictionary can be revealed:&lt;/p&gt;

&lt;pre&gt;&lt;code class=" csharp"&gt;foreach (var i in map)  
    Console.WriteLine("{0}={1}", i.Key, i.Value);
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;code&gt;IndistinguishableDictionary&lt;/code&gt; does not allow enumeration by imposing a mathematical hurdle. The only operation it allows is lookup by a key:&lt;/p&gt;

&lt;pre&gt;&lt;code class=" csharp"&gt;value = map[key]  
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;If attacker has no key, he cannot extract the association. The record in indistinguishable dictionary remains unobservable unless a proper lookup key is supplied. &lt;/p&gt;

&lt;p&gt;To our surprise, we got a positive result. We were able to construct indistinguishable associative array with the help of homomorphic encryption. It was somewhat unpractical though as it required large keys with lots of bits, and that would lead to gigantic machine instructions.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;And then, it hit us.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;value = map[key]&lt;/code&gt; is just a specific case of a general notion of program &lt;code&gt;O = P(I)&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The program &lt;code&gt;P&lt;/code&gt; by itself cannot contain a key suitable for black box encryption; but it has input &lt;code&gt;I&lt;/code&gt; with &lt;em&gt;lots of entropy&lt;/em&gt;, and that &lt;code&gt;I&lt;/code&gt; is generally unknown to an attacker.&lt;/p&gt;

&lt;p&gt;&lt;u&gt;Program input &lt;code&gt;I&lt;/code&gt; &lt;em&gt;is&lt;/em&gt; the secret. This is a valid key material for cryptographic obfuscation.&lt;/u&gt;&lt;/p&gt;

&lt;p&gt;On a closer inspection of Kris' Kaspersky work, we were able to finally identify some hints to this phenomenon [Kris03], albeit they were expressed not as clearly as we would generally prefer:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;... Looking to [function] arguments allows the sequences sought to be caught in data streams, irrespective of how these sequences were obtained. For example, an authentication procedure expecting the password "MyGoodPassword" does not care where it came from (the keyboard, a remote terminal, a file, etc.).&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2 id="moredetailedviewonsoftwareobfuscation"&gt;More Detailed View on Software Obfuscation&lt;/h2&gt;

&lt;p&gt;Let's take a closer look at the detailed interaction diagram between participants:&lt;/p&gt;

&lt;p&gt;&lt;img src="https://cdn.gapotchenko.com/website/blog/2019/10/software-obfuscation-interactions.png?v=3" alt="Software obfuscation interaction diagram between participants" /&gt;
Figure 4. Software obfuscation and interactions between participants&lt;/p&gt;

&lt;p&gt;Note how natural security barriers appeared between participants once we identified that program input &lt;code&gt;I&lt;/code&gt; can be a reliable source of key material for encryption of program parts.&lt;/p&gt;

&lt;p&gt;Indeed, every user of an obfuscated program has its own set of unique input data. For example, if an obfuscated app (say, word processor) works on some files (say &lt;code&gt;.doc&lt;/code&gt; files), an attacker cannot fully decompile the app unless he has all the possible file variations the app can work on. Which is not going to happen as an attacker cannot realistically have an access to all that data due to natural barriers of physical separation.&lt;/p&gt;

&lt;p&gt;The conditional indistinguishability obfuscation (CiO) of software is now intuitively feasible. So it turns out that software obfuscation dilemma looks pretty solvable in terms of proposed model. &lt;/p&gt;

&lt;h2 id="realization"&gt;Realization&lt;/h2&gt;

&lt;p&gt;The intuitive feasibility of proposed CiO model would not mean a lot, unless at least one practical implementation is found.&lt;/p&gt;

&lt;p&gt;The CiO model implies a conditional obfuscation, so we had to focus on conditional blocks of code, and specifically on predicates:&lt;/p&gt;

&lt;pre&gt;&lt;code class=" csharp"&gt;if (p)  
    DoSomething();
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The conditional block should only be revealed when &lt;code&gt;p&lt;/code&gt; is true. And we know that &lt;code&gt;p&lt;/code&gt; should be tied to program input &lt;code&gt;I&lt;/code&gt; somehow.&lt;/p&gt;

&lt;p&gt;Thanks to the work described in paper "Indistinguishable Predicates: A New Tool for Obfuscation" by Zobernig et al. [Zobernig17], we focused our attention on evasive predicates.&lt;/p&gt;

&lt;p&gt;An example of evasive predicate is a password check function &lt;code&gt;p(x) = "x == pw"&lt;/code&gt;. Since it is hard to find an input &lt;code&gt;x&lt;/code&gt; that satisfies an evasive predicate, this class of predicates is a good candidate for obfuscation.&lt;/p&gt;

&lt;p&gt;Initially we weren't sure if that was a possible endeavor, but on October 24, 2018 around 4 AM we came up with a plausible solution.&lt;/p&gt;

&lt;p&gt;Let's take a look at the following code circuit:&lt;/p&gt;

&lt;pre&gt;&lt;code class=" csharp"&gt;if (x == C)  
{
    DoSomething();
    …
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;where &lt;code&gt;x == C&lt;/code&gt; is an evasive predicate with input &lt;code&gt;x&lt;/code&gt; and constant &lt;code&gt;C&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;A good thing about homomorphic encryption is that it allows to view the data through the prism of equations. Note that our evasive predicate is an equation:&lt;/p&gt;

&lt;pre&gt;
x == C
&lt;/pre&gt;

&lt;p&gt;This fact allows us to apply a deterministic encryption function &lt;code&gt;E&lt;/code&gt; to both sides:&lt;/p&gt;

&lt;pre&gt;
E(x) == E(C)
&lt;/pre&gt;

&lt;p&gt;Once encryption is applied, please note that &lt;code&gt;E(C)&lt;/code&gt; can be calculated at compile time as constant &lt;tt&gt;C&lt;sub&gt;E&lt;/sub&gt; = E(C)&lt;/tt&gt;, thus irreversibly hiding the original value of &lt;code&gt;C&lt;/code&gt;:&lt;/p&gt;

&lt;pre&gt;
E(x) == C&lt;sub&gt;E&lt;/sub&gt;
&lt;/pre&gt;

&lt;p&gt;As a result, we get an encrypted predicate &lt;code&gt;p(x)&lt;/code&gt; that is perfectly functional at run time but never discloses the original value of &lt;code&gt;C&lt;/code&gt; while providing us with 1 bit of &lt;em&gt;unencrypted&lt;/em&gt; output:&lt;/p&gt;

&lt;pre&gt;
p(x) = "E(x) == C&lt;sub&gt;E&lt;/sub&gt;"
&lt;/pre&gt;

&lt;p&gt;Unencrypted output eliminates the necessity of HE function &lt;code&gt;D&lt;/code&gt; that would thwart the obfuscation otherwise. The elimination of &lt;code&gt;D&lt;/code&gt; effectively transforms &lt;code&gt;E&lt;/code&gt; to a trapdoor function.&lt;/p&gt;

&lt;p&gt;So, now we have a conditional statement with a homomorphically encrypted predicate &lt;code&gt;p(x)&lt;/code&gt;:&lt;/p&gt;

&lt;pre&gt;
if (E(x) == C&lt;sub&gt;E&lt;/sub&gt;)
{
    DoSomething();
    …
}
&lt;/pre&gt;

&lt;p&gt;An important observation is that &lt;code&gt;x&lt;/code&gt; may or may not be tied to program input &lt;code&gt;I&lt;/code&gt;. In order to find the exact relation of &lt;code&gt;x&lt;/code&gt; to &lt;code&gt;I&lt;/code&gt;, all program data flows would need to be traced. Such kind of tracing may be an enormous or even computationally impossible task. So let's just assume that &lt;code&gt;x&lt;/code&gt; of every predicate is related to program input &lt;code&gt;I&lt;/code&gt; with some not insignificant probability.&lt;/p&gt;

&lt;p&gt;The next question is how to encrypt the conditional block of the &lt;code&gt;if&lt;/code&gt; statement.&lt;/p&gt;

&lt;p&gt;First of all, we need to ensure that the code of conditional block is translated to the data form:&lt;/p&gt;

&lt;pre&gt;
BL = { DoSomething(); … }

if (E(x) == C&lt;sub&gt;E&lt;/sub&gt;)
    eval(BL);
&lt;/pre&gt;

&lt;p&gt;Eazfuscator.NET achieves that by allowing homomorphic encryption only in virtualized methods, as the virtualized code is in data form already.&lt;/p&gt;

&lt;p&gt;Secondly, we need to introduce another encryption function. Let's call it &lt;tt&gt;E&lt;sub&gt;s&lt;/sub&gt;&lt;/pre&gt;&lt;/tt&gt; as it should be symmetric. &lt;tt&gt;D&lt;sub&gt;s&lt;/sub&gt;&lt;/pre&gt;&lt;/tt&gt; is a corresponding decryption function.&lt;/p&gt;

&lt;p&gt;Then, we can use the predicate constant &lt;code&gt;C&lt;/code&gt; as a key material for &lt;tt&gt;E&lt;sub&gt;s&lt;/sub&gt;&lt;/tt&gt; in order to encrypt the conditional block &lt;code&gt;BL&lt;/code&gt; at compile time:&lt;/p&gt;

&lt;pre&gt;
BL&lt;sub&gt;E&lt;/sub&gt; = E&lt;sub&gt;s&lt;/sub&gt;(BL, C)
&lt;/pre&gt;

&lt;p&gt;Thanks to evasiveness of predicate, we can rely on the fact that &lt;code&gt;x&lt;/code&gt; equals to &lt;code&gt;C&lt;/code&gt; when the conditional block hits the execution path. In this way, the encrypted conditional block &lt;tt&gt;BL&lt;sub&gt;E&lt;/sub&gt;&lt;/tt&gt; can be revealed (decrypted) in run time when and only when &lt;code&gt;x == C&lt;/code&gt;:&lt;/p&gt;

&lt;pre&gt;
if (E(x) == C&lt;sub&gt;E&lt;/sub&gt;)
    eval(D&lt;sub&gt;s&lt;/sub&gt;(BL&lt;sub&gt;E&lt;/sub&gt;, x));
&lt;/pre&gt;

&lt;p&gt;The goal is achieved.&lt;/p&gt;

&lt;p&gt;The obfuscated predicate is indistinguishable. The code of conditional block is also indistinguishable and can only be revealed when it hits the execution path. This behavior corresponds to the proposed model of conditional indistinguishability obfuscation (CiO).&lt;/p&gt;

&lt;h2 id="somepracticalexamples"&gt;Some Practical Examples&lt;/h2&gt;

&lt;p&gt;In accordance to original spirit of the product, Eazfuscator.NET automatically finds and indistinguishably obfuscates all the circuits that are suitable for homomorphic encryption (HE) in virtualized methods.&lt;/p&gt;

&lt;p&gt;Currently it covers just one circuit class and integer data types, but we plan to significantly extend HE coverage in the future.&lt;/p&gt;

&lt;p&gt;We quickly identified that customers will want to visualize the homomorphically encrypted regions of code. That's why we've built HE visualization tool right into Eazfuscator.NET 2019.3 &lt;a href="https://blog.gapotchenko.com/eazfuscator.net/deeper-visual-studio-integration"&gt;extension&lt;/a&gt; for Visual Studio:&lt;/p&gt;

&lt;p&gt;&lt;img src="https://cdn.gapotchenko.com/website/blog/2019/10/he-visualization-1.png" alt="Visualization of homomorphically encrypted blocks of code" /&gt;
Figure 5. Visualization of homomorphically encrypted regions of code&lt;/p&gt;

&lt;p&gt;Whenever a suitable code circuit is found, a green circled H symbol appears at the left side of the editor. Hovering the mouse over that symbol reveals some useful information such as the boundaries of encrypted region and the number of entropy bits in key material.&lt;/p&gt;

&lt;h3 id="whatcanitbeusedfor"&gt;What can it be used for?&lt;/h3&gt;

&lt;p&gt;HE is a tool, and your imagination is the driver. Here is an interesting quote from Kaspersky [Kris03]:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;... trying the combinations of all [...] conceivable arguments will take an infinite amount of time. Reconstructing the source code of the program thus protected will not be possible before each of its branches gains control at least once. &lt;strong&gt;However, the frequency of calling different branches is not identical;&lt;/strong&gt; it is very low for some of them. For example, a special handler can be installed for the word "pine" entered in the text editor. This handler may carry out some additional checks for integrity of the program code, or for the cleanliness of the license for the software being used.&lt;/p&gt;
  
  &lt;p&gt;The hacker will not be able to figure out whether the program is [fully] cracked and [will] end quickly. Careful and laborious testing will be necessary, but even carrying out this will not be [that] helpful.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2 id="tryityourself"&gt;Try It Yourself&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://www.gapotchenko.com/eazfuscator.net/download"&gt;Download Eazfuscator.NET&lt;/a&gt; and try HE on your own code.&lt;/p&gt;

&lt;hr /&gt;

&lt;p&gt;DISCLAIMER: This research and discovery is property of public domain. &lt;br /&gt;
AUTHORS: Oleksiy Gapotchenko, Kirill Rode &lt;br /&gt;
ORGANIZATION: Gapotchenko LLC &lt;br /&gt;
LOCATION: Kharkiv &lt;br /&gt;
YEAR: 2019&lt;/p&gt;

&lt;h2 id="references"&gt;References&lt;/h2&gt;

&lt;p&gt;[Barak01]&lt;br/&gt;
B. Barak and O. Goldreich and R. Impagliazzo and S. Rudich and A. Sahai and S. P. Vadhan and Ke Yang, “On the (im)possibility of obfuscating programs,” in &lt;em&gt;Advances in Cryptology&lt;/em&gt; -- CRYPTO 2001, 21st Annual International Cryptology Conference, Santa Barbara, California, USA, August 19-23, 2001, Proceedings&lt;/p&gt;

&lt;p&gt;[Kris03]&lt;br/&gt;
K. Kaspersky, “Hacker Disassembling Uncovered: Powerful Techniques To Safeguard Your Programming,” ISBN 978-1-931769-22-8, 2003&lt;/p&gt;

&lt;p&gt;[Zobernig17]&lt;br/&gt;
L. Zobernig and S. D. Galbraith and G. Russello, “Indistinguishable Predicates: A New Tool for Obfuscation,” IACR Cryptology ePrint Archive, 2017&lt;/p&gt;

&lt;p&gt;P.S. We aimed to use as few paragraphs as possible but the resulting article nevertheless have become rather large. More advanced topics like handling of low-entropy inputs, HE vs custom-built encrypted point functions, malleability and algebraic attacks, dictionary and replay attacks on a deterministic cryptosystem etc are thus omitted. They are subjects of a future, probably more formal publication.&lt;/p&gt;</description>
      <pubDate>Thu, 10 Oct 2019 02:32:00 Z</pubDate>
    </item>
    <item>
      <guid isPermaLink="false">216ac1b6-f5b4-4925-87a8-5ce38a746ec0</guid>
      <link>https://blog.gapotchenko.com/eazfuscator.net/improved-nuget-integration</link>
      <category>Eazfuscator.NET</category>
      <category>Features</category>
      <category>NuGet</category>
      <title>Improved NuGet Integration</title>
      <description>&lt;p&gt;NuGet became an essential part of the development for .NET platform over the recent years, as it provided the convenience of creating and consuming the packages.&lt;/p&gt;

&lt;p&gt;The packages are easy to discover and use with the help of &lt;a href="https://docs.microsoft.com/en-us/nuget/tools/package-manager-ui"&gt;Package Manager UI&lt;/a&gt; in Visual Studio. In reality, adding a package reference to a project often comes down to a single line:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&amp;lt;Project&amp;gt;  
  ...
  &amp;lt;ItemGroup&amp;gt;
    &amp;lt;!-- The line below adds Contoso.HelpfulLibrary NuGet package to the project --&amp;gt;
    &amp;lt;PackageReference Include="Contoso.HelpfulLibrary" Version="1.3.0" /&amp;gt;
  &amp;lt;/ItemGroup&amp;gt;
  ...
&amp;lt;/Project&amp;gt;  
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Once the package reference is in place, &lt;code&gt;Contoso.HelpfulLibrary&lt;/code&gt; can be used by the code.&lt;/p&gt;

&lt;p&gt;NuGet does all the heavy lifting. It automatically downloads the package (if it is not downloaded yet), adds an assembly reference to the project, copies required package files at the build time and so on.&lt;/p&gt;

&lt;p&gt;Development tends to be much easier with NuGet. And even more so since it also allows to consume &lt;strong&gt;tools&lt;/strong&gt;.&lt;/p&gt;

&lt;!-- more --&gt;

&lt;p&gt;Back in 2014, in addition to &lt;code&gt;.msi&lt;/code&gt; setup file, we started to distribute Eazfuscator.NET as a NuGet package. It was essential for build servers as they often prohibited direct software installations. We chose to host Eazfuscator.NET package at a private NuGet server. The integration with the package was made at the solution level, so every protected project would share the same version of Eazfuscator.NET. It did the job and looked good, at first.&lt;/p&gt;

&lt;p&gt;The time revealed some significant imperfections. One of them was related to new &lt;code&gt;PackageReference&lt;/code&gt; format that had to replace an older &lt;code&gt;packages.config&lt;/code&gt;. The new format had no support for solution-level NuGet packages. It meant that some newer project types such as .NET Standard and .NET Core could not consume Eazfuscator.NET as a package. Also the original package did not play well with NuGet restore operation due to implementation specifics. Finally, as NuGet was gradually becoming a more mature technology, we faced a considerable demand for a public Eazfuscator.NET package at &lt;a href="https://nuget.org/packages/Gapotchenko.Eazfuscator.NET"&gt;nuget.org&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The new Eazfucsator.NET 2019.1 takes it all to the perfect state:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Eazfuscator.NET package is publicly hosted on &lt;a href="https://www.nuget.org/packages/Gapotchenko.Eazfuscator.NET"&gt;nuget.org&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Both &lt;code&gt;PackageReference&lt;/code&gt; and &lt;code&gt;packages.config&lt;/code&gt; formats are supported out of the box&lt;/li&gt;
&lt;li&gt;The package is now integrated at the project level&lt;/li&gt;
&lt;li&gt;All known edge corners are rectified&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Using the new Eazfuscator.NET is no different from any other NuGet package:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&amp;lt;Project&amp;gt;  
  ...
  &amp;lt;ItemGroup&amp;gt;
    &amp;lt;PackageReference Include="Gapotchenko.Eazfuscator.NET" Version="2019.1.538" /&amp;gt;
  &amp;lt;/ItemGroup&amp;gt;
  ...
&amp;lt;/Project&amp;gt;  
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Once the package is added, the project is automatically obfuscated every time you build it in &lt;em&gt;Release&lt;/em&gt; configuration.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://nuget.org/packages/Gapotchenko.Eazfuscator.NET"&gt;Try it now&lt;/a&gt;&lt;/p&gt;</description>
      <pubDate>Tue, 21 May 2019 09:05:21 Z</pubDate>
    </item>
    <item>
      <guid isPermaLink="false">96d61946-cb8a-4ce9-b397-934b8f336c92</guid>
      <link>https://blog.gapotchenko.com/eazfuscator.net/automatic-handling-of-windows-forms-data-binding</link>
      <category>Eazfuscator.NET</category>
      <category>Features</category>
      <title>Automatic Handling of Windows Forms Data Binding</title>
      <description>&lt;p&gt;Many users of Eazfuscator.NET use Windows Forms technology to build application UI. Windows Forms provides a set of controls that allows to display data and interact with a user. Sometimes, the displayed data is not set to UI controls directly. A common practice is to use a data binding mechanism that allows to tie the object properties by name. To get property values by name, data binding uses Reflection API.&lt;/p&gt;

&lt;p&gt;Consider a simple code that creates a list of products:&lt;/p&gt;

&lt;pre&gt;&lt;code class=" csharp"&gt;class Product  
{
   public int ID { get; set; }
   public string Title { get; set; }
   public string Description { get; set; }
}

// …

var products = new List&amp;lt;Product&amp;gt;  
{
   new Product { ID = 1, Title = "Juice", Description = "Juice description" },
   new Product { ID = 2, Title = "Tea", Description = "Tea description" },
   new Product { ID = 3, Title = "Coffee", Description = "Coffee description" }
};
&lt;/code&gt;&lt;/pre&gt;

&lt;!-- more --&gt;

&lt;p&gt;Let’s display the products in the ComboBox control by title:&lt;/p&gt;

&lt;pre&gt;&lt;code class=" csharp"&gt;productsComboBox.DisplayMember = "Title";  
productsComboBox.DataSource = products;  
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;That’s how it all works:&lt;/p&gt;

&lt;p&gt;&lt;img src="https://cdn.gapotchenko.com/website/blog/2019/04/windows-forms-data-binding-1.png" alt="ComboBox uses Reflection API in order to display products by Title" /&gt;&lt;/p&gt;

&lt;p&gt;But what happens if we obfuscate such code? During obfuscation, the names of classes and their members change. When renamed, the &lt;strong&gt;Title&lt;/strong&gt; property is no more available for binding by its old name:&lt;/p&gt;

&lt;p&gt;&lt;img src="https://cdn.gapotchenko.com/website/blog/2019/04/windows-forms-data-binding-2.png" alt="The Title property is obfuscated and cannot be found by Reflection API anymore" /&gt;&lt;/p&gt;

&lt;p&gt;Before now, the workaround was to manually exclude the &lt;strong&gt;Title&lt;/strong&gt; property from renaming using the &lt;code&gt;ObfuscationAttribute&lt;/code&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code class=" csharp"&gt;using System.Reflection;

class Product  
{
   public int ID { get; set; }

   [Obfuscation] // &amp;lt;-- the obfuscation attribute excludes Title property from renaming
   public string Title { get; set; }

   public string Description { get; set; }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;It looks simple, but in a real application with a large amount of data displayed, this can turn into a nightmare. That’s why we added out of the box coverage for this scenario in Eazfuscator.NET 2018.4. It features support for Windows Forms binding semantics by automatically tracking corresponding properties and preserving them during obfuscation:&lt;/p&gt;

&lt;p&gt;&lt;img src="https://cdn.gapotchenko.com/website/blog/2019/04/windows-forms-data-binding-3.png" alt="The Title property is preserved and the binding works fine" /&gt;&lt;/p&gt;

&lt;p&gt;Of course, all the other class members get completely obfuscated to the maximum possible extent.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.gapotchenko.com/eazfuscator.net/download"&gt;Try Eazfuscator.NET now&lt;/a&gt;&lt;/p&gt;</description>
      <pubDate>Tue, 30 Apr 2019 18:35:42 Z</pubDate>
    </item>
    <item>
      <guid isPermaLink="false">7ab8d09b-5605-48ab-82e2-20dcab4e2ea2</guid>
      <link>https://blog.gapotchenko.com/eazfuscator.net/elements-of-homomorphic-code-encryption</link>
      <category>Eazfuscator.NET</category>
      <category>Features</category>
      <title>Elements of Homomorphic Code Encryption</title>
      <description>&lt;p&gt;I have great news to share.&lt;/p&gt;

&lt;p&gt;We were able to identify and leverage some useful properties of a partially homomorphic cryptosystem to achieve a considerably better obfuscation results.&lt;/p&gt;

&lt;p&gt;How much better? Up to the point where parts of a program remain totally &lt;strong&gt;unobservable&lt;/strong&gt; unless they hit the actual execution path. This means that such parts cannot be decompiled unless they are executed. In other words, they become statically &lt;strong&gt;undecompilable.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Full disclosure and details are to follow. Stay tuned for the future Eazfuscator.NET release and accompanying publications. Obfuscation remained one of the most intriguing challenges of a humankind. And it looks like we became one step closer to nailing it.&lt;/p&gt;

&lt;p&gt;Eazfuscator.NET 2018.4 provides just &lt;em&gt;some&lt;/em&gt; elements of homomorphic encryption as a part of code and data virtualization. The fully featured release of this technology is planned for Eazfuscator 2019.1.&lt;/p&gt;

&lt;p&gt;Homomorphic encryption feature is on by default. If you have a project that was previously obfuscated by an earlier version of Eazfuscator.NET then you need to &lt;a href="https://www.gapotchenko.com/eazfuscator.net/kb/100030"&gt;bump project compatibility version to 2018.4 or higher&lt;/a&gt; in order to take the benefits of homomorphic encryption.&lt;/p&gt;

&lt;p&gt;UPDATE: The discovery is fully disclosed at &lt;a href="https://blog.gapotchenko.com/eazfuscator.net/homomorphic-encryption-of-code"&gt;dedicated article&lt;/a&gt;.&lt;/p&gt;</description>
      <pubDate>Wed, 05 Dec 2018 19:02:27 Z</pubDate>
    </item>
    <item>
      <guid isPermaLink="false">18767d11-6a02-4efc-9f7e-fd1f84ad5612</guid>
      <link>https://blog.gapotchenko.com/eazfuscator.net/your-first-product</link>
      <category>Eazfuscator.NET</category>
      <category>Product Development</category>
      <title>Your First Product</title>
      <description>&lt;p&gt;I know that a lot of Eazfuscator.NET users are product makers. And product creation still remains a twilight area.&lt;/p&gt;

&lt;p&gt;Yesterday I stumbled upon Leon's Bambrick &lt;a href="https://yourfirstproduct.com/Info" target="_blank"&gt;Your First Product&lt;/a&gt; and it got me hooked. Here is the excerpt I liked the most:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;When you're building a product you need to view your product from the customer's point of view. You need to see it with "fresh eyes", with the eyes of a beginner.&lt;/p&gt;
  
  &lt;p&gt;This is very hard to do. In fact, it's impossible. But you must try.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That's an important point.&lt;/p&gt;

&lt;p&gt;Software developers are often plagued by a &lt;a href="https://en.wikipedia.org/wiki/Tunnel_vision"&gt;tunnel vision&lt;/a&gt;. They may think they do the good to a customer, but in reality they do the damage. Growing an empathy for customers is a natural way to overcome that inherent mentality.&lt;/p&gt;

&lt;p&gt;There is a lot more:&lt;/p&gt;

&lt;p&gt;&lt;img src="https://cdn.gapotchenko.com/website/blog/2018/06/Your%20First%20Product%20by%20Leon%20Bambrick.png" alt="Your First Product by Leon Bambrick" /&gt;&lt;/p&gt;

&lt;p&gt;Check it out: &lt;a href="https://yourfirstproduct.com/Info" target="_blank"&gt;https://yourfirstproduct.com/Info&lt;/a&gt;&lt;/p&gt;</description>
      <pubDate>Tue, 19 Jun 2018 08:53:20 Z</pubDate>
    </item>
    <item>
      <guid isPermaLink="false">d807431a-08b0-4942-a2a7-b6dbc02d78f4</guid>
      <link>https://blog.gapotchenko.com/eazfuscator.net/seamless-integration-with-unity</link>
      <category>Eazfuscator.NET</category>
      <category>Features</category>
      <category>Unity</category>
      <title>Seamless Integration with Unity</title>
      <description>&lt;p&gt;Eazfuscator.NET 2018.2 brings seamless integration with Unity.&lt;/p&gt;

&lt;p&gt;&lt;img src="https://cdn.gapotchenko.com/website/blog/2018/05/Eazfuscator.NET%20Unity%20Project%20Settings.png" alt="Seamless Eazfuscator.NET integration with Unity" /&gt;&lt;/p&gt;

&lt;!-- more --&gt;

&lt;p&gt;Before, you had to obfuscate your &lt;code&gt;Assembly-CSharp.dll&lt;/code&gt; assemblies manually:&lt;/p&gt;

&lt;p&gt;&lt;img src="https://cdn.gapotchenko.com/website/blog/2018/05/AssemblyCSharp_DragAndDrop.png" alt="Manual Assembly-CSharp.dll obfuscation" /&gt;&lt;/p&gt;

&lt;p&gt;That is a simple and good approach. Yet it's not workable for Unity targets with more complex build pipelines (Android et al). For such targets, not only &lt;code&gt;Assembly-CSharp.dll&lt;/code&gt; should be built and obfuscated at the right time, it also has to be processed with platform-specific tools. And this is where it gets hard.&lt;/p&gt;

&lt;p&gt;Instead of manual &lt;code&gt;Assembly-CSharp.dll&lt;/code&gt; obfuscation, you can now add Eazfuscator.NET protection right to your Unity project and get everything automated. The easiest way to do so is to drag &lt;code&gt;Assets&lt;/code&gt; folder from Unity IDE, and drop it in the green zone of Eazfuscator.NET Assistant:&lt;/p&gt;

&lt;p&gt;&lt;img src="https://cdn.gapotchenko.com/website/blog/2018/05/Unity_Project_DragAndDrop.png" alt="Unity project drag and drop into the green zone of Eazfuscator.NET Assitant" /&gt;&lt;/p&gt;

&lt;p&gt;Once you do that, Eazfuscator.NET Assistant applies protection to the project:&lt;/p&gt;

&lt;p&gt;&lt;img src="https://cdn.gapotchenko.com/website/blog/2018/05/Unity%20Project%20Protection%20Completed.png" alt="Unity project protection completed" /&gt;&lt;/p&gt;

&lt;p&gt;Now when you build the project with &lt;em&gt;Development Build&lt;/em&gt; setting off, &lt;code&gt;Assembly-CSharp.dll&lt;/code&gt; will be obfuscated automatically during the build. Eazfuscator.NET does it right no matter what platform a Unity project currently targets thanks to the seamless integration.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.gapotchenko.com/eazfuscator.net/download"&gt;Download new version of Eazfuscator.NET&lt;/a&gt;&lt;/p&gt;</description>
      <pubDate>Fri, 11 May 2018 21:00:48 Z</pubDate>
    </item>
    <item>
      <guid isPermaLink="false">a8f73f8d-ae1b-441d-a187-bf962c80e550</guid>
      <link>https://blog.gapotchenko.com/eazfuscator.net/netcore-netstandard-portablepdb-support-delivered</link>
      <category>Eazfuscator.NET</category>
      <category>Features</category>
      <title>.NET Core, .NET Standard and Portable PDB Support. Delivered</title>
      <description>&lt;p&gt;Eazfuscator.NET now officially supports .NET Core and .NET Standard technologies.&lt;/p&gt;

&lt;p&gt;&lt;img src="https://cdn.gapotchenko.com/website/blog/2017/06/Eazfuscator.NET%20Supports%20Them%20All%20%5BBanner%20800x500%5D.jpg" alt="Eazfuscator.NET supports them all" /&gt;&lt;/p&gt;

&lt;!-- more --&gt;

&lt;p&gt;It was a long ride.&lt;/p&gt;

&lt;p&gt;.NET Core started with a bit astronautical project system based on &lt;code&gt;project.json&lt;/code&gt; files. While they were useful to some degree, the overall experience was at times disappointing.&lt;/p&gt;

&lt;p&gt;Thanks to the Gods of Common Sense, Microsoft then refactored the .NET Core project system to a proven MSBuild format. Visual Studio 2017 brought the new MSBuild-based tooling for .NET Core, so you could enjoy all the goodies of a mature build system.&lt;/p&gt;

&lt;p&gt;Not that &lt;code&gt;project.json&lt;/code&gt; was an absolute evil. Actually it gave birth to two important concepts we use today:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;MSBuild project file format was tidied up and is more friendly to human beings now&lt;/li&gt;
&lt;li&gt;It can contain &lt;code&gt;&amp;lt;PackageReference&amp;gt;&lt;/code&gt; items in order to effortlessly reference NuGet packages&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;code&gt;&amp;lt;PackageReference&amp;gt;&lt;/code&gt; items are interesting beasts. While they originated in a galaxy far far way, you can add them to your Windows Forms (or whatever) MSBuild project like this:&lt;/p&gt;

&lt;pre&gt;&lt;code class=" XML"&gt;&amp;lt;ItemGroup&amp;gt;  
  &amp;lt;PackageReference Include="Newtonsoft.Json" Version="10.0.2" /&amp;gt;
&amp;lt;/ItemGroup&amp;gt;  
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;And then the magic happens. Newtonsoft.Json library becomes instantly available to your code. I wouldn't be too far away if I say that &lt;code&gt;&amp;lt;PackageReference&amp;gt;&lt;/code&gt; is the future.&lt;/p&gt;

&lt;p&gt;The new Eazfuscator.NET 5.7 brings full support for all these goodies plus a bit more. Portable PDB is the new file format for debug information. It is not so widespread nowadays but this is the default representation of debug symbols for .NET Standard assemblies. We've got it covered in Eazfuscator.NET 5.7, too.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.gapotchenko.com/eazfuscator.net/download"&gt;Download the new version of Eazfuscator.NET&lt;/a&gt;&lt;/p&gt;</description>
      <pubDate>Fri, 16 Jun 2017 02:10:22 Z</pubDate>
    </item>
    <item>
      <guid isPermaLink="false">0b9e0544-e449-4703-8c26-2c5f77905440</guid>
      <link>https://blog.gapotchenko.com/eazfuscator.net/obfuscation-of-value-tuples</link>
      <category>Eazfuscator.NET</category>
      <category>Features</category>
      <title>Obfuscation of Value Tuples</title>
      <description>&lt;p&gt;C# 7 and Visual Basic 15 introduced the notion of value tuples. The concept is similar to what you may find in &lt;a href="https://msdn.microsoft.com/en-us/library/system.tuple.aspx"&gt;System.Tuple&lt;/a&gt; but with two important distinctions:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;The new &lt;a href="https://msdn.microsoft.com/en-us/library/system.valuetuple.aspx"&gt;System.ValueTuple&lt;/a&gt; is a value type while the older System.Tuple is a reference type.&lt;/strong&gt; The value type tends to be a more efficient data type when it comes to passing the values in and out of the method calls&lt;!-- more --&gt;  &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;System.ValueTuple has a special compiler support and thus allows to define named fields.&lt;/strong&gt; This is a big advantage comparing to System.Tuple which only has &lt;em&gt;Item1&lt;/em&gt;, &lt;em&gt;Item2&lt;/em&gt;, ... properties.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;How does it affect the obfuscation? Let's take a look at C# example:&lt;/p&gt;

&lt;pre&gt;&lt;code class=" csharp"&gt;static (int sum, int count) Calc(IEnumerable&amp;lt;int&amp;gt; source)  
{
    var r = (sum: 0, count: 0);
    foreach (var value in source)
    {
        r.sum += value;
        r.count++;
    }
    return r;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The given method &lt;code&gt;Calc&lt;/code&gt; can be used like this:&lt;/p&gt;

&lt;pre&gt;&lt;code class=" csharp"&gt;static void Main()  
{
    var seq = new[] { 1, 2, 3 };
    var r = Calc(seq);
    Console.WriteLine("Sum: {0}", r.sum);
    Console.WriteLine("Count: {0}", r.count);
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Please note that method &lt;code&gt;Calc&lt;/code&gt; returns a value tuple with two named fields: &lt;code&gt;sum&lt;/code&gt; and &lt;code&gt;count&lt;/code&gt;. Do those names find their ways into resulting .NET assembly? The short answer is yes. They are specified by C# compiler behind the scenes with &lt;a href="https://msdn.microsoft.com/en-us/library/system.runtime.compilerservices.tupleelementnamesattribute.aspx"&gt;TupleElementNamesAttribute&lt;/a&gt; as shown below:&lt;/p&gt;

&lt;pre&gt;&lt;code class="csharp"&gt;&lt;mark&gt;[return: TupleElementNamesAttribute(new[] { "sum", "count" })]&lt;/mark&gt;
static System.ValueTuple&amp;lt;int, int&amp;gt; Calc(IEnumerable&amp;lt;int&amp;gt; source)&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This is how it looks after compilation:&lt;/p&gt;

&lt;p&gt;&lt;img src="https://cdn.gapotchenko.com/website/blog/2017/04/Leaked%20ValueTuple%20Metadata.png" alt="Leaked ValueTuple metadata" /&gt;&lt;/p&gt;

&lt;p&gt;As you can see, the field names of value tuples basically become the part of .NET assembly metadata. And they will stay there disclosing the private implementation details to the outside world even when you build the assembly in &lt;em&gt;Release&lt;/em&gt; configuration.&lt;/p&gt;

&lt;p&gt;You can automatically strip the unneeded field names of value tuples by obfuscating the assembly with Eazfuscator.NET:&lt;/p&gt;

&lt;p&gt;&lt;img src="https://cdn.gapotchenko.com/website/blog/2017/04/Assistant%20DND.png" alt="Obfuscate Visual Studio project with Eazfuscator.NET" /&gt;&lt;/p&gt;

&lt;p&gt;Starting with &lt;a href="https://www.gapotchenko.com/eazfuscator.net/download/changes/5.6"&gt;version 5.6&lt;/a&gt;, Eazfuscator.NET fully understands the semantics implied by value tuples and takes care to automatically prune the unused value tuple metadata, including the aforementioned field names. Such transformation is not only a win in terms of security, but it also gives slight size and performance benefits.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.gapotchenko.com/eazfuscator.net/download"&gt;Give Eazfuscator.NET a try&lt;/a&gt;&lt;/p&gt;</description>
      <pubDate>Mon, 17 Apr 2017 11:50:51 Z</pubDate>
    </item>
    <item>
      <guid isPermaLink="false">51c9c2d6-3a5c-4664-9c4c-1a03f014c768</guid>
      <link>https://blog.gapotchenko.com/eazfuscator.net/deeper-visual-studio-integration</link>
      <category>Eazfuscator.NET</category>
      <category>Features</category>
      <title>Deeper Visual Studio Integration</title>
      <description>&lt;p&gt;What if you had a personal assistant that could guide you through particulars of obfuscation?&lt;/p&gt;

&lt;p&gt;Wait no more. Eazfuscator.NET 5.3 introduces a deeper Visual Studio integration that improves your productivity when it comes to obfuscation directives and configuration:&lt;/p&gt;

&lt;p&gt;&lt;img src="https://cdn.gapotchenko.com/website/blog/2016/06/Eazfuscator.NET%20VS%20IntelliSense.png" alt="Eazfuscator.NET IntelliSense Suggestions" style="margin-left: 0; max-width: 100%;"/&gt;&lt;/p&gt;

&lt;!-- more --&gt;

&lt;p&gt;This is achieved by Visual Studio extension which is (optionally) installed by Eazfuscator.NET. Not only it provides the IntelliSense suggestions but also shows you quick tips right in the code:&lt;/p&gt;

&lt;p&gt;&lt;img src="https://cdn.gapotchenko.com/website/blog/2016/06/Eazfuscator.NET%20VS%20IntelliSense%20Tooltip.png" alt="Eazfuscator.NET IntelliSense Help Tips" style="margin-left: 0;"/&gt;&lt;/p&gt;

&lt;p&gt;Eazfuscator.NET also gives you relevant real-time information about possible misconfiguration:&lt;/p&gt;

&lt;p&gt;&lt;img src="https://cdn.gapotchenko.com/website/blog/2016/06/Eazfuscator.NET%20VS%20IntelliSense%20Issue%20Hint.png" alt="Eazfuscator.NET IntelliSense Tip About Misconfiguration" style="margin-left: 0;"/&gt;&lt;/p&gt;

&lt;p&gt;Eazfuscator.NET extension for Visual Studio was made with performance in mind. For example, it is activated for obfuscated projects only and never looks at the projects which do not use Eazfuscator.NET. Moreover, it uses only the most efficient data structures, code and algorithms to make your work productive and pleasant.&lt;/p&gt;

&lt;p&gt;Please note that Eazfuscator.NET extension for Visual Studio is optional (though highly recommended). You can remove it from the list of installed components in Eazfuscator.NET Setup or right from Visual Studio:&lt;/p&gt;

&lt;p&gt;&lt;img src="https://cdn.gapotchenko.com/website/blog/2016/06/Eazfuscator.NET%20VS%20Integration%20Setup.png" alt="Eazfuscator.NET Visual Studio Integration Setup" /&gt;&lt;/p&gt;

&lt;p&gt;The presence of Visual Studio extension does not affect the core obfuscation. It works fine with or without the extension.&lt;/p&gt;

&lt;p&gt;Eazfuscator.NET extension for Visual Studio has a minimum requirement of Visual Studio 2015. It does not work with older Visual Studio versions.&lt;/p&gt;

&lt;p&gt;Here is a brief overview of the extension in action: &lt;br /&gt;
&lt;a href="https://www.gapotchenko.com/eazfuscator.net/integration/visual-studio"&gt;www.gapotchenko.com/eazfuscator.net/integration/visual-studio&lt;/a&gt;&lt;/p&gt;</description>
      <pubDate>Thu, 16 Jun 2016 18:18:00 Z</pubDate>
    </item>
    <item>
      <guid isPermaLink="false">efbbcdb6-35ef-44cf-a2aa-63e459c26af8</guid>
      <link>https://blog.gapotchenko.com/eazfuscator.net/resource-sanitization</link>
      <category>Eazfuscator.NET</category>
      <category>Features</category>
      <title>Resource Sanitization</title>
      <description>&lt;p&gt;Eazfuscator.NET 5.3 has been released just a few hours ago, and it brings a particularly useful feature: resource sanitization.&lt;/p&gt;

&lt;p&gt;Say you have the following XML file as an embedded resource of your .NET assembly:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&amp;lt;!--  
  Please thoroughly consult
  https://www.dropbox.com/s/jv1my3n1e0d/GrandPlanOfThings.pdf?dl=0
  before making a change.
--&amp;gt;
&amp;lt;lisp&amp;gt;  
  (define one? (λ (z) (= z 1)))
  ...
&amp;lt;/lisp&amp;gt;  
&lt;/code&gt;&lt;/pre&gt;

&lt;!-- more --&gt;

&lt;p&gt;The given Dropbox link is super helpful for developers who are working on the project. It gives them a valuable contextual hint, improves their productivity and lowers the chance of introducing a bug.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;The only problem is that you probably &lt;strong&gt;don't&lt;/strong&gt; want to share those useful hints with your competitors.&lt;/em&gt; So how to keep the highest productivity level without compromising the security?&lt;/p&gt;

&lt;p&gt;Just add the following obfuscation directive to your assembly:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;[assembly: Obfuscation(Feature = "sanitize resources *.xml", Exclude = false)]
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;and Eazfuscator.NET will sanitize all XML resources of your assembly during obfuscation, rendering the perfect outcome:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&amp;lt;lisp&amp;gt;  
  (define one? (λ (z) (= z 1)))
  ...
&amp;lt;/lisp&amp;gt;  
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;You can configure resource sanitization in &lt;a href="https://learn.gapotchenko.com/eazfuscator.net/docs/sensei-features/resource-sanitization"&gt;a way you like&lt;/a&gt; to meet the specific needs of your project.&lt;/p&gt;</description>
      <pubDate>Thu, 16 Jun 2016 17:00:00 Z</pubDate>
    </item>
  </channel>
</rss>