Programinės įrangos licenzijavimas 2023.12.21 at 08:37

Kažkada sugalvojau, kad visai norėčiau apsaugoti savo programėles nuo nelegalaus kopijavimo. Ne tam, kad daugiau pinigų ar kažko gauti, bet tiesiog šiaip, dėl tvarkos. Nu ir – nes galiu 😋. Taigi, tikslas – padaryti, kad programėlė veiktų tik tame kompiuteryje, kuriame aš noriu. Reiškia, kad programėlė turi žinoti kuriame kompiuteryje jai galima veikti, o kuriame negalima. Kaip ir paprasta, bet – o tai kaip programėlė tą sužinos ? Yra keletas variantų, bet jeigu, tarkime apsiribotumėme Windows operacine sistema, tada, mano galva, paprasčiausi yra du būdai – rištis prie procesoriaus ID arba MAC adreso. MACas dar kai kada gali būti keičiamas, procesoriaus ID jau taip paprastai nepakeisi. Jo net standartiniai Windows įrankiai nerodo, bent jau man nepavyko aptikti. Todėl rašome nedidelė programėlę su Visual Studio, kuri tą dalyką sužinos ir mums parodys. Tam reikia parašyti dvi paprastas programėles:

        private string Get_MAC_Id()
        {
            foreach (NetworkInterface nic in NetworkInterface.GetAllNetworkInterfaces())
            {
                if (nic.OperationalStatus == OperationalStatus.Up)
                {
                    PhysicalAddress mac = nic.GetPhysicalAddress();
                    currentMacAddress = BitConverter.ToString(mac.GetAddressBytes()).Replace("-", "");
                    break;
                }
            }
            return currentMacAddress;
        }

Šita programėlė suranda aktyvios tinklo kortos MAC adresą ir pagražina jį pagrindinei programai.

        private string GetProcessorId()
        {
            ManagementClass managClass = new ManagementClass("win32_processor");
            ManagementObjectCollection managCollec = managClass.GetInstances();

            foreach (ManagementObject managObj in managCollec)
            {
                cpuInfo = managObj.Properties["processorID"].Value.ToString();
                break;
            }
            return cpuInfo;
        }

O šita programėlė tą patį padaro su CPU ID. Po to belieka tik susidėti tuos duomenis ten, kur mums reikia, pavyzdžiui, į programėlės grafinę sąsają (va kaip lietuviškai parašiau 🙃):

Veikimas paprastas, paleidus programėlę ji iš karto prasuka informacijos surinkimą ir parodo jį atitinkamuose laukeliuose. Vienintelis mygtukas tik uždaro programėlę. Paveiksliuke jau matosi ir mano kompiuterio MAC ir CPU ID. O kodėl reikia dviejų dalykų ? Principe, užtektų ir vieno – CPU ID. Logika paprasta – kompiuteryje gali nebūti jokios tinklo kortos, taigi MAC ID nieko nesugeneruos, o procesorius, nori nenori, o visada bus, todėl galima rištis prie jo ID. Savo programėlėse aš tikrinsiu abu ID ir, jeigu bent vienas atitiks, tuomet programėlė veiks. Programėlėse patikra daroma taip:

        private int get_MAC_Id()
        {
            string predefinedMacAddress = "B07D64766C0E";
            

            foreach (NetworkInterface nic in NetworkInterface.GetAllNetworkInterfaces())
            {
                if (nic.OperationalStatus == OperationalStatus.Up)
                {
                    PhysicalAddress mac = nic.GetPhysicalAddress();
                    string currentMacAddress = BitConverter.ToString(mac.GetAddressBytes()).Replace("-", "");

                    if (currentMacAddress.Equals(predefinedMacAddress, StringComparison.OrdinalIgnoreCase))
                    {
                        mac_flag = 1;
                        break; // No need to continue checking if we found a match
                    }
                }
            }
            return mac_flag;
        }

        private int getProcessorId()
        {

            string predefinedcpuInfo = "BFEBFBFF000A0652";
            string cpuInfo = string.Empty;

            ManagementClass managClass = new ManagementClass("win32_processor");
            ManagementObjectCollection managCollec = managClass.GetInstances();

            foreach (ManagementObject managObj in managCollec)
            {
                cpuInfo = managObj.Properties["processorID"].Value.ToString();
                break;
            }
            if (cpuInfo.Equals(predefinedcpuInfo, StringComparison.OrdinalIgnoreCase))
            {
                CpuID_flag = 1;
            }
            return CpuID_flag;
        }

Į pagrindinę programą grąžinamos vėliavėlės (flag), jeigu CPU ID arba MAC ID atitinka programėlėje jau įrašytus – tuomet vėliavėlės bus 1. Tuos vienetus pagauna pagrindinė programa ir padaro paprastą patikrą.

Nepamirštam inicializuoti flag’us :

        int mac_flag = 0;
        int CpuID_flag = 0;
Tuomet kažkur kode, ten kur norime patikros:
            get_MAC_Id();
            getProcessorId();
            if (mac_flag == 1 || CpuID_flag == 1)
            {
                // Darome tą, ką reikia, jeigu ID atitinka. Loginis "arba" || leis veikti jeigu bent vienas flag'as = 1, jeigu naudoti loginį "ir" && tuomet leis veikti tik jeigu abu flag'ai bus vienetukai.
            }
            else
            {
                MessageBox.Show("Contact creator of this program.", "Error", MessageBoxButtons.OK);
            }

O čia Visual Studio failiukai, išeitinis kodas, sukompiliuotas exec’as.

2 Responses to “Programinės įrangos licenzijavimas”

  1. Tik tokia apsauga labai basic. Su dissambler’iu labai greitai galima „pagydyti” tokią programėlę 🙂
    Tiesą sakant, net ir nežinau kaip šiais laikais apsaugo soft’ą. Gal vienintelis būdas, kad būtų online ir pastoviai su sertifikatu ir timestamp’ais kažką bandyti tikrinti.

  2. Taip, tokia apsauga labai paprastutė, o kadangi ir pats įvaldęs disamblerius dar nuo Win32Dasm laikų, puikiai suprantu, kad čia neilgam. O ypač kai programos rašomos .net’u, ten disassembleriai iš viso vos ne į gryną suorsą išsuka (naudoju .net Reflector, mokamas, ir Teleric JustDecompaile su Reflexil pluginu, nemokamas). Išvada – už softą reikia paimti tiek pinigų, kad net ir ne apsaugos pirkėjui būtų gaila dalintis :). Nors toje srityje, kuriose tos programos naudojamos, ten ir disassembleriai jau būtų per aukštos materijos :D.

Leave a Reply

*