jy04468108 发表于 2020-7-30 11:25

.net 无壳 无混淆 无虚拟机,纯算法的KeyGenMe

本帖最后由 jy04468108 于 2020-7-30 11:43 编辑

代码是用C#写的,
相互嵌套层数有点多,
既然都没有加壳,没有加混淆,也没有虚拟机,
而且所有解密算法都已经包含在程序内部了,
所以,爆破说明不了技术,
当然了,
要是你实在不会玩,也可以爆破。
希望大神能逆向出算法,甚至做出注册机。

以下是软件运行界面。


注册成功之后会弹出消息框(messagebox),回帖中贴出消息框内容即认为是注册成功。



源码的截图,我可不是来找破解的。


Dnspy中打开的截图:




qzhsjz 发表于 2020-7-30 12:07

本帖最后由 qzhsjz 于 2020-7-30 12:16 编辑

分析按钮代码并下断点可得到如下被反序列化并执行的VB代码:
{

'垃圾字符一定要多
Public Class MS
Inherits Methods'继承
Public Function Process() As Boolean
Try
Dim resultFag As Boolean = True
'Public Class MS
'Inherits Methods'继承
'Public Function Process() As Boolean
ModuleForm.registcode=123
if TimeClass.InitRegedit=0 then
'messagebox.show("傻逼了把,这些都不是真的代码")
messagebox.show("懵逼了把,被忽悠成这样!")'大写的懵逼
'messagebox.show("fuck you!")
end if
Return resultFag
Catch ex As Exception
'LogError(ex.ToString()) 大家自己可以打印日志
Return false
'end if
'Return resultFag
'Catch ex As Exception
'End Try
'End Function
End Try
End Function
End Class}
根据这段VB代码可知,点击验证按钮后真正有用的代码是TimeClass.InitRegedit,并且它成功运行的话需要返回0。于是分析之:

public static int InitRegedit(){
      int result;
      try
      {
                string text = TimeClass.DisEncryPW(ModuleForm.registcode, TimeClass.password);
                bool flag = text == "-1";
                if (flag)
                {
                        result = 1;
                }
                else
                {
                        string softEndDateAllCpuId = TimeClass.GetSoftEndDateAllCpuId(1, text);
                        string cpuId = TimeClass.GetCpuId();
                        bool flag2 = softEndDateAllCpuId != cpuId;
                        if (flag2)
                        {
                              result = 2;
                        }
                        else
                        {
                              string nowDate = TimeClass.GetNowDate();
                              string softEndDateAllCpuId2 = TimeClass.GetSoftEndDateAllCpuId(0, text);
                              bool flag3 = Convert.ToInt32(softEndDateAllCpuId2) - Convert.ToInt32(nowDate) < 0;
                              if (flag3)
                              {
                                        result = 3;
                              }
                              else
                              {
                                        result = 0;
                              }
                        }
                }
      }
      catch (Exception)
      {
                result = 1;
      }
      return result;
}

通过调用分析可知它调用了以下几个方法来构造序列号:


public static string GetSoftEndDateAllCpuId(int i, string SerialNumber)
{
      bool flag = i == 1;
      string result;
      if (flag)
      {
                string text = SerialNumber.Substring(0, SerialNumber.LastIndexOf("-"));
                result = text;
      }
      else
      {
                bool flag2 = i == 0;
                if (flag2)
                {
                        string text2 = SerialNumber.Substring(SerialNumber.LastIndexOf("-") + 1);
                        result = text2;
                }
                else
                {
                        result = string.Empty;
                }
      }
      return result;
}

public static string GetNowDate()
{
      return DateTime.Now.ToString("yyyyMMdd");
}


public static string GetCpuId()
{
      ManagementClass managementClass = new ManagementClass("Win32_Processor");
      ManagementObjectCollection instances = managementClass.GetInstances();
      string str = null;
      using (ManagementObjectCollection.ManagementObjectEnumerator enumerator = instances.GetEnumerator())
      {
                if (enumerator.MoveNext())
                {
                        ManagementObject managementObject = (ManagementObject)enumerator.Current;
                        str = managementObject.Properties["ProcessorId"].Value.ToString();
                }
      }
      return TimeClass.encode(str);
}


构造分析完毕,接下来是加密算法,是普通的DES,密码是52pojie.

算法部分代码如下:

public static string encode(string str)
{
      string text = "";
      for (int i = 0; i < str.Length; i++)
      {
                text += str.ToString();
                i++;
      }
      for (int j = 1; j < str.Length; j++)
      {
                text += str.ToString();
                j++;
      }
      return TimeClass.EncryPW(text, TimeClass.password);
}

public static string EncryPW(string Pass, string Key)
{
      return TimeClass.DesEncrypt(Pass, Key);
}

public static string DesEncrypt(string encryptString, string key)
{
      byte[] bytes = Encoding.UTF8.GetBytes(key.Substring(0, 8));
      byte[] rgbIV = bytes;
      byte[] bytes2 = Encoding.UTF8.GetBytes(encryptString);
      DESCryptoServiceProvider descryptoServiceProvider = new DESCryptoServiceProvider();
      MemoryStream memoryStream = new MemoryStream();
      CryptoStream cryptoStream = new CryptoStream(memoryStream, descryptoServiceProvider.CreateEncryptor(bytes, rgbIV), CryptoStreamMode.Write);
      cryptoStream.Write(bytes2, 0, bytes2.Length);
      cryptoStream.FlushFinalBlock();
      return Convert.ToBase64String(memoryStream.ToArray());
}

懒得跑注册码了,但是根据那段VB代码,弹窗内容应该是:
懵逼了把,被忽悠成这样!
嗯,我是挺懵逼的。

jy04468108 发表于 2020-7-30 12:59

wwh1004 发表于 2020-7-30 12:38
比如注册码填

MessageBox.Show("懵逼了把,被忽悠成这样!")


说的对,
但是字符串里面必须要先写两个双引号然后才能填写任意代码执行。因为字符串拼接的前面写的是:"某string="
这个是我们的一个项目里面的VB脚本引擎中的功能提取出来做的,在原功能中本来就是一个VB脚本执行器。
下图为完整功能。

jy04468108 发表于 2020-7-30 12:20

qzhsjz 发表于 2020-7-30 12:07
分析按钮代码并下断点可得到如下被反序列化并执行的VB代码:
{



对的,唯一不对的地方是那段VB代码,并非反序列化。

qzhsjz 发表于 2020-7-30 12:27

jy04468108 发表于 2020-7-30 12:20
对的,唯一不对的地方是那段VB代码,并非反序列化。

是Support模块现场编译的,总之挺不错

wwh1004 发表于 2020-7-30 12:29

字符串拼接不是想弹啥就弹啥么

ㄔㄣㄑㄧㄈㄟ 发表于 2020-7-30 12:36

本帖最后由 ㄔㄣㄑㄧㄈㄟ 于 2020-7-30 12:37 编辑

那个代码是固定的吗

wwh1004 发表于 2020-7-30 12:38

本帖最后由 wwh1004 于 2020-7-30 12:42 编辑

比如注册码填

MessageBox.Show("懵逼了把,被忽悠成这样!")

随便填点代码进去就可以,想弹什么就弹什么

或者如果方法没返回值,就

"随便来点字符串" : Action1(arg1,arg2)

这样的,都可以执行任意代码

qzhsjz 发表于 2020-7-30 12:48

wwh1004 发表于 2020-7-30 12:38
比如注册码填

MessageBox.Show("懵逼了把,被忽悠成这样!")


是的,因为用户的输入部分会在拼接出的VB代码里执行,并赋值给ModuleForm.registcode,所以这部分可以运行任意代码:lol

jy04468108 发表于 2020-7-30 12:52

qzhsjz 发表于 2020-7-30 12:27
是Support模块现场编译的,总之挺不错

大佬是很仔细!一般人看到那一串字符串估计都不会仔细观察。
页: [1] 2 3
查看完整版本: .net 无壳 无混淆 无虚拟机,纯算法的KeyGenMe