Linux系统中软件简单License的实现
概述
目前,很多商用应用系统是运行在Linux系统之上的,为了维护开发者利益,有必要为软件添加license功能,防止软件被盗用和挪用。本文探讨如何在Linux软件中添加license功能,用到的算法是MD5算法。
关键字: MD5
一 目的和思路
设置License就是要将软件和运行该软件的机器进行简单“绑定”,该软件只能在某台指定机器上使用,如果将该软件挪动到其他机器上则无法运行。
根据以上目的,那么思路就很清晰,则我们需要读取该指定机器的某些特征,这里我们只抓取两个特征,即CPU特征和机器MAC地址。
这样,我们需要一个获得机器特征的程序,一个生成license的程序以及在所要加license的程序中嵌入检查license的代码。生成license程序可以是在windows操作系统下编写,也可以在Linux系统下编写,本文只讨论后面一种。
二 关键技术
这里的三个关键技术是获得本机的CPU信息、获得网卡MAC地址信息以及MD5加密。
1. 获得CPU信息
兼容x86的CPU的信息存储在数据结构:
struct cpuinfo_x86 {
__u8 x86;
__u8 x86_vendor;
__u8 x86_model;
__u8 x86_mask;
char wp_works_ok;
char hlt_works_ok;
char hard_math;
char rfu;
int cpuid_level;
unsigned long x86_capability[7];
char x86_vendor_id[16];
char x86_model_id[64];
int x86_cache_size;
int x86_cache_alignment;
int fdiv_bug;
int f00f_bug;
int coma_bug;
unsigned long loops_per_jiffy;
unsigned char x86_num_cores;
};
中,对于我们来说,只要获得x86_vendor_id和x86_model_id两项信息即可,前者记录的是CPU的制造商的信息,后者记录CPU的记录信息。在Linux下,可以通过以下代码获得:
static inline void
cpuid(int op, unsigned int *eax, unsigned int *ebx,
unsigned int *ecx, unsigned int *edx)
{
__asm__("cpuid"
: "=a" (*eax),
"=b" (*ebx),
"=c" (*ecx),
"=d" (*edx)
: "0" (op));
}
static unsigned int
get_cpu_id()
{
unsigned int *v;
cpuid(0x00000000, &cpu_info.cpuid_level,
(int *)&cpu_info.x86_vendor_id[0],
(int *)&cpu_info.x86_vendor_id[8],
(int *)&cpu_info.x86_vendor_id[4]);
v = (unsigned int *) cpu_info.x86_model_id;
cpuid(0x80000002, &v[0], &v[1], &v[2], &v[3]);
cpuid(0x80000003, &v[4], &v[5], &v[6], &v[7]);
cpuid(0x80000004, &v[8], &v[9], &v[10], &v[11]);
return 0;
}
这样,CPU的信息就存储在cpu_info中。
2.
概述
目前,很多商用应用系统是运行在Linux系统之上的,为了维护开发者利益,有必要为软件添加license功能,防止软件被盗用和挪用。本文探讨如何在Linux软件中添加license功能,用到的算法是MD5算法。
关键字: MD5
一 目的和思路
设置License就是要将软件和运行该软件的机器进行简单“绑定”,该软件只能在某台指定机器上使用,如果将该软件挪动到其他机器上则无法运行。
根据以上目的,那么思路就很清晰,则我们需要读取该指定机器的某些特征,这里我们只抓取两个特征,即CPU特征和机器MAC地址。
这样,我们需要一个获得机器特征的程序,一个生成license的程序以及在所要加license的程序中嵌入检查license的代码。生成license程序可以是在windows操作系统下编写,也可以在Linux系统下编写,本文只讨论后面一种。
二 关键技术
这里的三个关键技术是获得本机的CPU信息、获得网卡MAC地址信息以及MD5加密。
1. 获得CPU信息
兼容x86的CPU的信息存储在数据结构:
struct cpuinfo_x86 {
__u8 x86;
__u8 x86_vendor;
__u8 x86_model;
__u8 x86_mask;
char wp_works_ok;
char hlt_works_ok;
char hard_math;
char rfu;
int cpuid_level;
unsigned long x86_capability[7];
char x86_vendor_id[16];
char x86_model_id[64];
int x86_cache_size;
int x86_cache_alignment;
int fdiv_bug;
int f00f_bug;
int coma_bug;
unsigned long loops_per_jiffy;
unsigned char x86_num_cores;
};
中,对于我们来说,只要获得x86_vendor_id和x86_model_id两项信息即可,前者记录的是CPU的制造商的信息,后者记录CPU的记录信息。在Linux下,可以通过以下代码获得:
static inline void
cpuid(int op, unsigned int *eax, unsigned int *ebx,
unsigned int *ecx, unsigned int *edx)
{
__asm__("cpuid"
: "=a" (*eax),
"=b" (*ebx),
"=c" (*ecx),
"=d" (*edx)
: "0" (op));
}
static unsigned int
get_cpu_id()
{
unsigned int *v;
cpuid(0x00000000, &cpu_info.cpuid_level,
(int *)&cpu_info.x86_vendor_id[0],
(int *)&cpu_info.x86_vendor_id[8],
(int *)&cpu_info.x86_vendor_id[4]);
v = (unsigned int *) cpu_info.x86_model_id;
cpuid(0x80000002, &v[0], &v[1], &v[2], &v[3]);
cpuid(0x80000003, &v[4], &v[5], &v[6], &v[7]);
cpuid(0x80000004, &v[8], &v[9], &v[10], &v[11]);
return 0;
}
这样,CPU的信息就存储在cpu_info中。
2.