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

来源:互联网 发布:c游戏编程从入门到精通 编辑:程序博客网 时间:2024/05/18 00:55
今天在公司看一个软件注册验证机制,由于没有源代码,只能通过反编译工具看了。当看到下边这段代码的时候,就觉得有点奇怪。
                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 ();        }
  写好后,运行起来试了一下,奇迹出现了,这个类库被我导出来了,剩下的工作就好办了,只要反编译就可以看到它的实现了。
原创粉丝点击