首页
社区
课程
招聘
[原创]菜鸟从0开始学破解
发表于: 2009-3-16 18:22 12337

[原创]菜鸟从0开始学破解

2009-3-16 18:22
12337
先自我介绍一下,本人菜鸟一个。由于工作主要基于unix/linux平台,所以没有太多windows
编程经验及编程思想。而且。。还是做unix/linux应用层开发。。5555555,汇编丢给老师太
久了。

而本人又热衷游戏。所以看了不少文章和帖子后想提高下自己技能~~
很菜很菜的帖子,各位看官表笑。如果有可能,希望被加精~

开始吧

这是一个老游戏了,在中国开了没多久。。运营商倒闭。。囧
最近发现欧服可以免费玩了,于是开始重温,代号game1。

首先,拿报文开刀。截取一次正确登录的报文,如下

2009-02-03 19:57:57,310 INFO CLT->SRV length=100:
0x00 0x00 0x00 0x60 0xc2 0xd2 0xa9 0x98 == 0xfa 0x52 0xac 0xca 0x02 0x39 0x27 0x2b
0x5d 0x64 0x35 0x98 0x2a 0xfe 0x68 0x0a == 0x80 0xb1 0xd4 0x4c 0xcf 0xdc 0xbc 0xb0
0xb8 0xda 0xea 0xe5 0xa0 0xbc 0x13 0xc3 == 0xf7 0x1e 0x75 0xc2 0x8c 0xdd 0x8d 0xac
0xe5 0xf6 0x06 0xeb 0xb5 0x2f 0x99 0xa0 == 0x2d 0x67 0xfe 0x42 0xda 0x59 0x23 0xe4
0xd7 0x24 0x37 0x13 0xfc 0xa2 0xe8 0x2e == 0xed 0x6d 0xae 0x95 0x15 0x79 0xc5 0x18
0x93 0x56 0xb6 0x73 0x51 0xc1 0x54 0x29 == 0xc3 0x27 0x4d 0x7c 0x54 0xb6 0x95 0x44
0x9e 0xbb 0xd4 0x67

2009-02-03 19:57:57,733 INFO SRV->CLT length=100:
0x00 0x00 0x00 0x60 0x3d 0x3a 0xf4 0x0f == 0x39 0x5d 0x1d 0x99 0x36 0x82 0xdc 0xeb
0x5e 0x1a 0xd4 0x00 0xa7 0x16 0xaf 0x42 == 0x26 0x0e 0x90 0x43 0xfb 0x65 0x1d 0x56
0x0d 0x17 0x31 0xff 0xc5 0x5f 0xff 0x91 == 0xe4 0x0c 0xb0 0x62 0xb8 0x04 0x92 0x16
0xbf 0x20 0x38 0x4a 0xfa 0xaf 0xee 0x3b == 0xd0 0xc1 0x80 0xd1 0xdb 0xa7 0xab 0x2f
0x95 0x57 0x60 0x30 0xdb 0x96 0x66 0xef == 0x75 0x9a 0x6f 0xf5 0x85 0xe8 0xa4 0x4b
0x2c 0xd5 0x59 0xe2 0x5c 0x68 0x3f 0xaf == 0xaf 0x63 0xc0 0xdd 0x11 0x63 0x37 0x2a
0x16 0xd7 0x21 0xa6

2009-02-03 19:57:57,756 INFO CLT->SRV length=40:
0x5d 0x61 0xf7 0xda 0x84 0x5a 0x69 0x61 == 0x3b 0x80 0x45 0xfb 0x14 0x30 0x7e 0x3c
0x7a 0x9c 0xc2 0x27 0xe0 0xb7 0xad 0xef == 0x5e 0x12 0x5b 0xd3 0xa2 0xe7 0x9f 0x4d
0xff 0x75 0x24 0x6b 0x4f 0xf9 0xe6 0xd2 ==

2009-02-03 19:57:58,219 INFO SRV->CLT length=40:
0x5d 0x61 0xf7 0xda 0x84 0x5a 0x69 0x61 == 0x3b 0x80 0x45 0xfb 0x14 0x30 0x7e 0x3c
0x7a 0x9c 0xc2 0x27 0xe0 0xb7 0xad 0xef == 0x5e 0x12 0x5b 0xd3 0xa2 0xe7 0x9f 0x4d
0xff 0x75 0x24 0x6b 0x4f 0xf9 0xe6 0xd2 ==

2009-02-03 19:57:58,239 INFO CLT->SRV length=84:
0x77 0xa6 0xcd 0xd6 0x29 0x48 0xa8 0xce == 0xe2 0xe1 0x9d 0xfe 0x49 0x03 0x4b 0xf8
0x50 0x13 0x49 0xaf 0xa2 0x94 0x68 0xe0 == 0x2a 0xda 0x53 0x7d 0x8d 0xf6 0x09 0xa8
0x7e 0x84 0xd7 0xbe 0x4d 0x72 0xa4 0x7b == 0x51 0x82 0x4f 0x0e 0x86 0xaf 0x64 0xf3
0x6d 0x21 0x14 0x05 0xb9 0x58 0xdf 0xf8 == 0x0e 0xd7 0x9c 0x7d 0xb4 0x57 0x89 0xcd
0xde 0xc8 0x36 0x57 0x58 0xdb 0xb2 0x0b == 0x58 0x17 0xb4 0x43 0xe8 0x96 0xaf 0xcc
0xec 0x81 0xd0 0x95

2009-02-03 19:57:58,978 INFO SRV->CLT length=4096:
0x77 0xa6 0xcd 0xd6 0x29 0x48 0xa8 0xce == 0xe2 0xe1 0x9d 0xfe 0x49 0x03 0x4b 0xf8
0x50 0x13 0x49 0xaf 0xa2 0x94 0x68 0xe0 == 0x2a 0xda 0x53 0x7d 0x8d 0xf6 0x09 0xa8
0x7e 0x84 0xd7 0xbe 0x4d 0x72 0xa4 0x7b == 0x51 0x82 0x4f 0x0e 0x86 0xaf 0x64 0xf3
0x6d 0x21 0x14 0x05 0xb9 0x58 0xdf 0xf8 == 0x0e 0xd7 0x9c 0x7d 0xb4 0x57 0x89 0xcd
0xde 0xc8 0x36 0x57 0x58 0xdb 0xb2 0x74 == 0xd4 0x85 0x28 0xf7 0xaf 0x3b 0x58 0x93
0xc1 0x44 0x1b 0xcc 0x6e 0xc5 0x9a 0x24 == 0xa7 0x1f 0x96 0x05 0x2a 0x99 0x7e 0xc3
0x86 0x7c 0xdf 0x75 0x6d 0x0e 0x3f 0xfe == 0x70 0xa7 0xc4 0xc2 0x40 0xd7 0x51 0x3e
......
......

嗯,先拿报文(主要是游戏中的报文,不是登录报文)端详了半天,看不出什么共性,初步判断
报文加密了(题外话:对于未加密的报文,一般都有规律可循,例如选怪报文,头几位一般都有
相同的opcode,可能就是后面的值不同代表不同的怪),那么就是说先用用WPE的可能性为0了(貌似现在报文不加密就是外挂多的代名词)

另外进行了小小的报文猜测,开始clt->srv和srv->clt 100 字节应该是交换密钥
接下来的 40 字节可能是客户端用自己密钥加密一段数据后上送服务器,服务器解密后再用服务器
密钥加密返回客户端。 客户端通过再解密确定整个通讯过程无问题。 如果不能解密出和原始发送
报文一致的数据则需要重新互换密钥
再往下84字节应该是密码口令等认证信息加密上送
再往后数据应该就是登录成功后的角色信息了。
(以上纯属猜想)

嗯,本小鸟也祭出OD,打开,运行,经过按了n次shift-F9后,登录界面来到眼前。
依葫芦画瓢,来个鼠标点击断点,详情请看:
http://bbs.pediy.com/showthread.php?s=&threadid=21532

可结果,每次在WM_LBUTTONUP 下断都提示:
”无法读取调试进程的内存,位于FFFF09CF的断点已被删除“

日日,一下子傻眼了。
这怎么下断呢。
经过n久摸索(谁让我菜呢),终于会断send了,(汗。真够菜的)
http://bbs.pediy.com/showthread.php?s=&threadid=21330

往上一层,来到send前一层。个中注释是小菜当时的想法。。   

call    <jmp.&MSVCRT.operator new>
mov     dword ptr [esi+18], eax          ;  new出一块空间用于send
push    eax                              ;  esi+14存放长度60H,[esi+18]存放要发送数据
mov     eax, dword ptr [esi+4]
mov     ecx, dword ptr [eax+14]
push    ecx
call    <getfirstkey>
mov     edx, dword ptr [esi+14]
add     esp, 10
push    edx                              ; /NetLong
call    <jmp.&WSOCK32.#8_htonl>          ; \ntohl
mov     ecx, dword ptr [ebp+8]
lea     edi, dword ptr [esi+10]
push    eax
mov     byte ptr [ebp-4], 0B
lea     ebx, dword ptr [ecx+4]
mov     dword ptr [edi], eax
mov     ecx, ebx
mov     edx, dword ptr [ebx]
call    dword ptr [edx+18]               ;  send:开头4字节
mov     ecx, dword ptr [esi+14]
mov     edx, dword ptr [esi+18]
mov     eax, dword ptr [ebx]
push    ecx
push    edx
mov     ecx, ebx
call    dword ptr [eax+30]               ;  send:4H字节后的60H字节的client key
mov     eax, dword ptr [ebx]
mov     ecx, ebx
call    dword ptr [eax+4]
mov     ebx, dword ptr [ebp+8]
push    edi
mov     ecx, ebx
mov     edx, dword ptr [ebx]
call    dword ptr [edx+14]               ;  recieve 4字节。。
mov     eax, dword ptr [edi]
mov     dword ptr [ebp-4], 0
push    eax                              ; /NetLong
call    <jmp.&WSOCK32.#14_ntohl>         ; \ntohl
cmp     eax, 400
mov     dword ptr [edi], eax
jle     short 00517F5B
mov     ecx, dword ptr [esi+18]
push    ecx
call    <FREE>
add     esp, 4
lea     ecx, dword ptr [ebp-58]
push    0
push    016CE1D8                         ;  ASCII "ArcDHKeyExchange::GenerateSharedKey: key size too long."
call    00420A40
lea     edx, dword ptr [ebp-58]
push    015C5980
push    edx
mov     dword ptr [ebp-58], 01541880
call    <jmp.&MSVCRT._CxxThrowException>
cmp     eax, dword ptr [esi+14]
jle     short 00517F77
mov     eax, dword ptr [esi+18]
push    eax
call    <FREE>
mov     eax, dword ptr [edi]
push    eax
call    <jmp.&MSVCRT.operator new>
add     esp, 8
mov     dword ptr [esi+18], eax
mov     eax, dword ptr [edi]
mov     ecx, dword ptr [esi+18]
mov     edx, dword ptr [ebx]
push    eax
push    ecx                              ;  [esi+18]保存recieve的数据
mov     ecx, ebx
mov     byte ptr [ebp-4], 0D
call    dword ptr [edx+2C]               ;  recieve 后面 60H的字节
mov     dword ptr [ebp-4], 0
call    00CD97F0                         ;  貌似加密函数
mov     edx, dword ptr [edi]
mov     ebx, eax
mov     eax, dword ptr [esi+18]
push    ebx
push    edx
push    eax
call    <serverkey处理>                    ;  都是算法。。。
add     esp, 0C
test    eax, eax
jnz     short 00517FDB
mov     ecx, dword ptr [esi+18]
push    ecx
call    <FREE>
add     esp, 4
lea     ecx, dword ptr [ebp-40]
push    0
push    016CE194                         ;  ASCII "ArcDHKeyExchange::GenerateSharedKey: failed to get key."
call    00420A40
lea     edx, dword ptr [ebp-40]
push    015C5980
push    edx
mov     dword ptr [ebp-40], 01541880
call    <jmp.&MSVCRT._CxxThrowException>
mov     eax, dword ptr [esi+4]
push    eax
call    00CDA980                         ;  不知道干嘛
mov     ecx, dword ptr [ebp+10]
push    eax
mov     dword ptr [ecx], eax
call    <jmp.&MSVCRT.operator new>
mov     edx, dword ptr [ebp+C]
mov     dword ptr [edx], eax
mov     ecx, dword ptr [esi+4]
push    ecx
push    ebx
push    eax
call    00CDA9C0                         ;  又是加密算法,还调用到了getfirstkey
mov     esi, dword ptr [esi+18]
mov     edi, eax
push    esi
call    <FREE>                           ;  Free函数
push    ebx
call    00CD9770                         ;  不知道是啥 莫非是计算key?
add     esp, 1C
cmp     edi, -1
jnz     short 0051804A
mov     edx, dword ptr [ebp+C]
mov     eax, dword ptr [edx]
push    eax
call    <FREE>
add     esp, 4
lea     ecx, dword ptr [ebp-4C]
push    0
push    016CE14C                         ;  ASCII "ArcDHKeyExchange::GenerateSharedKey: error computing key."
call    00420A40
lea     ecx, dword ptr [ebp-4C]
push    015C5980
push    ecx
mov     dword ptr [ebp-4C], 01541880
call    <jmp.&MSVCRT._CxxThrowException>
mov     ecx, dword ptr [ebp-18]
mov     dword ptr [ebp-4], -1
test    ecx, ecx
je      short 0051805D
call    004149C5
mov     ecx, dword ptr [ebp-C]
pop     edi
pop     esi
mov     dword ptr fs:[0], ecx

按下逐个call F7进去看不表,这是体力活,没啥可讲的,关键是耐心和毅力。。
终于功夫不负有心人呀。找到了这样一个函数入口

push    ebp                              ;  encode函数
mov     ebp, esp
mov     eax, dword ptr [ebp+10]          ;  形参4 ebp+10 待encode长度
test    eax, eax
jbe     short 005115DF
lea     edx, dword ptr [ecx+1068]
push    1                                ;  可能是参数1代表encode,0代表decode
push    edx                              ;  ecx+1068 压栈
lea     edx, dword ptr [ecx+1058]
add     ecx, 0C
push    edx                              ;  ecx+1058压栈
push    ecx                              ;  ecx+0C 压栈
mov     ecx, dword ptr [ebp+8]           ;  形参2 [ebp+8] 待encdoe buff
push    eax                              ;  encode字符串长度
mov     eax, dword ptr [ebp+C]           ;  形参3 [ebp+C] encode后结果
push    eax                              ;  encode后结果指针
push    ecx                              ;  encode字符串指针
call    <encode/decode函数>
add     esp, 1C                          ;  未知参数来源于外层ecx
pop     ebp
retn    0C

嘿嘿嘿,未encode前的buff展露眼前~
好了,菜鸟哥现在总算到达了类似爆破找到关键call时的快感~
一切数据尽在眼前。
某猥琐男在后面提醒。。那现在不是可以。。。username->save() password->save()了。
囧,本菜鸟不干这一行,只想了解下本游戏协议报文。。囧

接下来又傻眼了。要知道,本菜鸟此时对什么CreateRemoteThread, DEBUG API 完全没有概念。
就想把未encode报文先log下来分析。。怎么办呢?还能怎么办。论坛问,google搜,自学呗

又经过天折腾。有基本思路了
使用DEBUG API,在call encode/decode函数前下断。运行到encode/decode函数时 保存待发送数据和其长度,
写入log,然后eip--,恢复原始eip内容。
类似如下代码

  if(DbgEv.u.Exception.ExceptionRecord.ExceptionAddress == (PVOID)encode_base)
  {
    dwThreadPid=DbgEv.dwThreadId;                                                               
    DebugHandle=OpenThread(THREAD_ALL_ACCESS,FALSE,dwThreadPid);                                 
                                                                                                
    thContext.ContextFlags = CONTEXT_FULL;                                                      
    GetThreadContext(DebugHandle,&thContext);                                                   
    thContext.Eip--;                                                                             
                                                                                                
    memaddr=thContext.Ebp+0x10;     //[ebp+c]result buff                                         
                                    //ebp+10 origin len                                            
                                    //[ebp+8]origin buff                                          
    ReadProcessMemory(DbgHandle,(LPVOID)(memaddr),&addr,4,NULL);                                 
    len=(int)addr;                                                                              
                                                                                                
    memaddr=thContext.Ebp+0x08;     //[ebp+8]origin len                                          
    ReadProcessMemory(DbgHandle,(LPVOID)(memaddr),&addr,4,NULL);                                 
    memset(Buf,0x00,sizeof(Buf));                                                               
    memset(Hex,0x00,sizeof(Hex));                                                               
    ReadProcessMemory(DbgHandle,(LPVOID)(addr),Buf,len,NULL);                                    
                                                                                                
    BinToHexFormat(Buf,Hex,len);                                                                 
                                                                                                
    sprintf(loghead,"\nSrv->Clt: %d ",len);                                                      
    logger->Add( loghead );                                                                     
    logger->Add(  Hex );                                                                        
                                                                                                
    WriteProcessMemory(DbgHandle,(LPVOID)decode_base,decode_temp1,1,&dwWritten);  // 恢复原有指令
                                                                                                
    WriteProcessMemory(DbgHandle,(LPVOID)decode_after,int3,1,&dwWritten);                        
    WriteProcessMemory(DbgHandle,(LPVOID)encode_base,int3,1,&dwWritten);                        
    WriteProcessMemory(DbgHandle,(LPVOID)encode_after,int3,1,&dwWritten);      
  }  
(由于本人依旧很菜的原因,SINGLE_STEP总不成功,只好用此土法,两个断点,互相写int3)

各位应该已经开始发笑了。。这人代码风格怎么这么不统一呀。。。嗯。。。。其实。。俺是C程序员。。。囧
通过这么一处理,报文都存下来了。现在可以开始分析报文了。

通过在游戏里做一些简单的选怪,以及log信息,可以判断出当clt选怪时候,会发如下报文

0x64 0xe1 0x09 0x38 0x0c 0x80 0x00 0x00 == 0x00 0xee 0x93 0xe4            
0x64 0xe1 0x09 0x38 0x0c 0x80 0x00 0x00 == 0x00 0xac 0x55 0xd2
0x64 0xe1 0x09 0x38 0x0c 0x80 0x00 0x00 == 0x00 0xbb 0xa7 0xe4  
0x64 0xe1 0x09 0x38 0x0c 0x80 0x00 0x00 == 0x00 0xe1 0x91 0x78
0x64 0xe1 0x09 0x38 0x0c 0x80 0x00 0x00 == 0x00 0x32 0x40 0xa3

前面8字节是一致的,再次开始猜测
0x64 0xe1 0x09 0x38 是opcode,代表是选择npc
0x0c 0x80 0x00 0x00 是类型,怪,npc,player值分别不同
0x00 0xee 0x93 0xe4 .... 是id,应该是整个game世界唯一id号之类。

忘了说一句,前面未获得原始报文时候对于处理clt<-->srv 40字节的猜测是错误的,其实是客户端版本号信息上传。。

现在,我此行的最主要目标来了。
咳咳。。外置选上一个怪的函数,囧,你不是想做外挂吧。非也,就是方便自己,趁机学习而已。

好了,再次开始论坛问,google搜。基本思路:
过滤未加密报文,对于0x64 0xe1 0x09 0x38开头的,保存后面的 global id备用
编写函数,参数为一个指针,指向一个global id
在目标进程分配空间,将此函数写入目标进程内存
在目标进程分配空间,将global id写入目标进程内存
最后CreateRemoteThread,在目标进程create一个线程,线程执行发送那个选怪的报文。
over

哈哈,目的达成了~
(最后一步的代码就不提供了。因为我也还没调试好,而且代码写的很垃圾。。。。谁让我菜呢,继续学习)

通过此文,主要是给广大初学者一点鼓励,只要有耐心,有毅力,有基本编程基础也可以学破解。
当然了。记住一点,学破解只学到会爆破就心满意足是绝对不行的。

好了,菜文到此结束,希望各位看官见谅。
菜就一个字,请别再说一次~

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

收藏
免费 7
支持
分享
最新回复 (32)
雪    币: 212
活跃值: (31)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
2
帮顶       呵呵
2009-3-16 19:15
0
雪    币: 190
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
哎!可惜我想看windows的!!
不过还是顶楼主拉!!
2009-3-17 05:56
0
雪    币: 2368
活跃值: (81)
能力值: (RANK:300 )
在线值:
发帖
回帖
粉丝
4
楼主写的就是windows的...楼上没有仔细看哦...
2009-3-17 08:18
0
雪    币: 2067
活跃值: (82)
能力值: ( LV9,RANK:180 )
在线值:
发帖
回帖
粉丝
5
楼主是天才!
2009-3-17 08:31
0
雪    币: 360
活跃值: (77)
能力值: ( LV9,RANK:250 )
在线值:
发帖
回帖
粉丝
6
我是路过的!!!
2009-3-17 09:32
0
雪    币: 201
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
up
2009-3-17 13:12
0
雪    币: 144
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
8
楼主太谦虚了~因为我根本就看不懂
2009-3-17 13:22
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
9
谢拉我是新手学习学习
2009-3-17 14:08
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
10
我是超级的新手..也来学学..
2009-3-17 16:16
0
雪    币: 221
活跃值: (33)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
11
恩,看到,支持下楼主了!我也菜,同样学习中!
2009-3-17 19:47
0
雪    币: 263
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
12
你还自称菜鸟?BS一下你的谦虚~~~
2009-3-18 19:05
0
雪    币: 194
活跃值: (10)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
13
学习要自己努力,我还在前行
2009-3-18 22:55
0
雪    币: 474
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
14

这也叫菜鸟啊
我能看懂的还不到二分之一
那不是更菜
2009-3-19 09:46
0
雪    币: 206
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
15
楼主太谦虚了
2009-3-19 13:36
0
雪    币: 92
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
16
恩,看到,支持下楼主了!我也菜,同样学习中!
2009-3-19 14:05
0
雪    币: 235
活跃值: (10)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
17
真的,高手一看就知道确实是初学刚入门者了。
很多东西还停留在了解皮毛的基础上
2009-3-19 15:16
0
雪    币: 299
活跃值: (126)
能力值: ( LV5,RANK:60 )
在线值:
发帖
回帖
粉丝
18
佩服楼主解决问题的精神,"钳"而不舍
2009-3-19 16:54
0
雪    币: 203
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
19
菜菜菜菜鸟来此学习。谢谢啊。
2009-3-19 17:03
0
雪    币: 264
活跃值: (11)
能力值: ( LV9,RANK:250 )
在线值:
发帖
回帖
粉丝
20
以后再不说自己 菜鸟了 我不配阿 嘿嘿 膜拜楼上ID
2009-3-20 08:40
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
21
晕啊 这哪里是从0开始啊。。。。。谦虚的不行了
2009-3-21 13:37
0
雪    币: 201
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
22
我是新手学习学习
2009-3-21 13:51
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
23
你要是菜鸟,那我可以跳楼了。
2009-3-22 08:34
0
雪    币: 133
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
24
写得好啊写得好啊
2009-3-22 09:40
0
雪    币: 89
活跃值: (185)
能力值: ( LV9,RANK:270 )
在线值:
发帖
回帖
粉丝
25
基本看不懂,看来我的基础是小于0了,好好学习ing
2009-3-22 12:38
0
游客
登录 | 注册 方可回帖
返回
//