5952
看到不是蓝色的蓝屏还是挺让人震惊的,就连我也一样。就目前TechEd听众的反应来看,我估计你们一会就要去弄出各种颜色的蓝屏向你的朋友炫耀去了。我最早在几年前看到Dave Solomon Dan Pearson在一次分析崩溃转储的会议上这么搞过,这次我在Case of the Unexplained演讲结束的时候还让观众选蓝屏的颜色。不过注意了,我接下来要说的改颜色的方法是手动的,只在当次有效,所以很适合演示目的。不要错过我在文章结尾为大家准备的节日蓝屏图。 准备工作 我们要修改内核代码,首先就是要打开修改内存中的内核代码的功能。Windows在小于2GB内存的系统上用4KB的内存页来存储内核代码,这样比较方便设置合适的页保护属性。比如内核数据页应该允许读取和写入访问,而内核代码页就只应该允许读取和执行访问。为了提高虚拟地址翻译的速度,Windows在资源充足的系统上使用大内存页(4 MB)。这就是说如果有代码和数据同时存储在一个内存页里,这个内存页就必须允许读取、写入和执行访问。所以为了确保你可以编辑内存页,你可以建议Windows使用大内存页。如果你的系统是Windows XP或者Server 2003,并且内存小于256 MB,或者是Windows Vista或更高版本且内存小于2 GB,在HKLM\System\CurrentControlSet\Control\Session Manager\Memory Management下建立一个名为LargePageMinimum,类型为REG_DWORD,数据为1的注册表值: 为了让你不必在Windows自动重启前手忙脚乱地冲到朋友面前炫耀你的成果,你可以关闭自动重启。在Windows XP和Server 2003系统中,右键单击“我的电脑”,选择“高级”选项卡,单击“启动和故障恢复”中的“设置”按钮。在Windows Vista及更高版本中,右键单击开始菜单中的“计算机”选择“属性”,单击“高级系统设置”,选择“高级”选项卡,单击“启动和故障恢复”中的“设置”按钮。最后,取消选择“自动重新启动”复选框: 如果你在用64位 Windows Vista或更高版本,你需要用调试模式启动系统,这样才可以用内核调试器的“本地调试”模式。你可以在开机的时候按F8然后选择“调试模式启动”或者在“系统配置”工具中选择“调试”复选框: 下面重启并以管理员身份运行调试器(如果开了UAC,以管理员身份运行)。在File菜单中打开“Symbol Search Path”对话框,输入这个字符串:srv*c:\symbols*http://msdl.microsoft.com/download/symbols(c:\symbols 可以是任意本地目录,用于给调试器存放缓存的符号),这样就可以将调试器符号路径指向微软符号服务器。下面在File菜单中打开“Kernel Debugging”对话框,单击“Local”选项卡,按“确定”按钮: 接下来的步骤会因你的系统版本而有所不同。 32位Windows XP和Windows Server 2003 这些系统上显示蓝屏的函数是KeBugCheck2。你要找的是这个函数把颜色值传递给填充屏幕背景的函数InbvSolidColorFill的地方。输入“u kebugcheck2”命令来显示函数开头,然后继续输入“u”命令显示更多的内存页,直到你看到对InbvSolidColorFill的调用为止。 (在输入一次“u”之后,你只要一直按回车就可以重复这个命令了)。你大概要显示30-40个内存页才能看到这个调用: 在这个调用之前,你会看到一个带有参数4的指令(“push 4”),如上图。选择地址行并按下Ctrl+C以复制这个指令的地址。接下来在调试器命令窗口中输入“eb ”,然后按Ctrl+V粘贴这个地址,然后输入“+1”,然后按回车。调试器会进入内存编辑模式,并从那个颜色代码的地址开始编辑。现在你可以选颜色了,1是红色,2是绿色,你还可以试试别的颜色。只要输入数字然后按两次回车就可以保存修改并退出编辑模式。退出后你的屏幕应该是这个样子: 64位Windows以及32位Windows Vista及更高版本 在这些版本的Windows里,画蓝屏的函数叫KiDisplayBlueScreen。输入“u kidisplaybluescreen”然后一直输入“u”命令显示函数的内存页,直到你找到对InbvSolidColorFill函数的调用为止。在32位Windows上,你可以按上一节给出的方法来编辑颜色值。在64位系统上,InvbSolidColorFill前的那个指令是传递颜色的指令,所以复制它的地址并输入“eb <地址>+4”进行编辑。调试器会进入内存编辑模式,然后你就可以修改它的值(比如1是红色,2是绿色): 查看结果 你现在可以准备让系统蓝屏了。如果你用的是64位系统,那可能已经蓝屏了。这是因为Kernel Patch Protection会发现这些修改,然后使系统蓝屏。这样做可以避免一些第三方软件厂商考虑用修改内核代码的方式实现某些功能。不过,系统最多可能会延迟7分钟才蓝屏。要想随时蓝屏,可以运行Notmyfault工具(你可以从《Windows Internals》的相关页面中下载到),然后按下“Do Bug”按钮(为避免数据丢失,请确保你保存了所有文件并关闭了其它程序): 然后你就会得到一个自选颜色的蓝屏了,比如我选的红屏: 节日蓝屏 为了增添节日气氛,我还要生成一个节日主题的蓝屏:不仅要修改背景色,还要修改文字颜色。在64位Windows Vista及更高版本下,找到紧跟InvbSolidColorFill函数调用的InvbSetTextColor,并找到将文字颜色传给该函数的指令“move ecx, 0Fh”: 0Fh参数表示白色,但你可以用同样的方法改成别的颜色。使用“eb”命令,传入该指令的地址加1。在下图中我设置成了红色(也就是1): 这就是我弄出的很有喜庆气氛的蓝屏: 节日快乐! FlowerCode 译自Mark's Blog
0
0 2908天前
5171
一个男人在外工作20年,终于要回家了,老板问他:你是要20年的工资还是要3句忠告?男人说我明天上路,明早给您答案好吗?老板说可以。 当晚男人未眠…早晨,他对老板说:我要3个忠告。 于是老板给他3句话。 一、不要试图寻找不可能的捷径,世上没有便宜的事,只有脚踏实地才是最好的方法…无论做何事。 二、不要对明知不是好事的事过分好奇,有可能你会因此而丧命。 三、不要在冲动时做任何决定,否则这个决定就有可能成为你一辈子的遗憾。 说完老板给男人一些钱和三个面包,并叮嘱:最大的面包在到家后才能吃。 男人上路了…他走了好几天…把第一个面包吃了一半了,没过多久遇到一个路口,他打听:请问到**走哪条路近?路人甲:走小路吧,近。路人乙:走大路吧,安全。 他迫不急待要与妻子见面,于是走了小路。走了没多久就听到有路人说附近闹山贼,于是他想起了老板的第一个忠告:不要试图寻找捷径。于是他回头去走那条大路。又走了几天,第二个面包也吃了一部分了…他找到一家极便宜的客栈投宿。半夜听见有女子哭声,他睡不下。于是决定出门看看。这时他想到了第二个忠告:不要对明知不是好事的事过分好奇。于是他又睡下了。第二日起程时,店家惊道:你还活着?!他不解,遂问原由。店家说他有个疯女儿,发病时用哭声引人出来再将其杀害,昨晚投宿的客人只有你一个活着。男人长叹:啊…又走了几天,当第二个面包吃完时他已离家不远了。他更加激动了。天刚黑下来没多久,他就走到了自己的村子。到家时他刚准备敲门,却听到屋里有男人的声音。他气极了,拿起一把砍柴刀就准备冲进屋子将那男的杀掉。但这时他想到了第三个忠告:不要在冲动时做任何决定,可能这个决定会让你后悔一辈子。于是他冷静下来,在屋外坐了一夜。第二天早上他很早就敲开了门,妻子见他回来十分高兴。但他却很冷漠:那个男人是谁?他妻子笑曰:那是我们的儿啊…你走后没多久我就生了他…这时他发现这个约二十岁的年轻小伙竟和自己长得相似极了。父子初次见面,相拥而泣…一阵关切过后男人拿出第三个面包准备和妻、子一齐分享…切开之后却发现20年的工资全在里面。
0
0 2908天前
5395
0.999... = 1 吗?此问题在国内外大大小小的网络社区里出现了无数多次,每次都能引来上百人激烈的争论,可谓是最经久不衰的老问题了。其实,在学术界里,这个问题也是出了名的争论热点。让我们来看看,数学家们都是怎么来看待这个问题的。 最简单的“证明” 最简单的证明是这样的:1/3 = 0.333...,两边同时乘以 3,1 = 0.999... 。1998 年,弗雷德·里奇曼(Fred Richman)在《数学杂志》(Mathematics Magazine)上的文章《0.999... 等于 1 吗?》中说到:“这个证明之所以如此具有说服力,要得益于人们想当然地认为第一步是对的,因为第一步的等式从小就是这么教的。”大卫·托(David Tall)教授也从调查中发现,不少学生看了这个证明之后都会转而开始怀疑第一个等式的正确性。仔细想想你会发现,“1/3 等于 0.333…” 与 “1 等于 0.999…” 其实别无二致,它们同样令人难以接受。正如很多人会认为 “0.999… 只能越来越接近 1 而并不能精确地等于 1” 一样,“0.333… 无限接近但并不等于 1/3” 的争议依旧存在。问题并没有解决。 另一个充满争议的证明 大卫·福斯特·华莱士(David Foster Wallace)在他的 《Everything and More》一书中介绍了另外一个著名的证明:令 x = 0.999...所以 10x = 9.999...两式相减得 9x = 9所以 x = 1威廉·拜尔斯(William Byers)在《How Mathematicians Think》中评价这个证明:“0.999... 既可以代表把无限个分数加起来的过程,也可以代表这个过程的结果。许多学生仅仅把 0.999... 看作一个过程,但是 1 是一个数,过程怎么会等于一个数呢?这就是数学中的二义性⋯⋯他们并没有发现其实这个无限的过程可以理解成一个数。看了上面这个证明而相信等式成立的学生,可能还没有真正懂得无限小数的含义,更不用说理解这个等式的意义了。” 逐渐靠谱的证明 等比级数具有这么一个性质:如果 |r| 那么我们就又有了一个快速的证明: 这个证明最早出现在 1770 年大数学家欧拉(Leonhard Euler)的《代数的要素》(Elements of Algebra)中,不过当时他证明的是 10=9.999... 。之后的数学课本中渐渐出现了更为形式化的极限证明: 1846 年,美国教科书《大学算术》(The University Arithmetic)里这么说:在 0.999... 里,每增加一个 9,它都离 1 更近。1895 年的另一本教科书《学校算术》(Arithmetic for School)则说:如果有非常多的 9,那么它和 1 就相差无几了。意外的是,这些“形象的说法”却适得其反,学生们常常以为 0.999... 本身其实是比 1 小的。随着人们对实数更加深入的理解,0.999... = 1 有了一些更深刻的证明。1982 年,巴图(Robert. G. Bartle)和谢波特(D. R. Sherbert)在《实分析引论》(Introduction to Real Analysis)中给出了一个区间套的证明:给定一组区间套,则数轴上恰有一点包含在所有这些区间中;0.999... 对应于区间套[0, 1]、[0.9, 1]、[0.99, 1]、[0.999, 1] ... ,而所有这些区间的唯一交点就是 1,所以 0.999... = 1。 弗雷德·里奇曼的文章《0.999... 等于 1 吗?》里则用戴德金分割给出了一个证明:所有比 0.999... 小的有理数都比 1 小,而可以证明所有小于 1 的有理数总会在小数点后某处异于 0.999... (因而小于 0.999... ),这说明 0.999... 和 1 的戴德金分割是一模一样的集合,从而说明 0.999... = 1 。格里菲思(H. B. Griffiths)和希尔顿(P. J. Hilton)在 1970 年出版的《A Comprehensive Textbook of Classical Mathematics: A Contemporary Interpretation》中,用柯西序列给出了另一个证明。 从未停止过的讨论 尽管证明越来越完备,学生们的疑惑却从来没有因此减少。在品托(Pinto)和大卫·托教授的一份调查报告中写到,当学生们用高等方法证明了这个等式之后,会大吃一惊地说,这不对呀,0.999… 显然应该比 1 小呀。在互联网上,这个等式的魅力也依然不减。辩论 0.999… 是否等于 1 被讨论组 sci.math 评为“最受欢迎的运动”,各类问答网站中也总是会有网友激烈的讨论。 诺贝尔奖获者费曼(Richard Feynman)也用这个等式开过一句玩笑。有一次他说到:“如果让我背圆周率,那我背到小数点后 762 位,然后就说 99999 等等等,就不背了。”这句话背后有一个很奇怪的笑点:从 π 的小数点后 762 位开始,出现了连续的 6 个 9,偏偏在这里来一个“等等等”,就会给人感觉好像后面全是 9,这相当于把 π 变成了一个有限小数。此后,π 的小数点后 762 位就被戏称为了费曼点(Feynman Point)。 本文版权属于果壳网(guokr.com),转载请注明出处。商业使用请联系果壳
1
0 2908天前
7138
如果你养过小鸡,应该知道小鸡适合生长的温度是摄氏 25 度,但因为太小还无法自己调节体温,在寒冷的天气里都得靠保温器材取暖。如果没有东西可以保暖,小鸡只好自己搜寻取暖器了...。日本网友 yakisoba 就上传了一张照片到推特,原来感觉很冷的 4 只小鸡擅作主张的把家里的猫咪当作取暖器,直接侵门踏户的爬到猫大王的背上坐下,让猫咪回头时表现出傻眼的表情:欸欸!你们幹嘛啦?! ▼瞬间就是永恆,猫咪这个神情实在太爆笑了
0
1 2908天前