【续集】小白上路之第一次编写注册机——字符串解密函数分析并重写注册机

查看 333|回复 11
作者:wangxiangtan2   
上次在《小白上路之第一次编写注册机》里面主要分析了机器码的获取、真码的生成、手动编写注册机的过程,
后面我又尝试去混淆、分析字符串解密函数、按照评论老哥pj612大神的指导用反射重新写了注册机,在此一并记录一下;
主角还是“MX虚拟串口”这个小工具:


主角照.png (36.17 KB, 下载次数: 0)
下载附件
2023-3-28 09:02 上传

1,去混淆效果不明显
用DIE和Exeinfo查壳,发现用了Dotfuscator混淆器,


DIE和Exeinfo查克.png (121.12 KB, 下载次数: 0)
下载附件
2023-3-28 09:03 上传

Dotfuscator专业版是一款专业的.NET代码反编译工具,它可以混淆流程、加密字符串、加入水印、程序签名等,让你的程序不被人反编译,可以更好的保护属于你的版权。但是拖进Dnspy里面发现类、属性、方法名字是正常的,但是代码部分不正常,多了混淆部分,比如下面LicenseCode属性
[C#] 纯文本查看 复制代码public string LiceneCode
                {
                        get
                        {
                                short num = (short)95813632;
                                short num2 = num;
                                num = (short)151394258;
                                short num3 = num;
                                num = (short)421009362;
                                switch (num3 == num)
                                {
                                }
                                num = (short)1802305537;
                                if (num != 0)
                                {
                                }
                                num = (short)335806464;
                                if (num != 0)
                                {
                                }
                                return this.licenecode;
                        }
                }
应该是下面的样子:
[C#] 纯文本查看 复制代码public string LiceneCode
        {
            get
            {               
                return this.licenecode;
            }
        }
能不能把这混淆的部分去掉呢?拿de4dot试试吧,用“-p df”指令:


De4net脱壳.png (15.16 KB, 下载次数: 0)
下载附件
2023-3-28 09:21 上传

显示检测到了Dotfuscator混淆器,并对所有混淆字符进行了重命名,再拖进Dnspy,没什么卵用,类名属性名方法名本来就是正常的,
可能作者混淆时没有设置对名字进行混淆,
算了,名字能看懂就好很多了,混淆部分的代码也能猜个大概
2,字符串解密函数分析
将de4dot处理过的exe拖进Dnspy,所有涉及字符串的地方都用了同一个解密函数去解析,


字符串样子.png (124.47 KB, 下载次数: 0)
下载附件
2023-3-28 09:31 上传

打开这个TestQRCodeForm的字符串解密方法如下图所示:


源码字符串解密.png (45.72 KB, 下载次数: 0)
下载附件
2023-3-28 09:33 上传

该方法的参数为一个加密后的字符串,一个整型,返回值为string字符串,看着不是很复杂,直接写一个吧,
[C#] 纯文本查看 复制代码private string StringDecrypt(string strIn, int index)
        {
            string res = string.Empty;
            char[] array = strIn.ToArray();
            int num = 1027443329 + index + 57 + 60 + 82 + 90;
            for(int i=0; i> 8) ^ num++);
                byte b3 = b2;
                b2 = b;
                b = b3;
                array2 = (char)((int)b2
然后找几个地方的加密字符串试一下:


源码函数样子字符串逆解析.png (72.85 KB, 下载次数: 0)
下载附件
2023-3-28 09:36 上传

哈哈哈,解析出来了。什么,整数参数哪儿来的?Dnspy里面看到的,每个调用该解密方法的地方,开始的时候都会提供这么个整型参数值。


源码函数样子.png (61.66 KB, 下载次数: 0)
下载附件
2023-3-28 09:39 上传

重新写一下字符串解密方法:
[C#] 纯文本查看 复制代码private string StringDecrypt2(string strIn, int index)
        {
            string res = string.Empty;
            char[] array = strIn.ToArray();
            int num = index + 0x3D3D8A81 + '9' + '> 8) ^ num++);
                array = (char)(b
再测试一下,没问题:


源码函数样子字符串逆解析2.png (100.66 KB, 下载次数: 0)
下载附件
2023-3-28 09:41 上传

这是utf-16编码的代码,让我明白'a'是一个char,'虚'也是一个char,'쒤'也是一个char,\uddb3也是一个char……
3,重写注册机
根据pj612大神的指导,用.net的反射功能重新编写了注册机,


反射实现注册码计算.png (101.15 KB, 下载次数: 0)
下载附件
2023-3-28 09:48 上传

如上图所示,新建项目,直接引入该exe,引入命名空间using com2com_csharp;后,public类MachineCode、DESEncrypt就直接可以用了,后面CRC32Cls和Base62则用反射方法进行调用,这样就轻松多了,这才是这个注册机的正确编写方式
工程代码如下:
[C#] 纯文本查看 复制代码using System;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Reflection;
using com2com_csharp;
namespace Keygen
{
    public partial class mainForm : Form
    {
        public mainForm()
        {
            InitializeComponent();
        }
        private async void btnAutoGenerate_Click(object sender, EventArgs e)
        {
            tbxLicenseCode.Text = "计算中……";
            tbxLicenseCode.Text = await Task.Run(new Func(CalcCode));  
        }
        private string CalcCode()
        {
            string filePath = @"D:\Program Files (x86)\MX虚拟串口\mxVisualSerialPort.exe";
            string machineCodeString = MachineCode.GetMachineCodeString();
            string macidMD5 = DESEncrypt.MD5Encrypt32(machineCodeString);
            string text = DESEncrypt.MD5Encrypt32(macidMD5);
            Assembly assembly = Assembly.LoadFile(filePath);
            Type crc32Type = assembly.GetType("com2com_csharp.CRC32Cls");
            object crc32Obj = Activator.CreateInstance(crc32Type);
            ulong num = (ulong)crc32Type.GetMethod("GetCRC32Str").Invoke(crc32Obj, new object[] { text });            
            Type base62Type = assembly.GetType("com2com_csharp.Base62");
            return (string)base62Type.GetMethod("Encoder").Invoke(null, new object[] { num });            
        }
    }
}
界面如下图所示:


计算中.png (53.24 KB, 下载次数: 0)
下载附件
2023-3-28 09:53 上传



计算后.png (53.23 KB, 下载次数: 0)
下载附件
2023-3-28 09:54 上传

微软, 字符串

3yu3   

[C#] 纯文本查看 复制代码
private void checkAuth()
                {
                        if (string.IsNullOrEmpty(this.licenecode))
                        {
                                this.isAuth = false;
                                return;
                        }
                        string text = DESEncrypt.MD5Encrypt32(this.macidMD5);
                        ulong num = new CRC32Cls().GetCRC32Str(text);
                        if (num
pjy612   


wangxiangtan2 发表于 2023-3-28 16:51
这个我也试了,报错

你最好别改名,直接指向源程序...反字符串需要载入程序和相关引用的好像...如果还不行我就不清楚了
不刻意解混淆的话,我都是直接把exe或dll往de4dot上一拖就行了
Jingdiwa123   

虽然不懂,但是感觉很震撼,楼主做了我一直想做但是没有做的事情
wangxiangtan2
OP
  


Jingdiwa123 发表于 2023-3-28 10:06
虽然不懂,但是感觉很震撼,楼主做了我一直想做但是没有做的事情

你的手速也令我很震撼
muweng   

6666,楼主牛逼
Miluzhe   

楼主牛逼
Wisdom_xiaogui   

每次也想进行解析,但都不懂如何入手
殇。默语   

跟随楼主步伐学习
ashortname   

确实反射挺好用的。
您需要登录后才可以回帖 登录 | 立即注册