如何在一个程序集中引用另一个程序集Resource的问题

  今天在公司看一个软件注册验证机制,由于没有源代码,只能通过反编译工具看了。当看到下边这段代码的时候,就觉得有点奇怪。
                Assembly assembly = Assembly. Load (Resource.Register);
                object obj = assembly. CreateInstance ("DCommon.Register" );
                Type type = obj. GetType ();
                MethodInfo method = type. GetMethod ("Register" );

  什么情况,反射我是见过的,但貌似没见过反射Resource里的东西,请教了一下老大,原来是有些软件为了防止别人看到它的代码,就把它编成一个DLL,然后做为项目资源文件,添加到主程序的资源中。这样做的好处是你没办法看到它的源代码。老大说这种情况要想看它的原代码,就只有想办法把Resource中的内容读出来,写到一个文件中,就可以还原出原来的类库了。思路有了,具体怎么操作,还得我自己想办法。
  我首先想到的是能不能找到一种方法将它的私有属性调出来,在网上搜索到了如下代码,可以在没有代码的情况下,直接读取和修改它的私有属性、字段。

public static class PrivateExtension
    {
        public static T GetPrivateField <T >( this object instance , string fieldname )
        {
            BindingFlags flag = BindingFlags. Instance | BindingFlags . NonPublic;
            Type type = instance. GetType ();
            FieldInfo field = type. GetField (fieldname , flag);
            return (T ) field. GetValue (instance );
        }

        public static T GetPrivateProperty <T >( this object instance , string propertyname )
        {
            BindingFlags flag = BindingFlags. Instance | BindingFlags . NonPublic;
            Type type = instance. GetType ();
            PropertyInfo field = type. GetProperty (propertyname , flag);
            return (T ) field. GetValue (instance , null);
        }

        public static void SetPrivateField (this object instance , string fieldname, object value )
        {
            BindingFlags flag = BindingFlags. Instance | BindingFlags . NonPublic;
            Type type = instance. GetType ();
            FieldInfo field = type. GetField (fieldname , flag);
            field .SetValue ( instance, value );
        }

        public static void SetPrivateProperty (this object instance , string propertyname, object value )
        {
            BindingFlags flag = BindingFlags. Instance | BindingFlags . NonPublic;
            Type type = instance. GetType ();
            PropertyInfo field = type. GetProperty (propertyname , flag);
            field .SetValue ( instance, value , null );
        }

        public static T CallPrivateMethod <T >( this object instance , string name , params object[] param )
        {
            BindingFlags flag = BindingFlags. Instance | BindingFlags . NonPublic;
            Type type = instance. GetType ();
            MethodInfo method = type. GetMethod (name , flag);
            return (T ) method. Invoke (instance , param);
        }
    }

  拷到项目中试了一下,不行,因为Resource是Interal的,在我的外部程序中引用它的Resource都无法通过编译。
  看来这个办法不行了,还得想想别的办法,记得以前看过一种方法,可以在不动原类的情况下给它加一个扩展方法。

    public static class  ExtendProperty
    {
        public static String Connect (this String s ,string a)
        {
            return s + a;
        }
    }

    public class Test
    {
        public void Test1()
        {
            String s = "aa";
            s .Connect ( "cc");
        }
    }
  像这样,我就可以给Resource类加一个扩展方法,然后就可以做我想做的事了,试验下来,还是因为Internal的问题,不能用。该想的办法都想了,还有什么办法呢?有,但只剩下最后一招了,不行我就打算放弃了。最后一招就是www.google.com,搜了一下,有网友说可以用反射调用私有类,那就在试试了,代码如下。
         private void GetResource()
        {
            Assembly assembly = Assembly. LoadFile (@"d:\test.exe" );
            ResourceManager resourceManager = new ResourceManager ("Test.Resource" , assembly);
            object obj = resourceManager. GetObject ("Register" );
            byte [] byetes = ( byte[]) obj ;
            FileStream fs = new FileStream (@"d:\result.dll" , FileMode. CreateNew );
            BinaryWriter bw = new BinaryWriter (fs );
            bw .Write ( byetes);
            bw .Flush ();
            bw .Close ();
            fs .Close ();
        }
  写好后,运行起来试了一下,奇迹出现了,这个类库被我导出来了,剩下的工作就好办了,只要反编译就可以看到它的实现了。
posted on 2013-01-14 21:22  陆晓龙  阅读(485)  评论(0编辑  收藏  举报