1724663133 发表于 2022-3-24 10:23:09

SDF Viewer KEY算法分析

使用工具:1.Detect It Easy(查壳工具)
2.dnspy(反编译工具)
3.De4Dot ToolKit V 2.0(脱壳工具)
4.C#代码在线执行网站(加密解密代码执行 KeyGen)分析过程首先我们先用查壳工具看一下
https://attach.52pojie.cn/forum/202203/22/040403vhhjhkhah4hyyej4.png
显示VB.NET,嗯有的搞
dnspy载入看一下
https://attach.52pojie.cn/forum/202203/22/040445gi391uradu9dd0b9.png
这明显就是加了壳的
试着用De4Dot脱一下
https://attach.52pojie.cn/forum/202203/22/040514g7k7kpaapk9k7ppa.png
https://attach.52pojie.cn/forum/202203/22/040518zqllkvbbsltq4tll.png
代码基本上算是能看了
https://attach.52pojie.cn/forum/202203/22/040558jh3ev0v5yazo3y6g.png
打开软件的注册,试着随便输入注册,看提示信息
https://attach.52pojie.cn/forum/202203/22/040612l9zvp3pepjhi9xh3.png https://attach.52pojie.cn/forum/202203/22/040614l2l27wvflpc8jsjf.png
Name or Key error
记住这个消息,然后用dnspy打开脱壳后的程序.
CTRL+F打开查找信息框输入这个错误信息
漫长的查找时间...
https://attach.52pojie.cn/forum/202203/22/040643ynlzhuy3lshwhf56.png
最后在资源文件的SDFviewer.SDF.resources找到了这个字符串
记住前面这个str120,这个是程序里引用的资源名
顺便记录一下其他的关键信息
复制代码 隐藏代码
// str116‎ = "Licence has been Withdrawn."//注册码被撤销// str117‎ = "Please contact sales@flyhoward.com for further details."// str118‎ = "Licence Error"// str119‎ = "Registered to "//注册到    这里很关键,提示注册成功了// str12‎ = "Enter Password for: "// str120‎ = "Name or Key error"//注册码错误信息然后我们在所有代码数据里面查找str120和str119
又是漫长的查找过程...
https://attach.52pojie.cn/forum/202203/22/040721hz24a4t5ay4wsytz.png
复制代码 隐藏代码
if (Operators.CompareString(Class1.smethod_3(Class1.string_17), Class1.string_16, false) == 0){      Class1.string_11 = Class1.resourceManager_0.GetString("str119") + Class1.string_16;//Registered to      Class1.int_0 = 2;}else{      Class7.smethod_0().Name = string.Empty;      Class7.smethod_0().KeyString = string.Empty;//Name or Key error      Interaction.MsgBox(Class1.resourceManager_0.GetString("str120"), MsgBoxStyle.OkOnly, Class1.resourceManager_0.GetString("str121"));      Class1.smethod_2();}仔细看代码if (Operators.CompareString(Class1.smethod_3(Class1.string_17), Class1.string_16, false) == 0)
其中调用了Class1.smethod_3,我们找一下这个方法的作用
复制代码 隐藏代码
private static string smethod_3(string string_29){      byte[] rgbKey = new byte[0];      byte[] rgbIV = new byte[] { 18, 52, 86, 115, 144, 171, 205, 239 };      byte[] array = new byte1)];      string result;      try      {                rgbKey = Encoding.UTF8.GetBytes("f1owChk1");                DESCryptoServiceProvider descryptoServiceProvider = new DESCryptoServiceProvider();                array = Convert.FromBase64String(string_29);//1.Key先从BASE64转换成二进制                MemoryStream memoryStream = new MemoryStream();                CryptoStream cryptoStream = new CryptoStream(memoryStream, descryptoServiceProvider.CreateDecryptor(rgbKey, rgbIV), CryptoStreamMode.Write);//2.然后执行Decryptor解密方法                cryptoStream.Write(array, 0, array.Length);//3.然后把二进制Key写进解密方法                cryptoStream.FlushFinalBlock();                result = Encoding.UTF8.GetString(memoryStream.ToArray());//4.最后ToArry的数据转换成字符串      }      catch (Exception ex)      {                result = string.Empty;      }      return result;解密算法就摆在眼前
仔细看这行代码array = Convert.FromBase64String(string_29);
还有CreateDecryptor(rgbKey, rgbIV), CryptoStreamMode.Write)梳理一下这个算法1.Key先从BASE64转换成二进制
2.然后执行Decryptor解密方法
3.然后把二进制Key写进解密方法
4.最后ToArry的数据转换成字符串5.把结果返回到上一个方法进行比较加密算法就是反过来
1.把Name(字符串)转换成二进制
2.然后执行Encryptor加密方法
3.然后把二进制Name写进加密算法
4.最后ToArry的数据转换成BASE64字符串5.最后BASE64字符串就是Key 复制代码 隐藏代码
private static string smethod_3(string Nametext){      byte[] rgbKey = new byte[0];      byte[] rgbIV = new byte[] { 18, 52, 86, 115, 144, 171, 205, 239 };      byte[] array = new byte;      string result;      try      {                rgbKey = Encoding.UTF8.GetBytes("f1owChk1");                DESCryptoServiceProvider descryptoServiceProvider = new DESCryptoServiceProvider();                array = new ASCIIEncoding().GetBytes(NameText);//1.把Name(字符串)转换成二进制                MemoryStream memoryStream = new MemoryStream();                CryptoStream cryptoStream = new CryptoStream(memoryStream, descryptoServiceProvider.CreateEncryptor(rgbKey, rgbIV), CryptoStreamMode.Write);//2.然后执行Encryptor加密方法                cryptoStream.Write(array, 0, array.Length);//3.然后把二进制Name写进加密算法                cryptoStream.FlushFinalBlock();                result = Convert.ToBase64String(memoryStream.ToArray());//4.最后ToArry的数据转换成BASE64字符串      }      catch (Exception ex)      {                result = string.Empty;      }      return result;把这些代码转化一下,找个在线C#代码执行网站试一下看看能不能算出来注册码完整代码如下: 复制代码 隐藏代码
using System;using System.Text;//文本处理命名空间using System.IO;//MemoryStream读写数据流用的命名空间using System.Security.Cryptography;//加密解密用的命名空间namespace KeyGen{    class Program    {      static void Main(string[] args)      {            string Name = "52pojie";//双引号内是Name内容,不支持特殊符号和中文            //            byte[] rgbKey = Encoding.UTF8.GetBytes("f1owChk1");            byte[] rgbIV = new byte[] { 18, 52, 86, 115, 144, 171, 205, 239 };            byte[] array = new ASCIIEncoding().GetBytes(Name);            DESCryptoServiceProvider descryptoServiceProvider = new DESCryptoServiceProvider();;            MemoryStream memoryStream = new MemoryStream();            CryptoStream cryptoStream = new CryptoStream(memoryStream, descryptoServiceProvider.CreateEncryptor(rgbKey, rgbIV), CryptoStreamMode.Write);            cryptoStream.Write(array, 0, array.Length);            cryptoStream.FlushFinalBlock();            string result = Convert.ToBase64String(memoryStream.ToArray());            Console.WriteLine(result);      }    }}
把执行的代码结果在软件内进行注册,完美!


插曲
其实分析期间在解密的代码那里我是下过断点调试过的,因为不确定是不是解密的Key秘钥.
在对比秘钥之前的代码里有一段代码非常有意思
复制代码 隐藏代码
if (Operators.CompareString(Class1.string_17, "SIWphRddOncC+9dfqM39Cw==", false) == 0 || Operators.CompareString(Class1.string_17, "yoU2LTox9ji1ME2xsQ21UA==", false) == 0 || Operators.CompareString(Class1.string_17, "9hzsfFcMHlaq7e9ItbsEHsutKigmkZgM", false) == 0 || Operators.CompareString(Class1.string_17, "5Prfc4iGPGwH3w84uOx84w==", false) == 0 || Operators.CompareString(Class1.string_17, "oIGoCNG9iBn0GaHaD1KuAA==", false) == 0 || Operators.CompareString(Class1.string_17, "bi1F2hrFoxWbDy9/9XW38A==", false) == 0 || Operators.CompareString(Class1.string_17, "o4rHyS9417d+TiSf6vpCxA==", false) == 0 || Operators.CompareString(Class1.string_17, "8vUnN+97Lmo=", false) == 0)                {                        Class7.smethod_0().Name = string.Empty;                        Class7.smethod_0().KeyString = string.Empty;                        Class7.smethod_0().Save();                        Interaction.MsgBox(Class1.resourceManager_0.GetString("str116") + "\r\n" + Class1.resourceManager_0.GetString("str117"), MsgBoxStyle.OkOnly, Class1.resourceManager_0.GetString("str118"));                        Class1.int_0 = 0;                        Class3.smethod_3().method_28().Close();                        ProjectData.EndApp();                }仔细看代码里有GetString("str116")
前面有提到: 复制代码 隐藏代码
// str116‎ = "Licence has been Withdrawn."//注册码被撤销软件开发者比较狠,因为不知道是注册码泄露还是其他人破解的秘钥,作者发现了直接把这些秘钥列到黑名单里面啦,哈哈哈~
不过因为上面判断代码里面Class1.string_17的判断字符串都是BASE64编码,所以我很确定解密算法里面肯定是解密的Key,而且是BASE64编码
通过我用C#做的界面程序进行解密,把这些黑名单的用户名发一下:
KeyName
SIWphRddOncC+9dfqM39Cw==dan quinn
yoU2LTox9ji1ME2xsQ21UA==Carlos Cardona
9hzsfFcMHlaq7e9ItbsEHsutKigmkZgMGail Fitzmaurice
5Prfc4iGPGwH3w84uOx84w=Ng Choon Bok
oIGoCNG9iBn0GaHaD1KuAA==Yam Poudel
bi1F2hrFoxWbDy9/9XW38A==Cameron Kelly
o4rHyS9417d+TiSf6vpCxA==omegaredgroup
8vUnN+97Lmo=Kyu Kim
以上黑名单人员看用户名就没有中国的,看来作者是没到国内的网站搜索过啊,呵呵呵~

baobao 发表于 2023-4-21 22:35:22

大神能带带我码
页: [1]
查看完整版本: SDF Viewer KEY算法分析