zoukankan      html  css  js  c++  java
  • 字符串混淆技术在.NET程序保护中的应用及如何解密被混淆的字符串

    Visual Studio提供的Dotfuscator保护程序,可以对用户代码中包含的字符串进行加密。比如下面的例子,为了找到这个程序的注册算法,用.NET Reflector加载程序集后,发现代码中的字符串,都变成这种形式的:

    Assembly executingAssembly = Assembly.GetExecutingAssembly();
    ArrayList list = new ArrayList();
    string str = Class64.smethod_0("ᓊᓜᓙᒷᓎᓝᒶᒱᒽ");
    string fullName = executingAssembly.FullName;
    Version version = new Version();
    bool flag = false;
    int index = fullName.ToLower().IndexOf(Class64.smethod_0("ᓟᓎᓛᓜᓒᓘᓗᒦ"));
    

    注意到这几行代码中的方法调用的参数,已经完全不是我们熟悉的English,我把它放到Google翻译中去寻找它的语言,结果是一种东欧的国家的语言,为了得到它对应的英语,我得找这方面的翻译资料。如何将这种语言,翻译成英语,结果只有专门做翻译的公司才可以做,而且报价不便宜,按字数来收费。这一条路似乎走不通……

    意识到自己走错方向之后,马上把自己的想法,翻译成英语,用Google来搜索。Google翻译的质量,确实不错。

    很快,我就得到这篇文章Decrypting strings in obfuscated assemblies,它告诉我,这个程序集应用了字符串混淆算法,同样的例子是这样的

    int num = 19;
    if (args.Length < 1)
    {
            Console.WriteLine(a("昞传圢䐤弦न个弬崮帰䄲༴᜶稸吺似䴾⑀⁂ㅄ杆㩈㉊⍌㭎ぐ⭒畔㹖⩘筚♜潞ᱠ䍢奤ቦ᭨ݪ卬佮⩰ᱲtͶॸ๺ॼ᥾�uda86", num), a("东瘞䰠匢䤤䈦洨䐪娬䄮崰尲吴匶尸䤺", num));
            Console.ReadKey();
    }
    

    老外一看到这些方块的文字,第一想到的就是Chinese,呵呵,中文语言在世界上还真有点名气。难怪Windows的安装程序中,专门有一项是Aisan Language是专门用来安装东方语言文字字符集的。

    解决方案也比较简单,调用加密的办法,获取它的运行时的值:

    string encryptedString = "东瘞䰠匢䤤䈦洨䐪娬䄮崰尲吴匶尸䤺";
    int key = 19;
    
    Assembly assembly = Assembly.LoadFile(assemblyPath);
    
    // Okay, It’s sample code.. what do you expect! :)
    MethodInfo secretMethod = assembly.GetModules()[0]
                      .GetMethods(BindingFlags.NonPublic| BindingFlags.Public| BindingFlags.Static)[0];
    string decryptedString = secretMethod.Invoke(null, new object[] {encryptedString, key}) as string;
    
    

    这样就解决了字符串的反混淆。如果需要对程序中的每个字符串进行调用,需要写一个GUI,用来批量的解决反混淆。

    做到这里,基本上可以理解被混淆的程序集中的字符串的含义,然而,网上的一篇文章介绍的工具DotNetStringSearch,引起了我的注意,我确实是在找这样的工具,也一直想做一个一劳永逸的工作,就是我需要一个工具程序,打开一个应用过字符串混淆的程序,点一个按钮,它马上可以为我显示原文字符串和混淆后的字符串。

    可细DotNetStringSearch的作者并没有公布这个软件的细节,源代码也没有开放,唯一提到的Rainst.net这个网站中的一篇文章,现在已经打不开,无从得知它应用的技术。这一条路似乎也走不下去……

    一个偶然的原因,看到CodeProject上面的一篇文章,讲解如何应用Mono.Cecil实现.NET代码注入,这一下子引起了我的注意。与我们通常用的反射不同,它实现的是直接修改程序集的代码,比起16进制工具修改EXE/DLL的二进制文件要高级得多,毕竟是原来的.NET代码,可以直接调试,观察实现过程。一下小心,找到SystemInternal上面的一个实用工具,Strings,这个程序可以提取PE文件中的字符串内容。

    image 

    思路一下就打开了,原来不是反射,是直接对PE文件格式进行读取,运行Strings程序,果然它顺利的读取了PE格式中的字符串资源,而且源代码是开放的,里面的例子程序是这样的

    static void Main(string[] args)
    {
                try
                {
                    string exePath = args[0];
    
                    List<string> allUserStrings = ReadAllUserStrings(exePath);
    
                    File.WriteAllLines(exePath + ".txt", allUserStrings.Select(str => CSStringConverter.Convert(str)));
    
                    Console.WriteLine("hotovo... ");
                }
                catch (Exception ex)
                {
                    Console.WriteLine("Exception: " + ex.ToString());
                    Console.WriteLine("press a key...");
                    Console.ReadKey();
                }
     }
     

    通过上面的一段代码,你可以很容易的找到它的源代码文件,于是可以解决我说的目标:做一个通用的字符串反混淆程序,可以对当前流行的加密工具加密后的字符串进行反混淆。

  • 相关阅读:
    Kotlin调用lambda表达式时,lambda中的参数名字省略问题
    Kotlin读取控制台输入
    安卓P(9)及以上Cleartext HTTP traffic to xxx not permitted错误,无法HTTP明文连接错误解决方法
    AS4.0以上查看R.id
    Kotlin Standard.kt解析(also,apply,let.run...)
    ext4文件解包打包
    Kotlin中的var、val和const
    Kotlin的构造方法探究
    Markdown语法
    uniapp遇到的小问题
  • 原文地址:https://www.cnblogs.com/JamesLi2015/p/3164327.html
Copyright © 2011-2022 走看看