goupviet / obfuscar

Automatically exported from code.google.com/p/obfuscar
0 stars 0 forks source link

Obfuscated program crashes with exception (sometimes) #37

Open GoogleCodeExporter opened 9 years ago

GoogleCodeExporter commented 9 years ago
What steps will reproduce the problem?
1. run MY program
2. obfuscate it
3. run again

What is the expected output? 
Running program as well as non-obfuscated version.

What do you see instead?
Crash with exception.

What version of the product are you using?
1.5.4

On what operating system?
openSuse 10.3.

Please provide any additional information below.
There are two problems:
a) not always obfuscating my program leads to crash, some previous versions of 
my program were obfuscated correctly
b) it is hard to say what causes crash in obfuscated version, because stack 
trace is also obfuscated

"Sometimes" in summary means, that for given sources compiling and obfuscating 
always will lead to crash, but for some other sources compiling and obfuscating 
will work.

Please let me know how I can be more helpful and make your obfuscator better.

Original issue reported on code.google.com by pilichow...@gmail.com on 10 Jul 2010 at 6:21

GoogleCodeExporter commented 9 years ago
When obfuscating an assembly the names of class types and members are changed. 
Any program that accesses types and members by using the reflection API has to 
be aware of that.
Some .NET components use reflection internally. For example WinForms and WPF 
for data binding and the different data serialization and remoting technologies.
Obfuscar tries to automatically handle a few of the most common pitfalls and 
rewrites the code accordingly. But it is impossible to handle all possible 
cases.
But most of the problems that arise from changed type and member names can 
(with some planning) be easily worked around.

Obfuscar creates a file (Mappings.txt) which allows you to interpret stack 
traces of the obfuscated program.

(One hint: If you try to trick WinForms binding by using reflection to get the 
obfuscated member names, be aware that WinForms binding is case insensitive but 
Obfuscar creates names which can differ only in casing. Such code might work 
initially but can lead to crashes after only minor changes to the code anywhere 
in the assembly.)

Original comment by webbi...@gmail.com on 11 Jul 2010 at 4:35

GoogleCodeExporter commented 9 years ago
Thank you for your answer.

> Any program that accesses types and members by using the 
> reflection API has to be aware of that.

I don't rely on reflection.

> Some .NET components use reflection internally. For example WinForms and 
> WPF for data binding and the different data serialization and remoting 
> technologies.

I don't use WF or WPF, however in fact some lib I use could do it (SharpLibZip 
or Gtk#), but as I understand you don't obfuscate the calls to the libraries?

> Obfuscar creates a file (Mappings.txt) which allows you to interpret 
> stack traces of the obfuscated program.

I missed that somehow, of course, I look into stack trace and try to figure out 
where is the problem.

Original comment by pilichow...@gmail.com on 13 Jul 2010 at 6:24

GoogleCodeExporter commented 9 years ago
Ok, so I found the piece:

IEnumerable<VisualAnswer> result = (from link in links

    group link by new { Text = link.Text(), Meaning = link.meaning } into gr // 1
    group link by new TEST(link.Text(), link.meaning ) into gr               // 2

    select new VisualAnswer(
                      String.Join(", ",gr.Select(it => it.category).ToArray()),
                      Meaning.Merge(gr.Select(it => it.meaning)),
                      gr.Key.Text));

The interesting lines are // 1 and // 2. If you use the 1 piece this code will 
work, but if you try to read result variable (for example convert it ToList(), 
or iterate foreach) program will crash (in obfuscated version).

But I define 100% equivalent of anonymous class:

    public class TEST
    {
        public string Text { get; set; }
        public Meaning Meaning { get; set; }

        public TEST(string t,Meaning m)
        {
            Text = t;
            Meaning = m;
        }

    }

and use line 2 instead of 1, the program will work even in obfuscated version.

So it seems like a bug with obfuscating anonymous class.

Original comment by pilichow...@gmail.com on 15 Jul 2010 at 5:12

GoogleCodeExporter commented 9 years ago
I tried to create a test program based on the code fragments you posted. But it 
worked as expected after obfuscation. (I guess you are using the Mono compiler. 
Therefore it could be possible, although I think it is not very likely, that 
the IL code created by the MS compiler does not trigger the problem you 
described.)

Maybe you could provide me with a small sample program so I can reproduce the 
problem.

Original comment by webbi...@gmail.com on 17 Jul 2010 at 10:07

GoogleCodeExporter commented 9 years ago
Yes, I use Mono.

Sample -- after some work to my surprise, it appeared that such trivial code 
causes crash. Comment as before:

    public class Anon

    {

        public string Text { get; set; }

        public Anon(string t)

        {

            Text = t;

        }

    }

    class MainClass

    {

        public static void Main (string[] args)

        {

            //var test = new { Text = "OK"};

            var test = new Anon("OK");

            Console.WriteLine(test.Text);

        }

    }

Original comment by pilichow...@gmail.com on 20 Jul 2010 at 6:19

GoogleCodeExporter commented 9 years ago
Thank you for the sample code.

I compiled, obfuscated and executed it (with the anonymous class commented in) 
on Windows and on a Debian Lenny (64bit) with Mono 2.6.1 installed.
It worked in both cases with no problems.

On Linux I used gmcs.exe to compile the code, because monodevelop created 
mixed-mode assemblies (why?) which Obfuscar cannot handle.

It seems that this issue might be specific to the version of Mono (i.e. the 
compiler) you are using.

If you like, you can post the un-obfuscated assembly of the above sample. Maybe 
I can find a difference in the IL and check if Obfuscar also breaks the code on 
my machine.

Original comment by webbi...@gmail.com on 21 Jul 2010 at 11:49

GoogleCodeExporter commented 9 years ago
I cut off all the code except for main with anonymous class. So, on my box, it 
runs fine, but once obfuscated it crashes.

Original comment by pilichow...@gmail.com on 21 Jul 2010 at 5:05

Attachments:

GoogleCodeExporter commented 9 years ago
I obfuscated the tester.exe on Windows and Linux and the result works fine on 
both platforms.

Now I am really clueless. Maybe Obfuscar loads an old Cecil library on your 
machine. Or your version of Mono has a problem with the resulting assembly.

I attached the result of my obfuscation run.

Original comment by webbi...@gmail.com on 22 Jul 2010 at 7:38

Attachments:

GoogleCodeExporter commented 9 years ago
Thank you for the binary, it works fine. So it has to be something with 
libraries -- obviously I have to read how to make current dir libs the top 
priority (Mono comes with its libraries).

Sorry for taking your time and thank you for your help!

Original comment by pilichow...@gmail.com on 22 Jul 2010 at 3:24

GoogleCodeExporter commented 9 years ago
This should be marked as Closed.

Original comment by lextu...@gmail.com on 28 Apr 2013 at 7:55