首页
社区
课程
招聘
[原创]Wing IDE 5.0 破解之寻找注册码
发表于: 2013-12-6 10:41 90774

[原创]Wing IDE 5.0 破解之寻找注册码

2013-12-6 10:41
90774
小弟混迹于看雪多年,今天首发破文,文笔太差,请大家指正

有前人爆破的经验就是好,前人是爆破abstract.pyo中的代码来实现的,对于完美主义的我们来说,直接弄个注册码多好~~
一.        工具:
1.        uncompyle2
2.        IDA Pro 6.1
3.        WingIDE 5.0本身
二.        工具安装
1.        安装Python2.7
2.        安装WinIDE 5.0
3.        解压uncompyle2,进入解压目录,执行命令python setup.py install
三.        破解过程
1.        直接拷贝C:\Wing IDE 5.0\bin\2.7\src.zip到C:\crack,解压。
2.        cd C:\Python27\Scripts,运行python uncompyle2 --py -o . c:\crack\src,反编译所有的pyo文件。
3.        启动WingIDE 5.0,选择”Obtain or extend a trial license”,获得个10天的试用。
点击help-->Enter License…,弹出的对话框中选择”Install and activate a permant license”,
随便输几个啥,我这里输入”FFFF”,提示如下图:

哈,说的很明白了。
4.        找License ID的规律
用WingIDE打开c:\crack\src\process\wingctl.py,搜索字符串”Invalid license id”,定位到这串代码
        if self.__fRadioActivate.get_active():
            id = self.__fLicenseIDEntry.get_text()
            errs, lic = abstract.[COLOR="Red"]ValidateAndNormalizeLicenseID(id)[/COLOR]
            if len(errs) == 0 and id[0] == 'T':
                errs.append(_('You cannot enter a trial license id here'))
            if len(errs) > 0:
                msg = _('Invalid license id: %s. Please check and correct it.  Errors found were:\n\n%s') % (id, '\n'.join(errs))
                buttons = [dialogs.CButtonSpec(_('_OK'), None, wgtk.STOCK_OK)]
                dlg = messages.CMessageDialog(self.fSingletons, _('Invalid License ID'), msg, [], buttons)
                dlg.RunAsModal(self)
                return True

这可以看到,License ID首字符如果是’T’的话,则是trial license,这当然不是我们要的。
右键点击ValidateAndNormalizeLicenseID,选Go to Definition,到
def ValidateAndNormalizeLicenseID(id):
    errs, id2 = __ValidateAndNormalize(id)
    if len(id2) > 0 and id2[0] not in kLicenseUseCodes:
        errs.append(_('Invalid first character: Should be one of %s') % str(kLicenseUseCodes))
    if len(id2) > 1 and id2[1] != kLicenseProdCode:
        cur_product = 'Wing IDE %s' % config.kProduct
        lic_product = kLicenseProdForCode.get(id2[1], None)
        if lic_product is None:
            lic_product = _('an unknown product')
        else:
            lic_product = 'Wing IDE %s' % config.k_ProductNames[lic_product]
        errs.append(_('Your license is for %s, but you are currently running %s.  Please download the correct product from http://wingware.com/downloads or upgrade your license at https://wingware.com/store/upgrade') % (lic_product, cur_product))
    if len(errs) > 0:
        check_code = id.strip().upper().replace('-', '')
        if len(check_code) == 16:
            looks_like_11 = True
            for c in check_code:
                if c not in '0123456789ABCDEF':
                    looks_like_11 = False

            if looks_like_11:
                errs = [_('You cannot activate using a Wing IDE 1.1 license:  Please use a trial license or upgrade your license at http://wingware.com/store/upgrade')]
    if len(errs) > 0:
        return (errs, None)
    else:
        return ([], id2)

这时我们发现,这个函数是在abstract.py中的。
我们首先看看__ValidateAndNormalize在干些啥,转到定义,
def __ValidateAndNormalize(code):
    """Remove hyphens and extra space/chars in a license id or activation
    request, and validate it as within the realm of possibility.  Returns
    errs, value."""
    errs = []
    code = code.strip().upper()
    code2 = ''
    badchars = ''
    for c in code:
        if c in ('-', ' ', '\t'):
            pass
        elif c not in textutils.BASE30:
            code2 += c
            if badchars.find(c) == -1:
                badchars += c
        else:
            code2 += c

    if len(badchars) > 0:
        errs.append(_('Contains invalid characters: %s') % badchars)
    if len(code2) != 20:
        errs.append(_('Wrong length (should contain 20 non-hyphen characters)'))
    if len(errs) > 0:
        return (errs, code2)
    else:
        return ([], AddHyphens(code2))

这我们可以看到,License ID的字符必须在BASE30的范围内并且除掉’-’、’ ’、’\t’等字符后必须有20个字符。
程序定义的BASE30 = '123456789ABCDEFGHJKLMNPQRTVWXY',
这个定义是在C:\crack\src\wingutils\ textutils.py中。
现在返回ValidateAndNormalizeLicenseID函数,从第二行知道License ID的首字符必须是
kLicenseUseCodes中的一个kLicenseUseCodes = ['T', 'N', 'E', 'C', '1', '3', '6'],前面说过,’T’表示trial license
第四行告诉我们,License ID的第二个字符必须是kLicenseProdCode中的一个
这个kLicenseProdCode定义如下
kLicenseProdCodes = {config.kProd101: '1',
 config.kProdPersonal: 'L',
 config.kProdProfessional: 'N',
 config.kProdEnterprise: 'E'}
kLicenseProdCode = kLicenseProdCodes[config.kProductCode]

因为我们安装的是Professional版本,所以第二个字符应该是’N’,Enterprise版本还真不知道在哪里下载,反正官网上找不到~~~
好了,总结一下:
License ID 必须有20个字符且每个字符必须是'123456789ABCDEFGHJKLMNPQRTVWXY'中的;
字符必须首字母必须是['T', 'N', 'E', 'C', '1', '3', '6']中的一个,但是我们不会用’T’;
第二个字符必须是['1','L','N','E']中的一个

那现在随便搞个”CN123-12345-12345-12345”输入:

Continue,哈,出来了这个,选择输入激活码

先不管,直接Continue,看看啥反应

哦,又是需要20个字符,并且必须是”AXX”开头,好吧,好戏要上场了。
5.        找Activation Code
还是在c:\crack\src\process\wingctl.py查找字符串” Invalid activation key”,来到这:
def __PageTwoContinue(self):
        if self.__fRadioDirect.get_active():
            self.__StartActivation()
            return True
        if self.__fRadioManual.get_active():
            act = self.__fManualEntry.get_text()
            errs, act = abstract.ValidateAndNormalizeActivation(act)
            if len(errs) > 0:
                title = _('Invalid License ID')
                msg = _('Invalid activation key: %s. Please check and correct it.  Errors found were:\n\n%s') % (self.__fManualEntry.get_text(), '\n'.join(errs))
                self.__ErrorDlg(title, msg)
                return True
            actbase = os.path.normpath(fileutils.join(config.kUserWingDir, 'license.pending'))

转到ValidateAndNormalizeActivation的定义处:
def ValidateAndNormalizeActivation(id):
    errs, id2 = __ValidateAndNormalize(id)
    if id2[:3] != kActivationPrefix:
        errs.append(_("Invalid prefix:  Should be '%s'") % kActivationPrefix)
    if len(errs) > 0:
        return (errs, None)
    else:
        return ([], id2)

又是__ValidateAndNormalize,前面已经分析过了。看后面,第二行代码清楚的告诉我们,
激活码前三个字符必须是kActivationPrefix ,这个kActivationPrefix = 'AXX'。
好了,我们随便输个”AXX23-12345-12345-12345”,这个当然是错误的。
在c:\crack\src\process\wingctl.py查找字符串” Invalid activation key”的下一处出现的地方,来到:
self.fLicense['activation'] = act
            err, info =[COLOR="Red"] self.fLicMgr._ValidateLicenseDict(self.fLicense, None)[/COLOR]
            if err != abstract.kLicenseOK:
                msg = _('Invalid activation key: %s. Please check and correct it.') % self.__fManualEntry.get_text()
                errs.append('Current activation -- failed:')
                errs.extend([ '  ' + t for t in self.fLicMgr._StatusToErrString((err, info)) ])
                if len(errs) > 0:
                    msg += _('  Validation errors were:\n\n%s') % '\n'.join(errs)
                title = _('Invalid License ID')

但是这里的函数self.fLicMgr._ValidateLicenseDict,用鼠标右键找不到定义的地方。
我们先看看self.fLicMgr是个啥东西,转到定义:
class CObtainLicenseDialog(dialogs.CGenericDialog):
    """Dialog used to obtain a new license"""
    kCharWidth = 60

    def __init__(self, singletons, lic = None):
        self.fSingletons = singletons
        [COLOR="red"]self.fLicMgr = singletons.fLicMgr[/COLOR]
        self.fLicense = lic

self.fLicMg是这个类初始化时传进来的,在类名上右键,点Find Points of Use,来到这里
def _ObtainLicense(self):
        """Prompt user to obtain a license, or quit if they don't get one"""
        if self._fPromptForSaveDialog or not wgtk.kQt and wgtk.gdk.pointer_is_grabbed():
            return
        if self.__fObtainLicenseDialog is not None:
            self.__fObtainLicenseDialog.Show()
            return
        self.__fObtainLicenseDialog =[COLOR="red"] CObtainLicenseDialog(self.fSingletons)[/COLOR]

这个_ObtainLicense函数是类CWingLicenseManager的成员,
初始化CObtainLicenseDialog的参数是类CWingLicenseManager的成员,转到定义
class CWingLicenseManager(abstract.CLicenseManager):
    """ Specialization of the generic license manager for use in Wing IDE """

    def __init__(self, singletons):
        """ Constructor """
        abstract.CLicenseManager.__init__(self)
        [COLOR="red"]self.fSingletons = singletons[/COLOR]
        self._fExpiringLicenseCheck = False
        self.__fObtainLicenseDialog = None
        self._fPromptForSaveDialog = False

找CWingLicenseManager这个类的使用点,来到singleton.py中
    def CreateLicMgr(self):
        """ Create license manager. Mucking with this code is a violation of
        your software license and a generally sleazy thing to do to a bunch of
        guys trying to make a living by creating some decent tools for you. So
        please don't do it. """
       [COLOR="red"] lic_mgr = process.wingctl.CWingLicenseManager(self)
        self.fLicMgr = lic_mgr[/COLOR]
        self.emit('changed', self)

这里终于可以知道CObtainLicenseDialog中的self.fLicMgr其实是CWingLicenseManager。
那么看看CWingLicenseManager的基类是啥?是abstract.py文件中的CLicenseManager,
这个类中有_ValidateLicenseDict()函数的定义。好了,转到这个函数去看看:
def _ValidateLicenseDict(self, lic, filename):
        """ Check license for internal integrity and expiration """
        lic['daysleft'] = _('expired')
        for key in kRequiredLicenseFields:
            if not lic.has_key(key):
                return (kLicenseCorrupt, _('Missing a required line %s') % key)

        err, msg = self._ValidatePlatform(lic['license'], lic['os'])
        if err != None:
            return (err, msg)
        err, msg = self._ValidateProduct(lic['product'])
        if err != None:
            return (err, msg)
        err, msg = self._ValidateVersion(lic['version'])
        if err != None:
            return (err, msg)
        try:
            lichash = CreateActivationRequest(lic)
            act30 = lic['activation']
            if lichash[2] not in 'X34':
                hasher = sha.new()
                hasher.update(lichash)
                hasher.update(lic['license'])
                digest = hasher.hexdigest().upper()
                lichash = lichash[:3] + textutils.SHAToBase30(digest)
                errs, lichash = ValidateAndNormalizeRequest(lichash)
            act = act30.replace('-', '')[3:]
            hexact = textutils.BaseConvert(act, textutils.BASE30, textutils.BASE16)
            while len(hexact) < 20:
                hexact = '0' + hexact

            config._locale_valid = 0
            [COLOR="red"]valid = control.validate(lichash, lic['os'], lic['version'][:lic['version'].find('.')], hexact)[/COLOR]
            valid = config._locale_valid
        except:
            valid = 0

        if not valid:
            return (kLicenseCorrupt, _('Invalid license activation'))
        daysleft = self._GetTermDaysLeft(lic)
        if daysleft == -1:
            lic['daysleft'] = _('unlimited')
        else:
            if daysleft == -2:
                return (kLicenseCorrupt, _('Invalid date or termdays in file'))
            if daysleft == 0:
                return (kLicenseExpired, None)
            if daysleft > 12 and lic['license'][0] == 'T':
                return (kLicenseCorrupt, _('Invalid date or termdays in file'))
            if daysleft > 190 and lic['license'][0] != 'T':
                return (kLicenseCorrupt, _('Invalid date or termdays in file'))
            lic['daysleft'] = str(daysleft) + _(' days left')
        errs = hostinfo.IDMatch(lic['hostinfo'])
        if len(errs) > 0:
            return (kLicenseHostMismatch, None)
        if filename is not None:
            err, info = self.__CheckUserCount(lic, filename)
        else:
            err = kLicenseOK
            info = []
        return (err, info)

可以看到,算法不复杂,用lichash和lic[‘license’]做sha运算,之后将sha的值用BASE30变换,
将lichash的前三个字符附加在前面的到新的lichash。
最初的lichash是CreateActivationRequest得到的,
这其实就是在要我们输入激活码那个对话框中显示的Request Code=’ RW518-Q2NNM-13PRE-JQ3JR’。
lic[‘license’]其实就是输入的License ID。
通过看ValidateAndNormalizeRequest的代码,可知lichash的前三个字符分别是:
’R’代表这个是Request code;’W’表示是Windows;’5’表示是5.*版本。
关键就在这句
valid = control.validate(lichash, lic['os'], lic['version'][:lic['version'].find('.')], hexact)
,好,看看control是啥定义:
if sys.platform[:5] in ('win32', 'darwi') or sys.platform[:5] == 'linux' and os.uname()[4] not in ('ppc', 'ppc64', 'arm7l'):
    [COLOR="Red"]import ctlutil as control[/COLOR]
else:
    try:
        import pycontrol
        control = pycontrol
    except ImportError:
        dirname = os.path.dirname(__file__).replace('.zip', '')
        control = LoadFromDat(fileutils.join(dirname, 'pycontrol.dat'), 'pycontrol')

这个ctlutil是啥?搜,我用的Everyting这软件,搜到C:\Wing IDE 5.0\bin\2.7\src\process\ctutil.pyd,这其实就是个dll,IDA反编译它。
反编译后的哑名函数不多,就5个,挨个看。看到sub_10001410这函数的时候,猛然发现有个”_locale_valid”
.text:10001410 sub_10001410    proc near               ; DATA XREF: .data:100030A8o
.text:10001410
.text:10001410 var_110         = dword ptr -110h
.text:10001410 var_10C         = dword ptr -10Ch
.text:10001410 var_108         = dword ptr -108h
.text:10001410 var_104         = dword ptr -104h
.text:10001410 var_100         = byte ptr -100h
.text:10001410 arg_4           = dword ptr  8
.text:10001410
.text:10001410                 sub     esp, 110h
.text:10001416                 cmp     dword_100030E0, 0
.text:1000141D                 jnz     short loc_10001432
.text:1000141F                 push    offset aConfig  ; "config"
.text:10001424                 call    ds:PyImport_ImportModule
.text:1000142A                 add     esp, 4
.text:1000142D                 mov     dword_100030E0, eax
.text:10001432
.text:10001432 loc_10001432:                           ; CODE XREF: sub_10001410+Dj
.text:10001432                 push    esi
.text:10001433                 mov     esi, ds:PyInt_FromLong
.text:10001439                 push    edi
.text:1000143A                 push    0
.text:1000143C                 call    esi ; PyInt_FromLong
.text:1000143E                 mov     edi, ds:PyObject_SetAttrString
.text:10001444                 push    eax
.text:10001445                 mov     eax, dword_100030E0
.text:1000144A                 [COLOR="red"]push    offset a_locale_valid ; "_locale_valid"[/COLOR]
.text:1000144F                 push    eax
.text:10001450                 call    edi ; PyObject_SetAttrString
.text:10001452                 lea     ecx, [esp+128h+var_108]

想到前面_ValidateLicenseDict的代码中也有这么一句:valid=config._local_valid,料想这函数就是在验证了。使用IDA强大的F5,马上就知道,sub_10001020是在计算真正的激活码
.text:10001489                 mov     ecx, [esp+118h+var_10C]
.text:1000148D                 lea     eax, [esp+118h+var_100]
.text:10001491                 push    eax             ; char *
.text:10001492                 mov     eax, [esp+11Ch+var_104]
.text:10001496                 push    ecx             ; int
.text:10001497                 mov     ecx, [esp+120h+var_110]
.text:1000149B                 call    sub_10001020    ; 计算真正的activation key
.text:100014A0                 add     esp, 8
.text:100014A3                 test    eax, eax
.text:100014A5                 jnz     short loc_100014FC
[COLOR="red"].text:100014A7                 mov     edx, [esp+118h+var_108] ; 得到输入的activation key的地址
.text:100014AB                 lea     ecx, [esp+118h+var_100] ; 得到计算的Activation Key的地址[/COLOR]
.text:100014AF                 nop
.text:100014B0
.text:100014B0 loc_100014B0:                           ; CODE XREF: sub_10001410+BAj
.text:100014B0                 mov     al, [ecx]
.text:100014B2                 cmp     al, [edx] ; 我的妈呀,明文比较呀,这是要发啊~~~
.text:100014B4                 jnz     short loc_100014D0
.text:100014B6                 test    al, al
.text:100014B8                 jz      short loc_100014CC
.text:100014BA                 mov     al, [ecx+1]
.text:100014BD                 cmp     al, [edx+1]
.text:100014C0                 jnz     short loc_100014D0
.text:100014C2                 add     ecx, 2
.text:100014C5                 add     edx, 2
.text:100014C8                 test    al, al
.text:100014CA                 jnz     short loc_100014B0

现在用IDA在1000149B处下断点调试,直接附加到wing.exe,输入License ID:” CN123-12345-12345-12345”,
输入假的激活码” AXX23-12345-12345-12345”。F8单步过lea ecx,[esp+118h+var_100],
内存窗口里转到ecx的地址,得到的是:
“55DF6297CE47296C1916”,这是真正的激活码的sha值,现在要做的就是把这sha转换到BASE30,
然后前面附加”AXX”就行了。新建一个py文件,转换代码如下:
realcode='55DF6297CE47296C1916'
act30=BaseConvert(realcode,BASE16,BASE30)
while len(act30) < 17:
    act30 = '1' + act30

这里的BaseConvert函数是从c:\crack\src\wingutils\textutils.py中拷贝来的。运行一下这个py,得到:
act30=”1X8TBXQFVWRYLBDKB”
所以激活码是AXX1X8TBXQFVWRYLBDKB
6.注册机的制作
进入sub_10001020,算法非常简单,不多说了,直接上注册机
CalcActivationCode.rar
注册机是个python源代码文件,没有使用任何附加库,直接可以跑
使用时,编辑下RequestCode就行了
看下效果吧

[课程]FART 脱壳王!加量不加价!FART作者讲授!

上传的附件:
收藏
免费 5
支持
分享
最新回复 (76)
雪    币: 2664
活跃值: (3401)
能力值: ( LV13,RANK:1760 )
在线值:
发帖
回帖
粉丝
2
沙发...   支持...
2013-12-6 11:58
0
雪    币: 271
活跃值: (13)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
支持,虽然没看懂。
2013-12-6 12:28
0
雪    币: 360
活跃值: (122)
能力值: ( LV2,RANK:15 )
在线值:
发帖
回帖
粉丝
4
楼主真棒
2013-12-6 12:29
0
雪    币: 3202
活跃值: (1917)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
目测又是一枚精华,请坛主鉴定宝物真伪。
2013-12-6 12:36
0
雪    币: 48
活跃值: (491)
能力值: ( LV8,RANK:130 )
在线值:
发帖
回帖
粉丝
6
哈哈,5.0内测的时候我就算出来了,没有时间写帖子。
2013-12-6 13:31
0
雪    币: 221
活跃值: (2256)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
7
能把工具uncompyle2发上来?
2013-12-6 14:20
0
雪    币: 358
活跃值: (45)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
8
从官网新下载的计算那里已经改了,刚整了下
license id:CN123-12345-12345-12345
key:AXX2MDR8NRCBHD74TVJ1
2013-12-6 14:36
0
雪    币: 228
活跃值: (35)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
9
每个机子的Request Code不一样,所以用同一个license id算出来的是不一样的
2013-12-6 15:00
0
雪    币: 228
活跃值: (35)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
10
大哥你google一下嘛
https://github.com/wibiti/uncompyle2/archive/master.zip
2013-12-6 15:06
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
11
这个分析的太棒了
2013-12-11 22:23
0
雪    币: 621
活跃值: (114)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
12
好吧,今天刚撞了kali,之前用的wingide4想试试5,谷歌下就找到了楼主的帖子...很好用!!
2013-12-24 11:51
0
雪    币: 201
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
13
请教下:data=[7,123,23,87],这个从哪里得出的呢?不太明白。
2014-1-5 19:47
0
雪    币: 228
活跃值: (35)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
14
[QUOTE=kavern;1252933]请教下:data=[7,123,23,87],这个从哪里得出的呢?不太明白。[/QUOTE]

分析IDA反编译ctutil.pyd后的函数sub_10001020里面的代码可以得到这些
2014-1-7 21:39
0
雪    币: 31
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
15
可以用,但是不能升级。说是license中不包含升级。
2014-2-10 19:23
0
雪    币: 31
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
16
[/QUOTE]
License ID 必须有20个字符且每个字符必须是'123456789ABCDEFGHJKLMNPQRTVWXY'中的;
字符必须首字母必须是['T', 'N', 'E', 'C', '1', '3', '6']中的一个,但是我们不会用’T’;
第二个字符必须是['1','L','N','E']中的一个。
那现在随便搞个”CN123-12345-12345-12345
[QUOTE]


这个可以注册,但是在线升级时提示license中没升级的权限。
后来,换了license id ,以EN开头,后面的按照要求随机填。就可以了。
2014-2-10 23:18
0
雪    币: 139
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
17
楼主辛苦了,补充一下:直接运行楼主的py文件是不行的,要动态把request code修改成本机的就行
2014-2-13 09:57
0
雪    币: 35
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
18
很佩服楼主!
2014-2-18 09:36
0
雪    币: 41
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
19
学习了 这分析得太厉害了
2014-2-19 20:06
0
雪    币: 406
活跃值: (164)
能力值: ( LV12,RANK:250 )
在线值:
发帖
回帖
粉丝
20
py的,感谢分享
2014-2-19 20:27
0
雪    币: 6
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
21
分析的非常好,学习了!
2014-2-21 16:01
0
雪    币: 39
活跃值: (154)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
22
收藏一下
2014-3-5 13:00
0
雪    币: 18
活跃值: (16)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
23
ver 5.0.3-1,用楼主的注册机算出来的号提示不对,RequestCode已经改成自己的了。
2014-3-13 15:06
0
雪    币: 35
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
24
楼主太猛了
2014-3-15 21:05
0
雪    币: 142
活跃值: (310)
能力值: ( LV4,RANK:40 )
在线值:
发帖
回帖
粉丝
25
厉害。。。
2014-3-26 03:48
0
游客
登录 | 注册 方可回帖
返回
//