首页
社区
课程
招聘
[原创]010editor4.03注册算法分析
发表于: 2012-12-22 22:06 11739

[原创]010editor4.03注册算法分析

2012-12-22 22:06
11739
写在前面:
大半年忙东忙西,很少有时间弄技术上的东西了,前几天和一个学长闲聊,他说之前做了一个小东西,就是分析010editor的注册算法,然后就找了一个"最新"的来试试。弄了几天基本算完成了,后面一直偷懒没有写文档,这会儿慢慢补充好吧。

.text:00550267                 cmp     edi, 0DBh       ; 同时,要来到这里进行判断,有三条路线
.text:0055026D                 jnz     short loc_5502A7 ; 只有这条路线是正确的,此时edi必须要等于0xDB
.text:0055026F                 push    0FFFFFFFFh
.text:00550271                 push    offset aPasswordAccept ; "Password accepted. Thank you for purcha"...
.text:00550276                 call    ebp ; QString::fromAscii_helper(char const *,int) ; QString::fromAscii_helper(char const *,int)
.text:00550278                 mov     [esp+40h+var_18], eax



根据IDA的交叉引用,我们可以看到,达到这一步,必须满足:
loc_550267:             ; 同时,要来到这里进行判断,有三条路线
cmp     edi, 0DBh
jnz     short loc_5502A7 ; 只有这条路线是正确的,此时edi必须要等于0xDB


我们看到,理论上从在三种可能性,我们逐一来看:
总原则:
Edi必须等于0xDB

push    3C70h
push    5
call    sub_403963      ; 有三种返回情况:0xE7,0x4E,0x2D
mov     ecx, dword_7D6E24 ; 关键算法点之一
push    3C70h
push    5
mov     ebx, eax
call    sub_40897C      ; 这个函数会影响到edi的值(返回值赋值给edi)
mov     ecx, dword_7D6E24 ; 尽管后面有三条路线,但是不管怎么说edi都必须为0xDB
xor     edx, edx        ; '关键算法点之一'如果返回的是0x2D,那么edi就为0xDB
mov     edi, eax        ; ‘关键算法点之一’如果返回的是0xE7,那么edi为0x177
mov     eax, [ecx+34h]
test    eax, eax
setz    dl
mov     [esp+38h+var_10], edx
cmp     ebx, 0E7h
jz      loc_550267      ; 如果这一条路想走通,必须满足:ebx为0xE7,edi为0xDB


我们注意到,前面调用了两个函数:sub_403963和sub_40897C。并且,sub_403963的返回值决定了ebx的值,而sub_40897C的返回值决定了edi的值。
如果jz跳转成立,则跳转到了图2处,则此时满足ebx为0x2d,edi为0xDB既可实现注册。

下面,分析sub_616050函数

.text:00616081                 jz      loc_6163DF      ; 类中的标志位比较
.text:00616087                 mov     ecx, [esi+8]
.text:0061608A                 cmp     [ecx+8], ebp
.text:0061608D                 jz      loc_6163DF      ; 类中的标志位比较
.text:00616093                 push    edi
.text:00616094                 lea     edx, [esp+30h+var_18] ; edx的值就是存放处理之后的密码串的地址
.text:00616098                 push    edx
.text:00616099                 mov     ecx, esi
.text:0061609B                 call    sub_40889B      ; 这个函数里面对输入的密码进行了操作
.text:006160A0                 mov     edi, offset off_7D58B8
.text:006160A5
.text:006160A5 loc_6160A5:                             ; CODE XREF: sub_616050+71j
.text:006160A5                 mov     eax, [edi]
.text:006160A7                 push    eax
.text:006160A8                 mov     ecx, ebx
.text:006160AA                 call    ds:??8QString@@QBE_NPBD@Z ; QString::operator==(char const *)
.text:006160B0                 test    al, al
.text:006160B2                 jnz     loc_616279
.text:006160B8                 add     edi, 4
.text:006160BB                 cmp     edi, offset unk_7D58BC
.text:006160C1                 jl      short loc_6160A5


首先,判断了两个标志位之后,会进入sub_40889B函数对输入的密码串进行操作,每位字符转化成相应的hex值(目前只考虑0-f的情况,不区分大小写)。
现在,我们假设到这里的时候,我们输入的密码串转换成了一个byte数组,称其为数组a。
比如,输入的用户名:loongzyd,密码:0fb6bcace7870c1fe696

数组a:
注意到这个函数有三种返回值:0xE7,0x4E,0x2D,而依据总原则:”edi必须等于0xDB”,加上后面的逆向倒推分析可知:该函数的返回值必须为0x2D。

那现在往下分析,怎么样才能让程序流程执行下去使得函数返回0x2D.

.text:006160C3                 mov     al, [esp+30h+var_15] ; al = a[3]
.text:006160C7                 mov     bl, byte ptr [esp+30h+var_14+1] ; bl = a[5]
.text:006160CB                 cmp     al, 9Ch         ; 判断a[3]是否为0x9c
.text:006160CD                 jnz     short loc_616149 ; 判断7,8位是不是F,C

如果a[3]为0x9c,则有一条分支往下走;

.text:00616149                 cmp     al, 0FCh        ; 判断7,8位是不是F,C
.text:0061614B                 jnz     short loc_616165


如果a[3]为0xfc,则有一条分支往下走;

.text:00616165                 cmp     al, 0ACh
.text:00616167                 jnz     loc_616279      ; 判断7,8位是不是A,C


如果a[3]为0xac,则有一条分支往下走;
结论:a[3]必须为0x9c,0xfc,,0xac这三个值之一,否则就会失败。

当a[3]为0x9c时:
.text:006160CF                 mov     dl, byte ptr [esp+30h+var_14+3] ; 第8位 a[7]
.text:006160D3                 xor     dl, [esp+30h+var_17] ; dl = a[7] ^ a[1] (第二位)
.text:006160D7                 mov     cl, byte ptr [esp+30h+var_14+2] ; 第7位 a[6]
.text:006160DB                 xor     cl, [esp+30h+var_18] ; cl = a[6] ^ a[0] (第一位)
.text:006160DF                 movzx   ax, dl          ; ax = a[7] ^ a[1]
.text:006160E3                 mov     byte ptr [esp+30h+var_1C], cl ; [esp+14] = a[6] ^ a[0]
.text:006160E7                 mov     ecx, 100h
.text:006160EC                 imul    ax, cx          ; ax = (a[7] ^ a[1]) << 8
.text:006160F0                 mov     dl, bl          ; dl = a[5] (第6位)
.text:006160F2                 xor     dl, [esp+30h+var_16] ; dl = a[5] ^ a[2] (第三位)
.text:006160F6                 movzx   cx, dl          ; cx = a[5] ^ a[2]
.text:006160FA                 mov     edx, [esp+30h+var_1C]
.text:006160FE                 add     ax, cx          ; ax = (a[7] ^ a[1]) << 8 + a[5] ^a[2]
.text:00616101                 push    edx             ; edx的值来源于[esp+14],等于a[6] ^ a[0]
.text:00616102                 movzx   edi, ax         ; edi = (a[7] ^ a[1]) << 8 + a[5] ^a[2]
.text:00616105                 call    sub_406D6B      ; eax = ((arg0 ^ 0x18) + 0x3D) ^ 0xA7
.text:0061610A                 movzx   eax, al         ; eax = (([esp+14] ^ 0x18) + 0x3D) ^ 0xA7
.text:0061610D                 push    edi
.text:0061610E                 mov     [esi+1Ch], eax  ; [esi+1c] = (([esp+14] ^ 0x18) + 0x3D) ^ 0xA7
.text:00616111                 call    sub_4077D4      ; eax = (((arg0 ^ 0x7892) + 0x4d30) ^ 0x3421) / 0xB
.text:00616116                 mov     ecx, [esi+1Ch]  ; 上一步中,除以0xB必须要整出,否则eax = 0,失败
.text:00616119                 movzx   eax, ax
.text:0061611C                 add     esp, 8
.text:0061611F                 mov     [esi+20h], eax  ; 假设得到的eax恰好为0x3E8
.text:00616122                 test    ecx, ecx        ; 坚决不能转 [esi+0x1C]的值不能为0
.text:00616124                 jz      loc_616279


要进过上述的计算,为了不是其跳转到eax=0xE7分支上面造成失败,必须满足:
1.((a[6] ^ a[0] ^ 0x18) + 0x3D ) ^ 0xA7 != 0 (令商为dev1)
2.arg0 = (a[7] ^ a[1])  <<  8 + a[5] ^ a[2]
  ((arg0 ^ 0x7892 + 0x4d30 ) ^ 0x3421) &&0x0ffff必须整除0xB,并且商不能大于0x3E8
(令商为dev2)


edi的值影响后面的计算流程

.text:006162BA loc_6162BA:                             ; CODE XREF: sub_616050+24Cj
.text:006162BA                 mov     cl, [esp+30h+var_15] ; 取a[3],判断标志位
.text:006162BE                 cmp     cl, 9Ch
.text:006162C1                 jnz     short loc_6162D2 ; 判断a[3]是否为0x9c


.text:006162C3                 mov     eax, [esp+30h+arg_0] ; 参数固定为5
.text:006162C7                 or      edx, 0FFFFFFFFh
.text:006162CA                 cmp     eax, [esi+1Ch]  ; (pass[6] ^ pass[0] ^ 0x18 + 0x3D ) ^ 0xA7的值必须要大于等于5
.text:006162CD                 jmp     loc_616352


条件3:
((a[6] ^ a[0] ^ 0x18) + 0x3D ) ^ 0xA7 >= 5

.text:00616220                 mov     eax, [ecx+0Ch]  ; 此时eax的值,为用户名字符串的地址
.text:00616223                 mov     edx, [esi+20h]  ; 上面除以0xB后的商
.text:00616226                 xor     ecx, ecx
.text:00616228                 cmp     [esp+30h+var_15], 0FCh ; 根据a[3]是否为0xFC,来决ecx为0,还是1
.text:0061622D                 push    edx
.text:0061622E                 setnz   cl              ; a[3]等于0xfc,则ecx=0,否则ecx=1
.text:00616231                 push    edi
.text:00616232                 push    ecx
.text:00616233                 push    eax             ; 根据用户名,进行一系列的运算
.text:00616234                 call    sub_40263F      ; 计算出来的'hash'值,决定了a[4],a[5],a[6],a[7]的值


sub_40263F是一个比较关键的函数,它可以根据上面的几个运算结果及用户名,算出一个’hash’,而这个’hash’可以决定a[4],a[5],a[6],a[7]的值
a[4] = hash & 0xff; a[5] = (hash >> 8) &0xff
a[6] = (hash >> 16) &0xff; a[7] = (hash >> 24) &0xff


将hash获取之后,再根据条件1,2,3我们就可以确定所有的密码字符(情况不唯一),具体参看源代码。

当a[3]为0xac时:


这个和前面的条件2是相同的:
arg0 = (a[7] ^ a[1])  <<  8 + a[5] ^ a[2]
((arg0 ^ 0x7892 + 0x4d30 ) ^ 0x3421) &&0x0ffff必须整除0xB,并且商不能大于0x3E8

.text:006161BB                 movzx   ecx, [esp+30h+var_F] ; ecx = A[9]
.text:006161C0                 movzx   eax, byte ptr [esp+30h+var_14] ; eax = a[4]
.text:006161C5                 movzx   edx, bl         ; edx = a[5]
.text:006161C8                 xor     ecx, edx        ; ecx = A[9] ^ a[5]
.text:006161CA                 movzx   edx, [esp+30h+var_10] ; edx = A[8]
.text:006161CF                 xor     eax, edx        ; eax = a[4] ^ A[8]
.text:006161D1                 movzx   edx, [esp+30h+var_18] ; edx = a[0]
.text:006161D6                 shl     ecx, 8
.text:006161D9                 add     ecx, eax        ; ecx = (A[9] ^ a[5]) << 8 + a[4] ^ A[8]
.text:006161DB                 movzx   eax, byte ptr [esp+30h+var_14+2] ; eax = a[6]
.text:006161E0                 shl     ecx, 8          ; ecx = ((A[9] ^ a[5]) << 8 + a[4] ^ A[8]) << 8
.text:006161E3                 xor     eax, edx        ; eax = a[6] ^ a[0]
.text:006161E5                 add     ecx, eax        ; ecx = ((A[9] ^ a[5]) << 8 + a[4] ^ A[8]) << 8 + a[6] ^ a[0]
.text:006161E7                 push    (offset loc_5B8C26+1)
.text:006161EC                 push    ecx
.text:006161ED                 call    sub_403882
.text:006161F2                 mov     ebp, eax        ; 不为0,且要大于等于0x3c70


.text:0061634B                 or      edx, 0FFFFFFFFh ; sub_403882的返回值必须大于0x3c70
.text:0061634E                 cmp     [esp+30h+arg_4], ebp ; 参数固定为0x3c70


sub_403882是个关键的函数,参数的值ecx涉及了多个密码数组元素,它必须满足返回值不为0,同时要大于等于0x3c70

.text:00616220                 mov     eax, [ecx+0Ch]  ; 此时eax的值,为用户名字符串的地址
.text:00616223                 mov     edx, [esi+20h]  ; 上面除以0xB后的商
.text:00616226                 xor     ecx, ecx
.text:00616228                 cmp     [esp+30h+var_15], 0FCh ; 根据a[3]是否为0xFC,来决ecx为0,还是1
.text:0061622D                 push    edx
.text:0061622E                 setnz   cl              ; a[3]等于0xfc,则ecx=0,否则ecx=1
.text:00616231                 push    edi
.text:00616232                 push    ecx
.text:00616233                 push    eax             ; 根据用户名,进行一系列的运算
.text:00616234                 call    sub_40263F      ; 计算出来的'hash'值,决定了a[4],a[5],a[6],a[7]的值


同样,也是根据用户名计算出一个hash,值得注意的是,当a[3]为0xac的时候,sub_40263f的一个参数是之前sub_403882函数的返回值。

大致的逻辑就可以确定了,详细见源代码。

当a[3]为0xfc时,这种情况不能满足条件。

下面关注一下获取hash的函数sub_614560,总体来看是根据用户名字符串依次进行循环操作,因为设计很多的移位,特别是imul指令,不太好用C语言表示,故直接用内联汇编来编写:
hash获取函数
int get_hash(char *name, int arg4, int arg8, int argc)
{
	int name_length;
	int argc_tmp;
	int arg8_tmp;
	int eax_tmp;
	int ecx_tmp;
	int edx_tmp;
	int index_i;
	int index_j;
	int index;
	int hash;

	name_length = strlen(name);
	argc_tmp = argc << 4;
	argc_tmp -= argc;   //edi
	arg8_tmp = arg8 << 4;
	arg8_tmp += arg8;   //esi
	index_i = 0;
	index_j = 0;
	hash = 0;

	if (arg4 != 0)
	{
		for(index = 0; index < name_length; index++)
		{
			if (name[index] >= 'a' && name[index] <= 'z')
			{
				eax_tmp = name[index] - 0x20;
			}
			else
			{
				eax_tmp = name[index];
			}
			_asm
			{
				mov eax, eax_tmp
				mov ecx, hash_table[eax*4]
				lea edx, [eax+0xd]
				and edx, 0xff
				add ecx, hash
				xor ecx, hash_table[edx*4]
				add eax, 0x2f
				and eax, 0xff
				imul ecx, hash_table[eax*4]
				mov edx, arg8_tmp
				and edx, 0xff
				add ecx, hash_table[edx*4]
				mov edx, index_j
				mov eax, argc_tmp
				and eax, 0xff
				add ecx, hash_table[eax*4]
				and edx, 0xff
				add ecx, hash_table[edx*4]
				mov hash, ecx
			}
			index_j += 0x13;
			argc_tmp += 0xd;
			arg8_tmp += 9;
		}
	}
	else
	{
		
		for(index = 0; index < name_length; index++)
		{
			if (name[index] >= 'a' && name[index] <= 'z')
			{
				eax_tmp = name[index] - 0x20;
			}
			else
			{
				eax_tmp = name[index];
			}
			_asm
			{
				mov eax, eax_tmp
				mov ecx, hash_table[eax*4]
				lea edx, [eax+0x3f]
				add edx, hash
				add eax, 0x17
				and ecx, 0xff
				xor ecx, hash_table[ecx*4]
				and eax, 0xff
				imul ecx, hash_table[eax*4]
				mov eax, arg8_tmp
				and eax, 0xff
				add edx, hash_table[eax*4]
				mov eax, index_i
				mov ecx, argc_tmp
				and ecx, 0xff
				add edx, hash_table[ecx*4]
				and eax, 0xff
				add edx, hash_table[eax*4]
				mov hash, edx
			}
			index_i += 0x7;
			arg8_tmp += 0x9;
			argc_tmp += 0xd;
		}
	}
	return hash;
}


其中,要涉及一个数组表,这里采用IDA中的IDC脚本语言来获取(具体参加代码),运行之后在C盘根目录中会出现一个1.txt文件,里面就是需要的数组。
IDC脚本:
auto address;
auto num;
auto str;
auto index;
auto file_handle;

address = 0x7D53E8;
index = 0;

file_handle = fopen("c:\\1.txt", "w");
writestr(file_handle, "hash_table[] = {");
while(1)
{
   num = Dword(address);
   if (num != 0)
   {
      str = ltoa(num, 16);
      str = "0x" + str + ", ";
      Message("%s\n", str);
      writestr(file_handle, str);
      address = address + 4;
      index = index + 1;
      if (index % 4 == 0)
      {
         writestr(file_handle, "\n");
      }
   }
   else
   {
      break;
   }
}
writestr(file_handle, "};");
fclose(file_handle);
Message("over\n", num);


比较纠结的还有一个,sub_614880,逆向推理之后进行了偷懒,简化成:
(不是考虑了所有的情况)

for (i = 0x40370; i < 0xffffff; i += 0x11)
	{
		_asm
		{
			mov eax, 0x0f0f0f0f1
			mov ecx, i
			mul ecx
			shr edx, 4
			mov t, edx
		}
		if (t < 0x3c70)
		{
			continue;
		}
		if (t * 0x11 == i)
  {
  符合条件
  }
   }


通过上面的分析,算法部分就完成了,注册机里面的密码,绝大部分都是符合算法本身的;
不过因为软件有联网的检测,注册一段时间之后不能重新注册,应该是和MAC地址绑定了,在虚拟机注册之后回滚了,然后几天之后发现同样的用户名和密码就不能用了。
有两处是需要注意的:
.text:00617B53                 cmp     dword ptr [esi+2Ch], 0 ; 如果[esi+0x2C]不为0,则返回的是0x113,应该就失败了

.text:005500D8                 cmp     dword ptr [ecx+2Ch], 0 ; 这里ecx应该是某个对象的指针 要搞清楚[ecx+0x2C]的含义

这两处中ecx和esi的值是一样的,所代表的含义也是一样的。在第一次进行注册之前,[this+0x2c]为0,用户名和密码符合算法要求后即可正确注册,虚拟机回滚几天之后,再次注册的时候,[this+0x2c]的值变成了1,意味着即使有相同的用户名和密码也不能注册了。估计是通过网络验证限制了一台机器的注册次数,当我们验证的时候需要注意到这点,[this+0x2c]的值和我们输入的用户名和密码是无关的,手动修改即可。

简易注册机:
010editor.txt
注册机算法里面,简略了很多数学的操作,从严谨上来说,忽略了很多情况,只是能找到符合算法的用户名和密码。从使用角度上来说,爆破即可。

赶着末日重生第一天,有些措辞或者介绍的不详细,慢慢修复,敬请谅解

[培训]《安卓高级研修班(网课)》月薪三万计划,掌握调试、分析还原ollvm、vmp的方法,定制art虚拟机自动化脱壳的方法

上传的附件:
收藏
免费 6
支持
分享
最新回复 (16)
雪    币: 44229
活跃值: (19965)
能力值: (RANK:350 )
在线值:
发帖
回帖
粉丝
2
末日重生第1天~
2012-12-22 22:11
0
雪    币: 303
活跃值: (30)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
未日重生第1天~
2012-12-22 22:13
0
雪    币: 316
活跃值: (128)
能力值: ( LV7,RANK:110 )
在线值:
发帖
回帖
粉丝
4
老大是故意打错字还是?
2012-12-22 22:14
0
雪    币: 316
活跃值: (128)
能力值: ( LV7,RANK:110 )
在线值:
发帖
回帖
粉丝
5
大哥,你比我快。
2012-12-22 22:14
0
雪    币: 44229
活跃值: (19965)
能力值: (RANK:350 )
在线值:
发帖
回帖
粉丝
6
五笔输入,一快就错了,呵~
2012-12-22 22:25
0
雪    币: 433
活跃值: (1875)
能力值: ( LV17,RANK:1820 )
在线值:
发帖
回帖
粉丝
7
编译源码出错,求一份注册码,不知道mac版的适用不?
2012-12-23 10:24
0
雪    币: 1015
活跃值: (235)
能力值: ( LV12,RANK:440 )
在线值:
发帖
回帖
粉丝
8
我这边编译没有问题啦。
用户名: riusksk
pass: 3064e89cf9d332cd
pass: 3164e89cf9d332cd
pass: 3264e89cf9d332cd
pass: 3364e89cf9d332cd
pass: 3464e89cf9d332cd
pass: 3564e89cf9d332cd
pass: 3664e89cf9d332cd
pass: 3764e89cf9d332cd
pass: 3864e89cf9d332cd
pass: 3964e89cf9d332cd
pass: 6164e89cf9d332cd
pass: 6264e89cf9d332cd
pass: 6364e89cf9d332cd
pass: 6464e89cf9d332cd
pass: 6564e89cf9d332cd
pass: 6664e89cf9d332cd
pass: 6764e89cf9d332cd
pass: 6864e89cf9d332cd
pass: 6964e89cf9d332cd
pass: 6a64e89cf9d332cd
pass: 6b64e89cf9d332cd
pass: 6c64e89cf9d332cd
pass: 6d64e89cf9d332cd
pass: 6e64e89cf9d332cd
pass: 6f64e89cf9d332cd
pass: 7064e89cf9d332cd
pass: 7164e89cf9d332cd
pass: 7264e89cf9d332cd
pass: 7364e89cf9d332cd
pass: 7464e89cf9d332cd
pass: 7564e89cf9d332cd
pass: 7664e89cf9d332cd
pass: 7764e89cf9d332cd
pass: 7864e89cf9d332cd
pass: 7964e89cf9d332cd
pass: 7a64e89cf9d332cd
pass: 1bf9a2acd799c8506803
pass: 8c697cac244788c09cdd
pass: 35fcceacc7f500557f6f
pass: 0eadfcacb7c768040f5d
pass: 1b7556ac216d0cdc99f7
pass: d0de90ac98ab98772031
pass: d401d7ac0decada8b576
pass: b817c3ac3ff812be8062
pass: 01507cacd1474af969dd
pass: 988527acba1c242c0086
pass: 99d9ffacd8c43470625e

后面的一些pass从算法上讲应该都能用的噢。
mac就不晓得了... 没钱买
2012-12-23 14:43
0
雪    币: 9583
活跃值: (1935)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
9
大牛神作,请问下楼主,你的注册机源代码用的什么编译器?我用Gcc出错,用vc6有6个警告,虽然可以编译出exe文件,但执行时会无限循环。
2012-12-23 15:13
0
雪    币: 1015
活跃值: (235)
能力值: ( LV12,RANK:440 )
在线值:
发帖
回帖
粉丝
10
不好意思,弄得是有点粗糙。vc6.0即可,警告可以忽略。至于“无限循环"是因为一个用户名对应的可用密码太多,一直在计算而已,可以简单修改一下,添加一个计数器,指定显示出部分可用密码就行了。
2012-12-23 15:31
0
雪    币: 1919
活跃值: (901)
能力值: ( LV9,RANK:490 )
在线值:
发帖
回帖
粉丝
11
不错,学习哈,同时说明我还健在
2012-12-23 15:50
0
雪    币: 292
活跃值: (153)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
12
你是留在 北京了 还是 成都了?  最近怎么样啊?
2012-12-23 17:19
0
雪    币: 433
活跃值: (1875)
能力值: ( LV17,RANK:1820 )
在线值:
发帖
回帖
粉丝
13
非常感谢 loongzyd,我试试,哈哈
2012-12-23 21:55
0
雪    币: 136
活跃值: (105)
能力值: ( LV9,RANK:140 )
在线值:
发帖
回帖
粉丝
14
膜拜下算法大人的
2012-12-23 22:12
0
雪    币: 10867
活跃值: (17252)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
15
来学习一下经验啊
2012-12-26 08:26
0
雪    币: 219
活跃值: (1634)
能力值: ( LV9,RANK:410 )
在线值:
发帖
回帖
粉丝
16
强大的很,学习了
2012-12-26 18:23
0
雪    币: 93944
活跃值: (200219)
能力值: (RANK:10 )
在线值:
发帖
回帖
粉丝
17
Thanks for share.
上传的附件:
2012-12-30 04:00
0
游客
登录 | 注册 方可回帖
返回
//