算法分析第二课 --WinNc的算法分析--我爱雪坡姐
本帖最后由 LYQingYe 于 2015-8-27 21:58 编辑{:5_116:}我是LYQingYe,今天是算法分析的第二课,第一次课时,疏忽大意,写糟了,这次课会很详细的。希望大家能耐心的看下去,享受分析带来的困境与成就。 {:5_184:}不要问我 雪坡姐 是谁。其实是 "吾爱汇编论坛" 的同音词,我的输入法有问题。 {:5_123:}最后在声明下,我爱雪坡姐。
软件名称: WinNc
编译器: PEID查不出,貌似 VC++无关紧要 无壳
WinNc 简体中文汉化版是一款极好的文件管理器,如同DOS时代的NC一样相当的好用,极似Total Commander,除了提供一般的重命名、查看、编辑、复制、删除、移动、新建等功能外,还提供了统计目录大小和压缩解压缩的功能!
软件下载地址 http://www.orsoon.com/Soft/14586.html
愉快的开始吧!未注册版本打开就会弹出一个NAG窗口 要你BUY ,他的验证方式是 时时验证 :所谓时时验证就是 当你输入注册码 或者 用户名 或者更改 某个数值他都会触发 验证CALL 如果错误 他会有字符串提示 ,
验证CALL可以通过 右键->中文搜索引擎->搜索错误提示字符串 在这我就不解释了。很简单的。是个重启验证。
此次调试所用到的用户名 "WWW.XUEPOJIE.COM" 长度为 0x10假码为"888888888" 长度为0x9
那就愉快的开始吧。
00D1043C/.55 push ebp ;CLOCK_PROC
00D1043D|.8BEC mov ebp,esp
00D1043F|.33C9 xor ecx,ecx
00D10441|.51 push ecx
00D10442|.51 push ecx
00D10443|.51 push ecx
00D10444|.51 push ecx
00D10445|.51 push ecx
00D10446|.53 push ebx
00D10447|.8BD8 mov ebx,eax
00D10449|.33C0 xor eax,eax
00D1044B|.55 push ebp
00D1044C|.68 4206D100 push WinNc.00D10642
00D10451|.64:FF30 push dword ptr fs:
00D10454|.64:8920 mov dword ptr fs:,esp
00D10457|.8D55 F0 lea edx,
00D1045A|.8B83 AC030000 mov eax,dword ptr ds:
00D10460|.E8 877D7AFF call WinNc.004B81EC ;GetText(Void) 系统操作,无需理。
00D10465|.8B45 F0 mov eax, ;EAX -> 用户名 -> WWW.XUEPOJIE.COM-> 表示指针的意思
00D10468|.8D55 FC lea edx, ;一段空的内存空间地址 -> 给 edx
00D1046B|.E8 F84971FF call WinNc.00424E68 ;eax -> *P -> 用户名 二级指针
00D10470|.8D55 EC lea edx, ;一段空的内存空间地址 -> 给 edx
00D10473|.8B83 B4030000 mov eax,dword ptr ds:
00D10479|.E8 6E7D7AFF call WinNc.004B81EC
00D1047E|.8B45 EC mov eax, ;EAX -> key'888888888'这段假注册码 长度 = 9
00D10481|.8D55 F8 lea edx,
00D10484|.E8 DF4971FF call WinNc.00424E68
00D10489|.8B45 FC mov eax, ;eax -> 用户名 -> WWW.XUEPOJIE.COM
00D1048C|.85C0 test eax,eax ;判断用户名所在内存地址 是否为0
00D1048E|.74 05 je short WinNc.00D10495
00D10490|.83E8 04 sub eax,0x4 ;指向字符串指针 - 0x4 向左移动 4个字节
00D10493|.8B00 mov eax,dword ptr ds: ;获得 移动后指针 指向的内容 4个字节 如果没错 应该是字符串长度
00D10495|>83F8 04 cmp eax,0x4 ;就是用户名的长度 和 0x4 对比 如果用户名长度 小于4 则报错
00D10498|.7D 3C jge short WinNc.00D104D6 ;这里必须跳走
00D1049A|.BA 5C06D100 mov edx,WinNc.00D1065C ;Please enter a valid registration name
00D1049F|.8B83 D4030000 mov eax,dword ptr ds:
00D104A5|.E8 9E7D7AFF call WinNc.004B8248
00D104AA|.8B8B EC030000 mov ecx,dword ptr ds:
00D104B0|.33D2 xor edx,edx
00D104B2|.8B83 9C030000 mov eax,dword ptr ds:
00D104B8|.E8 1F6687FF call WinNc.00586ADC
00D104BD|.8B83 D8030000 mov eax,dword ptr ds:
00D104C3|.8B80 B8010000 mov eax,dword ptr ds:
00D104C9|.8B93 EC030000 mov edx,dword ptr ds:
00D104CF|.E8 BC0278FF call WinNc.00490790
00D104D4|.EB 3A jmp short WinNc.00D10510
00D104D6|>33D2 xor edx,edx ;edx 清零
00D104D8|.8B83 D4030000 mov eax,dword ptr ds:
00D104DE|.E8 657D7AFF call WinNc.004B8248
00D104E3|.8B8B EC030000 mov ecx,dword ptr ds:
00D104E9|.BA 02000000 mov edx,0x2
00D104EE|.8B83 9C030000 mov eax,dword ptr ds:
00D104F4|.E8 E36587FF call WinNc.00586ADC
00D104F9|.8B83 D8030000 mov eax,dword ptr ds:
00D104FF|.8B80 B8010000 mov eax,dword ptr ds:
00D10505|.8B93 EC030000 mov edx,dword ptr ds:
00D1050B|.E8 800278FF call WinNc.00490790
00D10510|>E8 D33FC4FF call WinNc.009544E8
00D10515|.8B4D F8 mov ecx, ;ecx -> 假码
00D10518|.8B55 FC mov edx, ;edx = 用户名
00D1051B|.E8 204CC4FF call WinNc.00955140 ;关键CALL 洛跟进去
00D10520|.84C0 test al,al
00D10522|.75 14 jnz short WinNc.00D10538
00D10524|.E8 BF3FC4FF call WinNc.009544E8
00D10529|.8B4D F8 mov ecx,
00D1052C|.8B55 F4 mov edx,
00D1052F|.E8 0C4CC4FF call WinNc.00955140
00D10534|.84C0 test al,al
00D10536|.74 72 je short WinNc.00D105AA ;如果不跳 走向死亡 所以就要跳 顾名思义 上面就是 关键 CALL
00D10538|>33D2 xor edx,edx
00D1053A|.8B83 D0030000 mov eax,dword ptr ds:
00D10540|.E8 037D7AFF call WinNc.004B8248
00D10545|.B2 01 mov dl,0x1
00D10547|.8B83 A4030000 mov eax,dword ptr ds:
00D1054D|.8B08 mov ecx,dword ptr ds:
00D1054F|.FF91 80000000 call dword ptr ds:
00D10555|.8B83 A4030000 mov eax,dword ptr ds:
00D1055B|.E8 4C3893FF call WinNc.00643DAC
00D10560|.33D2 xor edx,edx
00D10562|.8B83 C4030000 mov eax,dword ptr ds:
00D10568|.8B08 mov ecx,dword ptr ds:
00D1056A|.FF91 80000000 call dword ptr ds:
00D10570|.8B83 C4030000 mov eax,dword ptr ds:
00D10576|.E8 313893FF call WinNc.00643DAC
00D1057B|.8B8B EC030000 mov ecx,dword ptr ds:
00D10581|.BA 02000000 mov edx,0x2
00D10586|.8B83 9C030000 mov eax,dword ptr ds:
00D1058C|.E8 4B6587FF call WinNc.00586ADC
00D10591|.8B83 B0030000 mov eax,dword ptr ds:
00D10597|.8B80 B8010000 mov eax,dword ptr ds:
00D1059D|.8B93 EC030000 mov edx,dword ptr ds:
00D105A3|.E8 E80178FF call WinNc.00490790
00D105A8|.EB 70 jmp short WinNc.00D1061A
00D105AA|>BA B806D100 mov edx,WinNc.00D106B8 ;Please enter a valid key
00D105AF|.8B83 D0030000 mov eax,dword ptr ds:
00D105B5|.E8 8E7C7AFF call WinNc.004B8248
算法一开始都是这样的先判断下KEY 或者 USERNAME的 长度。所以说没啥大惊小怪的了,我们继续 进入关键CALL
00955140这段还是跟开始一样对数据的简单处理。核心的还在里面。
00955140/[ DISCUZ_CODE_73 ]nbsp; 55 push ebp
00955141|.8BEC mov ebp,esp
00955143|.83C4 F4 add esp,-0xC
00955146|.53 push ebx
00955147|.56 push esi
00955148|.33DB xor ebx,ebx ;EDX 清零
0095514A|.895D F4 mov ,ebx ;初始化变量
0095514D|.894D F8 mov ,ecx ;-> 假码 赋值给变量 '888888888'
00955150|.8955 FC mov ,edx ;-> 用户名 赋值给变量 'WWW.XUEPOJIE.COM'
00955153|.8BF0 mov esi,eax
00955155|.8B45 FC mov eax, ;EAX -> 用户名 'WWW.XUEPOJIE.COM'
00955158|.E8 9B3CABFF call WinNc.00408DF8 ;简单 判断用户名所在内存地址 是否合法
0095515D|.8B45 F8 mov eax, ;EAX -> 假码 '888888888'
00955160|.E8 933CABFF call WinNc.00408DF8 ;和上面那个CALL一样 判断 是否合法
00955165|.33C0 xor eax,eax ;EAX 清零
00955167|.55 push ebp
00955168|.68 BC519500 push WinNc.009551BC
0095516D|.64:FF30 push dword ptr fs:
00955170|.64:8920 mov dword ptr fs:,esp
00955173|.33DB xor ebx,ebx ;EBX 清零
00955175|.8B45 FC mov eax, ;EAX -> 用户名 'WWW.XUEPOJIE.COM'
00955178|.85C0 test eax,eax
0095517A|.74 05 je short WinNc.00955181 ;地址是否合法
0095517C|.83E8 04 sub eax,0x4 ;用户名指针 前移 四个字节
0095517F|.8B00 mov eax,dword ptr ds: ;前四字节所指向的内容 就是他的长度 某编译器专用 哈哈
00955181|>85C0 test eax,eax ;确定长度不为0
00955183|.74 1C je short WinNc.009551A1 ;为0则跳
00955185|.8D4D F4 lea ecx,
00955188|.8B55 FC mov edx, ;EDX -> 用户名 'WWW.XUEPOJIE.COM'
0095518B|.8BC6 mov eax,esi
0095518D|.E8 1AFEFFFF call WinNc.00954FAC ;或许这就是关键了,因为 下面没啥东西了我跟了
00955192|.8B45 F4 mov eax,
00955195|.8B55 F8 mov edx,
00955198|.E8 5750ABFF call WinNc.0040A1F4
0095519D|.75 02 jnz short WinNc.009551A1
0095519F|.B3 01 mov bl,0x1
009551A1|>33C0 xor eax,eax
009551A3|.5A pop edx
009551A4|.59 pop ecx
009551A5|.59 pop ecx
009551A6|.64:8910 mov dword ptr fs:,edx
009551A9|.68 C3519500 push WinNc.009551C3
009551AE|>8D45 F4 lea eax,
009551B1|.BA 03000000 mov edx,0x3
009551B6|.E8 B93BABFF call WinNc.00408D74
009551BB\.C3 retn
00954FAC 这一段会获取一个重要固定的字符串,具体往下看。
00954FAC/[ DISCUZ_CODE_74 ]nbsp; 55 push ebp
00954FAD|.8BEC mov ebp,esp
00954FAF|.51 push ecx
00954FB0|.53 push ebx
00954FB1|.56 push esi
00954FB2|.8BF1 mov esi,ecx
00954FB4|.8955 FC mov ,edx ;将用户名放入变量
00954FB7|.8BD8 mov ebx,eax
00954FB9|.8B45 FC mov eax,
00954FBC|.E8 373EABFF call WinNc.00408DF8 ;EAX -> 用户名 'WWW.XUEPOJIE.COM'
00954FC1|.33C0 xor eax,eax ;清零 EAX
00954FC3|.55 push ebp
00954FC4|.68 F34F9500 push WinNc.00954FF3
00954FC9|.64:FF30 push dword ptr fs:
00954FCC|.64:8920 mov dword ptr fs:,esp
00954FCF|.56 push esi
00954FD0|.8D4B 60 lea ecx,dword ptr ds: ;在这里获得一个 固定的字符 '7' 因为上面用到了FS寄存器,SO 敢说他是固定的
00954FD3|.8B55 FC mov edx, ;EDX -> 用户名 'WWW.XUEPOJIE.COM'
00954FD6|.8BC3 mov eax,ebx
00954FD8|.E8 13FEFFFF call WinNc.00954DF0 ;接下来的就是迎接死亡吧, 断断续续之间存在密切联系。来探索吧
00954FDD|.33C0 xor eax,eax
00954FDF|.5A pop edx
00954FE0|.59 pop ecx
00954FE1|.59 pop ecx
00954FE2|.64:8910 mov dword ptr fs:,edx
00954FE5|.68 FA4F9500 push WinNc.00954FFA
00954FEA|>8D45 FC lea eax,
00954FED|.E8 223DABFF call WinNc.00408D14
00954FF2\.C3 retn
00954DF0 下面就是核心部分了,大家集中精神。我会详解 他的两层算法。
00954DF0/[ DISCUZ_CODE_75 ]nbsp; 55 push ebp
00954DF1|.8BEC mov ebp,esp
00954DF3|.83C4 BC add esp,-0x44
00954DF6|.53 push ebx
00954DF7|.56 push esi
00954DF8|.57 push edi
00954DF9|.33DB xor ebx,ebx
00954DFB|.895D BC mov ,ebx
00954DFE|.895D F8 mov ,ebx
00954E01|.894D F4 mov ,ecx ;刚才获取的 字符 '7' 放入变量 local.3
00954E04|.8955 FC mov ,edx ;用户名 'WWW.XUEPOJIE.COM' 放入变量
00954E07|.8B45 FC mov eax, ;EAX -> 用户名
00954E0A|.E8 E93FABFF call WinNc.00408DF8
00954E0F|.33C0 xor eax,eax
00954E11|.55 push ebp
00954E12|.68 704F9500 push WinNc.00954F70
00954E17|.64:FF30 push dword ptr fs:
00954E1A|.64:8920 mov dword ptr fs:,esp
00954E1D|.8B55 FC mov edx, ;EDX - >用户名
00954E20|.8BC2 mov eax,edx
00954E22|.85C0 test eax,eax
00954E24|.74 05 je short WinNc.00954E2B
00954E26|.83E8 04 sub eax,0x4
00954E29|.8B00 mov eax,dword ptr ds:
00954E2B|>83F8 03 cmp eax,0x3 ;用户名 长度 和 0X3 比较
00954E2E|.7F 12 jg short WinNc.00954E42 ;已经要过去 否则 就 Invalid
00954E30|.8B45 08 mov eax,
00954E33|.BA 8C4F9500 mov edx,WinNc.00954F8C ;Invalid
00954E38|.E8 B742ABFF call WinNc.004090F4
00954E3D|.E9 0B010000 jmp WinNc.00954F4D
00954E42|>C745 F0 03020>mov ,0x203 ;将一个常量 放入 变量 LOCAL.4 这里要注意
00954E49|.8BC2 mov eax,edx ;EAX - >用户名
00954E4B|.85C0 test eax,eax
00954E4D|.74 05 je short WinNc.00954E54
00954E4F|.83E8 04 sub eax,0x4
00954E52|.8B00 mov eax,dword ptr ds: ;eax = 长度
00954E54|>8BF0 mov esi,eax ;长度给ESI
00954E56|.85F6 test esi,esi ;和上面 一样 确定 长度是否合法
00954E58|.7E 3F jle short WinNc.00954E99 ;一级算法开始 :
第一层算法开始
00954E5A|.BB 01000000 mov ebx,0x1 ;初始化 ebx 循环
00954E5F|>55 /push ebp
00954E60|.8B45 FC |mov eax, ;eax ->用户名
00954E63|.4B |dec ebx ;ebx -1
00954E64|.85C0 |test eax,eax
00954E66|.74 05 |je short WinNc.00954E6D ;测试 用户名 是否为 空
00954E68|.3B58 FC |cmp ebx,dword ptr ds: ;判断 长度 是否为 0
00954E6B|.72 05 |jb short WinNc.00954E72
00954E6D|>E8 561FABFF |call WinNc.00406DC8
00954E72|>43 |inc ebx ;ebx ++ 开始 循环 了
00954E73|.0FB74458 FE |movzx eax,word ptr ds:[eax+ebx*2-0x2>;第一次循环-取用户名前两个字节 ASCII值给 EAX = 0057
00954E78|.E8 2BFFFFFF |call WinNc.00954DA8 ;这个CALL要 进去,肯定是计算的
第一次循环,取的是用户名前两个字节 的ASCII值 0057 放到EAXECX初始化为 0XA
第一步 用EAX/ECX = 57 / 0XA商放在EAX 余数在 EDX此时 EAX = 8EDX = 7 同时 ESI = EDX+ESI= 7 + 0 = 7
第二步 又想上面那样,先回复下EAX原有的值,57 然后再计算,最后判断商是否为0 如果为0 跳出循环,显然第一次循环EAX不等于0
第二次循环 EAX = 8 ECX = 0XA EAX/ECX = 8 / 0XA EAX = 0EDX = 8 ESI = EDX+ESI = 8 + 7 = 0XF 十六进制的此时EAX = 0
跳出循环 ESI和0X9 比较 不满足 条件 EAX = ESI 继续重复我们上面的 运算 最后得出 ESI = 6将ESI的值给EAXRETU返回。别忘记外面还有一层循环,别着急。
我们返回到调用CALL的下一行代码我们继续 。
00954E7D|.59 |pop ecx ;0012F44C
00954E7E|.0145 F0 |add ,eax ;还记得这个 LOCAL.4么 上面已经给了 一个常量值 0x203
00954E81|.71 05 |jno short WinNc.00954E88
00954E83|.E8 481FABFF |call WinNc.00406DD0
00954E88|>43 |inc ebx
00954E89|.4E |dec esi
00954E8A|.^ 75 D3 \jnz short WinNc.00954E5F ;注意 local .4 的值
LOCAL.4 = LOCAL.4 + ESI本身LOCAL.4的值是一个常量0X203 第一次循环取得是 用户名前两位字节 并运算 得到 一个数值 6 并且和 LOCAL.4的值 进行运算 同样的 道理将 用户名 所有 值运算 在 和 LOCAL.4的值运算 结果得到 一个数值LOCAL.4 = 0X250这个数值很有用。
下面进行第二层算法,就是要对 这个值 进行不一样的处理。 我们继续。
00954E8C|. /EB 0B jmp short WinNc.00954E99
00954E8E|> |8D45 FC /lea eax,
00954E91|. |8B55 FC |mov edx,
00954E94|. |E8 6B51ABFF |call WinNc.0040A004
00954E99|> \8B45 FC mov eax,
00954E9C|.E8 6B43ABFF |call WinNc.0040920C ;得出 长度
00954EA1|.83F8 0C |cmp eax,0xC
00954EA4|.^ 7C E8 \jl short WinNc.00954E8E
00954EA6|.BB 01000000 mov ebx,0x1 ;初始化 ebx
00954EAB|.8B75 F4 mov esi, ;esi = 字符 '7'即住他ESI 指向他
00954EAE|.8D7D C0 lea edi, ;估计 猫腻
00954EB1|>55 /push ebp
00954EB2|.8B45 FC |mov eax,
00954EB5|.4B |dec ebx
00954EB6|.85C0 |test eax,eax
00954EB8|.74 05 |je short WinNc.00954EBF
00954EBA|.3B58 FC |cmp ebx,dword ptr ds:
00954EBD|.72 05 |jb short WinNc.00954EC4 ;判断是否为 0 罢了
00954EBF|>E8 041FABFF |call WinNc.00406DC8
00954EC4|>43 |inc ebx ; 计数开始
00954EC5|.0FB74458 FE |movzx eax,word ptr ds:[eax+ebx*2-0x2>; 用户名前两字节ASCII 值给EAX 0057
00954ECA|.0306 |add eax,dword ptr ds: EAX = EAX + 37 37就是 那个字符‘7’的ASCII 直
00954ECC|.71 05 |jno short WinNc.00954ED3
00954ECE|.E8 FD1EABFF |call WinNc.00406DD0
00954ED3|>0345 F0 |add eax, ;说了注意 local 4=EAX + LOCAL .4
00954ED6|.71 05 |jno short WinNc.00954EDD
00954ED8|.E8 F31EABFF |call WinNc.00406DD0
00954EDD|>99 |cdq
00954EDE|.33C2 |xor eax,edx
00954EE0|.2BC2 |sub eax,edx
00954EE2|.71 05 |jno short WinNc.00954EE9 ;判断是否为 0 罢了 另类
00954EE4|.E8 E71EABFF |call WinNc.00406DD0
00954EE9|>E8 BAFEFFFF |call WinNc.00954DA8 ;是否 跟不跟 跟 感觉这个CALL太 熟悉 了就是第一层算法用的CALL下面解析
00954EEE|.59 |pop ecx
00954EEF|.8907 |mov dword ptr ds:,eax
00954EF1|.43 |inc ebx
00954EF2|.83C7 04 |add edi,0x4
00954EF5|.83C6 04 |add esi,0x4
00954EF8|.83FB 0D |cmp ebx,0xD
00954EFB|.^ 75 B4 \jnz short WinNc.00954EB1
居然是第一层算法用的CALL不着急此时 EAX = LOCAL .4 + EAX = 250 + 57 + 37= 0X 2DE
第一次循环 EAX / ECX = 2DE / 0XA EAX = 49EDX = 4 ESI = EDX + ESI = 4 EAX 不为0继续循环
继续循环EAX = 49EAX / ECX= 49/ 0XA EAX = 7 EDX = 3 ESI = EDX + ESI = 7 EAX 不为0继续
EAX = 7EAX / ECX = 7 / 0XA EAX = 0 EDX = 7ESI = EDX + ESI=E EAX = 0跳出循环
ESI 和 0X9 比较 不满足再次 执行算法最后得出 ESI= 5EAX = ESI 返回CALL EAX = 5
用户名 前两个字节运算得出 一个数 = 5 同理 我们在继续循环 看下最后得出 一串 数字572633475727
其实 这串数字 就是 注册码了 ,看下面的 - 就知道 他是要 组装了,我就不分析了。。
00954EFD|.8D45 F8 lea eax,
00954F00|.E8 0F3EABFF call WinNc.00408D14
00954F05|.BB 01000000 mov ebx,0x1
00954F0A|.8D75 C0 lea esi,
00954F0D|>8D55 BC /lea edx,
00954F10|.8B06 |mov eax,dword ptr ds:
00954F12|.E8 2509ADFF |call WinNc.0042583C
00954F17|.8B55 BC |mov edx,
00954F1A|.8D45 F8 |lea eax,
00954F1D|.E8 E250ABFF |call WinNc.0040A004
00954F22|.83FB 04 |cmp ebx,0x4
00954F25|.74 05 |je short WinNc.00954F2C
00954F27|.83FB 08 |cmp ebx,0x8
00954F2A|.75 0D |jnz short WinNc.00954F39
00954F2C|>8D45 F8 |lea eax,
00954F2F|.BA A84F9500 |mov edx,WinNc.00954FA8 ;-
00954F34|.E8 CB50ABFF |call WinNc.0040A004
00954F39|>43 |inc ebx
00954F3A|.83C6 04 |add esi,0x4
00954F3D|.83FB 0D |cmp ebx,0xD
00954F40|.^ 75 CB \jnz short WinNc.00954F0D
00954F42|.8B45 08 mov eax,
00954F45|.8B55 F8 mov edx,
00954F48|.E8 A741ABFF call WinNc.004090F4
00954F4D|>33C0 xor eax,eax
00954F4F|.5A pop edx
00954F50|.59 pop ecx
00954F51|.59 pop ecx
00954F52|.64:8910 mov dword ptr fs:,edx
00954F55|.68 774F9500 push WinNc.00954F77
00954F5A|>8D45 BC lea eax,
00954F5D|.E8 B23DABFF call WinNc.00408D14
00954F62|.8D45 F8 lea eax,
00954F65|.BA 02000000 mov edx,0x2
00954F6A|.E8 053EABFF call WinNc.00408D74
00954F6F\.C3 retn
组装后的注册码是这样的 5726-3347-5727 我们输入测试下 。
本次算法教程到此结束。{:5_191:} 感谢大家支持。我是 LYQingYe我爱雪坡姐 。
膜拜算法大牛! 不得不再给精华~分析的很详细! Shark恒 发表于 2015-8-27 19:54
不得不再给精华~分析的很详细!
{:5_191:}感谢Shark恒的鼓励,会继续努力的。 支持楼主大神,期待更经典作品 先支持下{:5_116:} 膜拜会算法分析的楼主,为毛我一看算法分析的就头大啊{:5_184:} 坐等视频教程 wakichen 发表于 2015-8-27 21:30
坐等视频教程
因为本人 声音过嫩,{:5_121:}视频方面 会考虑 楼主可否把软件打包网盘搞起!让我等菜鸟按教程搞起..百度找太.....{:5_193:}