radtek / obfuscar

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

Mapping file as Xml? #4

Open GoogleCodeExporter opened 8 years ago

GoogleCodeExporter commented 8 years ago
What steps will reproduce the problem?
1. Run Obfuscar.exe
2. Mapping.txt is not in xml format.
3.

What is the expected output? What do you see instead?
I would expect an Xml format. That would make reversing a stack trace so 
much easier. 

What version of the product are you using? On what operating system?
WinXP, Obfuscar 1.0.0.0

Please provide any additional information below.
It would be a nice feature to add to obfuscar if you could reverse a call 
stack trace into original type and method names. You'd parse the call 
stack text based on its default format and perform lookups for all type 
and method names found. If you find it, you replace it, if not, you just 
leave the original call description intact.

Original issue reported on code.google.com by obiwanja...@hotmail.com on 8 May 2007 at 6:20

GoogleCodeExporter commented 8 years ago
What sort of xml would be useful?  Currently, the mapping looks like this:

BasicExampleExe, BasicExampleExe.ExampleUI -> BasicExampleExe, A.A
{
    BasicExampleExe, BasicExampleExe.ExampleUI::Dispose[1]( System.Boolean ) -> Dispose
    BasicExampleExe, BasicExampleExe.ExampleUI::InitializeComponent[0]( ) -> A

    System.ComponentModel.IContainer BasicExampleExe, System.ComponentModel.IContainer
BasicExampleExe.ExampleUI::components -> A
    System.Windows.Forms.Label BasicExampleExe, System.Windows.Forms.Label
BasicExampleExe.ExampleUI::label1 -> A
    System.Windows.Forms.Label BasicExampleExe, System.Windows.Forms.Label
BasicExampleExe.ExampleUI::displayText -> a
}

It wouldn't be difficult to generate an xml document like the following:

<Type assembly="BasicExampleExe" oldName="BasicExampleExe.ExampleUI" 
newName="A.A">
    <Method oldName="Dispose( System.Boolean )" newName="Dispose( System.Boolean )" />
    <Method oldName="InitializeComponent( )" newName="A( )" />
    <Field oldType="System.ComponentModel.IContainer" oldName="components"
        newType="System.ComponentModel.IContainer" newName="A" />
    <Field oldType="System.Windows.Forms.Label" oldName="label1"
        newType="System.Windows.Forms.Label" newName="A" />
    <Field oldType="System.Windows.Forms.Label" oldName="displayText"
        newType="System.Windows.Forms.Label" newName="a" />
</Type>

As for de-obfuscating a stack trace, it's not so simple...trouble is, the 
regular
stack trace doesn't contain enough information to disambiguate the obfuscated
methods; you'll have to walk it and format it in a custom manner.

To demonstrate:  Add code to throw an exception into BasicExample, in the
BasicExampleLibrary.ClassX.DisplayText property getter.  Build it and 
obfuscate. 
When BasicExampleExe is executed, the thrown Exception's StackTrace property 
looks
like the following:

   at A.A.A()
   at A.A..ctor()
   at A.a.A()

It's easy to determine which method threw the exception...if one examines the
Exception's Source or TargetSite properties, it clearly shows that the 
exception was
thrown from BasicExampleLibrary, and a quick glance at the map file shows A() 
in A.A
of BasicExampleLibrary to be ClassX.get_DisplayText.

The second frame is where it gets more interesting, since the regular stack 
trace
formatting doesn't include the assembly where the method lives.  In this case, 
it
shows that the call was made from the constructor for A.A, but there is a class 
A.A
in each assembly, and it does not show _which_ A.A made the call.  We can infer 
that
the call came from BasicExampleExe, since the constructor for class A.A in
BasicExampleExe accepts no parameters (unlike the A.A in BasicExampleLibrary).  
In
this case, we can also infer which assembly is involved with the third frame, 
as the
only method A.a.A that accepts no parameters is in BasicExampleExe.

For a larger project, with more assemblies, it's not that simple.  Given only a 
stack
trace and information about the topmost assembly, it can be very difficult to
determine which other assemblies were involved.  One quickly runs into 
ambiguous calls.

Of course, if you write something to walk the stack, and dump each frame with a 
bit
more information, it becomes a lot easier:

   at BasicExampleLibrary, A.A.A()
   at BasicExampleExe, A.A..ctor()
   at BasicExampleExe, A.a.A()

This provides enough information to de-obfuscate, but getting it dumped is more 
of an
issue.

Original comment by drcfor...@gmail.com on 8 May 2007 at 8:29

GoogleCodeExporter commented 8 years ago
I see your point. Would it be an option to allow each Module to have its 
unique 'id'? For instance Types in the first Module will be obfuscated to A.?, 
the 
second to a.? and so on. You know what modules need to be obfuscated (in the 
settings file), so you can assign each module its unique 'namespace' 
identifier, 
also identifying the assembly.

I'm not aware of any standards for the xml format, but I can imagine that all 
obfusctators sort of output the same information in their map-file. So maybe we 
can 'get inspired' by looking at how other people did it? ;-)

Original comment by obiwanja...@hotmail.com on 13 May 2007 at 10:29

GoogleCodeExporter commented 8 years ago
Rather than a unique namespace per module, how about an option to give each 
thing a
unique name?  XenoCode does it that way...they use a reversible obfuscation 
where
each type/method gets a name like 'x63e1466b8d1d6e65' (I think it's generated 
as a
hash from the original full name).  It's nonunique, which would make reverse
engineering a little easier, but still better than the original code.

I'm not sure there is a standard for the xml...The mapping file generated by
RemoteSoft's obfuscator looks kinda like the one we currently generate, and the 
one
generated by XenoCode's obfuscator is basically a giant list of "MapEntry" 
elements,
like the following:

  <MapEntry Name="SuperMethodX" Value="x63e1466b8d1d6e65" />
  <MapEntry Name="TypeNameZ" Value="xabba5f18d6ef0c47" />
  <MapEntry Name="PropertyW" Value="x75ab358b19f79049" />

But they can get away with that because their names are all unique.

Original comment by drcfor...@gmail.com on 14 May 2007 at 2:07

GoogleCodeExporter commented 8 years ago
I think the structure of your mapping file is okay. Why don't we put that in 
Xml 
first and go from there. Then together with allowing each module to have a 
unique 'name' (an extra attribute on the Module tag in the settings file?) I 
think 
we can then reverse stack traces.

Original comment by obiwanja...@hotmail.com on 15 May 2007 at 5:29

GoogleCodeExporter commented 8 years ago
I broke the unique / reversible naming issue into a separate issue, see
http://code.google.com/p/obfuscar/issues/detail?id=5.

Original comment by drcfor...@gmail.com on 15 May 2007 at 12:55

GoogleCodeExporter commented 8 years ago

Original comment by drcfor...@gmail.com on 15 May 2007 at 12:56

GoogleCodeExporter commented 8 years ago
[deleted comment]
GoogleCodeExporter commented 8 years ago
Can obsfucar scramble the method logic?
Can it use unicode name for types?

Original comment by Maurya.A...@gmail.com on 23 Sep 2008 at 8:30

GoogleCodeExporter commented 8 years ago
It doesn't do anything with the method logic, it only modifies metadata.  My
understanding is that all the metadata is unicode.

Original comment by drcfor...@gmail.com on 24 Sep 2008 at 2:06

GoogleCodeExporter commented 8 years ago
This should mark as Closed.

Original comment by lextu...@gmail.com on 29 Apr 2013 at 10:49