6. 研究flexlm主要需要哪些资料?
flexlm相对来说资源丰富,基本上每个版本的sdk都有泄漏。
如果想深入研究flexlm的加密算法,flexlm sdk是必需的。
写kg是必须要读sdk的,值得注意的是v9.2 sdk sourcecode泄漏。这个网上可搜索到。
sdk有一部分是c代码,里面最有用的是l_prikey.c, 这里有ECDSA验证的函数。
这个文件的尾部有300行comments,其中有一封email很值得一读。
ECC核心库没有源文件,只有lib文件。
在certicom目录下的lib里面,主要为libsb.lib等(Certicom 的加密库:Security Builder)。
lib是混淆过了的,但是不影响ida反编译,只是不便于做sig文件。
主要依靠人脑识别函数,需要经验和时间。
7. flexlm的key加密强度有哪些?
以flexlm sdk v9为例,用宏定义表示LM_SIGN_LEVEL。
#define LM_SIGN2 2 /* SIGN2= */
#define LM_SIGN 1 /* SIGN= the default */
#define LM_NO_SIGN 0 /* license key */
v9以后,默认就采用ECC PUBKEY加密。SIGN支持ECC,所以大部分情况下用SIGN比较多,有些用SIGN2。
LM_NO_SIGN 是传统的license key, 强度最弱,不建议使用。
ECC PUBKEY 只有3种类别, 113, 163, 239 bits。
对应的sign长度(字符数) , 字节为( bits + 7 )/8 字节数 , 打印出来,
用hex digits表示,ECC的SIGN长度分别是一对 30,42,60 [0-9,A-F]。
采用ECC的,pubkey_strength 必须定义为下面的一个类别,否则l_pubkey_verify会出错:
LM_STRENGTH_113BIT,LM_STRENGTH_163BIT,LM_STRENGTH_239BIT。
#define LM_STRENGTH_LICENSE_KEY 0
#define LM_STRENGTH_DEFAULT 1
#define LM_STRENGTH_113BIT 2
#define LM_STRENGTH_163BIT 3
#define LM_STRENGTH_239BIT 4
#define LM_STRENGTH_PUBKEY LM_STRENGTH_113BIT
#define LM_STRENGTH_VERYHIGH LM_STRENGTH_239BIT
在l_pubkey_verify 有这么一段初始化代码, 判断pubkey_strength。
switch(pubkey_strength)
{
case LM_STRENGTH_LICENSE_KEY:
return 0;
case LM_STRENGTH_113BIT: ellipticCurve = &LM_PUBKEY_CURVE113BIT;
break;
case LM_STRENGTH_163BIT: ellipticCurve = &LM_PUBKEY_CURVE163BIT;
break;
case LM_STRENGTH_239BIT: ellipticCurve = &LM_PUBKEY_CURVE239BIT;
break;
default:
{
fprintf(stderr,
"LM_STRENGTH in lm_code.h has invalid value %d\n",
pubkey_strength);
fprintf(stderr,
"Use only LM_STRENGTH_[113|163|239]BIT, LM_STRENGTH_DEFAULT, OR LM_STRENGTH_LICENSE_KEY, exiting\n");
exit(1);
}
}
下面,演示 113, 163, 239 bits的ECDSA签名一段最简单的文本,
msg: "123"
sha hash:40BD001563085FC35165329EA1FF5C5ECBDBBEEF
#define LM_SEED1 0x47d381a0
#define LM_SEED2 0x4fadf97c
#define LM_SEED3 0xc4ae244c
l_genkeys: seed[3]=A081D3477CF9AD4F4C24AEC4
LM_PUBKEY_CURVE113BIT
prvlen=15, prv=00CFDF0247BF6EC0C8D1AA16DD505F
publen=16, pub=0301523DD4646BB65FE4238B8AB44D01
>> l_prikey_sign_dbg start >>
signing "123"
hash=40BD001563085FC35165329EA1FF5C5ECBDBBEEF
>> l_prikey_sign_dbg done >>
siglen=30
sig.r=0048D5DD2A57B1A1B357E98C193E63
sig.s=000A6FFDF76899F05ABFD2EDD9E065
LM_PUBKEY_CURVE163BIT
prvlen=21, prv=03DC603CB1683D43FF5631BBEEC5396D7BD4067300
publen=22, pub=0300368FE93082E1ACDD35222AD76782DBA8237B66EC
>> l_prikey_sign_dbg start >>
signing "123"
hash=40BD001563085FC35165329EA1FF5C5ECBDBBEEF
>> l_prikey_sign_dbg done >>
siglen=42
sig.r=039283F2FEA664BE7628F89BBA9D014E89E3868D2C
sig.s=017DA34A68C3FC64CB6EBE2B13676B04BE97EB5C20
LM_PUBKEY_CURVE239BIT
prvlen=30, prv=13C0E251A5130072A8D2D953EB2C94FAD487C0141B3197863BCC115D7B7E
publen=31, pub=035875A53B693A2861837E08FC6A7C58529DF52B565111C3DF55F18E34C9FA
>> l_prikey_sign_dbg start >>
signing "123"
hash=40BD001563085FC35165329EA1FF5C5ECBDBBEEF
>> l_prikey_sign_dbg done >>
inputlen=3, input=123
siglen=60
sig.r=1589FCFE91F988D28F7072DBF129424F0D71FA5E7AAC39258F3C408A656A
sig.s=0B50642E8ED77FC6A1E6F805CFA0299F44BC7B8035FE17142812B79EA576
sig.r sig.s组成一个完整的SIGN, 输出lic的时候,为了可读性, 一般切分为16 bit的分组(4个hex char)。
比如:
sig.r=038B9BE995B887B2665C02940C00155DD557C278AC95EADC1BD668DF185B
sig.s=1C50F25E81044E4DD9AD072699AAB4A63F4C99249AC8C091F476A6C73682
转化为:
SIGN=“ 038B9BE995B887B2665C02940C00155DD557C278AC95EADC1BD668DF185B
1C50F25E81044E4DD9AD072699AAB4A63F4C99249AC8C091F476A6C73682”
或者:
SIGN="038B 9BE9 95B8 87B2 665C 0294 0C00 155D D557 C278 AC95 EADC 1BD6 68DF 185B 1C50 F25E 8104 4E4D D9AD 0726 99AA B4A6 3F4C 9924 9AC8 C091 F476 A6C7 3682"
对flexlm的程序来说,是没有差别的。 都能处理。
8. flexlm用到的椭圆曲线有哪些?
flexlm用到三条椭圆曲线,都是有来历的, 名字分别为sect113r1, sect163k1, sect239k1。
具体参数可以参看:
http://en.wikipedia.org/wiki/SECG
SEC 2: Recommended Elliptic Curve Domain Parameters (Version 2.0)
在flexlm lib里面, 它是写死的静态变量。位置在
certicom\libcrvs.lib
保存为3个结构体:
struct ellipticCurveParameters sect113r1
struct ellipticCurveParameters ec163a02
struct ellipticCurveParameters ec239a03
头文件在
erticom\i86_n3\include\curves.h
/*=== Curves Definitions ==================
*
* sect113r1 (K-163 NIST), ec163a02 (SEC2, sect163k1) , ec239a03 (sec2, sect239k1)
*/
#define LM_PUBKEY_CURVE113BIT sect113r1
#define LM_PUBKEY_CURVE163BIT ec163a02
#define LM_PUBKEY_CURVE239BIT ec239a03
#define MAXIM_OID_CHARS 31
struct ellipticCurveParameters {
#pragma pack(4)
unsigned char oid[ MAXIM_OID_CHARS + 1 ];
struct {
unsigned char major[ 1 ];
unsigned char minor[ 1 ];
} version;
unsigned char checksum[ 4 ];
unsigned char fieldSize[ 2 ]; /* bits */
unsigned char fieldSizeOctets[ 1 ]; /* octets */
unsigned char basisType[ 1 ];
unsigned char modulus[ 32 ];
const unsigned char *ident1;
const unsigned char *ident2;
struct {
unsigned char a[ 32 ];
unsigned char b[ 32 ];
} curveParameter;
struct {
unsigned char value[ 64 ];
} generatingPoint;
struct {
unsigned char size[ 2 ]; /* bits */
unsigned char value[ 32 ];
} pointOrder;
struct {
unsigned char size[ 2 ]; /* bits */
unsigned char value[ 32 ];
} cofactor;
struct {
unsigned char size[ 2 ]; /* bits */
unsigned char value[ 32 ];
} curveOrder;
#pragma pack(2)
struct {
unsigned char A[ 32 ];
unsigned char B[ 32 ];
} reserved;
} ;
9. flexlm ecc ellipticCurveParameters 结构体中 checksum的怎么计算的?
ellipticCurveParameters 带有4字节checksum,
每次初始化ECC计算时,都会校验checksum。一方面为了避错, 另一方面为了反对篡改。
修改其中的公钥,必须重新计算checksum。
从libsb.lib里面分析反汇编代码, 逆向为c代码,经测试无误的代码:
int checksum(unsigned int len, void *src , int *val)
{
unsigned int i;
unsigned int h;
unsigned int c;
unsigned char *p = (unsigned char *)src;
if((p == 0) || (val == 0) || (len == 0))
return 1;
i = 0;
c = *val;
while(i < len)
{
c = p[i] + c * 16;
h = c & 0xF0000000;
if ( h != 0)
c ^= (h >> 24);
c &= ~h;
i++;
}
*val = c;
return 0;
}
unsigned int getbits(unsigned char *p, unsigned int len)
{
unsigned int val;
val = 0;
while(len --) {
val <<= 8;
val += *p++;
}
return val ;
}
unsigned int getbytes(unsigned char *p, unsigned int len)
{
unsigned int bits = getbits(p , len);
return ((bits + 7) >> 3);
}
int do_ecp_checksum(struct ellipticCurveParameters *e, int *sum1, int *sum2)
{
unsigned int val = getbytes(e->fieldSize, 2);
unsigned int bytes = val;
unsigned char *p = (unsigned char *)e;
#if 1
checksum(sizeof(e->oid), &e->oid, sum2);
checksum(sizeof(e->version.major), &e->version.major, sum2);
checksum(sizeof(e->version.minor), &e->version.minor, sum2);
checksum(sizeof(e->fieldSize), &e->fieldSize, sum2);
checksum(sizeof(e->fieldSizeOctets), &e->fieldSizeOctets, sum2);
checksum(sizeof(e->basisType), &e->basisType, sum2);
#endif
checksum(32u, p, sum1);
checksum(1u, p + 32, sum1);
checksum(1u, p + 33, sum1);
checksum(2u, p + 38, sum1);
checksum(1u, p + 40, sum1);
checksum(1u, p + 41, sum1);
#if 1
checksum(bytes, &e->modulus, sum2);
checksum(bytes, &e->curveParameter.a, sum2);
checksum(bytes, &e->curveParameter.b, sum2);
checksum(2 * bytes, &e->generatingPoint.value, sum2);
#endif
checksum(val, p + 42, sum1);
checksum(val, p + 84, sum1);
checksum(val, p + 116, sum1);
checksum(2 * val, p + 148, sum1);
#if 1
checksum(2, &e->pointOrder.size, sum2);
checksum(getbytes(e->pointOrder.size, 2), &e->pointOrder.value, sum2);
checksum(2, &e->cofactor.size, sum2);
checksum(getbytes(e->cofactor.size, 2), &e->cofactor.value, sum2);
checksum(2, &e->curveOrder.size, sum2);
checksum(getbytes(e->curveOrder.size, 2), &e->curveOrder.value, sum2);
checksum(bytes, &e->reserved.A, sum2);
checksum(bytes, &e->reserved.B, sum2);
#endif
checksum(2u, p + 212, sum1);
checksum(getbytes(e->pointOrder.size, 2), p + 214, sum1);
checksum(2u, p + 246, sum1);
checksum(getbytes(e->cofactor.size, 2), p + 248, sum1);
checksum(2u, p + 280, sum1);
checksum(getbytes(e->curveOrder.size, 2), p + 282, sum1);
checksum(val, p + 314, sum1);
checksum(val, p + 346, sum1);
return val;
}
10. flexlm ecc三条椭圆曲线的参数?
flexlm 采用GF(2^m)椭圆曲线。这三条椭圆曲线, 在openssl也有描述的。
在certicom\libcrvs.lib是纯数据保存。
openssl描述:
EcRecommendedParameters<EC2N>(ASN1::sect113r1(),
113, 9, 0,
A/a2 = "003088250CA6E7C7FE649CE85820F7",
B/a6 = "00E8BEE4D3E2260744188BE0E9C723",
"04009D73616F35F4AB1407D73562C10F00A52830277958EE84D1315ED31886",
"0100000000000000D9CCEC8A39E56F",
2),
EcRecommendedParameters<EC2N>(ASN1::sect239k1(),
239, 158, 0,
"000000000000000000000000000000000000000000000000000000000000",
"000000000000000000000000000000000000000000000000000000000001",
"04
29A0B6A887A983E9730988A68727A8B2D126C44CC2CC7B2A6555193035DC7
6310804F12E549BDB011C103089E73510ACB275FC312A5DC6B76553F0CA",
"2000000000000000000000000000005A79FEC67CB6E91F1C1DA800E478A5",
4),
EcRecommendedParameters<EC2N>(ASN1::sect163k1(),
163, 7, 6, 3, 0,
"000000000000000000000000000000000000000001",
"000000000000000000000000000000000000000001",
"0402FE13C0537BBC11ACAA07D793DE4E6D5E5C94EEE80289070FB05D38FF58321F2E800536D538CCDAA3D9",
"04000000000000000000020108A2E0CC0D99F8A5EF",
2),
flexlm sdk
\certicom\libcrvs.lib 内存dump, checksum只需要签名378 bytes的结构体。
为了调试和区分的方便, 我在尾部增加了标志:
'E' 'C' '1' '1' , 'E' 'C' '1' '6' , 'E' 'C' '2 '3' , 分别表示ecc 113, 163, 239 bits。
unsigned char ec113[384] = {
0x06, 0x05, 0x2B, 0x81, 0x04, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x02, 0x00, 0x04, 0x43, 0x8E, 0x10, 0x00, 0x71, 0x0F, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0xCB, 0x46, 0x00,
0xF0, 0xCA, 0x46, 0x00, 0x00, 0x30, 0x88, 0x25, 0x0C, 0xA6, 0xE7, 0xC7, 0xFE, 0x64, 0x9C, 0xE8,
0x58, 0x20, 0xF7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0xE8, 0xBE, 0xE4, 0xD3, 0xE2, 0x26, 0x07, 0x44, 0x18, 0x8B, 0xE0,
0xE9, 0xC7, 0x23, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x9D, 0x73, 0x61, 0x6F, 0x35, 0xF4, 0xAB, 0x14, 0x07, 0xD7, 0x35,
0x62, 0xC1, 0x0F, 0x00, 0xA5, 0x28, 0x30, 0x27, 0x79, 0x58, 0xEE, 0x84, 0xD1, 0x31, 0x5E, 0xD3,
0x18, 0x86, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x71, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xD9, 0xCC,
0xEC, 0x8A, 0x39, 0xE5, 0x6F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x72, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x01, 0xB3, 0x99, 0xD9, 0x14, 0x73, 0xCA, 0xDE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 'E', 'C', '1', '1'
};
unsigned char ec163[384] = {
0x06, 0x05, 0x2B, 0x81, 0x04, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x02, 0x00, 0x07, 0x48, 0x77, 0x70, 0x00, 0xA3, 0x15, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC9, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xB0, 0xD4, 0x4D, 0x00,
0x00, 0xD3, 0x4D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x02, 0xFE, 0x13, 0xC0, 0x53, 0x7B, 0xBC, 0x11, 0xAC, 0xAA, 0x07, 0xD7,
0x93, 0xDE, 0x4E, 0x6D, 0x5E, 0x5C, 0x94, 0xEE, 0xE8, 0x02, 0x89, 0x07, 0x0F, 0xB0, 0x5D, 0x38,
0xFF, 0x58, 0x32, 0x1F, 0x2E, 0x80, 0x05, 0x36, 0xD5, 0x38, 0xCC, 0xDA, 0xA3, 0xD9, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0xA3, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x02, 0x01, 0x08, 0xA2, 0xE0, 0xCC, 0x0D, 0x99, 0xF8, 0xA5, 0xEF, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA4, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x04, 0x02, 0x11, 0x45, 0xC1, 0x98, 0x1B, 0x33, 0xF1, 0x4B, 0xDE, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,'E', 'C', '1', '6'
};
unsigned char ec239[384] = {
0x06, 0x05, 0x2B, 0x81, 0x04, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x02, 0x00, 0x0A, 0xD7, 0xBD, 0x00, 0x00, 0xEF, 0x1E, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0xE0, 0xCA, 0x46, 0x00,
0x30, 0xC9, 0x46, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x01, 0x00, 0x00, 0x29, 0xA0, 0xB6, 0xA8, 0x87, 0xA9, 0x83, 0xE9, 0x73, 0x09, 0x88, 0xA6,
0x87, 0x27, 0xA8, 0xB2, 0xD1, 0x26, 0xC4, 0x4C, 0xC2, 0xCC, 0x7B, 0x2A, 0x65, 0x55, 0x19, 0x30,
0x35, 0xDC, 0x76, 0x31, 0x08, 0x04, 0xF1, 0x2E, 0x54, 0x9B, 0xDB, 0x01, 0x1C, 0x10, 0x30, 0x89,
0xE7, 0x35, 0x10, 0xAC, 0xB2, 0x75, 0xFC, 0x31, 0x2A, 0x5D, 0xC6, 0xB7, 0x65, 0x53, 0xF0, 0xCA,
0x00, 0x00, 0x00, 0x00, 0x00, 0xEE, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x5A, 0x79, 0xFE, 0xC6, 0x7C, 0xB6, 0xE9, 0x1F, 0x1C, 0x1D, 0xA8,
0x00, 0xE4, 0x78, 0xA5, 0x00, 0x00, 0x00, 0x03, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x69, 0xE7, 0xFB, 0x19, 0xF2, 0xDB, 0xA4,
0x7C, 0x70, 0x76, 0xA0, 0x03, 0x91, 0xE2, 0x94, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 'E', 'C', '2', '3'
};