首页
社区
课程
招聘
[分享]自己解决了!AspectC++ Add-In for Microsoft® Visual C++® 的破解过程
发表于: 2009-8-13 10:38 7689

[分享]自己解决了!AspectC++ Add-In for Microsoft® Visual C++® 的破解过程

2009-8-13 10:38
7689
AspectC++ Add-In for Microsoft® Visual C++®

http://www.pure-systems.com/fileadmin/downloads/acaddin/Aspectc-AddIn-Setup-010101.exe
我用的是VS2003环境
调试目标:C:\Program Files\pure-systems\AspectC++ Add-In\bin\CPPAddin.dll
工具:用OD调试,IDA+Hex-rays分析
重点集中在以下几个地址
0x10008e60 弹许可文件询问的对话框
0x10017a20 解析xml格式的许可文件
0x10017730 貌似许可检查的地方

这个是
0x10008e60的由Hex-ray分析出来的伪代码,
char __usercall sub_1000E860<al>(int a1<ebx>)
{
  int ST14_4_0; // ST14_4@0
  int v2; // ST10_4@1
  const CHAR *v3; // eax@3
  const CHAR *v4; // eax@10
  int v6; // eax@2
  char v7; // bl@2
  char v8; // al@9
  int v9; // [sp+Ch] [bp-9Ch]@1
  signed int v10; // [sp+A4h] [bp-4h]@1
  char v11; // [sp+10h] [bp-98h]@1
  char v12; // [sp+48h] [bp-60h]@2
  char v13; // [sp+2Ch] [bp-7Ch]@2
  LPCSTR lpText; // [sp+14h] [bp-94h]@3
  unsigned int v15; // [sp+28h] [bp-80h]@3
  char v16; // [sp+64h] [bp-44h]@15

  BYTE3(v9) = 0;
  sub_10016AA0();
  v10 = 0;
  std__basic_string_char_std__char_traits_char__std__allocator_char____basic_string_char_std__char_traits_char__std__allocator_char__(&v11);
  LOBYTE(v10) = 1;
  v2 = a1;
  while ( 1 )
  {
    sub_100169B0(16, (int)&v12);
    LOBYTE(v10) = 2;
    v6 = std__operator_(&v13, v6, "\\etc\\licence");
    LOBYTE(v10) = 3;
    v7 = sub_10017A20((int)&unk_10024460, v6, (int)&v11) == 0;
    LOBYTE(v10) = 2;
    std__basic_string_char_std__char_traits_char__std__allocator_char_____basic_string_char_std__char_traits_char__std__allocator_char__(&v13);
    LOBYTE(v10) = 1;
    std__basic_string_char_std__char_traits_char__std__allocator_char_____basic_string_char_std__char_traits_char__std__allocator_char__(&v12);
    if ( !v7 )
      break;
    std__basic_string_char_std__char_traits_char__std__allocator_char____operator__(
      &v11,
      "\nThe add-in will not work without a valid licence.\n\nInstall the licence file now?",
      v2);
    v3 = lpText;
    if ( v15 < 0x10 )
      v3 = (const CHAR *)&lpText;
    if ( MessageBoxA(0, v3, "AspectC++ Add-In for Visual Studio .NET", 0x24u) != 6 )
      break;
    if ( !sub_1000E690() )
    {
      MessageBoxA(0, "Installation of licence file failed.", "AspectC++ Add-In", 0x40u);
      break;
    }
  }
  if ( byte_10024465 )
  {
    sub_10017730((int)&unk_10024460, 16, (int)&v11);
    if ( v8 && (unsigned __int8)sub_10017520(&v11) != 1 )
    {
      BYTE3(v9) = 1;
    }
    else
    {
      std__basic_string_char_std__char_traits_char__std__allocator_char____operator__(
        &v11,
        "\nThe add-in will not work.",
        ST14_4_0);
      v4 = lpText;
      if ( v15 < 0x10 )
        v4 = (const CHAR *)&lpText;
      MessageBoxA(0, v4, "AspectC++ Add-In", 0x40u);
    }
  }
  LOBYTE(v10) = 0;
  std__basic_string_char_std__char_traits_char__std__allocator_char_____basic_string_char_std__char_traits_char__std__allocator_char__(&v11);
  v10 = -1;
  sub_10016910((int)&v16);
  return BYTE3(v9);
}

基本上可以得出默认是分析
C:\Program Files\pure-systems\AspectC++ Add-In\etc\licence 许可文件
分析过程应该在0x10017a20里
char __thiscall sub_10017A20(int this, int a2, int a3)
{
  int v3; // ebp@1
  int v4; // esi@1
  int v5; // eax@2
  int v6; // eax@4
  int v7; // edi@5
  char result; // al@8
  int v9; // ecx@1
  int v10; // eax@5
  int v11; // eax@6
  int v12; // ST04_4@6
  char v13; // bl@6
  char v14; // [sp+Ch] [bp-28h]@6
  signed int v15; // [sp+30h] [bp-4h]@6

  v3 = a3;
  v4 = this;
  v9 = this + 96;
  *(_DWORD *)v9 = 0;
  *(_DWORD *)(v9 + 4) = 0;
  *(_DWORD *)(v9 + 8) = 0;
  *(_DWORD *)(v9 + 12) = 0;
  *(_BYTE *)(v4 + 5) = 0;
  std__basic_string_char_std__char_traits_char__std__allocator_char____operator_(v3, "Loading licence file failed.");
  if ( *(_DWORD *)(a2 + 24) < 0x10u )
    v5 = a2 + 4;
  else
    v5 = *(_DWORD *)(a2 + 4);
  v6 = xmlParseFile(v5);
  *(_DWORD *)v4 = v6;
  if ( v6
    && (v10 = xmlDocGetRootElement(v6), v7 = v10, v10)
    && (v11 = std__basic_string_char_std__char_traits_char__std__allocator_char____basic_string_char_std__char_traits_char__std__allocator_char__(
                &v14,
                "licence"), v12 = *(_DWORD *)(v7 + 8), v15 = 0, v13 = std__operator__(v11, v12), v15 = -1, std__basic_string_char_std__char_traits_char__std__allocator_char_____basic_string_char_std__char_traits_char__std__allocator_char__(&v14), v13)
    && sub_10017930(v7) )
  {
    *(_BYTE *)(v4 + 5) = 1;
    sub_10017730(v4, v3, v3);
    result = 1;
  }
  else
  {
    result = 0;
  }
  return result;
}

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

收藏
免费 0
支持
分享
最新回复 (10)
雪    币: 165
活跃值: (11)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
这是0x10017730的过程
void __userpurge sub_10017730(int this<ecx>, int ebp0<ebp>, int a2)
{
  int ST18_4_0; // ST18_4@0
  int ST1C_4_0; // ST1C_4@0
  int v5; // esi@1
  signed int v6; // eax@4
  int v7; // ST18_4@6
  int v8; // eax@20
  int v9; // eax@4
  int v10; // ST1C_4@12
  int v11; // ST1C_4@18
  int  r; // [sp+60h] [bp+0h]@1
  int v13; // [sp+50h] [bp-10h]@1
  signed int v14; // [sp+5Ch] [bp-4h]@3
  char v15; // [sp+34h] [bp-2Ch]@4
  char v16; // [sp+18h] [bp-48h]@4
  int v17; // [sp+1Ch] [bp-44h]@12
  unsigned int v18; // [sp+30h] [bp-30h]@20
  int v19; // [sp+2Ch] [bp-34h]@22

  v5 = this;
  v13 =  r ^ dword_100242D0;
  std__basic_string_char_std__char_traits_char__std__allocator_char____operator_(a2, "Invalid licence file found.");
  if ( *(_BYTE *)(v5 + 5) && !*(_BYTE *)(v5 + 4) )
  {
    sub_10017B20((int)&a2, ebp0);
    v14 = 0;
    if ( !sub_1001A050((int)&a2) )
    {
LABEL_23:
      v14 = -1;
      sub_1001A060(&a2);
      goto LABEL_24;
    }
    v9 = std__operator_(&v15, v5 + 12, v5 + 40);
    LOBYTE(v14) = 1;
    std__operator_(&v16, v9, v5 + 68);
    LOBYTE(v14) = 3;
    std__basic_string_char_std__char_traits_char__std__allocator_char_____basic_string_char_std__char_traits_char__std__allocator_char__(&v15);
    v6 = *(_DWORD *)(v5 + 8);
    if ( v6 || !*(_DWORD *)(v5 + 96) )
    {
      if ( v6 == 1 && *(_DWORD *)(v5 + 96) && *(_DWORD *)(v5 + 100) && *(_DWORD *)(v5 + 104) && *(_DWORD *)(v5 + 108) )
      {
        std__basic_string_char_std__char_traits_char__std__allocator_char____operator__(&v16, "evaluation", ST18_4_0);
        std__basic_string_char_std__char_traits_char__std__allocator_char____operator__(
          &v17,
          *(_DWORD *)(v5 + 96),
          ST1C_4_0);
        std__basic_string_char_std__char_traits_char__std__allocator_char____operator__(
          &v17,
          *(_DWORD *)(v5 + 100),
          v10);
        std__basic_string_char_std__char_traits_char__std__allocator_char____operator__(
          &v17,
          *(_DWORD *)(v5 + 104),
          ST1C_4_0);
        v7 = *(_DWORD *)(v5 + 108);
      }
      else
      {
        if ( v6 != 2
          || !*(_DWORD *)(v5 + 96)
          || !*(_DWORD *)(v5 + 100)
          || !*(_DWORD *)(v5 + 104)
          || !*(_DWORD *)(v5 + 108) )
          goto LABEL_20;
        std__basic_string_char_std__char_traits_char__std__allocator_char____operator__(&v16, "user", ST18_4_0);
        std__basic_string_char_std__char_traits_char__std__allocator_char____operator__(
          &v17,
          *(_DWORD *)(v5 + 96),
          ST1C_4_0);
        std__basic_string_char_std__char_traits_char__std__allocator_char____operator__(
          &v17,
          *(_DWORD *)(v5 + 100),
          v11);
        std__basic_string_char_std__char_traits_char__std__allocator_char____operator__(
          &v17,
          *(_DWORD *)(v5 + 104),
          ST1C_4_0);
        v7 = *(_DWORD *)(v5 + 108);
      }
    }
    else
    {
      std__basic_string_char_std__char_traits_char__std__allocator_char____operator__(&v16, "beta", ST18_4_0);
      v7 = *(_DWORD *)(v5 + 96);
    }
    std__basic_string_char_std__char_traits_char__std__allocator_char____operator__(&v17, v7, ST1C_4_0);
LABEL_20:
    v8 = v17;
    if ( v18 < 0x10 )
      v8 = (int)&v17;
    *(_BYTE *)(v5 + 4) = sub_10019E30(v5 + 112, v8, v19, (int)&a2);
    LOBYTE(v14) = 0;
    std__basic_string_char_std__char_traits_char__std__allocator_char_____basic_string_char_std__char_traits_char__std__allocator_char__(&v16);
    goto LABEL_23;
  }
LABEL_24:
  sub_1001A7B0( r ^ v13, ebp0);
}


小弟是初学菜鸟,看了各位大大的很多教程,刚刚能使OD和IDA,分析的水平有限,虽然C语言自我感觉还比较熟悉。但是看上面的算法还是比较吃力,希望各位大大不吝赐教。
这个软件是作为VS2003的一个插件运行的,如果没有许可,好像菜单就是灰色的,菜单灰色不像按钮灰色可以用工具改亮。如果破解的话,思路又该如何??

如果没有VS2003,不方便调试CPPAddin.dll,也可以调试
C:\Program Files\pure-systems\AspectC++ Add-In\bin目录下,cl.exe 或GenImport.exe。
这里面都有检查许可文件的代码。

谢谢各位大大!
2009-8-13 10:46
0
雪    币: 165
活跃值: (11)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
看来各位大大都很忙,帖子发了半天也没人理。只好自己动手,丰衣足食了。
    其实,昨天我自己调试的时候也犯了一个错误,就是调试CppAddin.dll很痛苦,浪费不少时间和分散很多的精力,中间老是受到Va_X.dll的干扰,而且msdev.exe在CppAddin没加载时没法直接下断点,必须得在OD中设置一个新模块加载的断点(选项->调试选项->事件->中断于新模块),这样下来,每次调试失败后重启的过程很是漫长,浪费了不少时间,发帖子的求助的时候,我为了大大们给我能方便的解决问题,尽量把非技术问题都试验了一下,以免大大们被这些问题困住了,一怒之下不给我管我了。但是这样一来,也为我自己解决和发现问题加快了速度。

总结一下:
    1.解决问题要东方不亮,西方亮,不要将自己精力消耗在远离问题本身的地方
    2.坚持就是胜利,哪怕是菜鸟,不懂多少汇编(看代码还得靠伟大、光荣、正确的F5),也能取得成绩

下面写写分析过程:
其实昨天已经找到了关键的过程,那就是0x10017a20,这里面就是分析xml格式的许可文件
这里面有两个调用,sub_10017930()和 sub_10017730()
大概可以看得出来,sub_10017930参与了xml格式的许可数据的解析过程,它调用成功之后,才调用10017730对数据进行验证,要分析许可数据格式,必须研究10017930
char __stdcall sub_10017930(int a1)
{
  int v1; // ebp@1
  int v2; // esi@1
  int v3; // esi@3
  char result; // al@7
  int v5; // eax@1
  int v6; // eax@2
  char v7; // bl@2
  char v8; // [sp+Ch] [bp-28h]@2
  signed int v9; // [sp+30h] [bp-4h]@2

  v1 = a1;
  v5 = xmlGetProp(a1, "version");
  v2 = v5;
  if ( v5
    && (v6 = std__basic_string_char_std__char_traits_char__std__allocator_char____basic_string_char_std__char_traits_char__std__allocator_char__(
               &v8,
               L"1"), v9 = 0, v7 = std__operator__(v6, v2), v9 = -1, std__basic_string_char_std__char_traits_char__std__allocator_char_____basic_string_char_std__char_traits_char__std__allocator_char__(&v8), v7) )
  {
    v3 = *(_DWORD *)(v1 + 12);
    result = (unsigned __int8)sub_10016D60(*(_DWORD *)(v1 + 12))
          && (unsigned __int8)sub_10016E70(v3)
          && (unsigned __int8)sub_10017570(v3)
          && (unsigned __int8)sub_100172C0(v3);
  }
  else
  {
    result = 0;
  }
  return result;
}

在这里面取了xml的一个属性值version,并且还有四个都不能失败的过程:
10016d60  取product 元素
10016e70  取creation 元素
10017570  取type元素
100172c0  取signature元素
为了熟悉libxml,我特意编写了一段典型libxml用法,并分析了其反向工程后的代码,
	xmlDocPtr doc = NULL;
	xmlNodePtr cur = NULL;
	string filename("test.xml");
	doc = xmlParseFile(filename.c_str());
	cur = xmlDocGetRootElement(doc);
	if (xmlStrcmp(cur->name, BAD_CAST "licence")) 
	{

		fprintf(stderr,"document of the wrong type, root node != mail"); 

		xmlFreeDoc(doc); 

		/*return -1; */

	} 
	cur = cur->xmlChildrenNode;
	xmlNodePtr propNodePtr = cur;
	while(cur != NULL) 
	{   
		//取出节点中的内容
		if ((!xmlStrcmp(cur->name, (const xmlChar *)"product"))) 
		{
				
					string name;
					string version;
					xmlChar* szAttr = xmlGetProp(cur,BAD_CAST "name"); 

					name=(char*)szAttr;

					szAttr=xmlGetProp(cur,BAD_CAST "version");

					version=(const char *)szAttr;
					cout<<"Name:"<<name<<" Version:"<<version<<endl;


					
					xmlFree(szAttr);											
		}
		cur=cur->next;
	}


		

	xmlFreeDoc(doc);
	/*return 0;*/


得出的结论是,凡是属性值的获取,都会调用xmlGetProp,而子元素的获取则是通过直接访问内存结构或者类似c++的函数访问,不会看到函数名称的引用,根据这一结论和具体的调试,大致推出来licence文件的结构如下:
<?xml version="1.0" encoding="UTF-8"?>
<licence version="1">
<product name="aspect" version="1.0"/>
<product name="pointcut" version="1.0" />
<product name="advice"  version="1.0" />
<product name="slice"  version="1.0" />
<creation date="2009-8-13"/>
<type name="user">
<data code="xxxx" name="jans2002" email="jans2002@gmail.com" regnr="ccccc"/>
</type>
<signature sign="AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" />
</licence>
2009-8-14 09:13
0
雪    币: 165
活跃值: (11)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
有了这个licence文件,把它放到
C:\Program Files\pure-systems\AspectC++ Add-In\etc\目录下
一切问题就变得简单了,顺利执行完了0x10017930,一路杀到0x10017730
int __thiscall sub_10017730(int this, int a2)
{
  int v2; // esi@1
  signed int v3; // eax@4
  int v4; // ST14_4@6
  int v5; // eax@20
  int v7; // eax@4
  int  r; // [sp+4Ch] [bp+0h]@1
  int v9; // [sp+3Ch] [bp-10h]@1
  signed int v10; // [sp+48h] [bp-4h]@3
  char v11; // [sp+20h] [bp-2Ch]@4
  char v12; // [sp+4h] [bp-48h]@4
  int v13; // [sp+8h] [bp-44h]@20
  unsigned int v14; // [sp+1Ch] [bp-30h]@20
  int v15; // [sp+18h] [bp-34h]@22

  v2 = this;
  v9 =  r ^ dword_100242D0;
  std__basic_string_char_std__char_traits_char__std__allocator_char____operator_(a2, "Invalid licence file found.");
  if ( *(_BYTE *)(v2 + 5) && !*(_BYTE *)(v2 + 4) )
  {
    sub_10017B20();
    v10 = 0;
    if ( !(unsigned __int8)sub_1001A050() )
    {
LABEL_23:
      v10 = -1;
      sub_1001A060();
      return sub_1001A7B0();
    }
    v7 = std__operator_(&v11, v2 + 12, v2 + 40);
    LOBYTE(v10) = 1;
    std__operator_(&v12, v7, v2 + 68);
    LOBYTE(v10) = 3;
    std__basic_string_char_std__char_traits_char__std__allocator_char_____basic_string_char_std__char_traits_char__std__allocator_char__(&v11);
    v3 = *(_DWORD *)(v2 + 8);
    if ( v3 || !*(_DWORD *)(v2 + 96) )
    {
      if ( v3 == 1 && *(_DWORD *)(v2 + 96) && *(_DWORD *)(v2 + 100) && *(_DWORD *)(v2 + 104) && *(_DWORD *)(v2 + 108) )
      {
        std__basic_string_char_std__char_traits_char__std__allocator_char____operator__(&v12, "evaluation");
        std__basic_string_char_std__char_traits_char__std__allocator_char____operator__(&v12, *(_DWORD *)(v2 + 96));
        std__basic_string_char_std__char_traits_char__std__allocator_char____operator__(&v12, *(_DWORD *)(v2 + 100));
        std__basic_string_char_std__char_traits_char__std__allocator_char____operator__(&v12, *(_DWORD *)(v2 + 104));
        v4 = *(_DWORD *)(v2 + 108);
      }
      else
      {
        if ( v3 != 2
          || !*(_DWORD *)(v2 + 96)
          || !*(_DWORD *)(v2 + 100)
          || !*(_DWORD *)(v2 + 104)
          || !*(_DWORD *)(v2 + 108) )
          goto LABEL_20;
        std__basic_string_char_std__char_traits_char__std__allocator_char____operator__(&v12, "user");
        std__basic_string_char_std__char_traits_char__std__allocator_char____operator__(&v12, *(_DWORD *)(v2 + 96));
        std__basic_string_char_std__char_traits_char__std__allocator_char____operator__(&v12, *(_DWORD *)(v2 + 100));
        std__basic_string_char_std__char_traits_char__std__allocator_char____operator__(&v12, *(_DWORD *)(v2 + 104));
        v4 = *(_DWORD *)(v2 + 108);
      }
    }
    else
    {
      std__basic_string_char_std__char_traits_char__std__allocator_char____operator__(&v12, "beta");
      v4 = *(_DWORD *)(v2 + 96);
    }
    std__basic_string_char_std__char_traits_char__std__allocator_char____operator__(&v12, v4);
LABEL_20:
    v5 = v13;
    if ( v14 < 0x10 )
      v5 = (int)&v13;
    *(_BYTE *)(v2 + 4) = [COLOR="Red"]sub_10019E30[/COLOR](v2 + 112, v5, v15, (int)&a2);
    LOBYTE(v10) = 0;
    std__basic_string_char_std__char_traits_char__std__allocator_char_____basic_string_char_std__char_traits_char__std__allocator_char__(&v12);
    goto LABEL_23;
  }
  return sub_1001A7B0();
}

由于有了正确格式的licence,前面执行的都很顺利,一直到了sub_10019E30,跟进去一看,一切了然了:
bool __thiscall sub_10019E30(int this, int a2, int a3, int a4)
{
  int v5; // esi@1
  int v6; // eax@1
  int v7; // eax@1
  char v8; // [sp+4h] [bp-10h]@1

  v5 = this;
  v6 = EVP_sha1();
  EVP_DigestInit(&v8, v6);
  EVP_DigestUpdate(&v8, a2, a3);
  v7 = sub_1001A030();
[COLOR="Black"][B]  return EVP_VerifyFinal(&v8, v5, *(_DWORD *)(v5 + 4096), v7) == 1;[/B][/COLOR]}

前面一定都是加密验证的,但是函数最后来了一句:
EVP_VerifyFinal(&v8, v5, *(_DWORD *)(v5 + 4096), v7) == 1;

嘿嘿,看名字估计就是这个了,看看这个函数的返回值,1表示成功,其他表示失败,那就是只要让此函数永远返回1,就大功告成了,该到汇编代码了:
004066F0  /$  83EC 10       sub     esp, 10                          ;  数字签名验证部分
004066F3  |.  56            push    esi
004066F4  |.  8BF1          mov     esi, ecx
004066F6  |.  E8 81270000   call    <jmp.&LIBEAY32.#333>
004066FB  |.  50            push    eax
004066FC  |.  8D4424 08     lea     eax, dword ptr [esp+8]
00406700  |.  50            push    eax
00406701  |.  E8 70270000   call    <jmp.&LIBEAY32.#268>
00406706  |.  8B4C24 24     mov     ecx, dword ptr [esp+24]
0040670A  |.  8B5424 20     mov     edx, dword ptr [esp+20]
0040670E  |.  51            push    ecx
0040670F  |.  52            push    edx
00406710  |.  8D4424 14     lea     eax, dword ptr [esp+14]
00406714  |.  50            push    eax
00406715  |.  E8 56270000   call    <jmp.&LIBEAY32.#269>
0040671A  |.  8B4C24 34     mov     ecx, dword ptr [esp+34]
0040671E  |.  83C4 14       add     esp, 14
00406721  |.  E8 2A100000   call    00407750
00406726  |.  8B8E 00100000 mov     ecx, dword ptr [esi+1000]
0040672C  |.  50            push    eax
0040672D  |.  51            push    ecx
0040672E  |.  8D5424 0C     lea     edx, dword ptr [esp+C]
00406732  |.  56            push    esi
00406733  |.  52            push    edx
00406734  |.  E8 49270000   call    <jmp.&LIBEAY32.#290>
00406739  |.  83C4 10       add     esp, 10
0040673C  |.  48            dec     eax
0040673D  |.  F7D8          neg     eax
0040673F      1BC0          sbb     eax, eax
00406741      90         [B][Color="Red"]inc  eax[/COLOR][/B]
00406742      5E            pop     esi
00406743      83C4 10       add     esp, 10
00406746  \.  C2 0C00       retn    0C

一般来讲,函数返回值都会用EAX,不管三七二十一了,先吧eax做了在说,把上面那个黑体的
inc eax 改成nop(呵呵,nop是大家的最爱,别看机器码是90了,这是我改好的了)
保存到文件。
大功告成哈!!
身为菜鸟,真是无比荣幸,谢谢各位大大阅读,因为是菜鸟,好多地方都不知道,如果能有更好的方法和窍门,还请各位大大不吝赐教。
2009-8-14 09:53
0
雪    币: 146
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
学到不少 支持   按照文中方法  1.保存xml  2.将指令 40 改为 90 程序没反应,我的环境是vs 05  楼主能不能帮忙分析下
2009-12-28 23:04
0
雪    币: 166
活跃值: (12)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
学习了,分析的不错.
2009-12-29 08:46
0
雪    币: 122
活跃值: (11)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
自己能够解决的问题,最好不要麻烦别人!呵呵~
2009-12-29 09:12
0
雪    币: 3
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
8
学习一下呵呵!
2009-12-29 12:25
0
雪    币: 33
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
9
学习了,分析的不错.
2009-12-29 16:59
0
雪    币: 165
活跃值: (11)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
10
vs 2005我估计应该去patch那个CPPAddin80.dll
看名字就知道
2010-1-5 14:08
0
雪    币: 122
活跃值: (44)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
11
不错,学习了
2010-1-14 10:18
0
游客
登录 | 注册 方可回帖
返回
//