找回密码
 立即注册→加入我们

QQ登录

只需一步,快速开始

搜索
热搜: 下载 VB C 实现 编写
查看: 3585|回复: 2

重识new之二

[复制链接]
发表于 2014-10-12 17:42:11 | 显示全部楼层 |阅读模式

欢迎访问技术宅的结界,请注册或者登录吧。

您需要 登录 才可以下载或查看,没有账号?立即注册→加入我们

×
下面仅以VS调试子功能——查看汇编代码进行分析,以VS2012源码为例:

  1. int main( )
  2. {
  3. 00E282E0  push        ebp  
  4. 00E282E1  mov         ebp,esp  
  5. 00E282E3  push        0FFFFFFFFh  
  6. 00E282E5  push        0E29400h  
  7. 00E282EA  mov         eax,dword ptr fs:[00000000h]  
  8. 00E282F0  push        eax  
  9. 00E282F1  sub         esp,220h  
  10. 00E282F7  push        ebx  
  11. 00E282F8  push        esi  
  12. 00E282F9  push        edi  
  13. 00E282FA  lea         edi,[ebp-22Ch]  
  14. 00E28300  mov         ecx,88h  
  15. 00E28305  mov         eax,0CCCCCCCCh  
  16. 00E2830A  rep stos    dword ptr es:[edi]  
  17. 00E2830C  mov         eax,dword ptr ds:[00E300E0h]  
  18. 00E28311  xor         eax,ebp  
  19. 00E28313  mov         dword ptr [ebp-10h],eax  
  20. 00E28316  push        eax  
  21. 00E28317  lea         eax,[ebp-0Ch]  
  22. 00E2831A  mov         dword ptr fs:[00000000h],eax  
  23.         MyClass* fPtr1 = new MyClass;
  24. 00E28320  push        4  
  25.         MyClass* fPtr1 = new MyClass;
  26. 00E28322  call        operator new (0E21410h)  
  27. 00E28327  add         esp,4  
  28. 00E2832A  mov         dword ptr [ebp-218h],eax  
  29. 00E28330  mov         dword ptr [ebp-4],0  
  30. 00E28337  cmp         dword ptr [ebp-218h],0  
  31. 00E2833E  je          main+73h (0E28353h)  
  32. 00E28340  mov         ecx,dword ptr [ebp-218h]  
  33. 00E28346  call        MyClass::MyClass (0E210BEh)  
  34. 00E2834B  mov         dword ptr [ebp-22Ch],eax  
  35. 00E28351  jmp         main+7Dh (0E2835Dh)  
  36. 00E28353  mov         dword ptr [ebp-22Ch],0  
  37. 00E2835D  mov         eax,dword ptr [ebp-22Ch]  
  38. 00E28363  mov         dword ptr [ebp-224h],eax  
  39. 00E28369  mov         dword ptr [ebp-4],0FFFFFFFFh  
  40. 00E28370  mov         ecx,dword ptr [ebp-224h]  
  41. 00E28376  mov         dword ptr [fPtr1],ecx  
  42.         delete fPtr1;
  43. 00E28379  mov         eax,dword ptr [fPtr1]  
  44. 00E2837C  mov         dword ptr [ebp-200h],eax  
  45. 00E28382  mov         ecx,dword ptr [ebp-200h]  
  46. 00E28388  mov         dword ptr [ebp-20Ch],ecx  
  47. 00E2838E  cmp         dword ptr [ebp-20Ch],0  
  48. 00E28395  je          main+0CCh (0E283ACh)  
  49. 00E28397  push        1  
  50. 00E28399  mov         ecx,dword ptr [ebp-20Ch]  
  51. 00E2839F  call        MyClass::`scalar deleting destructor' (0E2101Eh)  
  52. 00E283A4  mov         dword ptr [ebp-22Ch],eax  
  53. 00E283AA  jmp         main+0D6h (0E283B6h)  
  54. 00E283AC  mov         dword ptr [ebp-22Ch],0  

  55.         MyClass* fPtr2 = new( nothrow ) MyClass;
  56. 00E283B6  push        0E30228h  
  57. 00E283BB  push        4  
  58. 00E283BD  call        operator new (0E210E1h)  
  59. 00E283C2  add         esp,8  
  60. 00E283C5  mov         dword ptr [ebp-1E8h],eax  
  61. 00E283CB  mov         dword ptr [ebp-4],1  
  62. 00E283D2  cmp         dword ptr [ebp-1E8h],0  
  63. 00E283D9  je          main+10Eh (0E283EEh)  
  64. 00E283DB  mov         ecx,dword ptr [ebp-1E8h]  
  65. 00E283E1  call        MyClass::MyClass (0E210BEh)  
  66. 00E283E6  mov         dword ptr [ebp-22Ch],eax  
  67. 00E283EC  jmp         main+118h (0E283F8h)  
  68. 00E283EE  mov         dword ptr [ebp-22Ch],0  
  69. 00E283F8  mov         eax,dword ptr [ebp-22Ch]  
  70. 00E283FE  mov         dword ptr [ebp-1F4h],eax  
  71. 00E28404  mov         dword ptr [ebp-4],0FFFFFFFFh  
  72. 00E2840B  mov         ecx,dword ptr [ebp-1F4h]  
  73. 00E28411  mov         dword ptr [fPtr2],ecx  
  74.         delete fPtr2;
  75. 00E28414  mov         eax,dword ptr [fPtr2]  
  76. 00E28417  mov         dword ptr [ebp-1D0h],eax  
  77. 00E2841D  mov         ecx,dword ptr [ebp-1D0h]  
  78. 00E28423  mov         dword ptr [ebp-1DCh],ecx  
  79. 00E28429  cmp         dword ptr [ebp-1DCh],0  
  80. 00E28430  je          main+167h (0E28447h)  
  81. 00E28432  push        1  
  82. 00E28434  mov         ecx,dword ptr [ebp-1DCh]  
  83. 00E2843A  call        MyClass::`scalar deleting destructor' (0E2101Eh)  
  84. 00E2843F  mov         dword ptr [ebp-22Ch],eax  
  85. 00E28445  jmp         main+171h (0E28451h)  
  86. 00E28447  mov         dword ptr [ebp-22Ch],0  

  87.         char x1[sizeof( MyClass )];
  88.         MyClass* fPtr3 = new( &x1[0] ) MyClass;
  89. 00E28451  mov         eax,1  
  90. 00E28456  imul        eax,eax,0  
  91. 00E28459  lea         ecx,x1[eax]  
  92. 00E2845D  push        ecx  
  93. 00E2845E  push        4  
  94. 00E28460  call        operator new (0E2105Ah)  
  95. 00E28465  add         esp,8  
  96. 00E28468  mov         dword ptr [ebp-1B8h],eax  
  97. 00E2846E  mov         dword ptr [ebp-4],2  
  98. 00E28475  cmp         dword ptr [ebp-1B8h],0  
  99. 00E2847C  je          main+1B1h (0E28491h)  
  100. 00E2847E  mov         ecx,dword ptr [ebp-1B8h]  
  101. 00E28484  call        MyClass::MyClass (0E210BEh)  
  102. 00E28489  mov         dword ptr [ebp-22Ch],eax  
  103. 00E2848F  jmp         main+1BBh (0E2849Bh)  
  104. 00E28491  mov         dword ptr [ebp-22Ch],0  
  105. 00E2849B  mov         edx,dword ptr [ebp-22Ch]  
  106. 00E284A1  mov         dword ptr [ebp-1C4h],edx  
  107. 00E284A7  mov         dword ptr [ebp-4],0FFFFFFFFh  
  108. 00E284AE  mov         eax,dword ptr [ebp-1C4h]  
  109. 00E284B4  mov         dword ptr [fPtr3],eax  
  110.         fPtr3 -> ~MyClass();
  111. 00E284B7  push        0  
  112. 00E284B9  mov         ecx,dword ptr [fPtr3]  
  113. 00E284BC  call        MyClass::`scalar deleting destructor' (0E2101Eh)  
  114.        
  115.         MyClass* fPtr4 = new MyClass[2];
  116. 00E284C1  push        0Ch  
  117. 00E284C3  call        operator new[] (0E2119Ah)  
  118. 00E284C8  add         esp,4  
  119. 00E284CB  mov         dword ptr [ebp-1A0h],eax  
  120. 00E284D1  mov         dword ptr [ebp-4],3  
  121. 00E284D8  cmp         dword ptr [ebp-1A0h],0  
  122. 00E284DF  je          main+23Bh (0E2851Bh)  
  123. 00E284E1  mov         eax,dword ptr [ebp-1A0h]  
  124.        
  125.         MyClass* fPtr4 = new MyClass[2];
  126. 00E284E7  mov         dword ptr [eax],2  
  127. 00E284ED  push        0E21023h  
  128. 00E284F2  push        0E210BEh  
  129. 00E284F7  push        2  
  130. 00E284F9  push        4  
  131. 00E284FB  mov         ecx,dword ptr [ebp-1A0h]  
  132. 00E28501  add         ecx,4  
  133. 00E28504  push        ecx  
  134. 00E28505  call        `eh vector constructor iterator' (0E21316h)  
  135. 00E2850A  mov         edx,dword ptr [ebp-1A0h]  
  136. 00E28510  add         edx,4  
  137. 00E28513  mov         dword ptr [ebp-22Ch],edx  
  138. 00E28519  jmp         main+245h (0E28525h)  
  139. 00E2851B  mov         dword ptr [ebp-22Ch],0  
  140. 00E28525  mov         eax,dword ptr [ebp-22Ch]  
  141. 00E2852B  mov         dword ptr [ebp-1ACh],eax  
  142. 00E28531  mov         dword ptr [ebp-4],0FFFFFFFFh  
  143. 00E28538  mov         ecx,dword ptr [ebp-1ACh]  
  144. 00E2853E  mov         dword ptr [fPtr4],ecx  
  145.         delete []fPtr4;
  146. 00E28541  mov         eax,dword ptr [fPtr4]  
  147. 00E28544  mov         dword ptr [ebp-188h],eax  
  148. 00E2854A  mov         ecx,dword ptr [ebp-188h]  
  149. 00E28550  mov         dword ptr [ebp-194h],ecx  
  150. 00E28556  cmp         dword ptr [ebp-194h],0  
  151. 00E2855D  je          main+294h (0E28574h)  
  152. 00E2855F  push        3  
  153. 00E28561  mov         ecx,dword ptr [ebp-194h]  
  154. 00E28567  call        MyClass::`vector deleting destructor' (0E2128Ah)  
  155. 00E2856C  mov         dword ptr [ebp-22Ch],eax  
  156. 00E28572  jmp         main+29Eh (0E2857Eh)  
  157. 00E28574  mov         dword ptr [ebp-22Ch],0  

  158.         MyClass* fPtr5 = new( nothrow ) MyClass[2];
  159. 00E2857E  push        0E30228h  
  160. 00E28583  push        0Ch  
  161. 00E28585  call        operator new[] (0E21311h)  
  162. 00E2858A  add         esp,8  
  163. 00E2858D  mov         dword ptr [ebp-170h],eax  
  164. 00E28593  mov         dword ptr [ebp-4],4  
  165. 00E2859A  cmp         dword ptr [ebp-170h],0  
  166. 00E285A1  je          main+2FDh (0E285DDh)  
  167. 00E285A3  mov         eax,dword ptr [ebp-170h]  
  168. 00E285A9  mov         dword ptr [eax],2  
  169. 00E285AF  push        0E21023h  
  170. 00E285B4  push        0E210BEh  
  171. 00E285B9  push        2  
  172. 00E285BB  push        4  
  173. 00E285BD  mov         ecx,dword ptr [ebp-170h]  
  174. 00E285C3  add         ecx,4  
  175. 00E285C6  push        ecx  
  176. 00E285C7  call        `eh vector constructor iterator' (0E21316h)  
  177. 00E285CC  mov         edx,dword ptr [ebp-170h]  
  178. 00E285D2  add         edx,4  
  179. 00E285D5  mov         dword ptr [ebp-22Ch],edx  
  180. 00E285DB  jmp         main+307h (0E285E7h)  
  181. 00E285DD  mov         dword ptr [ebp-22Ch],0  
  182. 00E285E7  mov         eax,dword ptr [ebp-22Ch]  
  183. 00E285ED  mov         dword ptr [ebp-17Ch],eax  
  184. 00E285F3  mov         dword ptr [ebp-4],0FFFFFFFFh  
  185. 00E285FA  mov         ecx,dword ptr [ebp-17Ch]  
  186. 00E28600  mov         dword ptr [fPtr5],ecx  
  187.         delete []fPtr5;
  188. 00E28603  mov         eax,dword ptr [fPtr5]  
  189. 00E28606  mov         dword ptr [ebp-158h],eax  
  190. 00E2860C  mov         ecx,dword ptr [ebp-158h]  
  191. 00E28612  mov         dword ptr [ebp-164h],ecx  
  192. 00E28618  cmp         dword ptr [ebp-164h],0  
  193. 00E2861F  je          main+356h (0E28636h)  
  194. 00E28621  push        3  
  195. 00E28623  mov         ecx,dword ptr [ebp-164h]  
  196. 00E28629  call        MyClass::`vector deleting destructor' (0E2128Ah)  
  197. 00E2862E  mov         dword ptr [ebp-22Ch],eax  
  198. 00E28634  jmp         main+360h (0E28640h)  
  199. 00E28636  mov         dword ptr [ebp-22Ch],0  

  200.         char x2[2*sizeof( MyClass ) + sizeof(int)];
  201.         MyClass* fPtr6 = new ( &x2[0] ) MyClass[2];
  202. 00E28640  mov         eax,1  
  203. 00E28645  imul        eax,eax,0  
  204. 00E28648  lea         ecx,x2[eax]  
  205. 00E2864C  push        ecx  
  206. 00E2864D  push        0Ch  
  207. 00E2864F  call        operator new[] (0E21389h)  
  208. 00E28654  add         esp,8  
  209. 00E28657  mov         dword ptr [ebp-140h],eax  
  210. 00E2865D  mov         dword ptr [ebp-4],5  
  211. 00E28664  cmp         dword ptr [ebp-140h],0  
  212. 00E2866B  je          main+3C7h (0E286A7h)  
  213. 00E2866D  mov         edx,dword ptr [ebp-140h]  
  214. 00E28673  mov         dword ptr [edx],2  
  215. 00E28679  push        0E21023h  
  216. 00E2867E  push        0E210BEh  
  217. 00E28683  push        2  
  218. 00E28685  push        4  
  219. 00E28687  mov         eax,dword ptr [ebp-140h]  
  220. 00E2868D  add         eax,4  
  221. 00E28690  push        eax  
  222. 00E28691  call        `eh vector constructor iterator' (0E21316h)  
  223. 00E28696  mov         ecx,dword ptr [ebp-140h]  
  224. 00E2869C  add         ecx,4  
  225. 00E2869F  mov         dword ptr [ebp-22Ch],ecx  
  226. 00E286A5  jmp         main+3D1h (0E286B1h)  
  227. 00E286A7  mov         dword ptr [ebp-22Ch],0  
  228. 00E286B1  mov         edx,dword ptr [ebp-22Ch]  
  229. 00E286B7  mov         dword ptr [ebp-14Ch],edx  
  230. 00E286BD  mov         dword ptr [ebp-4],0FFFFFFFFh  
  231. 00E286C4  mov         eax,dword ptr [ebp-14Ch]  
  232. 00E286CA  mov         dword ptr [fPtr6],eax  
  233.         fPtr6[1].~MyClass();
  234. 00E286CD  push        0  
  235. 00E286CF  mov         ecx,4  
  236. 00E286D4  shl         ecx,0  
  237. 00E286D7  add         ecx,dword ptr [fPtr6]  
  238. 00E286DA  call        MyClass::`scalar deleting destructor' (0E2101Eh)  
  239.         fPtr6[0].~MyClass();//按照和构造顺序相反顺序析构
  240. 00E286DF  push        0  
  241. 00E286E1  mov         ecx,4  
  242. 00E286E6  imul        ecx,ecx,0  
  243. 00E286E9  add         ecx,dword ptr [fPtr6]  
  244. 00E286EC  call        MyClass::`scalar deleting destructor' (0E2101Eh)  
  245. }
  246. 00E286F1  xor         eax,eax  
  247. }
  248. 00E286F3  push        edx  
  249. 00E286F4  mov         ecx,ebp  
  250. 00E286F6  push        eax  
  251. 00E286F7  lea         edx,ds:[0E28730h]  
  252. 00E286FD  call        @_RTC_CheckStackVars@8 (0E21145h)  
  253. 00E28702  pop         eax  
  254. 00E28703  pop         edx  
  255. 00E28704  mov         ecx,dword ptr [ebp-0Ch]  
  256. 00E28707  mov         dword ptr fs:[0],ecx  
  257. 00E2870E  pop         ecx  
  258. 00E2870F  pop         edi  
  259. 00E28710  pop         esi  
  260. 00E28711  pop         ebx  
  261. 00E28712  mov         ecx,dword ptr [ebp-10h]  
  262. 00E28715  xor         ecx,ebp  
  263. 00E28717  call        @__security_check_cookie@4 (0E21050h)  
  264. 00E2871C  add         esp,22Ch  
  265. 00E28722  cmp         ebp,esp  
  266. 00E28724  call        __RTC_CheckEsp (0E2135Ch)  
  267. 00E28729  mov         esp,ebp  
  268. 00E2872B  pop         ebp  
  269. 00E2872C  ret
复制代码



第一种形式为常规new,MyClass* fPtr1 = new MyClass;实现方式:
单步步入后IDE定位到new.cpp的

  1. void *__CRTDECL operator new(size_t size) _THROW1(_STD bad_alloc)
  2. {       // try to allocate size bytes
  3.     void *p;
  4.     while ((p = malloc(size)) == 0)
  5.     if (_callnewh(size) == 0)
  6.     {       // report no memory
  7.         _THROW_NCEE(_XSTD bad_alloc, );
  8.     }
  9.     return (p);
  10. }
复制代码

而步过之后直接跳转到构造函数中。
    从上面new函数实现可以看到是使用malloc函数进行分配,如果失败则调用_callnewh调用注册过的“new操作符失败回调”函数(注册用_set_new_handler),如果原先没注册new失败回调,则抛出bad_alloc异常,可见在默认情况下,该while只会执行1次,仅当自定义new失败回调函数返回true,才可能多次尝试分配。
该种形式delete实现方式,单步以后vs不能定位到源码,不过我们可以换一种思路,既然知道一定执行析构函数,那么就在析构中下断点,断下后查看反汇编,并执行到上一级调用即可找到delete实现方法,因此看汇编实现,发现是一个名为“scalar deleting destructor”的内部函数:

  1. 00EB3470  push        ebp  
  2. 00EB3471  mov         ebp,esp  
  3. 00EB3473  sub         esp,0CCh  
  4. 00EB3479  push        ebx  
  5. 00EB347A  push        esi  
  6. 00EB347B  push        edi  
  7. 00EB347C  push        ecx  
  8. 00EB347D  lea         edi,[ebp-0CCh]  
  9. 00EB3483  mov         ecx,33h  
  10. 00EB3488  mov         eax,0CCCCCCCCh  
  11. 00EB348D  rep stos    dword ptr es:[edi]  
  12. 00EB348F  pop         ecx  //以上部分为debug版API常见头,无需理会
  13. 00EB3490  mov         dword ptr [this],ecx  
  14. 00EB3493  mov         ecx,dword ptr [this]  
  15. 00EB3496  call        MyClass::~MyClass (0EB1023h)  //执行析构
  16. 00EB349B  mov         eax,dword ptr [ebp+8]  
  17. 00EB349E  and         eax,1  
  18. 00EB34A1  je          MyClass::`scalar deleting destructor'+3Fh (0EB34AFh)  //如果传入参数允许释放则进行调用对应delete函数(对于定位new对应的delete该参数是设置为不允许的)
  19. 00EB34A3  mov         eax,dword ptr [this]  
  20. 00EB34A6  push        eax  
  21. 00EB34A7  call        operator delete (0EB1154h)  
  22. 00EB34AC  add         esp,4  
  23. 00EB34AF  mov         eax,dword ptr [this]  //以下是无关的收尾工作
  24. 00EB34B2  pop         edi  
  25. 00EB34B3  pop         esi  
  26. 00EB34B4  pop         ebx  
  27. 00EB34B5  add         esp,0CCh  
  28. 00EB34BB  cmp         ebp,esp  
  29. 00EB34BD  call        __RTC_CheckEsp (0EB1352h)  
  30. 00EB34C2  mov         esp,ebp  
  31. 00EB34C4  pop         ebp  
  32. 00EB34C5  ret         4
复制代码


    执行到call operator delete这行,步入之后转到源码,可以看到使用的是dbgdel.cpp的delete函数。实现如下:

  1. void operator delete( void *pUserData )
  2. {
  3.         _CrtMemBlockHeader * pHead;

  4.         RTCCALLBACK(_RTC_Free_hook, (pUserData, 0));

  5.         if (pUserData == NULL)
  6.             return;

  7.         _mlock(_HEAP_LOCK);  /* 阻塞其他线程*/
  8.         __TRY

  9.             /* 得到用于内存块信息头指针*/
  10.             pHead = pHdr(pUserData);

  11.              /* 检查区块类型 */
  12.             _ASSERTE(_BLOCK_TYPE_IS_VALID(pHead->nBlockUse));

  13.             _free_dbg( pUserData, pHead->nBlockUse );//调用free函数释放内存

  14.         __FINALLY
  15.             _munlock(_HEAP_LOCK);  /* 解锁其他线程*/
  16.         __END_TRY_FINALLY

  17.         return;
  18. }
复制代码


第二种方式为不抛出异常的new,MyClass* fPtr2 = new( nothrow ) MyClass;实现方式:
单步到newopnt.cpp中,

  1. void * __CRTDECL operator new(size_t count, const std::nothrow_t&) _THROW0()
  2. {        // try to allocate count bytes
  3.         void *p;
  4.         _TRY_BEGIN
  5.         p = operator new(count);
  6.         _CATCH_ALL
  7.         p = 0;
  8.         _CATCH_END
  9.         return (p);
  10. }
  11. #define _TRY_BEGIN        try {
  12. #define _CATCH(x)        } catch (x) {
  13. #define _CATCH_ALL        } catch (...) {
  14. #define _CATCH_END        }
复制代码

可见,这里用try块捕获了异常,因此不再抛出异常,余下的就是调用常规new函数而已。

第三种方式为定位new,
char x1[sizeof( MyClass )];
MyClass* fPtr3 = new( &x1[0] ) MyClass;
这里所谓的定位就是说告诉new我们已经有一个内存位置了:
单步后发现new位于new文件:

  1. inline void *__CRTDECL operator new(size_t, void *_Where) _THROW0()
  2. {        // construct array with placement at _Where
  3.         return (_Where);
  4. }
复制代码

    可以发现该new什么都没做,那么为什么还要new呢?仔细想想可以知道,编译器对new的处理是调用new函数后,之后将该地址作为this指针进行初始化操作(比如设置虚表),再调用构造函数,而构造函数这玩意不能直接调用,不像析构函数那样,因为构造之前还没有对象和指针呢,对象和指针是构造以后才有的,而调用析构函数的时候,是已经有对象或指针的。所以这种定位new在我理解,就是可以相当于可以直接构造了。
    从上面可以看到new操作符先调用合适的new函数分配空间,之后调用构造函数构造,而delete函数刚好相对,先进行析构之后调用析构函数析构;同时可以看到布局new操作符的好处是可以手动指定构造和析构的时间,对于new无论哪种形式,在调用new函数分配好内存后都会调用构造函数进行构造,而定位new函数实则是直接返回,这就导致直接使用当前地址进行构造,相当于显示调用构造函数,而析构时由于没有实际分配空间,因此不能用delete,而是显示调用析构函数进行析构。
    上面都是对于有构造函数和析构函数对象的情况,用delete时,编译器会为该类专门生成一个scalar deleting destructor函数,该函数中先进行析构,之后调用operator delete函数。当然,如果没有析构函数,那么就不会有scalar deleting destructor函数了,此时单步是可以看到delete源码的,即dbgdel.cpp中的void operator delete(void *pUserData)函数。这一点在delete用于基本类型时显而易见。

    下面再来看数组的情况
第一种类型new,MyClass* fPtr4 = new MyClass[2],单步以后定位到newaop.cpp中:

  1. void *__CRTDECL operator new[](size_t count) _THROW1(std::bad_alloc)
  2. {        // try to allocate count bytes for an array
  3.         return (operator new(count));
  4. }
复制代码

而编译器传给该new[]函数的参数count是sizeof(MyClass[2])+sizeof(int)    该sizeof(int)用于内存管理
new[]()仍然调用了new();没有本质区别,即这么多对象占用的内存是当作整体分配的。再分配好之后,就需要对每个对象this指针处进行初始化和构造了。

这些都是边研究边写的,剩下2种情况下次讲述
回复

使用道具 举报

发表于 2014-10-12 17:47:31 | 显示全部楼层
赶上直播了
回复 赞! 靠!

使用道具 举报

发表于 2014-10-12 20:00:33 | 显示全部楼层
赞一个{:soso_e113:}
回复 赞! 靠!

使用道具 举报

本版积分规则

QQ|Archiver|小黑屋|技术宅的结界 ( 滇ICP备16008837号 )|网站地图

GMT+8, 2024-11-22 17:00 , Processed in 0.032157 second(s), 23 queries , Gzip On.

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表