XenocodeRCE / neo-ConfuserEx

Updated ConfuserEX, an open-source, free obfuscator for .NET applications
http://yck1509.github.io/ConfuserEx/
Other
756 stars 89 forks source link

Problem with multilingual .NET application #28

Closed rvalitov closed 5 years ago

rvalitov commented 5 years ago

Describe the bug I have a C# Windows WPF application with multilingual interface. I use a standard approach when the translatable strings are stored in dedicated resource files, one file per language:

image

Then the program sets the current language in constructor of the main form using the following code:

string InterfaceLanguage;
/*
Here goes a routine to load the language from config file
After that we have something like this:
InterfaceLanguage = "en-US";
*/
CultureInfo culture;
try
{
    culture = new CultureInfo(InterfaceLanguage);
}
catch (Exception)
{
    culture = CultureInfo.InvariantCulture;
}
System.Threading.Thread.CurrentThread.CurrentUICulture = culture;
System.Threading.Thread.CurrentThread.CurrentCulture = culture;

Expected behavior The interface of the program matches what is specified in CurrentUICulture. That's how the program works if ConfuserEx is not used. Instead I always see the default interface (specified by file Translations.resx).

ConfuserEx settings

<!-- This configuration file describes the protection applied to the project -->
<project outputDir=".\Confused" baseDir=".\MyProgram\bin\x64\Release" xmlns="http://confuser.codeplex.com">
  <packer id="compressor" />
  <module path="MyProgram.exe" snKey="..\..\..\MyProgram.pfx" snKeyPass="XXX">
    <rule pattern="true" preset="none" inherit="true">
        <protection id="anti debug">
            <argument name="mode" value="antinet" />
        </protection>
        <protection id="anti dump" />
        <protection id="anti ildasm" />
        <protection id="anti tamper">
            <argument name="mode" value="normal" />
            <argument name="key" value="dynamic" />
        </protection>
        <protection id="constants">
            <argument name="mode" value="dynamic" />
            <argument name="decoderCount" value="10" />
            <argument name="elements" value="SPI" />
            <argument name="cfg" value="false" />
        </protection>
        <protection id="ctrl flow">
            <argument name="type" value="switch" />
            <argument name="predicate" value="expression" />        
            <argument name="intensity" value="60" />
            <argument name="depth" value="4" />
            <argument name="junk" value="true" />
        </protection>       
        <protection id="invalid metadata" />
        <protection id="rename">
          <argument name="mode" value="unicode" />
          <argument name="renameArgs" value="false" />
          <argument name="renEnum" value="false" />
          <argument name="flatten" value="false" />
          <argument name="renXaml" value="false" />
        </protection>
        <protection id="ref proxy">
            <argument name="mode" value="mild" />
            <argument name="encoding" value="normal" />
            <argument name="depth" value="8" />
        </protection>       
        <protection id="resources">
            <argument name="mode" value="dynamic" />
        </protection>       
    </rule>
  </module>
  <module path="Helper.dll" snKey="..\..\..\Helper.pfx" snKeyPass="XXX">
    <rule pattern="true" preset="normal" inherit="true">
    </rule>
  </module>
</project>

I tried playing with different options, but it does not help. I get the correct behavior only if I strip everything from the ConfuserEx project file and leave only the simplest basic protections like anti debug.

mkaring commented 5 years ago

Hey, the compressor doesn't handle the satellite assemblies correctly in this version of ConfuserEx. Could you try disabling it and see if that fixes the problem?

rvalitov commented 5 years ago

@mkaring Thanks! But it didn't work. First I tried to remove the line

<packer id="compressor" />

Then I tried to explicitly disable it like that:

<packer id="compressor" action="remove"/>

But the result is the same: the UI language does not change. Any other ideas?

rvalitov commented 5 years ago

I also tried to add a call to CultureInfo.DefaultThreadCurrentUICulture inside the main form's constructor. This call is supposed to set the default UI culture for threads in the current application domain. Unfortunately, this approach does not solve my problem: again the language does not change.

mkaring commented 5 years ago

One very simple test: Could you try adding the localized resource file to the confuser project?

For example:

<module path="de\MyProgram.resources.dll" snKey="..\..\..\MyProgram.pfx" snKeyPass="XXX" />
rvalitov commented 5 years ago

It works!!! 😄 Thank you very much! Should I add all languages in the same way? Or is there any other better solution?

mkaring commented 5 years ago

I fear that is the only way as of right now. You have to add all satellite assemblies this way.

rvalitov commented 5 years ago

Thank you! Ok, will do like that. Do you know if there's any benefits in using the latest build of ConfuserEx instead of the version 1.0? I see there are 33 commits since this release.

mkaring commented 5 years ago

You can always view the diff. I'll leave it to @XenocodeRCE to fill in the details what was changed. :wink: This isn't my fork.

rvalitov commented 5 years ago

Thank you for your support! BTW, I can use the packer again and it works when I add the localized DLLs manually. I also see that some options make the ConfuserEx crash or make the confused app to crash or hang. I suppose that this should be fixed in the master branch, but usually if the release is not published, it means the master branch is not stable and is not safe to use.

mkaring commented 5 years ago

If you find options that cause crashes it would be very helpful if you report them. There're so many different cases that it is difficult to find all of them without reports.

XenocodeRCE commented 5 years ago

Problem with sattelite assemblis is fixed, open a new thread to talk about your crashing output