SmartAssembly obfuscates public type - c#

When I obfuscate this form, and "debug" it
public partial class Form1 : Form
{
public void Form1()
{
InitializeComponents();
}
protected override void OnShown(EventArgs e)
{
base.OnShown(e);
Console.WriteLine("Name: "+this.Name);
Console.WriteLine("FullName: "+this.GetType().FullName);
}
}
The output is like this:
Name: Form1
FullName: #Yab.#Zab
Question
Why is FullName obfuscated?
Form1 is public so I would expect SmartAssembly to ignore it.
Extra info
Form1 is public partial and so is the designer.cs
My SmartAssembly setup is like this:
<ApplicationName />
<Destination DestinationFileName=".\bin.obfuscated\MyProject.Form1.exe" />
<Assemblies>
<Assembly AssemblyName="MyProject.Form1, Culture=neutral, PublicKeyToken=omitted">
<Merging>
<ResourcesCompression Compress="0" />
<MemberRefsProxy />
<Pruning />
<Obfuscation Obfuscate="1">
<Exclusions />
</Obfuscation>
<ControlFlow Obfuscate="1" />
</Merging>
</Assembly>
</Assemblies>
<Options>
<Obfuscation FieldsNameMangling="2" NameMangling="1" />
<ExceptionReporting />
<FeatureUsageReporting Template="res:SmartUsageWithUIConsentFirstRun1033.dll" />
<StrongNameSigning KeyFileName="PathToKeyFile" Sign="1" />
<OtherProtections />
<StringsEncoding />
<OtherOptimizations />
<Debugging />
</Options>

Firstly, a public class isn't ignored by SmartAssembly in an application project (it will be ignored in a library project).
Secondly, the Name property of your form is a property set at runtime. In your case case, it may be initialized to "Form1" somewhere in your code, maybe in the designer.
This value can be changed anytime, example :
public Form1()
{
InitializeComponent();
this.Name = "foo";
}
So SmartAssembly cannot obfuscate this value, it would be wrong and would change the behavior of your code.
When SmartAssembly obfuscates your code, it only changes the names of the types, fields and methods. When your try to get the name of your type, it's logical to get the obfuscated name of your type.

Related

Setting up etw logs in azure table with mvc

Spent more than 4 hours trying to figure out why etw logs wont show up in my tables. I still am unable to figure out why my logs are not showing up in azure table.
EDIT
The service is hosted as cloud service.
Here is how my diagnostics xml looks like. This is auto generated by selecting options in visual studio
<?xml version="1.0" encoding="utf-8"?>
<DiagnosticsConfiguration xmlns="http://schemas.microsoft.com/ServiceHosting/2010/10/DiagnosticsConfiguration">
<PublicConfig xmlns="http://schemas.microsoft.com/ServiceHosting/2010/10/DiagnosticsConfiguration">
<WadCfg>
<DiagnosticMonitorConfiguration overallQuotaInMB="4096">
<EtwProviders>
<EtwEventSourceProviderConfiguration provider="AzureEventSource">
<Event id="1" eventDestination="Error" />
<Event id="2" eventDestination="Warning" />
<Event id="3" eventDestination="Debug" />
<Event id="4" eventDestination="Performance" />
<DefaultEvents eventDestination="Default" />
</EtwEventSourceProviderConfiguration>
</EtwProviders>
<Logs scheduledTransferPeriod="PT2M" />
</DiagnosticMonitorConfiguration>
</WadCfg>
<StorageAccount />
</PublicConfig>
<PrivateConfig xmlns="http://schemas.microsoft.com/ServiceHosting/2010/10/DiagnosticsConfiguration">
<StorageAccount endpoint="" />
</PrivateConfig>
<IsEnabled>true</IsEnabled>
</DiagnosticsConfiguration>
This is how my class looks like
using Microsoft.Diagnostics.Tracing;
namespace CommonUtils
internal sealed class AzureEventSource : EventSource, ILogger
{
public AzureEventSource(Type owner) : base(owner.FullName)
{
}
private bool IsInputInvalid(String message)
{
return String.IsNullOrWhiteSpace(message);
}
public void Error(string message, params object[] args)
{
if (IsInputInvalid(message))
{
throw new ArgumentNullException("message");
}
this.WriteEvent(1, string.Format(message, args));
}
}
}
I am pretty sure I am missing something simple.
Any help will be greatly appreciated
Assuming you're referring to Microsoft.Diagnostics.Tracing.EventSource in your above example.
You're missing EventSource Event attributes for your class and method respectively.
A simple hello world of eventsource looks like this.
[EventSource(Name = "HelloEventSource")]
internal sealed class HelloEventSource : EventSource
{
[Event(1, Level = EventLevel.Informational, Message = "Hello World! {0}")]
public void HelloWorld(string name)
{
WriteEvent(1, name);
}
}
You should fix the tracing part of your code and check the logs are getting generated locally on your machine/vm.
Sending the events via diagnostics pipeline of your choice comes next.

Unity configuration with inheritance

I have a simple structure of classes, interfaces as follows:
public interface IMessagingClient (interface supporting service bus queue operation)
public class ServiceBusMessagingClient : IMessagingClient (real implementation)
public class MockMessagingClient : IMessagingClient (mock implementation for our unit test)
public class FailoverMessagingClient : IMessagingClient (this implementation internally uses 2 clients and switches roles b/w 2 as and when disaster in a datacenter occur)
{
private IMessagingClient PrimaryClient { get; set; }
private IMessagingClient SecondaryClient { get; set; }
}
We load unity config from web.config/app.config and use it in our product code and test code.
We want following:
For production scenario, PrimaryClient and SecondaryClient should of type ServiceBusMessagingClient
For Test scenario, PrimaryClient and SecondaryClient should of type MockMessagingClient
Our current unity config looks like:
<container name="azure">
<register type="IMessagingClient" mapTo="FailoverMessagingClient"/>
</container>
Do we have to use some interceptors to achieve this? Or by defining a ctor in FailoverMessagingClient and using ctor injection?
Some suggestions would be great!
You can do this using named registrations.
For example, given the following example set up:
namespace ConsoleApplication8
{
using Microsoft.Practices.Unity;
using Microsoft.Practices.Unity.Configuration;
public interface IMessagingClient { }
public class ServiceBusMessagingClient : IMessagingClient { }
public class MockMessagingClient : IMessagingClient { }
public class FailoverMessagingClient : IMessagingClient
{
private readonly IMessagingClient primaryClient;
private readonly IMessagingClient secondaryClient;
public FailoverMessagingClient(IMessagingClient primaryClient, IMessagingClient secondaryClient)
{
this.primaryClient = primaryClient;
this.secondaryClient = secondaryClient;
}
}
class Program
{
static void Main(string[] args)
{
var container = new UnityContainer().LoadConfiguration();
var failOverMessagingClient = container.Resolve<IMessagingClient>("Two");
}
}
}
you can hook up the dependencies using the app.config
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<configSections>
<section name="unity" type="Microsoft.Practices.Unity.Configuration.UnityConfigurationSection, Microsoft.Practices.Unity.Configuration"/>
</configSections>
<unity xmlns="http://schemas.microsoft.com/practices/2010/unity">
<alias alias="IMessagingClient" type="ConsoleApplication8.IMessagingClient, ConsoleApplication8" />
<alias alias="ServiceBusMessagingClient" type="ConsoleApplication8.ServiceBusMessagingClient, ConsoleApplication8" />
<alias alias="MockMessagingClient" type="ConsoleApplication8.MockMessagingClient, ConsoleApplication8" />
<alias alias="FailoverMessagingClient" type="ConsoleApplication8.FailoverMessagingClient, ConsoleApplication8" />
<container>
<register type="IMessagingClient" name="One" mapTo="ServiceBusMessagingClient" />
<register type="IMessagingClient" name="Two" mapTo="FailoverMessagingClient">
<constructor>
<param name="primaryClient">
<dependency type="IMessagingClient" name="One" />
</param>
<param name="secondaryClient">
<dependency type="IMessagingClient" name="One" />
</param>
</constructor>
</register>
</container>
</unity>
</configuration>
Changing the line
<register type="IMessagingClient" name="One" mapTo="ServiceBusMessagingClient" />
to
<register type="IMessagingClient" name="One" mapTo="MockMessagingClient" />
will allow you to swap out your implementation of IMessagingClient as appropriate.
Personally, I would rather do this using the fluid syntax
var container = new UnityContainer();
container.RegisterType<IMessagingClient, ServiceBusMessagingClient>("One");
container.RegisterType<IMessagingClient, FailoverMessagingClient>("Two",
new InjectionConstructor(new ResolvedParameter<IMessagingClient>("One"), new ResolvedParameter<IMessagingClient>("One")));
var failOverMessagingClient = container.Resolve<IMessagingClient>("Two");
When using the unity container, you can override an existing registration by registering it again for a different class.
For example:
If you run this code:
container.RegisterType<IMessagingClient, ServiceBusMessagingClient>();
container.RegisterType<IMessagingClient, MockMessagingClient>();
The first registration is overridden and so IMessagingClient is mapped to MockMessagingClient. Its like the first line never executed.
You can use this fact, and in your unit test (in the arrange phase or in the setup method of your test class), simply register the IMessagingClient to the mock implementation like this (after loading the XML configuration):
container.RegisterType<IMessagingClient, MockMessagingClient>();
By the way, you might not want to use DI containers in unit tests. Take a look at this question.

An unhandled exception of type 'System.IO.FileNotFoundException' - Dll & remoting

I'm trying to make a game of Nim where the logic takes place on a server and a client presents the game to get better at .NET Remoting.
I have a dll I built from this class library:
namespace Nim_Common
{
public interface computerCommon
{
int[] startGame(int columnNumber);
int[] computeTurn(int[] penStatus);
bool checkWin();
}
}
That dll I add as a reference to my client project and my server project, and add the dll to the bin/Debug directory in each project.
This is the relevant part of my client code:
using Nim_Common;
namespace Nim
{
public partial class Form1 : Form
{
private computerCommon computerServerHandler;
...
public Form1()
{
InitializeComponent();
computerToolStripMenuItem.Select();
newColumnNumber = -1;
RemotingConfiguration.Configure("client.exe.config");
computerServerHandler = (computerCommon)Activator.GetObject(typeof(computerCommon), "http://localhost:1234/_Server_");
StartGame(this, null);
}
private void StartGame(object sender, EventArgs e)
{
int max = 0;
if(columns != null)
for (int i = 0; i < columns.Length; i++) Controls.Remove(columns[i]);
int[] temp = computerServerHandler.startGame(newColumnNumber);
columns = new Column[temp.Length];
...
}
And in the server part:
using Nim_Common;
namespace Nim_Server
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
RemotingConfiguration.Configure("server.exe.config");
}
}
class ServerPart : MarshalByRefObject, computerCommon
{
...
public ServerPart()
{
...
}
public int[] startGame(int columnNumber)
{
...
}
public int[] computeTurn(int[] penStatus)
{
...
}
public bool checkWin()
{
...
}
}
}
server.exe.config:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
</startup>
<system.runtime.remoting>
<application>
<channels>
<channel ref="http server" port="1234" />
</channels>
<service>
<wellknown mode ="SingleCall" type="Nim_Server.ServerPart, Nim_Server" objectUri="_Server_" />
</service>
</application>
</system.runtime.remoting>
</configuration>
client.exe.config:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
</startup>
<system.runtime.remoting>
<application>
<channels>
<channel ref="http client" />
</channels>
<client>
<wellknown type="Nim_Common.computerCommon, Nim_Common" url="http://localhost:1234" />
</client>
</application>
</system.runtime.remoting>
</configuration>
My firewall is off if that matters.
Everything is fine in compile time, the server runs fine. When the client reaches this line, it throws the exception:
int[] temp = computerServerHandler.startGame(newColumnNumber);
The exception is something like:
An unhandled exception of type 'System.IO.FileNotFoundException' occurred in mscorlib.dll
Additional information: Could not load file or one of its dependencies, the system could not find "Nim_Common". // This is shown in my native language so I'm improvising a bit with the translation.
What is going on and how do I fix this?
Thanks.
I was receiving this error from one of my own compiled dlls. It turns out I had filled in the AssemblyCultureAttribute in my AssemblyInfo.cs file. The project built without issue but would not load in any referenced projects when used.
According to msdn :
Putting this attribute on an assembly and using something other than the empty string ("") for the culture name will make this assembly look like a satellite assembly, rather than a main assembly that contains executable code. Labeling a traditional code library with this attribute will break it, because no other code will be able to find the library's entry points at runtime.

How to store custom data in web.config?

I have the following method in my apiController:
public IEnumerable<something> GetData(DataProvider dataProvider)
{
return dataProvider.GetData();
}
What I need is to invoke this method from javascript and pass it a parameter of DataProvider derived type. I can handle this by passing string, e.g. "FirstProvider" and than write N number of if's in GetData() method to create an instance of proper type.
But is there some way that I can write in web.config file something like:
<DataProviders>
<type = FirstDataProvider, alias = "FirstProvider">
<type = SecondDataProvider, alias = "SecondProvider">
</DataProviders>
Change getData method to:
public IEnumerable<something> GetData(string dataProviderAlias)
{
// get provider type by it's alias from web congfig,
// then instantiated and call:
return dataProvider.GetData();
}
And then find and instantiate the type by it's alias?
Note: I accepted the answer below cause it's pointed me in a right direction, but msdn says that IConfigurationSectionHandler is deprecated.
So I used ConfigurationSection, ConfigurationElementCollection, ConfigurationElement classes instead to build custom config section.
You can store arbitrary data in web.config in the appSettings element:
<configuration>
<appSettings>
<add key="FirstAlias" value="FirstProvider" />
<add key="SecondAlias" value="SecondProvider" />
</appSettings>
</configuration>
And you can then read the values using:
String firstAlias = System.Configuration.ConfigurationManager.AppSettings["FirstAlias"];
String secondAlias = System.Configuration.ConfigurationManager.AppSettings["SecondAlias"];
It's built-in. It's supported. It's where you're supposed to store custom data.
First of all, you can only store valid xml in web.config. <type = FirstDataProvider, alias = "FirstProvider"> is not valid xml.
Second, there are a lot of moving pieces. Please follow the steps carefully -
web.config
Make sure you enter the proper namespace for DataProviders. type="YOUR_APPLICATION.DataProviders".
<configuration>
<configSections>
<section name="DataProviders" type="WebApplication2010.DataProviders"
requirePermission="false"/>
</configSections>
<DataProviders>
<Provider type="FirstDataProvider" alias="FirstProvider"/>
<Provider type="SecondDataProvider" alias="SecondProvider"/>
</DataProviders>
....
</configuration>
Code
public class DataProviders : IConfigurationSectionHandler
{
private static bool _initialized;
public static List<Provider> _providers;
public object Create(object parent, object configContext, XmlNode section)
{
XmlNodeList providers = section.SelectNodes("Provider");
_providers = new List<Provider>();
foreach (XmlNode provider in providers)
{
_providers.Add(new Provider
{
Type = provider.Attributes["type"].Value,
Alias = provider.Attributes["alias"].Value,
});
}
return null;
}
public static void Init()
{
if (!_initialized)
{
ConfigurationManager.GetSection("DataProviders");
_initialized = true;
}
}
public static IEnumerable<Provider> GetData(string dataProviderAlias)
{
return _providers.Where(p => p.Alias == dataProviderAlias);
}
}
public class Provider
{
public string Type { get; set; }
public string Alias { get; set; }
}
Global.asax
For good design practice, you want to read data from web.config only once, and store them in static variables. Therefore, you want to initialize inside Application_BeginRequest of Global.asax.
public class Global : System.Web.HttpApplication
{
void Application_BeginRequest(object sender, EventArgs e)
{
DataProviders.Init();
}
}
Usage
var providers = DataProviders.GetData("FirstProvider").ToList();
Well, I'm not sure if I understand what you want to achieve, but to implement your idea you need a custom section handler.
http://msdn.microsoft.com/en-us/library/2tw134k3(v=vs.100).aspx
In case that you want to create a database connection for specific dataprovider, see this similar question:
ASP.NET: How to create a connection from a web.config ConnectionString?
In my case, I needed to store two byte[] variables in my Web.Config file. Since it must be valid XML data, I simply stored the contents of the arrays like so:
<appSettings>
<add key="Array1" value="0,1,2,3,4,5,6,7,8,9" />
<add key="Array2" value="0,1,2,3,4,5,6,7,8,9" />
</appSettings>
I then call a function that reads this into a C# string, split it into a string[], and parse each string element as a byte into a resulting byte[] and return it.

Add a element in a non static object from a static method?

I know how to use nlog to log my information in a file but now I would like to redirect my log to a ListView (C#) and do some actions. So I directed my log to a method as explained in the documentation nlog. It works.
<?xml version="1.0" ?>
<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<targets>
<target name="msgbox" xsi:type="MethodCall" className="SomeNamespace.MyClass, MyAssembly" methodName="LogMethod">
<parameter layout="${level}" />
<parameter layout="${message}" />
</target>
</targets>
<rules>
<logger name="*" minlevel="Debug" writeTo="msgbox" />
</rules>
</nlog>
Console.WriteLine works. It's not my problem.
namespace SomeNamespace
{
using System;
public class MyClass
{
public static void LogMethod(string level, string message)
{
Console.WriteLine("l: {0} m: {1}", level, message);
// logListView.Items.Add(Message);
// Do some other actions
}
}
}
I would like to add a line to my logListView (see commented line) but I can't because logListView is not static. How so? How do I proceed ?
One solution would be to add a static member to MyClass, like this:
public class MyClass
{
public static ListView MyListView { get; set; }
public static void LogMethod(string level, string message)
{
Console.WriteLine("l: {0} m: {1}", level, message);
var logListView = MyListView;
if (logListView != null) {
logListView.Items.Add(Message);
}
// Do some other actions
}
}
You can set the value of MyListView from some other part of your application when it is available.
While this solution would work, I would not prefer it because it is counter-intuitive. What you are doing here is declaring in static configuration a log target that is not meaningful at all in a static context: you want to log to a UI control that has not been created, there is no good way to refer to it until the application's UI has been shown, and the UI will be shown at some point or (academically speaking) maybe not at all.
I believe it is preferable to create your own log target class deriving from Target or TargetWithLayout. You can pass any parameters necessary (e.g. the ListView instance) to the log target's constructor, and add the log target programmatically at the point where the values of these parameters become known (i.e. the UI is shown and we have a ListView we can refer to).

Categories