Artykuł

freeimages.com freeimages.com
lis 08 2016
0

ILSpy - podgląd assembly i dekompilacja kodu

Czasem chcielibyśmy sprawdzić szczegóły techniczne wybranego Assembly, bądź też nawet fragmenty kodu źródłowego, które wspomniany zasób zawiera. Przyczyny takiego stanu rzeczy bywają różne. Najczęściej chcemy się upewnić, że wdrożony kod, to rzeczywiście ten którego oczekujemy, bądź też chcemy podejrzeć kod używanej przez nas biblioteki, w sytuacji w której brakuje nam dokumentacji.

Okazuje się, że w świecie .netowym jest to jak najbardziej wykonalne. Wystarczy tylko odpowiednie narzędzie i DLLka, która nie przeszła procesu obfuskacji.. W .Net standardowo obfuskacja jest wyłączona, dlatego też bardzo łatwo zdekompilować kod IL zawarty w DLLce/pliku exe do kodu, który będzie wyglądać prawie jak oryginał. Do szczęścia potrzebne jest tylko odpowiednie narzędzie - np. opensource'owa aplikacja ILSpy.

ILSpy

ILSpy jest bardzo prostą aplikacją, której główną funkcjonalnością jest opcja podglądania załadowanego Assembly oraz dekompilacja kodu IL. Bardzo fajnym dodatkiem jest w tym przypadku możliwość wczytania wszystkich zależnych assembly.

Po załadowaniu Assembly możemy sprawdzić podstawowe jej właściwości.

Jeszcze ciekawiej dzieje się, w momencie gdy zaczniemy rozwijać strukturę drzewiastą biblioteki. Znajdziemy tutaj kolejne namespace'y, a wewnątrz nich klasy.. i inne utworzone struktury. Oczywiście tak jak wspominałem wyżej, nawet w przypadku wyłączonej obfuskacji, kod nie będzie wyglądał w 100% tak jak ten wyjściowy, ale na pewno pozwoli nam zorientować co się w danym miejscu dzieje.

Poniżej oryginalna klasa Startup z przykładowego projektu Web.Api wykorzystującego OWINa:

using Dentist.WebApi.App_Start;
using Dentist.WebApi.Infrastructure;
using Microsoft.Owin;
using Ninject.Web.Common.OwinHost;
using Ninject.Web.WebApi.OwinHost;
using Owin;
using System.Web.Http;
using System.Web.Http.Cors;
using System.Web.Http.Tracing;


[assembly: OwinStartup(typeof(Dentist.WebApi.Startup))]

namespace Dentist.WebApi
{
    /// <summary>
    /// Startup module for OWIN
    /// </summary>
    public class Startup
    {
        /// <summary>
        /// OWIN configuration entry point
        /// </summary>
        /// <param name="app">IAppBuilder object reference</param>
        public void Configuration(IAppBuilder app)
        {
            GlobalConfiguration.Configuration.Services.Replace(typeof(ITraceWriter), new NLogger());

            var config = new HttpConfiguration();
            var cors = new EnableCorsAttribute("*", "*", "*");
            config.EnableCors(cors);

            WebApiConfig.Register(config);
            SwaggerConfig.Register(config);

            app.UseAuth();
            app.UseNinjectMiddleware(() => NinjectConfig.CreateKernel.Value);
            app.UseNinjectWebApi(config);
        }
    }
}

Oraz jej wersja odczytana za pomocą ILSpy:

using Dentist.WebApi.App_Start;
using Dentist.WebApi.Infrastructure;
using Ninject;
using Ninject.Web.Common.OwinHost;
using Ninject.Web.WebApi.OwinHost;
using Owin;
using System;
using System.Runtime.CompilerServices;
using System.Web.Http;
using System.Web.Http.Cors;
using System.Web.Http.Tracing;

namespace Dentist.WebApi
{
	/// <summary>
	/// Startup module for OWIN
	/// </summary>
	public class Startup
	{
		[CompilerGenerated]
		[Serializable]
		private sealed class <>c
		{
			public static readonly Startup.<>c <>9 = new Startup.<>c();

			public static Func<IKernel> <>9__0_0;

			internal IKernel <Configuration>b__0_0()
			{
				return NinjectConfig.CreateKernel.Value;
			}
		}

		/// <summary>
		/// OWIN configuration entry point
		/// </summary>
		/// <param name="app">IAppBuilder object reference</param>
		public void Configuration(IAppBuilder app)
		{
			GlobalConfiguration.Configuration.Services.Replace(typeof(ITraceWriter), new NLogger());
			HttpConfiguration config = new HttpConfiguration();
			EnableCorsAttribute cors = new EnableCorsAttribute("*", "*", "*");
			config.EnableCors(cors);
			WebApiConfig.Register(config);
			SwaggerConfig.Register(config);
			app.UseAuth();
			Func<IKernel> arg_78_1;
			if ((arg_78_1 = Startup.<>c.<>9__0_0) == null)
			{
				arg_78_1 = (Startup.<>c.<>9__0_0 = new Func<IKernel>(Startup.<>c.<>9.<Configuration>b__0_0));
			}
			app.UseNinjectMiddleware(arg_78_1);
			app.UseNinjectWebApi(config);
		}
	}
}

Jest tutaj kilka zauważalnych różnic, ale dotyczą one przede wszystkim zapisu poszczególnych konstrukcji. W moim odczuciu można jednak bardzo łatwo przeanalizować co się w określonym miejscu dzieje.

Podoba Ci się ten wpis? Powiedz o tym innym!

Send to Kindle

Komentarze

blog comments powered by Disqus