ApacheLogsView破解笔记


本文作者Sp4ce,转自https://0x20h.com/p/a73d.html

Apache Log Viewer 5.X 注册机

抽空研究了下ALV的注册机制,写了个注册机

分析

ALV的注册方法是unlockCodeToolStripMenuItem_Click方法,当点击Unlock按钮时会触发注册事件并调用Class2类中的smethod_1smethod_02个方法进行校验,详细流程见如下代码

unlockCodeToolStripMenuItem_Click方法

private void unlockCodeToolStripMenuItem_Click(object sender, EventArgs e)
    {
        string text = this.prefs_0.Key;
        if (!InputForm.smethod_3("Apache Logs Viewer | " + Class96.smethod_264(), Class96.smethod_143(), ref text))
        {
            return;
        }
        if (text != null)
        {
            text = text.Trim();
        }
        if (string.IsNullOrEmpty(text))
        {
            this.prefs_0.Key = string.Empty;
            this.bool_0 = false;
            Prefs.Save(Prefs.Filename, this.prefs_0);
            this.method_2(this.bool_0);
            return;
        }
        try
        {
            this.Cursor = Cursors.WaitCursor;
            if (text.Length < 22)//检查key长度是否大于22
            {
                throw new ApplicationException("Failed");
            }
            if (Class2.smethod_1(Class2.smethod_0(text)))//重点位置
            {
                this.prefs_0.Key = text;
                this.method_23();
                Prefs.Save(Prefs.Filename, this.prefs_0);
                this.Cursor = Cursors.Default;
                this.lbStatusStripNotify.Text = Class96.smethod_253() + " Apache Logs Viewer.";
                MessageBox.Show(this, Class96.smethod_253() + " Apache Logs Viewer.", "Apache Logs Viewer", MessageBoxButtons.OK, MessageBoxIcon.Asterisk);
                this.bool_0 = true;
            }
            else
            {
                MessageBox.Show(this, Class96.smethod_117(), "Apache Logs Viewer | " + Class96.smethod_264(), MessageBoxButtons.OK, MessageBoxIcon.Hand);
                this.bool_0 = false;
            }
        }
        catch (Exception)
        {
            this.Cursor = Cursors.Default;
            MessageBox.Show(this, Class96.smethod_90(), "Apache Logs Viewer | " + Class96.smethod_264(), MessageBoxButtons.OK, MessageBoxIcon.Hand);
            this.bool_0 = false;
        }
        finally
        {
            this.Cursor = Cursors.Default;
        }
        this.method_2(this.bool_0);
    }

Class2.smethod_0方法,

public static string smethod_0(string string_0)
    {
        if (string_0.IndexOf('-') < 0)//检查注册代码中是否有-
        {
            return string_0;
        }
        string str = "DBV";
        string_0 = string_0.Replace("-", string.Empty);//将字符-转为空
        string_0 = string_0.Replace('Q', '4');//Q转为4
        string_0 = string_0.Replace('G', '4');//G转为4
        string_0 = string_0.Replace('V', '0');//V转为0
        string_0 = string_0.Replace('N', '3');//N转为3
        str + string_0;//无用语句
        byte[] array = new byte[string_0.Length / 2];//新建个数组,长度是去掉-后的注册码长度的一半
        for (int i = 0; i < string_0.Length; i += 2)
        {
            byte b;
            byte.TryParse(new string(new char[]
            {
                string_0[i],
                string_0[i + 1]
            }), NumberStyles.HexNumber, CultureInfo.InvariantCulture, out b);//每两位进行拼接并转回字符串形式并依次存入b
            array[i / 2] = b;
        }
        string text = Encoding.ASCII.GetString(array);//将注册码转为字符串形式,传入的注册码为hex后的ascii值
        text = text.Insert(1, ":");//第2位插入:
        text = text.Insert(5, ":");//第6位插入:
        text = text.Insert(9, ":");//第10位插入:
        if (text.Length > 13)
        {
            text = text.Insert(13, ":");//如果注册码长度大于13则在第13位插入:
        }
        return text;
    }

Class2.smethod_1方法,

public static bool smethod_1(string string_0)
    {
        bool flag = true;
        string a = string_0.Substring(4, 5);//取经过smethod_0处理后的字符串中的第4到8位
    //如果a为IALV或注册码第一位不为F或第3位转为int型大于16或a不为I:ALV或注册码第4位转为int型大于16则抛出注册码错误
        if (a == "IALV")
        {
            flag = false;
        }
        if (string_0[0] != 'F')
        {
            flag = false;
        }
        int num = int.Parse(string_0[2].ToString(), NumberStyles.HexNumber);
        if (num > 16)
        {
            flag = false;
        }
        if (a != "I:ALV")
        {
            flag = false;
        }

        num = int.Parse(string_0[3].ToString(), NumberStyles.HexNumber);
        if (num > 16)
        {
            flag = false;
        }
        if (!int.TryParse(string_0.Substring(10, 3), out num))
        {
            flag = false;
        }
    //处理后的注册码如果长度小于14则抛错
        if (string_0.Length <= 14)
        {
            throw new ApplicationException("Invalid Unlock Code");
        }
    //命名num2变量,值为注册码的第15位,并判断num2是否为2或3,不是就抛错
        int num2 = int.Parse(string_0.Substring(15, 1));
        if (num2 != 2 && num2 != 3)
        {
            throw new ApplicationException("Incorrect Code for Version");
        }
        string s = string_0.Substring(0, 16);//s为1~17位
        string b = string_0.Substring(16);//b为17位后的校验位
        int num3 = 0;
        byte[] bytes = Encoding.ASCII.GetBytes(s);//将s转为字节码并存入数组
        for (int i = 0; i < bytes.Length; i++)
        {
            if (bytes[i] % 2 == 0)//每一位进行模2运算,为0则num3+1
            {
                num3++;
            }
        }
        return !(num3.ToString("00") != b) && flag;//num3向上取整后与校验位作比较,比较成功则返回真
    }

Keygen

有了注册机制就可以写注册机了,这里用python写了一个

'''
@Author         : Sp4ce
@Date           : 2020-02-19 19:17:59
@LastEditors    : Sp4ce
@LastEditTime   : 2020-02-19 23:27:40
@Description    : Challenge Everything.
'''

import random
import binascii

def banner():
    print(r"""
          _ __      __  _  __           _____            
    /\   | |\ \    / / | |/ /          / ____|           
   /  \  | | \ \  / /  | ' / ___ _   _| |  __  ___ _ __  
  / /\ \ | |  \ \/ /   |  < / _ \ | | | | |_ |/ _ \ '_ \ 
 / ____ \| |___\  /    | . \  __/ |_| | |__| |  __/ | | |
/_/    \_\______\/     |_|\_\___|\__, |\_____|\___|_| |_|
                                  __/ |                  
                                 |___/     

                Apache Log Viewer 5.X KeyGen
                                                  By:Sp4ce
    """)

def genLicenseCode(data):
    try:
        hexdata = data.replace('-', ':')
        data = "".join(data.split('-'))
        num = 0
        for i in hexdata:
            a = binascii.b2a_hex(i.encode('utf-8')).decode('utf-8')
            if int(a, 16) % 2 == 0:
                num = num+1
        hexData = binascii.b2a_hex((data+str(num)).encode('utf-8')) .decode('utf-8')
        hexData = list(hexData)
        hexData.insert(2, '-')
        hexData.insert(9, '-')
        hexData.insert(16, '-')
        hexData.insert(23, '-')
        licenseCode = ''.join(hexData)
        print("[+] License Code Generate Success!\nYour License Code: ->["+licenseCode.upper()+"]<-")
    except:
        print("[-] License Code Generate Failed!")



def main():
    banner()
    data = []
    data.append('F')  # 第一位必须:F
    data.append('-')  # 第一个-
    data.append(random.randint(1, 9))  # 第3位转为int后必须小于16
    data.append(random.randint(1, 9))  # 第4位转为int后必须小于16
    data.append('I')  # I
    data.append('-')  # 第二个-
    data.append('ALV')  # ALV
    data.append('-')  # 第三个-
    data.append(random.randint(100, 999))  # 第11~13位必须为int型
    data.append('-')  # 第四个-
    data.append(random.randint(1, 9))  # 第14位随机
    data.append(random.randint(2, 3))  # 第15位必须为2或3
    data = "".join('%s' % i for i in data).upper()
    genLicenseCode(data)

if __name__ == "__main__":
    main()

运行后

          _ __      __  _  __           _____
    /\   | |\ \    / / | |/ /          / ____|
   /  \  | | \ \  / /  | ' / ___ _   _| |  __  ___ _ __
  / /\ \ | |  \ \/ /   |  < / _ \ | | | | |_ |/ _ \ '_ \
 / ____ \| |___\  /    | . \  __/ |_| | |__| |  __/ | | |
/_/    \_\______\/     |_|\_\___|\__, |\_____|\___|_| |_|
                                  __/ |
                                 |___/

                Apache Log Viwer 5.X KeyGen
                                                  By:Sp4ce

[+] License Code Generate Success!
Your License Code: ->[46-313449-414C56-353934-33323130]<-

后话

该软件注册机制还有第二种方案,抽空再写


文章作者: sp4ce
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 sp4ce !
  目录