首页
社区
课程
招聘
[原创]星际霸主1.9j分析
发表于: 2011-2-1 18:20 32441

[原创]星际霸主1.9j分析

2011-2-1 18:20
32441

【文章标题】: 星际霸主1.9j分析
【文章作者】: thomasyzh
【作者邮箱】: machinesy@gmail.com
【软件名称】: 星际霸主1.9j
【软件大小】: 5.16 MB
【下载地址】: 自己搜索下载
【加壳方式】: Themida/WinLicense V1.8.X-V1.9.X DLL
【软件介绍】: 一个星际争霸1的游戏外挂
【作者声明】: 只是感兴趣,没有其他目的。失误之处敬请诸位大侠赐教!
--------------------------------------------------------------------------------
【详细过程】
  这是一个破解任务,一位朋友请我帮他破解,价格是1K。因为不是为了赚这个票子,所以就直接发表出来了。在发表之前
  我是在考虑这个帖子的标题写软件破解,还是软件分析。因为实际上现在有两个方法完成这个破解,1是继续按照我现在的
  思路把这个东西做完了。2是我去把Virtualizer加的虚拟器代码还原掉了。实际上我选择了2,所以我就没有继续把1的路子
  走完了。最后我把改vm代码还原后,一定的能够破译掉。
  那么,我把1的分析过程写出来,所以我把这文章的标题就写做分析了。
  
  一些文件啊,咋的咋的那些信息我就不说了。我直接说结论。
  
  1这是个大量使用hook挂接星际争霸的游戏外挂。
  2这个外挂是使用http验证的一个外挂。
  3这个外挂的验证在scHelper.king的代码里边。
  4这个外挂的数据收发在scking.exe里边,然后通过内存共享传送到scHelper.king里边。大概应该在那个sckhook.dll里边。
  
  因为加了tmd壳。我并没有选择一开始就CreateProcess 这种方式,而是让它在内存里解密完,并且anti代码跑完的石斛attack
  上去。最佳的效果是直接attack到加密验证代码那里。
  
  于是
  1.Hook一个函数,这个函数必须要是scHelper.king里边调用的一个函数。
  2.在scHelper.king一开始跑的时候,用一断hook代码把整个线程拥塞起来,然后我们attack,然后恢复拥塞。太好了messagebox满足我们的需求。
  
  于是就有了这样一段代码
  
  ;在此文档的文档工具栏项目上单击右键->参数属性
  
  .386
  .model flat, stdcall
  option casemap :none
  
  include windows.inc
  include user32.inc
  include kernel32.inc
  
  includelib user32.lib
  includelib kernel32.lib
  
  inlinehookfun        PROTO :DWORD,:DWORD,:DWORD       
  MyZwSetInformationThread PROTO
  Myconnect                                         PROTO
  MyCreateThread                                 PROTO
  
  patchcode                                         PROTO
  ThreadProc                                         PROTO
  
  .data
          lpszByDll                                           db "Welcome",0
          lpszErrorQuery                           db "query error",0
          lpszErrorProtected                  db "protected error",0
          lpszErrorProtected2                  db "protected error2",0
          lpszErrorGetModule                   db "get module handle error",0
          lpszconnect                                         db "no cmp error",0
         
          lpZwSetInformationThread db "ZwSetInformationThread",0
          lpNtDll                                                 db "NtDll.dll",0
         
          lpWS2_32Dll                                         db "ws2_32.dll",0
          lpConnect                                         db "connect",0
         
          lpKernel32Dll                                 db "kernel32.dll",0
          lpCreateThread                                 db "CreateThread",0
         
         
          lpthreadmsg                                        db "thread msg",0
         
          lptestbreakpointer                 db "testbreakpointer",0
          lpHideDebug                                         db "Hide Debug",0
          lphookcode                                          db  0e9h,90h,90h,90h,90h,90h,90h,90h,90h,90h       
         
         
         
         
  .data?
          hInstance dd ?
          hinsNtDll dd ?
          addrZwSetInformationThread dd ?
          myaddrZwSetInformationThread dd ?
         
          hinsWS2_32                                                dd ?
          addrconnect                                                dd ?
          myaddrconnect                                        dd ?
         
          hinsKernel32                                        dd ?
          addrCreateThread                                dd ?
          mydddrCreateThread                        dd ?
         
  .CODE
  
  ;入口.如果DLL需要加载资源,需要保存hIinstDLL这个句柄到全局变量.它才是模块句柄
  ;使用GetModuleHandle获得的永远是主程序的句柄
  LibMain proc hInstDLL:DWORD, reason:DWORD, unused:DWORD
          .if reason == DLL_PROCESS_ATTACH                                        ;动态库被加载时调用,返回0加载失败!
                  mov eax,hInstDLL
                  mov hInstance,eax
                 
                  invoke GetModuleHandle,addr lpNtDll
                  .if eax == NULL
                          invoke MessageBox,NULL,addr lpszErrorGetModule,addr lpszErrorGetModule,MB_OK
                          ret
                  .endif
                  mov hinsNtDll,eax
                  invoke GetProcAddress,hinsNtDll,addr lpZwSetInformationThread
                  mov addrZwSetInformationThread,eax
                  mov eax,MyZwSetInformationThread
                  mov myaddrZwSetInformationThread,eax
                 
                  invoke inlinehookfun,myaddrZwSetInformationThread,addrZwSetInformationThread,0
                 
                 
                  invoke LoadLibrary,addr lpWS2_32Dll
                  .if eax == NULL
                          invoke MessageBox,NULL,addr lpszErrorGetModule,addr lpszErrorGetModule,MB_OK
                          ret
                  .endif
                  mov hinsWS2_32,eax
                  invoke GetProcAddress,hinsWS2_32,addr lpConnect
                  mov addrconnect,eax
                  mov eax,Myconnect
                  mov myaddrconnect,eax
                  invoke inlinehookfun,myaddrconnect,addrconnect,0
                 
                  ;invoke patchcode
                  invoke CreateThread,NULL,NULL,ThreadProc,NULL,NULL,NULL
                 
                 
                  invoke GetModuleHandle,addr lpKernel32Dll
                  mov    hinsKernel32,eax
                  invoke GetProcAddress,hinsKernel32,addr lpCreateThread
                  mov    addrCreateThread,eax
                  mov    eax,MyCreateThread
                  mov    mydddrCreateThread,eax
                  invoke inlinehookfun,mydddrCreateThread,addrCreateThread,0
                 
                 
                  mov eax,TRUE
                  ret
          .elseif reason == DLL_PROCESS_DETACH
                 
          .elseif reason == DLL_THREAD_ATTACH
                 
          .elseif reason == DLL_THREAD_DETACH
            ;添加处理代码
          .endif
  ret
  LibMain Endp
  
  ;供主程序调用的函数
  MsgBox proc hWnd,lpszText,fStyle
          invoke MessageBox,hWnd,lpszText,offset lpszByDll,fStyle
  ret
  MsgBox endp
  
  
  inlinehookfun        proc dDest,dSrc,len
          LOCAL @mbi:MEMORY_BASIC_INFORMATION
          LOCAL @oldpro:DWORD
          invoke VirtualQuery,dSrc,addr @mbi,sizeof MEMORY_BASIC_INFORMATION
          .if eax== FALSE
                  invoke MessageBox,NULL,addr lpszErrorQuery,addr lpszErrorQuery,MB_OK       
                  ret
          .else
                  invoke VirtualProtect,@mbi.BaseAddress,@mbi.RegionSize,PAGE_EXECUTE_READWRITE,addr @oldpro
                  .if eax == FALSE
                          invoke MessageBox,NULL,addr lpszErrorProtected,addr lpszErrorProtected,MB_OK
                          ret
                  .else
                         
                          mov eax,dDest
                          mov ebx,dSrc
                          sub eax,ebx
                          sub eax,5
                          lea ebx,lphookcode
                          mov DWORD ptr [ebx+1],eax
                         
                          mov eax,dSrc
                          mov ch,0e9h
                          mov BYTE ptr [eax],ch
                          mov ecx,DWORD ptr [ebx+1]
                          mov DWORD ptr [eax+1],ecx
                          ;modify code
                         
                          invoke VirtualProtect,@mbi.BaseAddress,@mbi.RegionSize,@oldpro,addr @oldpro
                          .if eax == FALSE
                                  invoke MessageBox,NULL,addr lpszErrorProtected2,addr lpszErrorProtected2,MB_OK
                                  ret
                          .endif       
                 
                  .endif
          .endif
         
          ret
  inlinehookfun        endp
  
  patchcode proc
          Local         @mbi : MEMORY_BASIC_INFORMATION
          Local         @oldpro:DWORD
          invoke   VirtualQuery,2044747h,addr @mbi,sizeof MEMORY_BASIC_INFORMATION
          invoke   VirtualProtect,@mbi.BaseAddress,@mbi.RegionSize,PAGE_EXECUTE_READWRITE,addr @oldpro
          mov                 eax,204474Eh
          mov      dh,0ebh
          mov      BYTE ptr [eax],dh
          invoke   VirtualProtect,@mbi.BaseAddress,@mbi.RegionSize,@oldpro,addr @oldpro
  
  patchcode endp
  
  MyZwSetInformationThread        proc
  
          pushad
          pushfd
          ;invoke  MessageBox,NULL,addr lptestbreakpointer,addr lptestbreakpointer,MB_OK
                                                                             ;ret ;2
          mov eax,DWORD ptr [esp+20h+04h+08h]       
          cmp eax,11h
          jnz CMP_NO
         
          invoke MessageBox,NULL,addr lpHideDebug,addr lpHideDebug,MB_OK
         
  CMP_NO:       
          popfd
          popad
          mov eax,0e5h
          mov edx,addrZwSetInformationThread
          add edx,5
          jmp edx
  ret
  MyZwSetInformationThread         endp
  
  
  Myconnect proc
  pushad
  pushfd
                                                                                  ;ret ;2                               
          mov eax,DWORD ptr [esp+20h+04h+08h]       
          mov edx,DWORD ptr [eax+04h]
          cmp edx,0b75ab8abh
          jnz  NO_CMP
          invoke MessageBox,NULL,addr lpszconnect,addr lpszconnect,MB_OK
  
  NO_CMP:
  
  popfd
  popad
  mov  edi,edi
  push ebp
  mov  ebp,esp
  mov  eax,addrconnect
  add  eax,5
  jmp  eax
  
  
  
  Myconnect endp
  
  ThreadProc         proc
          invoke Sleep,5000
          ;invoke patchcode
          ret
  ThreadProc        endp
  
  MyCreateThread proc
          pushad
          pushfd
                  mov eax,DWORD ptr [esp+20h+04h]
                 
                  sub eax,        02020000h
                  ja         leb_2
  leb_1:
                  jmp NO       
  leb_2:
                  mov eax,DWORD ptr [esp+20h+04h]
                  sub eax,026fd000h   
                  jna leb_4
  leb_3:
                  jmp NO
  leb_4:               
                  invoke MessageBox,NULL,addr lpthreadmsg,addr lpthreadmsg,MB_YESNO
                 
  NO:       
          popfd
          popad
         
          mov  edi,edi
          push ebp
          mov  ebp,esp
         
          mov  eax,addrCreateThread
          add  eax,5
          jmp  eax
  MyCreateThread endp
  
  End LibMain
  
  
  实际上,在这个dll汇编代码里,我挂了几个函数,都是为了测试用的。
  
  但是这正有用的只有一个CreateThread 看看挂接后做了什么
  
  MyCreateThread proc
          pushad
          pushfd
                  mov eax,DWORD ptr [esp+20h+04h]
                 
                  sub eax,        02020000h
                  ja         leb_2
  leb_1:
                  jmp NO       
  leb_2:
                  mov eax,DWORD ptr [esp+20h+04h]
                  sub eax,026fd000h   
                  jna leb_4
  leb_3:
                  jmp NO
  leb_4:               
                  invoke MessageBox,NULL,addr lpthreadmsg,addr lpthreadmsg,MB_YESNO
                 
  NO:       
          popfd
          popad
         
          mov  edi,edi
          push ebp
          mov  ebp,esp
         
          mov  eax,addrCreateThread
          add  eax,5
          jmp  eax
  MyCreateThread endp
  
  
  写了一段代码判断是不是被scHelper.king这个模块调用的CreateProcess如果是的话就MessageBox一下。范围代码判断如下
                  mov eax,DWORD ptr [esp+20h+04h]
                 
                  sub eax,        02020000h
                  ja         leb_2
  leb_1:
                  jmp NO       
  leb_2:
                  mov eax,DWORD ptr [esp+20h+04h]
                  sub eax,026fd000h   
                  jna leb_4
  leb_3:
                  jmp NO
  leb_4:               
                  invoke MessageBox,NULL,addr lpthreadmsg,addr lpthreadmsg,MB_YESNO
                 
  先取一个esp的ret模块地址如果满足大于02020000h小于026fd000h 那么就messagebox.
  为啥要createthread喃!~????一个dll如果不写个线程去完成很多初使化的话,那这样做是不合适的。因为会拥塞主线程的线程。
  
  还有细节要处理下。Themida壳挂接了DbgUiRemoteBreakin这个函数,需要恢复之,然后我们就能带壳调试了。然后在messageboxa的尾巴上打上断点。
  我们就可以发现线程函数就是这个了
  02028964   .  55            push    ebp
  02028965   .  8BEC          mov     ebp, esp
  02028967   .  81C4 58F3FFFF add     esp, -0CA8
  0202896D   .  B8 A45E2302   mov     eax, 02235EA4
  02028972   .  53            push    ebx
  02028973   .  56            push    esi
  02028974   .  57            push    edi
  02028975   .  E8 D2DE0800   call    020B684C
  
  
  
  然后就进入到这里。然后它就开始他疯狂的vm了。进过一段时间的分析,我们就找到了vm_call_fun的位置。具体如何找到vm_call_fun其实一点都不难
  我是直接用od的自动跟入,跟入每一个分支,然后看到它跑到非vm的代码里边后,再用减号后退,就直接找到了vm_call_fun.
  
  
  
  
  01B815C0    8B0424          mov     eax, dword ptr [esp]             ; vm_call_XXX
  01B815C3    8DB0 44010000   lea     esi, dword ptr [eax+144]
  01B815C9    B9 1C000000     mov     ecx, 1C
  01B815CE    8B78 3C         mov     edi, dword ptr [eax+3C]
  01B815D1    F3:A5           rep     movs dword ptr es:[edi], dword p>
  01B815D3    5F              pop     edi
  01B815D4    C747 38 000000F>mov     dword ptr [edi+38], F0000000
  01B815DB    FF77 70         push    dword ptr [edi+70]
  01B815DE    FF77 74         push    dword ptr [edi+74]
  01B815E1    FFB7 84000000   push    dword ptr [edi+84]
  01B815E7    FFB7 8C000000   push    dword ptr [edi+8C]
  01B815ED    FF77 7C         push    dword ptr [edi+7C]
  01B815F0    FFB7 AC000000   push    dword ptr [edi+AC]
  01B815F6    FFB7 A4000000   push    dword ptr [edi+A4]
  01B815FC    FFB7 94000000   push    dword ptr [edi+94]
  01B81602    FFB7 9C000000   push    dword ptr [edi+9C]
  01B81608    C747 28 0000000>mov     dword ptr [edi+28], 0
  01B8160F    61              popad
  01B81610    9D              popfd
  01B81611    C3              retn
  
  
  这里就是vm_Call_Fun.
  
  虚拟机代码的还原部分,我会另外开篇帖子再写写,这里我就不再深入细解了。
  然后我们我们在vm_call_fun看这个验证dll是调用了哪些没有被vm的代码。有可能像memcpy这样功能的函数,他没有去vm掉或者怎样怎样。
  这样,我们就又找了这样一个函数。这个函数就是memcpy
  
  020B6418  /$  55            push    ebp
  020B6419  |.  8BEC          mov     ebp, esp
  020B641B  |.  56            push    esi
  020B641C  |.  57            push    edi
  020B641D  |.  8B7D 08       mov     edi, dword ptr [ebp+8]
  020B6420  |.  8BC7          mov     eax, edi
  020B6422  |.  8B75 0C       mov     esi, dword ptr [ebp+C]
  020B6425  |.  8B4D 10       mov     ecx, dword ptr [ebp+10]
  020B6428  |.  8BD1          mov     edx, ecx
  020B642A  |.  D1E9          shr     ecx, 1
  020B642C  |.  D1E9          shr     ecx, 1
  020B642E  |.  FC            cld
  020B642F  |.  F3:A5         rep     movs dword ptr es:[edi], dword p>
  020B6431  |.  8BCA          mov     ecx, edx
  020B6433  |.  83E1 03       and     ecx, 3
  020B6436  |.  F3:A4         rep     movs byte ptr es:[edi], byte ptr>
  020B6438  |.  5F            pop     edi
  020B6439  |.  5E            pop     esi
  020B643A  |.  5D            pop     ebp
  020B643B  \.  C3            retn
  
  
  
  然后我们就在这下断点看。
  2
  087FF0DC   020C2FBC  返回到 scHelper.020C2FBC 来自 scHelper.020B6418
  087FF0E0   04512630
  087FF0E4   04512614  ASCII "1234567890abcdef"""
  087FF0E8   00000010
  087FF0EC   0223A7F3  scHelper.0223A7F3
  087FF0F0   04512566
  087FF0F4   087FF130  指向下一个 SEH 记录的指针
  087FF0F8   020B6893  SE处理程序
  087FF0FC   02242AD0  scHelper.02242AD0
  087FF100   087FF0EC
  
  3
  087FF0D8   020C2FBC  返回到 scHelper.020C2FBC 来自 scHelper.020B6418
  087FF0DC   04512650
  087FF0E0   04512639  ASCII "0abcdef"
  087FF0E4   00000001
  087FF0E8   00000001
  087FF0EC   0000000A
  
  最终,我们就找到这个函数,这个函数就是报文的组织函数
  
  020C3448  /$  55            push    ebp                              ;  EDX_IS_INDEX
  020C3449  |.  8BEC          mov     ebp, esp
  020C344B  |.  83C4 D0       add     esp, -30
  020C344E  |.  53            push    ebx
  020C344F  |.  56            push    esi
  020C3450  |.  57            push    edi
  020C3451  |.  894D D0       mov     dword ptr [ebp-30], ecx
  020C3454  |.  8BDA          mov     ebx, edx
  020C3456  |.  8BF8          mov     edi, eax
  020C3458  |.  B8 342D2402   mov     eax, 02242D34
  020C345D  |.  E8 EA33FFFF   call    020B684C
  
  
  
  这里的edx,就是一个index,从随机变量到字符的转换。
  我们为什么要找随机变量?因为我们要定死随机变量。定死随机变量后,我们就能够以同样的发送报文得到同样的应答报文,这样,我们也就破译了这个外挂了。
  到这里,同学们如果呀破译这个外挂的话,只有再去分析完,这个edx,到底来自于内存的哪里!~~~然后去把这个edx,定死。然后再去通信一次,这个外挂就破解了。
  
  
  
  
  
  
  
  
  
  
--------------------------------------------------------------------------------
【经验总结】
  咋说喃,vm还原这个东西不一句两句就说的清楚的。我自己也在学习。过两天,我去把这个外挂的vm还原放出来。有兴趣的
  朋友也可以不还原vm破之。顺着我这个思路就成了。
  
--------------------------------------------------------------------------------
【版权声明】: 本文原创于看雪技术论坛, 转载请注明作者并保持文章的完整, 谢谢!

                                                       2011年02月01日 18:19:50


[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)

上传的附件:
收藏
免费 7
支持
分享
最新回复 (32)
雪    币: 291
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
LZ高产 啊~ 切入点很好~
欢迎LZ继续分享精彩文章~
2011-2-1 18:31
0
雪    币: 152
活跃值: (106)
能力值: ( LV7,RANK:100 )
在线值:
发帖
回帖
粉丝
3
质量低,今年来读了各位同学的写的各种底层的东西,自卑了。质量低,也就低发了。还是要怎怎VM还原啊,那些有点深度的基础东西,才是硬道理。
2011-2-1 18:40
0
雪    币: 39
活跃值: (40)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
4
楼主是BUG yang - - 膜拜
2011-2-1 18:54
0
雪    币: 225
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
欢迎LZ继续分享文章
2011-2-1 19:03
0
雪    币: 325
活跃值: (97)
能力值: ( LV13,RANK:530 )
在线值:
发帖
回帖
粉丝
6
膜拜一下。不是为了那段分享的代码,而是搂主分享了思路。这个很难能可贵。授之于鱼不如授之于渔

同时期待搂主的非人肉还原CV的精彩思路。
2011-2-2 09:08
0
雪    币: 2323
活跃值: (4113)
能力值: ( LV12,RANK:530 )
在线值:
发帖
回帖
粉丝
7
学习~~谢谢分享~~
2011-2-2 10:57
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
8
学习了,谢谢!!
2011-2-3 09:11
0
雪    币: 2105
活跃值: (424)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
9
方法是这样的。 不错
2011-2-4 10:38
0
雪    币: 451
活跃值: (78)
能力值: ( LV12,RANK:470 )
在线值:
发帖
回帖
粉丝
10
支持下vm的分析
2011-2-4 22:37
0
雪    币: 176
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
11
高手,文章学习了
2011-2-5 18:42
0
雪    币: 277
活跃值: (45)
能力值: ( LV5,RANK:60 )
在线值:
发帖
回帖
粉丝
12
mark下   水平到了再回头来看~
2011-2-6 14:57
0
雪    币: 6092
活跃值: (744)
能力值: ( LV4,RANK:45 )
在线值:
发帖
回帖
粉丝
13
下载研究
2011-2-9 12:44
0
雪    币: 202
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
14
楼主的破解思路很能给人启发,谢谢这种经验分享
2011-2-10 10:44
0
雪    币: 322
活跃值: (113)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
15
水平到了再回头来看!!!
2011-2-10 11:11
0
雪    币: 59
活跃值: (1516)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
16
膜拜,见到了高水平的文章了。
2011-2-11 08:52
0
雪    币: 203
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
17
楼主太厉害了,我不得不引用韦小宝那句话来表达对Thomasyzh的敬仰:我对你的敬仰之情,有如滔滔江水绵绵不绝,有如黄河之水泛滥一发不可收拾……
2011-2-11 12:02
0
雪    币: 391
活跃值: (135)
能力值: ( LV2,RANK:140 )
在线值:
发帖
回帖
粉丝
18
文中attack应该为attach吧
2011-2-11 16:51
0
雪    币: 248
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
19
已经强大的让我只能膜拜了...
2011-2-12 00:36
0
雪    币: 12628
活跃值: (3127)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
20
介绍一下怎样用吧?编译成dll后,直接用dllLoader加载吗?
2011-2-12 13:11
0
雪    币: 33
活跃值: (11)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
21
用 asm 写程序的都是高手
2011-2-12 21:44
0
雪    币: 523
活跃值: (278)
能力值: ( LV7,RANK:100 )
在线值:
发帖
回帖
粉丝
22
水平到了再回头来看!!!
2011-2-12 21:48
0
雪    币: 37
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
23
非常好的文章.學習中
2011-2-12 21:58
0
雪    币: 205
活跃值: (54)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
24
强大....

我只看过1.8版本,那时还没有VM,只有个穿山甲.....

话说这外挂够恶心的,从国外下载MAPHACK源码,内存地址一改重新打包就来卖钱了........
2011-2-14 16:29
0
雪    币: 199
活跃值: (65)
能力值: ( LV5,RANK:70 )
在线值:
发帖
回帖
粉丝
25
嗯,楼主的思路很不错.不错,不错高质量的文章啊.
2011-2-16 02:59
0
游客
登录 | 注册 方可回帖
返回
//