Google Safe Browsing API Demo

2007年6月24日 2 条评论

今天花了一下午整出来的东西,似乎是work的,从http://www.millersmiles.co.uk/上面找了两个phishing URL,比如这个。

E:\zhangc\Documents\Works\security\SafeBrowsing\GSBDemo\Debug>GSBDemo.exe
Google Malware Hash List: version 1.117, 51242 items.
Google Black Hash List: version 1.971, 9170 items.

URL:>http://singngngdaxngggg.pochta.ru/logi22.html
This URL is unsafe because "singngngdaxngggg.pochta.ru/logi22.html" is in goog-black-hash

不过有的还不work,比如Li Fanxi给出来的那两个:

URL:>http://220.225.4.14/icons/www.paypal.com/cgi-bin/SecureInfo=_update/
This URL seems safe.

URL:>http://kallu.ch/www.PaYPaL.Com/cgi-binn/verify-account/paypal12321625615235
2132314132123/paypal-email-verification/p1_webscr-cmd-login-run.htm
This URL seems safe.

不知道是我的实现的原因还是真的就在列表当中没有。

标签:

打算做两个Firefox的扩展

2007年6月23日 没有评论

一个是为了能够在切换标签的时候自动切换输入法。因为我现在有英文、中文和日文三个输入法,经常不同的标签页当中需要输入不同的语言,因为目前Firefox似乎做不到自动记住各个标签页的配置并切换输入法,所以感到不太方便(也许是我土,有谁知道有什么方法的告诉我一声)。我期望这个东西可以这样工作:我正在写space的标签页面当中,现在是中文输入法,当我切换到别的页面的时候,或者当我按下了Ctrl+D,或者用鼠标移动到地址栏的时候,自动切换成英文输入法。一旦我在一个页面上面把输入法切换成了非英文,这个输入法就可以记录下面,下次我换到这个标签页页可以自动的切换成相应的输入法。这还是很方便的。

另一个是因为VeryCD上面的资源更新。因为我经常会追一些新的动漫,想要知道一个发布页面是不是已经更新了还是比较麻烦的——VeryCD的索引页虽然有但是毕竟经常雪崩似的出一大堆更新,然后一页放不下,可能会错过很多。后来我就把这些发布页面放在收藏夹当中,然后一个个点开看,原来数据量小的时候还好搞定,后来越来越多,麻烦的一米,加上我又很懒,考虑是不是可以在我打开Firefox的时候或者点了某个菜单项的时候直接去检查所有的这些页面有没有更新,然后自动把更新的页面打开。

研究一下Firefox的Extension,看看有没有可能。第二个想起来应该不难实现。

标签:

Google Safe Browsing API

2007年6月22日 6 条评论

Google前些天刚刚发布了Safe Browsing API,虽然很早以来就有了,但是正式的公开API还是最近的事情。目前的版本就是两个URL的黑名单,phishing list (google black hash)和malware list (google malware list)。就目前的发布版本来看,这两个列表相对简单,只是一系列的URL的MD5,而且只是提供phishing保护和malware list,并没有网络分级,但是以Google一贯的风格来看,随着一路beta下来,加入分级是迟早的事情。

谁能给我一个phising site让我试试这个东西。

标签:

MSN Space果然很容易上搜索引擎的说

2007年6月17日 2 条评论

翻看自己space的统计信息,发现了两个来自于搜索引擎的来源:

Google struct tm mktime
Baidu 超级玛丽.nes

而且排名都比较靠前,尤其是前者,帖子早上发的,现在就已经排到了google结果的第一位。这种事情在csdn和blogdriver上面都是不曾有过的。

嗯,大树底下好乘凉。

标签:

软件的I18N问题

2007年6月17日 2 条评论

今天读到byte写的一篇blog,记录了一下vc当中的时间表达方式,随手回复了一篇,当敲入mktime的时候,突然心中一震,有一种误人子弟的感觉,因为想到了之前一个项目当中对于时间处理的问题的切肤之痛。

当时那个问题是这样的:程序会调用time函数得到time_t(这个是GMT时间距离1970年1月1日的秒数),然后用localtime把它转换成可读的struct tm格式,即年月日时分秒的格式,然后根据它来创建文件夹,比如我现在时区是GMT+8,即北京时间,凌晨3点32分,程序就会创建一个名为20070617\0332的文件夹,然后把一些东西放在里面。过一会之后,程序会去枚举所有的文件夹然后对其中的东西进行处理,枚举的时候,程序会根据这个目录的字符串来切开做成一个struct tm格式,然后调用mktime去转换成time_t进行进一步的处理。程序会传递这个time_t,并在必要的时候重新根据它来找到文件所在的目录。简单的逻辑可以这样认为:

time_t now = time(NULL);
struct tm* tnow = localtime(now);
sprintf(szPath, "%4d%02d%02d\\%02d%02d",
tm->tm_year+1900, tm->tm_mon+1, tm->mday,
tm->tm_hour, tm->tm_min);
CreateDirectory(szPath);

// later
// find each directory to szPath, and get year, month, day, hour, min from the szPath.
// Then set struct tm dirTm;

time_t dirTime = mktime(&dirTm);
ProcessThem(dirTime);

void ProcessThem(time_t dirTime) {
struct tm* dirTm = localtime(dirTime);
szPath = getPathFromTime(dirTm);
// open the file
}

这个逻辑在中国的区域设置下面毫无问题,一切都如预想的一样运行。但是这个产品还需要被卖到美国,区域设置为太平洋标准时间的地方。那个地方有一种东西叫做夏令时,Daylight Saving Time, DST。每年的4月的第一个周日(现在已经是3月的第二个周日了,这是今年的新规定,所谓的DSTE,为此还有更多的I18N的麻烦,有机会再说),当种走到凌晨1:59:59过后,并不是正常的跳到2:00:00,而是变成3:00:00。也就是说,钟快了一个小时。到了10月的最后一个星期天(现在是11月的第一个星期天)的钟表指到1:59:59之后,钟会跳到1:00:00,也就把钟调了回来。

于是产品在进入夏令时之后出了问题,日志当中报告了大量的“找不到文件”错误。经过分析发现,在上面的逻辑当中,在夏令时切换之后,比如钟表时间3:01:00(实际上物理时间是2:01:00),第一个localtime的调用创建了一个名为20060402\0301的文件夹,之后根据这个路径初始化struct tm dirTm,但是struct tm当中的tm_idst域并没有赋值(也就是0),所以调用mktime的时候,这个函数会把struct tm结构当中的值当作非夏令时,这样转换回的time_t就指到了物理时间的3:01:00,之后再次调用localtime,获取的struct tm当中,tm_hour变成了4。这样一来,程序试图去20060402\0401下面去寻找文件,这就导致了大量的找不到文件的错误。

解决的方法有两个,一个是初始化struct tm dirTm的时候,将tm_idst设成负数,例如-1,这样mktime会根据当前时区来决定是否根据夏令时进行校对。另一种方法是完全使用GMT函数替换本地时间函数。例如localtime->gmtime,mktime->_mkgmtime。

这个问题本质上就是一个软件的I18N问题。I18N=Internationalization,即国际化,因为I和N中间有18个字符而得名,类似的还有L10N(Localization,本地化),以及G11N(Globalization,全球化)。软件的I18N问题之所以成为一个问题,是因为这个世界上有接近200个国家和地区,2000多个民族,4200多种语言,以及,地球是圆的。

应该庆幸我们生活在中国,因为中国的很多东西都很简单,尤其是牵涉到软件I18N的时候。没错,可以认为中国有世界上最大的字符集,最复杂的文字表达方式,但是我们的时区是GMT+8,没有零头,没有夏令时;中文的编码GB2312å’ŒGB18030都是上下文无关的编码,而且广泛使用的GB2312还是定长的编码(两个字节一个汉字),而且任何字节不会和7位ASCII码重叠;我们使用格列高里历法,使用公元纪年;我们的默认键盘布局是标准101é”®qwerty键盘;我们的文字像世界上绝大多数文字一样从左向右横向书写……所有这一切对于写软件的人来说是这是多么美好的一件事情啊。我们可以获取当前的时间,存储其年月日时分秒,将来无论什么时候拿到这个年月日时分秒,都不会有什么问题;我们可以在一个中文编码的字符串当中肆意地用strchr查找’\\’来切割文件路径,而不用担心0x5C在当前的上下文当中是表示反斜线还是日元符号(在日文编码shiftJIS当中,日元符号的编码和ASCII当中反斜线编码重叠,都是0x5C,这种问题在GB系列编码中不会存在);还有,我们的小数点就是圆点,负数就是在数字前面加上负号,而不是用逗号表示小数点(德文地区是这样的),而且不会用括号表示负数(欧洲某地如此,不记得哪国了)。

但是这样也会让我们中国的软件工程师低估了软件I18N的难度:不是所有国家的人们的时间都是连续的,很多国家在使用夏令时;很多国家或地区不使用公元纪年,比如日本和台湾;还有些地方不使用格列高里历法,例如中东的很多国家。说起时间,时区也不一定总是东八区,西五区这么简单。印度大部分地区都是GMT+5.5,尼泊尔是GMT+5.75;太平洋上某岛国(TONGA)是GMT+13,这是全球最早的时间;中东某小国由于宗教原因时区是GMT-89,也许是全球最晚的时间了。可以看看这张全球时区划分图来看看有多少诡异的时区吧(这张图有些老,98年的,所以很多诡异的都还没有,不过已经够多了)。

而谈及语言编码,那又有了更多的问题,现在太晚了,有空再写。

标签:

Microsoft IIS/7.0

2007年6月16日 没有评论

http://www.microsoft.com

看来真的如传言所说,微软已经将自己的官方网站架构在Windows Server 2008 Beta 3上面了。没准微软真的打算在这个上面投入点大精力了。

不过,Windows Server 2008 Beta 3的Server Core安装模式真的很诱人~。

标签:

管理软件的隐藏复杂性

2007年6月15日 5 条评论

今天在bbs上看到一篇帖子,里面讲了这么一句话:有两种方式构建软件设计:一种是把软件做得很简单以至于明显找不到缺陷;另一种是把它做得很复杂以至于找不到明显的缺陷。很有意思的一段话。传说这段话来自于《A Byte of Python》,没看过,但是可以想象,既然来自于python的社区,作者应该是倾向于前面半句话的。

OK,现在是提问时间:为什么人们都在追求简单?正如这段话当中所说:软件做的简单的目的是为了能够减少缺陷。究其原因就是人类思考能力的限制:人们计算(1+100)*100/2和计算1+2+3+…+100的出错概率是不可以同日而语的。如果我们快速的过一下软件开发的历史,从最早的打孔纸带和汇编语言,到C语言和众多的具有不同设计哲学的高级语言,再到今日蓬勃发展的脚本语言,似乎都在做同一件事:让程序变得简单。这种简单源于语言对于特定概念的抽象和众多可以复用的库和框架,在这种软件简单性,源于封装起来的复杂性,在其背后,也许是更加复杂部分的逻辑。这种复杂性,也就是软件的隐藏复杂性。

显然,软件的隐藏复杂性是一把双刃剑,一方面,对于不必要复杂性的封装,让程序本身变得简单,能够更加直接 地表明业务的逻辑;另一方面,作为软件一部分的它们,本身也是一个软件,也有存在缺陷的可能,而一旦来自这种隐藏的复杂性当中的缺陷出来,却也会带来排错的巨大难度。从实际当中来说,这种隐藏的复杂性源于很多地方:操作系统,运行库,第三方库,以及框架。如何处理隐藏的复杂性,以及决定是否要引入一种隐藏的复杂性,这是一个项目的领导者必须做的一个决定。每个隐藏的复杂性都可以引入更简单的设计和更多的潜在的缺陷。

举几个例子吧,我们在做最近的一个产品的时候,出现了内存泄漏,经过一个星期的分析和排错,最终发现内存泄漏发生在微软的CRT库的istream当中;在同一个产品当中,beta客户处出现了程序hang住的情况,最终发现问题出在第三方的icu库当中。使用C++ iostream库和icu库毫无疑问使得程序变得简单,但是一旦出现了缺陷,却也是非常难以排除的。

还有其他的隐藏复杂性却有更隐晦的潜在问题,有些问题甚至无法解决。另一个小组正在做的项目当中出现了另一个问题,tomcat在特定的情况下可能崩溃。经过近半个月的排查发现,问题出现在JRE的socket对于solaris操作系统的socket封装问题:JRE的socket可能在系统已经将socket关闭之后再对其进行操作,这导致了tomcat的崩溃。这也是操作系统和运行库所带来的隐藏复杂性的代价。

但是这并不应该成为拒绝引入隐藏复杂性的理由,否则就是把孩子和洗澡水一起泼掉了。这里提到的几个例子都是源于著名的运行库,虽然出现了问题,但是它们所带来的便利也是毋庸置疑的。我们需要做的,就是在这种简单性和隐藏的复杂性之间做出权衡。

标签:

我的MSN头像的来源

2007年6月12日 3 条评论

今天又被人问到了我的MSN头像是个什么东西,不想不断的解释这个经典的宠物角色了,将来如果再有人问,我可以直接贴这篇文章的链接。

这个动物称为狐松鼠,英文名Sciurus niger,啮齿类动物,真实世界当中的照片如下图。

真正使这种动物为人所知是来自宫崎骏的7卷漫画《风之谷》,这种小动物当中的一只作为主角娜乌西卡的宠物存在,名为迪多(テト,Teto),不过通看整篇漫画,还是把它当作娜乌西卡的守护者之一比较合适(虽然整篇漫画当中似乎大家都是娜乌西卡的守护者)。而它的形象也出现在了《风之谷》第一卷的扉页上(见下图)

。漫画当中小东西从第一卷出场以来一直伴随娜乌西卡左右,直到第七卷当中死于巨神兵的致命光线,被安葬在修瓦的陵墓附近的大树下。自始至终每当娜乌西卡遇到了什么事情而走神或者迷失的时候,总是迪多将其召回,无论是在战斗艇当中,飞行翼之上还是在精神的旅行当中;甚至被安葬以后,娜乌西卡在世外桃源当中迷失在了美丽的景色和旧世界的音乐当中的时候,迪多的名字再次出现,又一次将其召回。这个小东西在整部漫画当中的角色就像一个称职的搭档,总是在最需要的时候出现。这也是我喜欢这个小东西的最大原因。

漫画当中的迪多的角色非常重要,但是在对应的剧场动画当中戏份不多,不过这张娜乌西卡带着迪多起舞的镜头还是用在了很多的《风之谷》海报当中。

类似的小动物还出现在《天空之城》当中。

这只狐松鼠的故事就是这样。

标签:

超级玛丽踩墙跳的技巧

2007年6月7日 5 条评论

自从看过了超级玛丽兄弟(最老的那个NES的版本)的变态过关录像之后,长期以来都想自己实现一次踩墙跳,今天无聊当中竟然真的跳出来一个,随即信心大增,试图再跳出来一起,在第一关的第二根管子前面Save了一下,随后就开始不停的Load,跳,Load,跳,却苦于无法重现,于是去网上找密技指南之类的东西,关键字从“超级玛丽兄弟 密技”开始,慢慢找,最后找到了Super Mario Bros Tricks。根据上面的介绍,重新开始,跳了大概100多次,果然跳出来两次。看来这个东西也不是很难,在我的SMYNES模拟器上面大体上就是一个0.1秒左右的时机把握,多练一练准确率应该会提高的。

顺便翻译一下文章当中关于踩墙跳的解释:

Walljump is when you jump towards a wall and somehow Mario’s foot catches the wall and allows to jump again, boosting from the wall. The walljump in the left image is easy to try even on the real console. In the right image (using a custom map), three walljumps are performed.

踩墙跳时当你跳向一堵墙的时候,当Mario的脚触到墙的一瞬间,允许你借助墙的作用再跳一次。左图中的跳法即使在真正的游戏机上面也很容易尝试,而在右图中(用了自定义地图),进行了三次踩墙跳。

Theory: Walljump happens because the game does a floor check (a simple "is position divided by 16 even? Is there a solid block below him?" test) even during a wall-ejection. Wall-ejection is SMB’s mechanism to adjust Mario’s horizontal position properly when his left side and right side have a different inside-wall status. The game ejects Mario towards the opposite of his steering.

理论:踩墙跳之所以能够成功是因为游戏即使在进行碰壁反弹的时候也会执行地板检测(这个检测只是检测”Mario的坐标可以被16整除吗?它下面有东西的支撑么?)。碰壁反弹是超级玛丽当中一种机制,用来在Mario的左侧或右侧具有墙壁的时候能够调整Mario的水平位置,把Mario向它运动的相反方向弹出。

right To perform a walljump, you need two things:
* Some horizontal speed (towards the wall)
* Mario’s feet must hit the wall exactly at a block boundary (every 16 pixels)

要实现踩墙跳,你需要两个条件:
* 水平速度(朝向墙壁)
* Mario的脚必须准确的落在图块边界上(每16个像素处)


It’s possible to perform walljump from any non-lethal solid material (bricks, pipes, etc).


只要这样,理论上可以在任何非致命性的静态物体(例如砖块和水管等)边缘完成踩墙跳。

In SMB3, the trick works exactly the same way as in SMB1, but is harder to perform, because the game is more effective in preventing inside-wall situations.

在超级玛丽III当中,这个技巧和超级玛丽I机制完全一样,但是更难做出来,因为游戏对于判断墙内情况更加有效。

[翻译完毕,图请到原网站看]

其实可以看出,让Mario在接触墙壁的瞬间脚的位置落在16的整数倍处,并在进行地板检测和碰壁检测之间的瞬间按下跳。这个时机还是很小的,但是经过练习应该可以增加准确度的,至少前面的一个条件比较容易达到。

发现我真的很无聊。

标签:

诺顿事件的深层思考

2007年6月4日 没有评论

不想在这个时候再炒这个冷饭,不过觉得还是有些话要说,原因是今天得到的一组数据。

今天下午会议上面听到公司某高层给出的数据,说现在病毒实验室每天能够收到超过2000个的病毒样本,最多的时候能够达到5000个。每天2000个病毒样本,这是个什么概念?如果所有的工作都要人工完成,假设我们有600个病毒分析工程师,每天工作8小时,三班倒制度,每班200个病毒分析师同时工作,那么每个病毒分析师需要在48分钟之内完成一个病毒码的分析验证和测试。本来48分钟出病毒码是只有对于VIP用户才有的待遇,但是现在却成了一种当务之急:这么多的样本逼迫着你去完成这项工作。

为了解决这个问题,根据赛门铁克所说,他们采用了某种自动化的手段,但是这个工具出了点故障,导致了误判。自动化工具也许能够缓解这种问题,但是也会带来更深层次的问题:以每天2000个病毒样本的速度增加,病毒码本身的大小将会以极快的速度增大。开源的clamWin今天的病毒码文件大小已经达到了10M,而加载进入内存之后的大小将达到60MB+,而趋势的病毒码也早就超过了30M。明年这个时候,恐怕已经没有哪台计算机有能力运行反病毒软件了。

这个背后所反映的,其实是这个时代的一个主要矛盾:爆炸性增长的信息量和无法同步增长的计算能力之间的矛盾。计算能力的第一层限制使人的头脑的处理能力的限制,所以才有了很多计算机辅助的方案,比如帮助用户寻找信息(搜索),帮助用户过滤不需要的信息(垃圾信息过滤),直至帮助用户过滤不需要的行为(防病毒)。所有这些东西的发展都是因为信息已经多到了任何人都搞不定的情况了。但是现在又有了更多一层的限制:信息爆炸到了单个计算机的处理能力也逐渐成为了限制——信息的发展速度已经超过了摩尔定律。在这种情况下面,如何存储和处理这些信息业成为了一个新的课题。Google的成功,很重要的一点就是掌握了存储和处理海量的数据的手段。

那么,这种环境下面的安全,我们应该怎么办?传统的扫描模式已经走到了尽头,接下来的,是什么?

标签: