tiamo
VIP专家组
VIP专家组
  • 注册日期2002-02-26
  • 最后登录2018-01-09
  • 粉丝17
  • 关注4
  • 积分50分
  • 威望142点
  • 贡献值1点
  • 好评度40点
  • 原创分2分
  • 专家分15分
  • 原创先锋奖
  • 社区居民
阅读:8185回复:17

[原创]vista启动时的数字签名检测算法和实现.源代码含

楼主#
更多 发布于:2008-09-10 02:09
数字签名想必大家都很熟悉了.就不再废话介绍了

数字签名系统中最重要的文件就是.cat后缀的文件
大家的驱动安装基本上是3种文件
第一种当然是驱动本身.sys文件
第二种就是.inf文件了
最后一种也就是数字签名使用的文件.cat文件

cat文件是一个符合ASN.1规范的文件(ASN = Abstract Syntax Notation one)
asn.1是一个描述数据的表示、编码、传输、解码的灵活的记法的规范
详细的内容大家可以google一下
这里只是简单的作个介绍

ASN.1格式是由一个一个的小元素拼接成的
每个小元素包含3个部分
(tag,length,data)

tag用来描述这个小元素是个什么类型(比如是int,是bool,是string等等)
length用来描述data部分的长度
data当然就是数据本身

微软的cat文件使用基本编码(BER = Basic Encoding Rules)规则来编码
这是比较简单的编码规则
简单介绍一下
tag:基本长度是一个字节.这个字节分成2个部分.如果[bit0,bit5) = 0x1f则这个tag要占据多个字节,否则tag就只是占据一个字节,[bit5,bit7]表示类型信息
length基本长度也是一个字节.如果这个字节的值 & 0x80 是非0的,也就是说他的最高位是1,那么这个长度也是要占多个字节.长度是这个字节的值&0x7f
接下来的数据是big-endian的长度

例子
0x06 0x01 0x78 0x02 0x81 0x03 0xa1 0xa2 0xa3

首先看第一个字节是0x06,他& 0x1f不等于0x1f,所以这个tag只是占据一个字节
接着看第二个字节是0x01,他最高位是0,所以这个长度也只是一个字节.他表示后面的数据长度是0x01
第三个0x78就是data
第一个小元素完结

接下来是0x02.同样的是单字节的tag
然后是0x81,他最高位是1,所以这个length占用多个字节..length本身数据的长度是0x81 & 0x7f也就说length本身的长度是1个字节
那么接下来的这个字节就是length,他等于0x03.所以后面的数据长度是3
接下来的0xa1,0xa2,0xa3就是数据
第二个元素完结...

如此循环流水分析就能把一个缓冲区分成若干个(tag,length,data)数组
最后要提一下的就是tag.
他有一个比较重要的特点就是如果他的bit5被设置成1,也就是说& 0x20非0
那么表示这个元素是一个容器..他包含有子元素
比如
0x30 0x06 0x02 0x04 0xd1 0xd2 0xd3 0xd4

首先第一个字节tag = 0x30.他的bit5是1,那么他是个容器
他的长度是0x06.也就是后面全部的数据都属于他
也就说他的数据是0x02 0x04 0xd1 0xd2 0xd3 0xd4
这个容器包含的数据本身仍然是BER编码的数据
继续解析tag = 0x02,length = 0x04,data = 0xd1 0xd2 0xd3 0xd4

体会这两个例子的不同
前一个例子的两个元素是平等的关系
后一个例子的两个元素是包含被包含的关系

因为有这个包含关系.asn.1格式的数据就能构成一个树状的结构

asn.1就介绍到这里..详细的信息请google

cat文件的基本格式大家了解了:他是使用BER编码的asn.1格式
那么cat文件里面究竟有些什么东西呢?

大体的讲.cat文件包含有3份重要数据
1.就是这个cat文件所签名的hash数据.如果A.cat用于签名b.sys,那么b.sys的hash数据就会保存到a.cat里面
2.就是这个cat文件签名时候使用的证书.通常的这个证书的父证书,祖父正式,也就是整个证书路径里面的全部证书数据都会放入到cat文件里面
3.就是签名者的信息

第一部分就是用来判断一个文件是否是被这个cat文件所签名的信息
第二部分是用来验证这个cat文件本身是否合法的
第三部分是签名者的信息.他提供一个线索把第一第二部分衔接起来

那么现在的问题有2个
1.如何判断一个文件是被签名的
2.如何判断某个cat文件是合法的

首先回答第一个问题
windows的cat文件都在一个目录下面
windows\system32\catroot\{F750E6C3-11D1-85E5-00C04FC295EE}\
如果一个文件是被正确签名的.
那么总是能在这个目录下面找到一个cat文件里面有那个被验证文件的hash值
注意.windows并不维护"某个文件被另外某个文件签名"这样一个一一对应的信息
而是每次都遍历全部的cat文件一一查找hash值看是否包含在cat文件里面
只要找到一个cat文件包含hash值就认为文件被签名了
同时的.windows只是检查hash值而不检查文件名..
所以你会发现同一个文件你只是修改名字而不动文件内容.他是否签名的属性是不变的

接着出现新的问题
如何计算某个文件的hash值?
这里我们只是讨论exe,sys这种可执行文件的hash计算方法.而不讨论inf文件的计算方法
首先hash算法是使用的SHA1
他的hash结果是一个20字节的数据
一个可执行文件的计算非常简单
注意这里的计算必须放在重定位之前

1.SHA_Update(ImageStart,&NtHeaders->OptionalHeader.CheckSum)
也就是从文件开始直到checksum.
2.SHA_Update(&NtHeaders->OptionalHeader.CheckSum + 1,ImageCertDataDirectory);
跳过checksum开始直到cert data dir 他的index = 4
3.SHA_Update(ImageCertDataDirectory + 1,ImageStart + FileHeaderSize);
跳过cert data dir直到文件头结束

也就说忽略checksum和cert data dir的1 + 2 个UINT32的数据

接下面SHA_Update每个section的raw data,长度也是raw的长度不要往上取2的倍数

最后SHA_Update剩下的文件数据.但是不要计算嵌入到pe文件里面的cert data
嵌入到pe文件里面的cert data总是在文件的末尾
他的大小和偏移由cert data dir指出.这部分的数据是不能hash的

这样计算出来的最终结果就是文件的hash值
详细的计算可以参考附件里面的代码

明白了可执行文件的hash计算方法和cat文件的大体情况以后
就来说一点具体的cat文件的内容
回忆cat文件最主要的3个部分
下面一个一个的来分析
首先是证书.
cat文件会打包全部使用到的证书到他里面(位于证书路径上的全部证书)
(什么是证书路径?找一个你系统里面的cat文件双击一下.出来的对话框点"显示签名"然后点"显示证书",然后切换到"证书路径"看一看)
那么每个被打包到cat文件里面的证书信息都包含什么内容呢?

大体被分成了3个部分
1.证书本身的信息.比如是哪个ca发布的这个证书.这个证书的public key是什么等等
2.验证这个证书信息使用的hash算法是什么..通常这个都是SHA1算法
3.验证这个证书是否是合法的数据.这个数据是一个RSA加密后的数据

那么一个证书是如何被验证是否合法的呢
先回答第三个部分的数据是怎么生成的
很简单
首先用第二部分的hash算法计算第一部分的hash值.然后用这个证书的父证书的private key加密这个hash值,加密的结果就是第三部分
那么验证办法就很简单了
在确保父证书合法的情况下使用父证书的public key解密这个第三部分,解密的结果跟第一部分的hash值比较,如果相同,那么就是合法的,否则就不合法

注意父证书的public key在父证书的第一部分里面.所以使用这个public key之前需要确保父证书是合法的
确保父证书的合法也就要确保父证书的父证书的public key合法.这样一直回溯到root证书.
那么如何保证root证书合法呢?root证书的public key是硬编码到bootmgr.exe和winload.exe文件里面的
保证root证书的public key就是要保证bootmgr.exe合法
这样听起来有点像先有鸡还是先有蛋的问题
不过这也是现状..并没有一个完美的确保这个验证链正确的方法.因为没有人来确保bootmgr.exe是合法的

那么你也许要问..怎么知道哪个证书才是自己的父证书呢
回答这个文件之前首先细化一下证书的第一部分数据
第一部分是证书本身的信息
这个信息里面重要的部分有
1.发行机关的名字
2.序列号
3.public key
4.自己这个证书的名字

看过上面4个部分你也许就明白了...
如果A证书是B证书的父证书
那么A证书的.4也就是A证书的名字等于B证书的.1发行机关的名字

同样的
如果一个证书的发行机关的名字等于自己的名字.那么这是一个root证书

证书信息明白了吧?
cat里面的证书信息首先他是一个数组
这个数组里面的每一个元素代表了证书路径上的一个证书信息
每个证书里面最重要的是他的public key.
证书的合法与否是要用他的父证书的public key验证的.
如果你想修改证书的内容,那么你需要父证书的private key来重新RSA加密证书信息的hash值.

证书信息是个数组
那么究竟是这个数组里面的哪个元素才是当前这个cat使用的呢?
这个cat使用的证书信息的public key是要用来验证其他数据的(比如文件的hash值).所以这个信息很重要
这个信息就是放到签名者信息里面的

签名者的信息里面都有什么呢
1.首先就是发行者的信息
2.然后就是序列号....这两个数据合起来去跟证书的.1发行机关和.2序列号比较..如果相同就表示这个cat文件是使用的这个证书来签名的(记住这个信息)
3.hash算法.这个hash算法的使用方法见下
4.签名者的属性信息,这个是可选的
5.RSA加密以后的数据.使用cat文件使用的那个证书的public key解密

要回答签名者信息的验证和使用方法需要先看看cat文件的3个重要数据里面剩下的那个没有详细介绍的部分
也就是cat文件的第一部分
我们称呼这个部分叫着签名数据
这个部分最重要的部分是一个数组
这个数组记录了许多属性数据
这些属性数据包含一些比如文件名字阿,操作系统版本号阿一类的数据
当然了被签名的exe,sys文件的hash值也是放到这个属性数据里面的
也就说这个签名数据里面有一个hash值的数组
数组里面的每个元素记录了一个hash值.这个hash值是某个文件的hash值
比如某个cat文件一共签名了5个文件
那么这个数组就有5个元素.每个元素都对应5个文件其中的某一个文件的hash值
回想签名判断的方法
就是遍历这个属性数组,一一比较数组里面的每个元素.只要找到一个相同的.就可以判断文件是被正确签名的

显然这个属性数组必须先被验证是合法的才能使用他
那个这个属性数组是如何被验证的呢?

很简单.
1.首先计算这个属性数组的hash值..hash算法使用签名者信息的第三部分记录的hash算法(往上拉看看签名者信息的内容)
2.然后看看签名者信息里面有没有属性信息(第四部分那个可选数据)
3.如果有
     那么这个签名者属性信息同样是个属性数组.其中必须有一个元素是等于前面计算的hash值的.如果没有.那么cat文件就是不合法的
     如果在签名者属性信息里面找到了刚刚计算的hash值.那么最终的hash值就是签名者属性信息的hash值.(hash算法还是使用签名者信息里面的hash算法)
4.如果没有
     那么最终的hash值就是前面计算的hash值
5.接着取出签名者信息里面的发行机关和序列号数据去证书数组里面寻找对应发行机关和序列号的证书.我们需要他的public key
6.使用上一步找的证书的public key解密签名者信息里面的第五部分数据
7.解密以后的结果跟第3或者第4步的最终hash值比较.如果相同就表示签名者信息和签名数据都是合法的.否则就是不合法的cat文件

注意这里使用了证书的public key,所以首先要保证这个证书是合法的.
如果你想修改签名数据数组里面的某个hash值.你需要对应证书的private key

回忆一下整个cat文件被验证的过程
体会一下一环扣一环的验证程序...
明确如果你要修改什么什么就需要什么什么的private key

可以看到关键的数据都经过hash然后RSA加密过.如果你要修改他们就需要private key
而从public key计算private key目前来讲是个不可能完成的任务

最后了..所谓"自签名"是什么意思呢?
自签名就是说原来放到cat文件里面的数据被放到了pe文件里面
当然有些小修改..
原来cat文件可以签名若干个文件.所以签名数据里面是个属性数组
而嵌入到pe文件里面的数据显然只是用来签名这一个pe文件
所以签名数据就不再需要是一个数组了.而是一个单独的元素

cat文件的描述就到这里了.下面是一些关于vista的背景知识
=====================================================================
vista的启动过程分成4个部分
第一个部分是bootmgr.exe加载运行
第二个部分是bootmgr.exe加载诸如winload.exe这样的boot application,并运行他们
第三个部分是winload.exe加载内核,hal,boot driver然后把控制权交给内核
第四个部分是内核加载其他驱动并完成启动

所以签名验证也是4个阶段
第一个阶段是bootmgr.exe验证他自己...显然这里有问题.自己验证自己.并不能保证一定是正确的
第二个阶段是bootmgr.exe验证winload.exe等等
第三个阶段是winload.exe验证内核,hal,boot driver
第四个阶段是内核验证其他驱动程序

其中第一和第二个阶段是bootmgr.exe来验证的.这个时候bootmgr不能加载cat文件.所以要求这个阶段被验证的文件都必须是自签名的
第三和第四个阶段可以加载cat文件,所以这个阶段是可以不用自签名的(微软说boot driver必须自签名?似乎不对?)
那么bootmgr都通常会加载些什么?最常见的就是winload.exe,然后就是当你从休眠中恢复的时候会是另外一个exe文件.但是不会是你的驱动

第一第二第三部分的验证都是由bootmgr.exe和winload.exe本身完成的
第四部分是由ci.dll来完成的.同时第四部分跟前三个部分有个显著的不同就是他对cat文件的解析要丰富得多
而不像前三个部分那样只是作最基本的解析..不过算法是一样的.没差别的

最后最后..vista限制死了root证书的发行机关必须是若干个有限的root
这个受信任的root个数是个常变化的值
比如rc1的时候是5个
到了正式版就是8个
而bootmgr和winload和ci.dll使用的受信任的root又有微小的差别

========================
不好意思...原来这里搞错了.修改一下
========================
综合我手上的各个版本的bootmgr和winload和ci收集一下一共有9个可能的root如下
Microsoft Authenticode(tm) Root Authority
Microsoft Root Authority
Microsoft Root Certificate Authority
Microsoft Test Root Authority
VeriSign Commercial Software Publishers CA                       某个beta的vista的efi版的bootmgrfw.efi和winldfw.efi使用了他.其他都没有使用过
Microsoft Code Verification Root                                                
Microsoft Digital Media Authority 2005
MS Protected Media Test Root                                                    要求test signing
Microsoft Digital Media Authority 2005 for preview releases

如果一个驱动是被签名的.但是root证书并不是微软要求的受信赖的root的时候会是怎么样子的呢?
如果是正常启动..那么就认为这个签名是非法的
如果是是test signing..那么认为这个签名是合法的

最后最后最后
证书是被打包到cat文件里面的
所以整个证书路径上的证书都必须打包到cat文件里面....
启动时候是不会去读取注册表里面的cert store信息的.......
如果cat里面并不包含需要的全部证书...那么这个结果等同与你使用了一个不受信赖的root

最后最后最后最后
附件里面是个2008的sln
里面有2个projects
一个叫MSCatViewer用来解析asn.1格式的cat文件
另外一个叫MinVerifier用来模拟vista启动时候对可执行文件的验证过程
MinVerifier里面有个readme.txt.里面有比较详细的cat文件格式和使用方法
不过是用英文写的....
我的英文属于非常烂的那种...
语法错文法错乱七八糟错的地方就请不要客气
附件名称/大小 下载次数 最后更新
MinCrypt.rar (58KB)  327 2008-09-10 02:09

最新喜欢:

sunseasunsea lipengyilipeng...
qiweixue
驱动小牛
驱动小牛
  • 注册日期2004-07-21
  • 最后登录2011-12-19
  • 粉丝0
  • 关注0
  • 积分1006分
  • 威望274点
  • 贡献值0点
  • 好评度268点
  • 原创分1分
  • 专家分0分
沙发#
发布于:2008-09-10 08:45
   
太牛x了,,,老仙,,,
坐个沙发,来学习。。。
WY.lslrt
驱动牛犊
驱动牛犊
  • 注册日期2004-07-30
  • 最后登录2009-10-27
  • 粉丝0
  • 关注0
  • 积分116分
  • 威望15点
  • 贡献值0点
  • 好评度10点
  • 原创分0分
  • 专家分0分
板凳#
发布于:2008-09-10 09:20
老仙你太鸟了,老鹰又该被你剃毛了。
---传说中的分割线--------
wowocock
VIP专家组
VIP专家组
  • 注册日期2002-04-08
  • 最后登录2016-01-09
  • 粉丝16
  • 关注2
  • 积分601分
  • 威望1651点
  • 贡献值1点
  • 好评度1227点
  • 原创分1分
  • 专家分0分
地板#
发布于:2008-09-10 10:53
  
不错,老兄难道是在暗示大家从BOOTMGR里开刀下手??btw vs2008不是每个人都装的,请体谅些劳苦大众.
花开了,然后又会凋零,星星是璀璨的,可那光芒也会消失。在这样 一瞬间,人降生了,笑者,哭着,战斗,伤害,喜悦,悲伤憎恶,爱。一切都只是刹那间的邂逅,而最后都要归入死亡的永眠
znsoft
管理员
管理员
  • 注册日期2001-03-23
  • 最后登录2023-10-25
  • 粉丝300
  • 关注6
  • 积分910分
  • 威望14796点
  • 贡献值7点
  • 好评度2410点
  • 原创分5分
  • 专家分100分
  • 社区居民
  • 最爱沙发
  • 社区明星
地下室#
发布于:2008-09-10 14:16
tiamo好久没发表大作了,一发表就是惊人之作阿
http://www.zndev.com 免费源码交换网 ----------------------------- 软件创造价值,驱动提供力量! 淡泊以明志,宁静以致远。 ---------------------------------- 勤用搜索,多查资料,先搜再问。
tiamo
VIP专家组
VIP专家组
  • 注册日期2002-02-26
  • 最后登录2018-01-09
  • 粉丝17
  • 关注4
  • 积分50分
  • 威望142点
  • 贡献值1点
  • 好评度40点
  • 原创分2分
  • 专家分15分
  • 原创先锋奖
  • 社区居民
5楼#
发布于:2008-09-10 17:58
64位的vista我也没装过
patchgurad也不太了解

patchgurad只是保护内核在运行的时候不被人动态修改
还是保护内核始终都不会被修改?
另外他保护除开ntoskrnl.exe以外的其他的文件吗?

如果patchgurad只是保护内核运行的时候不被修改
如果他仍然接受被静态修改过的内核
或者patchgurad不保护ci.dll
那就好办了

先从bootmgr开刀...给他的5个受信任的root列表里面增加一个你自己的
然后用增加的那个root发布一个证书.并用这个证书签名修改过的bootmgr
这样bootmgr就能通过对自己的签名验证
同样的方法把这个受信任的root加到winload.exe里面
还是用刚刚那个证书签名winload.exe
这样bootmgr就能通过对winload.exe的签名验证
同样的办法处理ci.dll.以及ring3的dll.然后这个root也要导入到注册表

这样以后你就用你自己的那个root发布的证书签名你的驱动就可以了
这个办法有些麻烦不过是最安全的
因为我们没有修改算法本身.而只是增加了一个受信任的root
所以任何依靠测试这个算法本身有问题还是没问题的检测方法都是行不通的
除非检测全部的受信任的root看看有没有不应该出现的...

如果直接修改这个算法的返回值..比如强制全部的签名判断结果都是正确的
那么我给一个已经知道结果是没有签名的数据传递给这个算法,
如果算法是正确的话就该返回一个错误的结果表示这个数据没有被正确签名
这样只要判断一下返回结果就能验证算法本身有没有被修改过

那么接下来的问题就是如何去修改这些个文件了
不过还好..vista不像xp,2003那样有windows file protection
对于内核和内核使用的dll还有驱动程序还有winload还有bootmgr
vista只是使用了一个特别的权限而已.
只有他们的所有者也就是NT Service\TrustedInstaller能修改他们
不过没关系...有administrator权限就行
在有administrator权限下更改他们的owner为administrator
然后就能直接修改他们了...除了这个以外就没有其他的保护措施了
修改完了再把owner换回NT Service\TrustedInstaller
唯一不能这样更改的就是ring3使用的dll.因为他在使用中
老办法...先rename他到别的文件名.然后修改他的副本.并把这个副本改名成他本来的名字
当然这些都得reboot以后生效

那么接下来就是如何获取administrator权限
这就更简单了....
答案就是
弹个对话框让你的用户点个确定给你这个权限就行了.......
哈哈哈...玩笑玩笑...

那么windows对于这种修改的应对策略是什么呢?
很不幸.这个策略也已经存在很久了

vista维护有一份revocation list.他本身也是保存到一个cat文件里面的
里面有一个hash数组...
这个数组里面的每个元素对于一个hash值
这个hash值表示了一个非法的cat文件......

也就说即使cat文件的检测全部通过了.受信任的root判断也通过了
在真正返回这个文件是被正确签名之前
还需要把这个cat文件里面的若干个信息(通常是5个,也许有些信息不存在.所以也会小于5个)hash一下
然后到revocation list的hash数组里面去找一下.
要全部的5个信息的hash值都不存在于revocation list的hash数组里面
才认为是正确签名的.否则当签名错误处理..
注意是返回错误..是认为这个文件是没有签名的.即使你使用了test signing也是一样是个错误

这个revocation list的文件是
windows\System32\CodeIntegrity\driver.stl
(似乎我就没发现这个文件真实存在过?)
前面说了这个文件本身也是一个cat格式的文件
所以他首先要通过cat文件的验证过程
这时候你就笑了
这太容易了..修改这个文件去掉凡是有关你的root的信息
然后重新用你的root发布的证书给他重新签名.
打完收功

究其原因就是bootmgr只能自己判断自己.
负责加载他的bios,efi firmware并不能对他进行数字签名判断
个人电脑目前来看
也就只有apple出的那个apple tv的efi firmware会对bootloader做签名判断
这样一来你就需要patch他的efi firmware才能使用修改过的bootloader.
这就安全多了.....

efi firmware在设计的时候本身就有数字签名的概念
不过似乎也没人去做复杂的比如RSA这一级别的算法?
x86目前efi的就apple一家....逆向mac pro的efi firmware看他就只是有pe checksum的判断而已
ia64安腾平台是个什么情况?谁用过ia64的机器?
我倒是搞到一个ia64版的checked windows 2003 enterprise edition.可惜没运行环境

=====================================
如果你只是自己写程序自己玩..
那你不用这么麻烦的patch过来patch过去的
用test signing模式启动就成了......

你要是发布产品
还是老老实实的去申请个证书..去过一下微软认证的好
据说微软的认证是不收钱的?
花钱的只是那个证书的费用?
据说大概是1年1000多美元?
rosemarry
驱动牛犊
驱动牛犊
  • 注册日期2008-08-29
  • 最后登录2009-02-25
  • 粉丝0
  • 关注0
  • 积分8分
  • 威望9点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
6楼#
发布于:2008-10-13 16:21
学到东西了 虽然还没完全弄懂
wanted999
驱动牛犊
驱动牛犊
  • 注册日期2006-03-28
  • 最后登录2012-08-13
  • 粉丝0
  • 关注0
  • 积分519分
  • 威望429点
  • 贡献值0点
  • 好评度48点
  • 原创分0分
  • 专家分0分
7楼#
发布于:2008-12-11 22:55
偶一直都在梦想能自己给自己数字签名......
guard366
驱动牛犊
驱动牛犊
  • 注册日期2009-04-30
  • 最后登录2010-10-21
  • 粉丝0
  • 关注0
  • 积分36分
  • 威望351点
  • 贡献值1点
  • 好评度0点
  • 原创分0分
  • 专家分0分
8楼#
发布于:2009-05-01 12:05
又见timao原创,膜拜一下。
成熟的产品!
seanwan
驱动牛犊
驱动牛犊
  • 注册日期2007-08-20
  • 最后登录2016-01-09
  • 粉丝0
  • 关注0
  • 积分14分
  • 威望96点
  • 贡献值0点
  • 好评度8点
  • 原创分0分
  • 专家分0分
9楼#
发布于:2009-06-20 22:29
 
进来拜
dreamsity
驱动小牛
驱动小牛
  • 注册日期2006-09-01
  • 最后登录2013-07-04
  • 粉丝0
  • 关注0
  • 积分40分
  • 威望821点
  • 贡献值1点
  • 好评度68点
  • 原创分1分
  • 专家分0分
10楼#
发布于:2009-06-22 06:31
太强悍了。
一切都是时间问题!
JenyCheng
驱动小牛
驱动小牛
  • 注册日期2005-07-26
  • 最后登录2021-01-24
  • 粉丝2
  • 关注0
  • 积分57分
  • 威望646点
  • 贡献值0点
  • 好评度119点
  • 原创分0分
  • 专家分0分
  • 社区居民
11楼#
发布于:2009-09-29 01:45
timao

总是不明则以,一鸣惊人!!!!
JenyCheng
驱动小牛
驱动小牛
  • 注册日期2005-07-26
  • 最后登录2021-01-24
  • 粉丝2
  • 关注0
  • 积分57分
  • 威望646点
  • 贡献值0点
  • 好评度119点
  • 原创分0分
  • 专家分0分
  • 社区居民
12楼#
发布于:2009-09-29 01:46
sorry
打错字

是 tiamo
mengfeng150
驱动牛犊
驱动牛犊
  • 注册日期2008-03-31
  • 最后登录2016-12-22
  • 粉丝0
  • 关注0
  • 积分61分
  • 威望583点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
  • 社区居民
13楼#
发布于:2010-07-14 11:20
楼主真是太强悍了
needye
驱动牛犊
驱动牛犊
  • 注册日期2010-07-05
  • 最后登录2010-08-31
  • 粉丝0
  • 关注0
  • 积分2分
  • 威望21点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
14楼#
发布于:2010-08-31 10:05
谢谢楼主分析
懒得睡觉了
zhuliang
驱动牛犊
驱动牛犊
  • 注册日期2008-04-16
  • 最后登录2012-10-05
  • 粉丝2
  • 关注1
  • 积分16分
  • 威望181点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
15楼#
发布于:2011-02-23 12:41
我来晚了,下载不了附件。哪位哥们下载了的能不能给我(huang-caihong@qq.com)传一份?十分感谢。
Netguy
驱动牛犊
驱动牛犊
  • 注册日期2001-04-02
  • 最后登录2012-05-25
  • 粉丝0
  • 关注0
  • 积分2分
  • 威望17点
  • 贡献值0点
  • 好评度6点
  • 原创分0分
  • 专家分0分
16楼#
发布于:2012-05-25 16:40
谁能重新上传一下代码?
ldljlzw
驱动中牛
驱动中牛
  • 注册日期2002-03-16
  • 最后登录2014-01-02
  • 粉丝1
  • 关注0
  • 积分1021分
  • 威望372点
  • 贡献值0点
  • 好评度187点
  • 原创分0分
  • 专家分0分
17楼#
发布于:2014-01-02 10:15
好东西,求下载~~~
好东西,求下载~~~
好东西,求下载~~~
游客

返回顶部