TypeLoadException after using obfuscar

230 views
Skip to first unread message

twostepted

unread,
Jan 23, 2008, 6:23:42 AM1/23/08
to obfuscar
I'm getting this exception after using obfuscar:
System.TypeLoadException: A type load exception has occurred. I'm
running obfuscar on fedora 8 with mono 1.2.5. The assembly is build
with mcs on the same and uses only 1.1 language features (no generics,
etc.). I'm not using reflection and just wondering if there are any
other common pitfalls which might cause this? I don't have a simple
test case to provide yet.

Regards,

Travis

Ryan Williams

unread,
Jan 23, 2008, 8:55:42 AM1/23/08
to obfu...@googlegroups.com
I can't immediately think of something that could cause that. Can you
provide a stack trace or other information?

twostepted

unread,
Jan 24, 2008, 3:53:39 AM1/24/08
to obfuscar
This is the stack trace from the exception:
System.TypeLoadException: A type load exception has occurred.
at <0x00000> <unknown method>
at A.f.A (A.E A, A.A a) [0x00000]
at A.f..ctor (A.E A, A.A a) [0x00000]
at A.g.A (System.String A, System.String a) [0x00000]
at A.g.b () [0x00000]

Ryan Williams

unread,
Jan 24, 2008, 10:29:10 AM1/24/08
to obfu...@googlegroups.com
Oh, it's not an exception from obfuscar, it's from something you obfuscated?

Look at your mapping file, and find the method that was obfuscated
into "A.f.A (A.E A, A.A a)". Look over the source code for the
method...it may using a type whose assembly is used for the first time
at that point in your code, and failing to find that type within it.
Unless you're doing something fancy with reflection, it's probably
because either the assembly containing the missing type isn't the same
one obfuscated with the calling code, or because of a bug in the
obfuscation tool.

twostepted

unread,
Jan 24, 2008, 3:03:15 PM1/24/08
to obfuscar
Sorry if I didn't make it clear, yes the exception came from an
assembly I had obfuscated with obfuscar, not from obfuscar itself.

After looking at the mapping.txt file and also looking at my
obfuscated assembly with reflector, its clear to me that the method
A.f.A(A.E, A.A) is actually a method who'se signature is init(Config,
XmlLogFile). I can see that there is no reflection being used and
that there are no types from other assemblies being referenced in the
remainder of the init() method. I thought that the error might have
been caused by the fact that XmlLogFile resides in a seperate
assembly, and so I included it in the obfuscation (by including it as
a Module in my obfuscar.xml configuration file). However this had no
effect. Maybe this is a bug? Is there any other information that I
can provide to help understand whats going on?

Thanks for you help.

Travis

On Jan 24, 10:29 am, "Ryan Williams" <drcfor...@gmail.com> wrote:
> Oh, it's not an exception from obfuscar, it's from something you obfuscated?
>
> Look at your mapping file, and find the method that was obfuscated
> into "A.f.A (A.E A, A.A a)". Look over the source code for the
> method...it may using a type whose assembly is used for the first time
> at that point in your code, and failing to find that type within it.
> Unless you're doing something fancy with reflection, it's probably
> because either the assembly containing the missing type isn't the same
> one obfuscated with the calling code, or because of a bug in the
> obfuscation tool.
>

Ryan Williams

unread,
Jan 25, 2008, 10:01:12 AM1/25/08
to obfu...@googlegroups.com
Using Reflector and the mapping file will be the best way to resolve
this...check that method (A.f.A(A.E, A.A) ) in your obfuscated
assembly, and try to resolve all the types involved (A.E, A.A, and
other types used in the method). Make sure that you can manually load
the assembly that would be loaded at runtime, that you can find the
type, and check the mapping file to make sure it's really the type
your code expects.

Is it possible you're mixing obfuscated and non-obfuscated assemblies?

If you have two assemblies, say MainAssembly and DependencyAssembly,
where MainAssembly is dependent on classes in DependencyAssembly, and
you include both of them in your config file, both will be obfuscated.
If at runtime, you have an obfuscated MainAssembly trying to load
types from a non-obfuscated DependencyAssembly, you could see this
issue.

twostepted

unread,
Jan 27, 2008, 11:29:19 AM1/27/08
to obfuscar
Ryan,

Thanks again for your help. I don't believe that I'm mixing
obfuscated and non-obfuscated assemblies accidentally. I'm still
trying to figure out whats going on with this. I'm wondering if you
can comment on what I'm noticing when I look at my obfuscated assembly
with Reflector. When I use Reflector to open up the method in
question (A.f.A(A.E, A.A) ) in the obfuscated version of MainAssembly
for the first time, it says "The following assembly name cannot be
resolved automatically: DependencyAssembly...". DependencyAssembly is
also obfuscated and exists in the same directory as MainAssembly.
After I tell Reflector the path to DependencyAssembly, everything if
fine.

Would you expect Reflector to ask for a path to DependencyAssembly in
all situations? Does this reveal my problem?

Ryan Williams

unread,
Jan 28, 2008, 9:03:52 AM1/28/08
to obfu...@googlegroups.com
Reflector would ask you for the path, but the default value should be
correct (i.e., you shouldn't have to browse or edit the default path /
filename, just hitting 'ok' should work).

From your earlier error message, it sounds like it's not failing to
find the assembly, just failing to find and load a type within
it...can you find them when looking with reflector?

Would it be possible to put together a minimal example that reproduces
the problem? Possibly extracting these classes or methods into
separate assemblies, changing the names, and removing proprietary
code? Without seeing some failing code or assemblies, I'm not sure
that I can help much.

twostepted

unread,
Jan 29, 2008, 2:23:48 PM1/29/08
to obfuscar
> From your earlier error message, it sounds like it's not failing to
> find the assembly, just failing to find and load a type within
> it...can you find them when looking with reflector?

As far as I can tell, reflector is able to load most of the types
within my obfuscated assembly. However, I've had it crash when trying
to look at some of the types in question.

I'll see what I can do to produce a minimal test case.

twostepted

unread,
Jan 29, 2008, 3:39:59 PM1/29/08
to obfuscar
Ryan,

My minimal test case doesn't produce the same type load error after
obfuscating. I can send you the original assembly if that would
help. Or let me know if there is anything else I can provide.

Ryan Williams

unread,
Jan 30, 2008, 1:09:44 PM1/30/08
to Travis S, obfu...@googlegroups.com
(posted to the list, in case someone else needs to debug something
like this and wants to see the process)

I was able to reproduce the problem you had, and made some progress
towards debugging it.

First, I made sure that the problem wasn't Mono.Cecil, by forcing
obfuscar to load and save the assemblies with no obfuscation...problem
went away, meaning Cecil isn't broken (I didn't expect it to be, but
it's an easy test).

I removed assemblies, one at a time from the obfuscar config, making
sure the problem occurred...narrowing it down until the problem could
be reproduced by obfuscating a single assembly.

Then, I turned off obfuscation of all types (<SkipType name="*" />),
and the problem still happened...so it's not the type renaming. I
turned off method renaming (<SkipMethod type="*" rx=".*" />)...problem
went away, meaning it's a problem with method renaming.

To narrow down which type(s) were causing problems, I skipped methods
in sets of types to see when the problem would or wouldn't occur.
Skipping methods in types whose names were A through P (<SkipMethod
type="^SomeNameSpace\.[A-P].*" rx=".*" />, namespace changed to
protect the innocent) still showed the problem, but skipping methods
in types whose names were A through R (<SkipMethod
type="^SomeNameSpace\.[A-R].*" rx=".*" />) did not. Skipping just the
methods in types beginning with R (<SkipMethod
type="^SomeNameSpace\.R.*" rx=".*" />) still had the problem, meaning
that the problem involves renaming methods in types beginning with R,
and renaming methods in types beginning with another letter.

Slicing the set of renamed methods, I narrowed it down to being able
to fix the problem by skipping the methods in two classes, then
narrowed it further to being able to fix the problem by skipping a
specific method in each class.

i.e., narrowed it down so that the problem goes away by adding
something like the following:

<SkipMethod type="SomeNameSpace.AwesomeClass" rx="set_SomeProperty" />
<SkipMethod type="SomeNameSpace.RegularClass" rx="set_SomeProperty" />


It looks like there's a problem where the the property setters of the
two properties should be obfuscated to the same name, but because
obfuscar can't tell they're related, they get different names and no
longer match up. I can't immediately tell how they're related (from
reflector, it doesn't look like a base/descendant relation), and I'd
rather not spend time reverse engineering / debugging the assemblies
to work it out. It should be possible with your knowledge of the
source to work it out and make a test case for fixing obfuscar, but in
the mean time, skipping the two methods fixes it.

Reply all
Reply to author
Forward
0 new messages